v240222 master
authorKilian <ksaffran@dks.lu>
Thu, 22 Feb 2024 14:04:39 +0000 (15:04 +0100)
committerKilian <ksaffran@dks.lu>
Thu, 22 Feb 2024 14:04:39 +0000 (15:04 +0100)
242 files changed:
.gitattributes [deleted file]
.gitignore
.gitmessage [deleted file]
.vscode/sftp.json
AA-TODO's [new file with mode: 0644]
doc/.gitignore [deleted file]
doc/images/README.md [deleted file]
doc/images/appicon_128.png [deleted file]
doc/images/appicon_16.ico [deleted file]
doc/images/appicon_16.png [deleted file]
doc/images/appicon_32.ico [deleted file]
doc/images/appicon_32.png [deleted file]
doc/images/appicon_48.ico [deleted file]
doc/images/appicon_64.png [deleted file]
doc/images/background_dolibarr.jpg [deleted file]
doc/images/doliadmin.ico [deleted file]
doc/images/dolibarr_256x256_black.png [deleted file]
doc/images/dolibarr_256x256_black.svg [deleted file]
doc/images/dolibarr_256x256_color.png [deleted file]
doc/images/dolibarr_256x256_color.svg [deleted file]
doc/images/dolibarr_256x256_white.jpg [deleted file]
doc/images/dolibarr_256x256_white.png [deleted file]
doc/images/dolibarr_256x256_white.svg [deleted file]
doc/images/dolibarr_512x512_color.png [deleted file]
doc/images/dolibarr_favicon.ico [deleted file]
doc/images/dolibarr_logo.jpg [deleted file]
doc/images/dolibarr_logo.png [deleted file]
doc/images/dolibarr_logo.svg [deleted file]
doc/images/dolibarr_screenshot10_1920x1080.jpg [deleted file]
doc/images/dolibarr_screenshot11_1024x768.jpg [deleted file]
doc/images/dolibarr_screenshot12_1920x1080.jpg [deleted file]
doc/images/dolibarr_screenshot1_1280x800.jpg [deleted file]
doc/images/dolibarr_screenshot1_1920x1080.jpg [deleted file]
doc/images/dolibarr_screenshot2_1280x800.jpg [deleted file]
doc/images/dolibarr_screenshot3_1280x800.png [deleted file]
doc/images/dolibarr_screenshot4_1920x1080.jpg [deleted file]
doc/images/dolibarr_screenshot5_1280x800.jpg [deleted file]
doc/images/dolibarr_screenshot5_1920x1080.jpg [deleted file]
doc/images/dolibarr_screenshot6_1920x1080.jpg [deleted file]
doc/images/dolibarr_screenshot7_1920x1080.jpg [deleted file]
doc/images/dolibarr_screenshot8_1920x1080.jpg [deleted file]
doc/images/dolibarr_screenshot9_1920x1080.jpg [deleted file]
doc/images/dolihelp.ico [deleted file]
doc/images/doliwampoff.ico [deleted file]
doc/images/doliwampon.ico [deleted file]
doc/images/invoice.png [deleted file]
doc/index.html [deleted file]
doc/install/README [deleted file]
doc/install/README-DE [deleted file]
doc/install/README-FR [deleted file]
doc/user/README [deleted file]
doc/user/README-DE [deleted file]
doc/user/README-FR [deleted file]
htdocs/admin/modules.php
htdocs/asterisk/wrapper.php [deleted file]
htdocs/conf/conf.php
htdocs/core/db/mysqli.class.php
htdocs/core/lib/admin.lib.php
htdocs/core/lib/asset.lib.php
htdocs/core/lib/company.lib.php
htdocs/core/lib/contact.lib.php
htdocs/core/lib/contract.lib.php
htdocs/core/lib/fourn.lib.php
htdocs/core/lib/invoice.lib.php
htdocs/core/lib/pdf.lib.php
htdocs/core/lib/product.lib.php
htdocs/core/lib/resource.lib.php
htdocs/core/lib/usergroups.lib.php
htdocs/core/lib/website.lib.php
htdocs/core/menus/standard/eldy.lib.php
htdocs/core/modules/propale/doc/doc_generic_proposal_html.modules.php [moved from htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php with 76% similarity]
htdocs/core/modules/propale/doc/pdf_peitureteufela.modules.php [new file with mode: 0644]
htdocs/custom/emailtracker/class/emails.class.php
htdocs/custom/emailtracker/core/modules/modEmailTracker.class.php
htdocs/custom/emailtracker/tab_invoice_supplier.php
htdocs/debugbar/class/DataCollector/DolConfigCollector.php [deleted file]
htdocs/debugbar/class/DataCollector/DolExceptionsCollector.php [deleted file]
htdocs/debugbar/class/DataCollector/DolLogsCollector.php [deleted file]
htdocs/debugbar/class/DataCollector/DolMemoryCollector.php [deleted file]
htdocs/debugbar/class/DataCollector/DolMessagesCollector.php [deleted file]
htdocs/debugbar/class/DataCollector/DolPhpCollector.php [deleted file]
htdocs/debugbar/class/DataCollector/DolQueryCollector.php [deleted file]
htdocs/debugbar/class/DataCollector/DolRequestDataCollector.php [deleted file]
htdocs/debugbar/class/DataCollector/DolTimeDataCollector.php [deleted file]
htdocs/debugbar/class/DataCollector/DolibarrCollector.php [deleted file]
htdocs/debugbar/class/DebugBar.php [deleted file]
htdocs/debugbar/class/TraceableDB.php [deleted file]
htdocs/debugbar/class/autoloader.php [deleted file]
htdocs/debugbar/js/widgets.js [deleted file]
htdocs/fourn/card.php
htdocs/fourn/class/fournisseur.facture.class.php
htdocs/fourn/facture/card.php
htdocs/fourn/facture/document.php
htdocs/fourn/facture/list.php
htdocs/includes/html2pdf/Segment.php [new file with mode: 0644]
htdocs/includes/html2pdf/SegmentIterator.php [new file with mode: 0644]
htdocs/includes/html2pdf/html2pdf.php [new file with mode: 0644]
htdocs/includes/html2pdf/zip/PclZipProxy.php [new file with mode: 0644]
htdocs/includes/html2pdf/zip/PhpZipProxy.php [new file with mode: 0644]
htdocs/includes/html2pdf/zip/ZipInterface.php [new file with mode: 0644]
htdocs/includes/html2pdf/zip/pclzip/LICENSE [moved from htdocs/modulebuilder/template/COPYING with 84% similarity]
htdocs/includes/html2pdf/zip/pclzip/composer.json [new file with mode: 0644]
htdocs/includes/html2pdf/zip/pclzip/gnu-lgpl.txt [new file with mode: 0644]
htdocs/includes/html2pdf/zip/pclzip/pclzip.lib.php [new file with mode: 0644]
htdocs/includes/html2pdf/zip/pclzip/readme.txt [new file with mode: 0644]
htdocs/mailmanspip/class/mailmanspip.class.php [deleted file]
htdocs/modulebuilder/README.md [deleted file]
htdocs/modulebuilder/admin/setup.php [deleted file]
htdocs/modulebuilder/index.php [deleted file]
htdocs/modulebuilder/template/ChangeLog.md [deleted file]
htdocs/modulebuilder/template/README.md [deleted file]
htdocs/modulebuilder/template/admin/about.php [deleted file]
htdocs/modulebuilder/template/admin/myobject_extrafields.php [deleted file]
htdocs/modulebuilder/template/admin/setup.php [deleted file]
htdocs/modulebuilder/template/ajax/myobject.php [deleted file]
htdocs/modulebuilder/template/build/doxygen/mymodule.doxyfile [deleted file]
htdocs/modulebuilder/template/build/makepack-mymodule.conf [deleted file]
htdocs/modulebuilder/template/class/actions_mymodule.class.php [deleted file]
htdocs/modulebuilder/template/class/api_mymodule.class.php [deleted file]
htdocs/modulebuilder/template/class/myobject.class.php [deleted file]
htdocs/modulebuilder/template/core/boxes/README.md [deleted file]
htdocs/modulebuilder/template/core/boxes/mymodulewidget1.php [deleted file]
htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php [deleted file]
htdocs/modulebuilder/template/core/modules/modMyModule.class.php [deleted file]
htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php [deleted file]
htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php [deleted file]
htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_standard.php [deleted file]
htdocs/modulebuilder/template/core/modules/mymodule/modules_myobject.php [deleted file]
htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php [deleted file]
htdocs/modulebuilder/template/core/triggers/README.md [deleted file]
htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php [deleted file]
htdocs/modulebuilder/template/css/mymodule.css.php [deleted file]
htdocs/modulebuilder/template/doc/Documentation.asciidoc [deleted file]
htdocs/modulebuilder/template/doc/Documentation_full_en.example.asciidoc [deleted file]
htdocs/modulebuilder/template/img/README.md [deleted file]
htdocs/modulebuilder/template/js/mymodule.js.php [deleted file]
htdocs/modulebuilder/template/langs/en_US/mymodule.lang [deleted file]
htdocs/modulebuilder/template/lib/mymodule.lib.php [deleted file]
htdocs/modulebuilder/template/lib/mymodule_myobject.lib.php [deleted file]
htdocs/modulebuilder/template/modulebuilder.txt [deleted file]
htdocs/modulebuilder/template/mymoduleindex.php [deleted file]
htdocs/modulebuilder/template/myobject_agenda.php [deleted file]
htdocs/modulebuilder/template/myobject_card.php [deleted file]
htdocs/modulebuilder/template/myobject_contact.php [deleted file]
htdocs/modulebuilder/template/myobject_document.php [deleted file]
htdocs/modulebuilder/template/myobject_list.php [deleted file]
htdocs/modulebuilder/template/myobject_note.php [deleted file]
htdocs/modulebuilder/template/scripts/mymodule.php [deleted file]
htdocs/modulebuilder/template/sql/data.sql [deleted file]
htdocs/modulebuilder/template/sql/dolibarr_allversions.sql [deleted file]
htdocs/modulebuilder/template/sql/llx_mymodule_myobject.key.sql [deleted file]
htdocs/modulebuilder/template/sql/llx_mymodule_myobject.sql [deleted file]
htdocs/modulebuilder/template/sql/llx_mymodule_myobject_extrafields.key.sql [deleted file]
htdocs/modulebuilder/template/sql/llx_mymodule_myobject_extrafields.sql [deleted file]
htdocs/modulebuilder/template/sql/update_x.x.x-y.y.y.sql [deleted file]
htdocs/modulebuilder/template/test/phpunit/MyModuleFunctionalTest.php [deleted file]
htdocs/modulebuilder/template/test/phpunit/MyObjectTest.php [deleted file]
htdocs/opensurvey/card.php [deleted file]
htdocs/opensurvey/class/opensurveysondage.class.php [deleted file]
htdocs/opensurvey/css/style.css [deleted file]
htdocs/opensurvey/exportcsv.php [deleted file]
htdocs/opensurvey/img/accept-24.png [deleted file]
htdocs/opensurvey/img/accept.png [deleted file]
htdocs/opensurvey/img/add-16.png [deleted file]
htdocs/opensurvey/img/add-24.png [deleted file]
htdocs/opensurvey/img/calendar-32.png [deleted file]
htdocs/opensurvey/img/chart-32.png [deleted file]
htdocs/opensurvey/img/date.png [deleted file]
htdocs/opensurvey/img/fforward.png [deleted file]
htdocs/opensurvey/img/medaille.png [deleted file]
htdocs/opensurvey/img/next.png [deleted file]
htdocs/opensurvey/img/object_opensurvey.png [deleted file]
htdocs/opensurvey/img/opensurvey.png [deleted file]
htdocs/opensurvey/img/previous.png [deleted file]
htdocs/opensurvey/img/rewind.png [deleted file]
htdocs/opensurvey/img/sondage2.png [deleted file]
htdocs/opensurvey/index.php [deleted file]
htdocs/opensurvey/lib/opensurvey.lib.php [deleted file]
htdocs/opensurvey/list.php [deleted file]
htdocs/opensurvey/results.php [deleted file]
htdocs/opensurvey/wizard/choix_autre.php [deleted file]
htdocs/opensurvey/wizard/choix_date.php [deleted file]
htdocs/opensurvey/wizard/create_survey.php [deleted file]
htdocs/opensurvey/wizard/index.php [deleted file]
htdocs/paybox/admin/paybox.php [deleted file]
htdocs/paybox/img/object_paybox.png [deleted file]
htdocs/paybox/lib/paybox.lib.php [deleted file]
htdocs/paypal/admin/paypal.php [deleted file]
htdocs/paypal/img/object_paypal.png [deleted file]
htdocs/paypal/lib/paypal.lib.php [deleted file]
htdocs/paypal/lib/paypalfunctions.lib.php [deleted file]
htdocs/stripe/admin/stripe.php [deleted file]
htdocs/stripe/ajax/ajax.php [deleted file]
htdocs/stripe/charge.php [deleted file]
htdocs/stripe/class/actions_stripe.class.php [deleted file]
htdocs/stripe/class/stripe.class.php [deleted file]
htdocs/stripe/config.php [deleted file]
htdocs/stripe/lib/stripe.lib.php [deleted file]
htdocs/stripe/payout.php [deleted file]
htdocs/stripe/transaction.php [deleted file]
htdocs/zapier/README.md [deleted file]
htdocs/zapier/admin/about.php [deleted file]
htdocs/zapier/admin/setup.php [deleted file]
htdocs/zapier/class/api_zapier.class.php [deleted file]
htdocs/zapier/class/hook.class.php [deleted file]
htdocs/zapier/lib/zapier.lib.php [deleted file]
installer/install_creorga.ps1 [new file with mode: 0644]
installer/installlist.json [new file with mode: 0644]
tmp.php [new file with mode: 0644]
tools/doap/README [deleted file]
tools/doxygen/dolibarr-doxygen-build.pl [deleted file]
tools/doxygen/dolibarr-doxygen-filter.pl [deleted file]
tools/doxygen/dolibarr-doxygen-getversion.pl [deleted file]
tools/doxygen/dolibarr-doxygen.doxyfile [deleted file]
tools/doxygen/doxygen_footer.html [deleted file]
tools/doxygen/doxygen_header.html [deleted file]
tools/examples/zapier/.editorconfig [deleted file]
tools/examples/zapier/.gitignore [deleted file]
tools/examples/zapier/.travis.yml [deleted file]
tools/examples/zapier/README.md [deleted file]
tools/examples/zapier/action.json [deleted file]
tools/examples/zapier/authentication.js [deleted file]
tools/examples/zapier/creates/contact.js [deleted file]
tools/examples/zapier/creates/member.js [deleted file]
tools/examples/zapier/creates/thirdparty.js [deleted file]
tools/examples/zapier/index.js [deleted file]
tools/examples/zapier/package.json [deleted file]
tools/examples/zapier/resources/resources.js [deleted file]
tools/examples/zapier/searches/contact.js [deleted file]
tools/examples/zapier/searches/member.js [deleted file]
tools/examples/zapier/searches/thirdparty.js [deleted file]
tools/examples/zapier/test/index.js [deleted file]
tools/examples/zapier/triggers/action.js [deleted file]
tools/examples/zapier/triggers/contact.js [deleted file]
tools/examples/zapier/triggers/member.js [deleted file]
tools/examples/zapier/triggers/order.js [deleted file]
tools/examples/zapier/triggers/thirdparty.js [deleted file]
tools/examples/zapier/triggers/ticket.js [deleted file]
tools/examples/zapier/triggers/user.js [deleted file]
tools/flatpack/org.flatpak.Dolibarr.json [deleted file]
tools/patch/README [deleted file]
tools/patch/buildpatch.sh [deleted file]

diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644 (file)
index de9ce33..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-# Set default behaviour, in case users don't have core.autocrlf set.
-# More info: https://help.github.com/articles/dealing-with-line-endings
-* text=auto
-
-
-# Explicitly declare text files we want to always be normalized and converted 
-# to native line endings on checkout.
-*.php text eol=lf
-*.pl text eol=lf
-*.sql text eol=lf
-*.htm text eol=lf
-*.html text eol=lf
-*.js text eol=lf
-*.json text eol=lf
-*.css text eol=lf
-*.lang text eol=lf
-*.txt text eol=lf
-*.md text eol=lf
-*.pp text eol=lf
-*.sh text eol=lf
-*.yml text eol=lf
-*.yaml text eol=lf
-*.conf text eol=lf
-
-.bash_aliases text eol=lf
-
-# Denote all files that are truly binary and should not be modified.
-*.bmp binary
-*.frm binary
-*.ico binary
-*.jpeg binary
-*.jpg binary
-*.MYD binary
-*.MYI binary
-*.odf binary
-*.odt binary
-*.png binary
-
-
-# Export ignores to generate clean production tarballs
-/build              export-ignore
-/dev                export-ignore
-/doc                export-ignore
-/test               export-ignore
-.buildpath          export-ignore
-/build.xml          export-ignore
-.codeclimate.yml    export-ignore
-Dockerfile          export-ignore
-.dockerignore       export-ignore
-.editorconfig       export-ignore
-.gitattributes      export-ignore
-.gitignore          export-ignore
-.mailmap            export-ignore
-.scrutinizer.yml    export-ignore
-.settings           export-ignore
-.travis.yml         export-ignore
-.tx                 export-ignore
index d0a99d9..a086757 100644 (file)
@@ -62,4 +62,7 @@ dev/tmp/
 dolibarr-18.0.0
 OLD/
 *.zip
-pgdata/
\ No newline at end of file
+pgdata/
+installer/*.msi
+installer/*.zip
+documentsdev/*
diff --git a/.gitmessage b/.gitmessage
deleted file mode 100644 (file)
index a5a7189..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-
-# ^=[ Subject: One line short summary ]=========^|
-# ~ Subject template: [KEYWORD] [ISSUENUM] DESC ~|
-
-# ^=[ Blank: Follow the Subject with a blank line, do NOT remove ]====^|
-
-# ^=[ Details: Describe what changed and explain why it changed ]=====^|
index e83b408..2883d6a 100644 (file)
@@ -9,6 +9,7 @@
     "host": "dksserver",
     "username": "dks",
     "privateKeyPath": ".vscode/id_rsa",
-    "remotePath": "/home/dks/dolibarr/htdocs/"
+    "remotePath": "/home/dks/dolibarr/htdocs/",
+    "connectTimeout": 40000
     }
 ]
diff --git a/AA-TODO's b/AA-TODO's
new file mode 100644 (file)
index 0000000..0a40a99
--- /dev/null
+++ b/AA-TODO's
@@ -0,0 +1 @@
+MAIN_PDF_FORCE_FONT => Font to us in PDFS => FontName (from System)
\ No newline at end of file
diff --git a/doc/.gitignore b/doc/.gitignore
deleted file mode 100644 (file)
index dccff0d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/dolibarr_*.pdf
diff --git a/doc/images/README.md b/doc/images/README.md
deleted file mode 100644 (file)
index e93c9f9..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# README (English)
---------------------------------
-
-
-* Screen captures and icons are Dolibarr contributions
-
-
-* Most logos were created by Dolibarr developers. You may find sources of them on:
-
-https://github.com/Dolibarr/foundation
-
-
-
-# LICENCE OF IMAGE RESOURCES
---------------------------------
-
-* All image resources (except dolihelp.ico and doliadmin.ico) in this directory are distributed under licence CC BY-SA
-
-List of icons from http://led24.de/iconset/ are:
-- doliadmin.ico
-- dolihelp.ico
-
-This is original README file for the package with this 2 images:
-You can do whatever you want with these icons (use on web or in desktop applications) as long as you don’t pass them off as your own and remove this readme file. A credit statement and a link back to
-http://led24.de/iconset/ or http://led24.de/ would be appreciated.
diff --git a/doc/images/appicon_128.png b/doc/images/appicon_128.png
deleted file mode 100644 (file)
index 4a93909..0000000
Binary files a/doc/images/appicon_128.png and /dev/null differ
diff --git a/doc/images/appicon_16.ico b/doc/images/appicon_16.ico
deleted file mode 100644 (file)
index 22b04f2..0000000
Binary files a/doc/images/appicon_16.ico and /dev/null differ
diff --git a/doc/images/appicon_16.png b/doc/images/appicon_16.png
deleted file mode 100644 (file)
index d5a9cda..0000000
Binary files a/doc/images/appicon_16.png and /dev/null differ
diff --git a/doc/images/appicon_32.ico b/doc/images/appicon_32.ico
deleted file mode 100644 (file)
index b0cba0f..0000000
Binary files a/doc/images/appicon_32.ico and /dev/null differ
diff --git a/doc/images/appicon_32.png b/doc/images/appicon_32.png
deleted file mode 100644 (file)
index 7c7cd15..0000000
Binary files a/doc/images/appicon_32.png and /dev/null differ
diff --git a/doc/images/appicon_48.ico b/doc/images/appicon_48.ico
deleted file mode 100644 (file)
index 5acfa77..0000000
Binary files a/doc/images/appicon_48.ico and /dev/null differ
diff --git a/doc/images/appicon_64.png b/doc/images/appicon_64.png
deleted file mode 100644 (file)
index 90b2e52..0000000
Binary files a/doc/images/appicon_64.png and /dev/null differ
diff --git a/doc/images/background_dolibarr.jpg b/doc/images/background_dolibarr.jpg
deleted file mode 100644 (file)
index ec101a0..0000000
Binary files a/doc/images/background_dolibarr.jpg and /dev/null differ
diff --git a/doc/images/doliadmin.ico b/doc/images/doliadmin.ico
deleted file mode 100644 (file)
index 060a606..0000000
Binary files a/doc/images/doliadmin.ico and /dev/null differ
diff --git a/doc/images/dolibarr_256x256_black.png b/doc/images/dolibarr_256x256_black.png
deleted file mode 100644 (file)
index 1abe4e2..0000000
Binary files a/doc/images/dolibarr_256x256_black.png and /dev/null differ
diff --git a/doc/images/dolibarr_256x256_black.svg b/doc/images/dolibarr_256x256_black.svg
deleted file mode 100644 (file)
index 727387b..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="124"
-   height="124"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.92.3 (2405546, 2018-03-11)"
-   sodipodi:docname="dolibarr_256x256_black.svg"
-   inkscape:export-filename="/home/ldestailleur/git/dolibarr-foundation/logo-cliparts/dolibarr_256x256_black.png"
-   inkscape:export-xdpi="96"
-   inkscape:export-ydpi="96">
-  <defs
-     id="defs4">
-    <linearGradient
-       id="linearGradient3767">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3755">
-      <stop
-         style="stop-color:#16317f;stop-opacity:1;"
-         offset="0"
-         id="stop3757" />
-      <stop
-         style="stop-color:#2b2baa;stop-opacity:0.98581558;"
-         offset="1"
-         id="stop3759" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3767-1"
-       id="linearGradient3773-6"
-       x1="205.42113"
-       y1="289.19193"
-       x2="330.96988"
-       y2="289.19193"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-129.5163,-666.48391)" />
-    <linearGradient
-       id="linearGradient3767-1">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(52.738112,-442.04909)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3837-1"
-       xlink:href="#linearGradient3767-1-3"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3767-1-3">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-9" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-6" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(53.452398,-634.19193)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3877-0"
-       xlink:href="#linearGradient3767-1-3-5"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3767-1-3-5">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-9-6" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-6-8" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(52.738112,-442.04909)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3837-5"
-       xlink:href="#linearGradient3767-1-0"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3767-1-0">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-0" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-3" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(195.59526,-442.76336)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3991-3"
-       xlink:href="#linearGradient3767-1-0-4"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3767-1-0-4">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-0-2" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-3-6" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(197.02383,-635.62051)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient4034-9"
-       xlink:href="#linearGradient3767-1-0-4-1"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3767-1-0-4-1">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-0-2-4" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-3-6-3" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(199.1667,-827.04909)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient4077-9"
-       xlink:href="#linearGradient3767-1-0-4-1-6"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3767-1-0-4-1-6">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-0-2-4-5" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-3-6-3-2" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(339.881,-442.76339)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3064"
-       xlink:href="#linearGradient3767-1-0-4-1-6"
-       inkscape:collect="always" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3767-1-0-4-1-6"
-       id="linearGradient3106"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(339.881,-442.76339)"
-       x1="205.42113"
-       y1="289.19193"
-       x2="330.96988"
-       y2="289.19193" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3767-1-0-4-1-6-6"
-       id="linearGradient3071-5"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(339.881,-442.76339)"
-       x1="205.42113"
-       y1="289.19193"
-       x2="330.96988"
-       y2="289.19193" />
-    <linearGradient
-       id="linearGradient3767-1-0-4-1-6-6">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-0-2-4-5-8" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-3-6-3-2-4" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="matrix(2.0603828,0,0,2.0603828,115.78961,-723.84612)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3113"
-       xlink:href="#linearGradient3767-1-0-4-8"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3767-1-0-4-8">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-0-2-8" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-3-6-4" />
-    </linearGradient>
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4311616"
-     inkscape:cx="-197.01761"
-     inkscape:cy="136.94147"
-     inkscape:document-units="px"
-     inkscape:current-layer="layer1"
-     showgrid="false"
-     inkscape:window-width="1920"
-     inkscape:window-height="1023"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1"
-     units="px"
-     borderlayer="true"
-     inkscape:showpageshadow="false"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     showborder="false"
-     inkscape:pagecheckerboard="true" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Calque 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(0,-1003.026)">
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-weight:normal;font-size:18.96238708px;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.58019912"
-       x="-12.676609"
-       y="1153.9496"
-       id="text3775"
-       transform="scale(1.0245459,0.9760422)"><tspan
-         sodipodi:role="line"
-         id="tspan3777"
-         x="-12.676609"
-         y="1153.9496"
-         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:189.50143433px;line-height:1.25;font-family:'Bauhaus 93';-inkscape-font-specification:'Bauhaus 93,';fill:#000000;fill-opacity:1;stroke-width:1.58019912">D</tspan></text>
-  </g>
-</svg>
diff --git a/doc/images/dolibarr_256x256_color.png b/doc/images/dolibarr_256x256_color.png
deleted file mode 100644 (file)
index b2d567d..0000000
Binary files a/doc/images/dolibarr_256x256_color.png and /dev/null differ
diff --git a/doc/images/dolibarr_256x256_color.svg b/doc/images/dolibarr_256x256_color.svg
deleted file mode 100644 (file)
index 5115a8f..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="128"
-   height="128"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.92.3 (2405546, 2018-03-11)"
-   sodipodi:docname="dolibarr_124x124_color.svg"
-   inkscape:export-filename="/home/ldestailleur/git/dolibarr-foundation/logo-cliparts/dolibarr_256x256_color.png"
-   inkscape:export-xdpi="192"
-   inkscape:export-ydpi="192">
-  <defs
-     id="defs4">
-    <linearGradient
-       id="linearGradient858">
-      <stop
-         id="stop854"
-         offset="0"
-         style="stop-color:#263c5c;stop-opacity:1" />
-      <stop
-         id="stop856"
-         offset="1"
-         style="stop-color:#263c5a;stop-opacity:1" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient858"
-       id="linearGradient3204"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-129.5163,-666.48391)"
-       x1="205.42113"
-       y1="289.19193"
-       x2="330.96988"
-       y2="289.19193" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="5.6"
-     inkscape:cx="68.321429"
-     inkscape:cy="61.400881"
-     inkscape:document-units="px"
-     inkscape:current-layer="g3197"
-     showgrid="false"
-     inkscape:window-width="1920"
-     inkscape:window-height="1023"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     inkscape:showpageshadow="false"
-     showborder="false"
-     inkscape:pagecheckerboard="true" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Calque 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(-315.1676,-72.803581)">
-    <g
-       id="g3197"
-       transform="matrix(1.0301914,0,0,1.0301914,-9.5153501,-6.0625407)">
-      <rect
-         inkscape:export-ydpi="90.544151"
-         inkscape:export-xdpi="90.544151"
-         inkscape:export-filename="/home/ldestail/git/foundation/logo/dolibarr_124x124.png"
-         transform="rotate(90)"
-         y="-439.41635"
-         x="76.554825"
-         height="124.24876"
-         width="124.24876"
-         id="rect3765"
-         style="fill:url(#linearGradient3204);fill-opacity:1;fill-rule:nonzero;stroke:none" />
-      <g
-         aria-label="D"
-         transform="matrix(1.0073139,0,0,0.99273916,-0.13867046,0.34667621)"
-         style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none"
-         id="text3775">
-        <path
-           d="m 361.99432,122.6877 -0.0304,57.43789 h -23.7433 V 99.733777 h 30.97607 c 13.58497,0 24.22263,3.083943 31.91298,9.251833 9.13472,7.37805 13.70208,17.39111 13.70208,30.03918 0,12.10156 -3.90373,21.97799 -11.71118,29.6293 -7.80746,7.6513 -17.85956,11.47695 -30.1563,11.47695 -1.44438,0 -7.08526,-0.0182 -7.08526,-0.0182 V 156.4159 h 3.80613 c 13.85823,0 20.78735,-5.79704 20.78735,-17.39111 0,-10.89139 -6.812,-16.33709 -20.43601,-16.33709 z"
-           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:119.92250824px;line-height:1.25;font-family:'Bauhaus 93';-inkscape-font-specification:'Bauhaus 93,';fill:#ffffff;fill-opacity:1"
-           id="path854"
-           inkscape:connector-curvature="0"
-           sodipodi:nodetypes="ccccscsssccsssc" />
-      </g>
-      <ellipse
-         style="display:inline;fill:#60bbc1;fill-opacity:1;stroke:none;stroke-width:0.62043476;stroke-opacity:1"
-         id="path957"
-         cx="407.14789"
-         cy="108.85997"
-         rx="10.732866"
-         ry="10.693515" />
-    </g>
-  </g>
-</svg>
diff --git a/doc/images/dolibarr_256x256_white.jpg b/doc/images/dolibarr_256x256_white.jpg
deleted file mode 100644 (file)
index e5c4e26..0000000
Binary files a/doc/images/dolibarr_256x256_white.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_256x256_white.png b/doc/images/dolibarr_256x256_white.png
deleted file mode 100644 (file)
index 1f5f745..0000000
Binary files a/doc/images/dolibarr_256x256_white.png and /dev/null differ
diff --git a/doc/images/dolibarr_256x256_white.svg b/doc/images/dolibarr_256x256_white.svg
deleted file mode 100644 (file)
index 79a8c9d..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="128"
-   height="128"
-   id="svg2"
-   version="1.1"
-   inkscape:version="0.92.3 (2405546, 2018-03-11)"
-   sodipodi:docname="dolibarr_256x256_white.svg"
-   inkscape:export-filename="/home/ldestailleur/git/dolibarr-foundation/logo-cliparts/dolibarr_256x256_white.png"
-   inkscape:export-xdpi="192"
-   inkscape:export-ydpi="192">
-  <defs
-     id="defs4">
-    <linearGradient
-       id="linearGradient858">
-      <stop
-         id="stop854"
-         offset="0"
-         style="stop-color:#ffffff;stop-opacity:1" />
-      <stop
-         id="stop856"
-         offset="1"
-         style="stop-color:#ffffff;stop-opacity:1" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3767">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771" />
-    </linearGradient>
-    <linearGradient
-       id="linearGradient3755">
-      <stop
-         style="stop-color:#16317f;stop-opacity:1;"
-         offset="0"
-         id="stop3757" />
-      <stop
-         style="stop-color:#2b2baa;stop-opacity:0.98581558;"
-         offset="1"
-         id="stop3759" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3767"
-       id="linearGradient3773"
-       x1="205.42113"
-       y1="289.19193"
-       x2="330.96988"
-       y2="289.19193"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-129.5163,-666.48391)" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3767-1"
-       id="linearGradient3773-6"
-       x1="205.42113"
-       y1="289.19193"
-       x2="330.96988"
-       y2="289.19193"
-       gradientUnits="userSpaceOnUse"
-       gradientTransform="translate(-129.5163,-666.48391)" />
-    <linearGradient
-       id="linearGradient3767-1">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(52.738112,-442.04909)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3837"
-       xlink:href="#linearGradient3767-1"
-       inkscape:collect="always" />
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(52.738112,-442.04909)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3837-1"
-       xlink:href="#linearGradient3767-1-3"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3767-1-3">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-9" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-6" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(53.452398,-634.19193)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3877"
-       xlink:href="#linearGradient3767-1-3"
-       inkscape:collect="always" />
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(53.452398,-634.19193)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3877-0"
-       xlink:href="#linearGradient3767-1-3-5"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3767-1-3-5">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-9-6" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-6-8" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(52.023817,-824.19192)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3917"
-       xlink:href="#linearGradient3767-1-3-5"
-       inkscape:collect="always" />
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(52.738112,-442.04909)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3837-5"
-       xlink:href="#linearGradient3767-1-0"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3767-1-0">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-0" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-3" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(195.59526,-442.76336)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3991"
-       xlink:href="#linearGradient3767-1-0"
-       inkscape:collect="always" />
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(195.59526,-442.76336)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient3991-3"
-       xlink:href="#linearGradient3767-1-0-4"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3767-1-0-4">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-0-2" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-3-6" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(197.02383,-635.62051)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient4034"
-       xlink:href="#linearGradient3767-1-0-4"
-       inkscape:collect="always" />
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(197.02383,-635.62051)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient4034-9"
-       xlink:href="#linearGradient3767-1-0-4-1"
-       inkscape:collect="always" />
-    <linearGradient
-       id="linearGradient3767-1-0-4-1">
-      <stop
-         style="stop-color:#4479ab;stop-opacity:1;"
-         offset="0"
-         id="stop3769-2-0-2-4" />
-      <stop
-         style="stop-color:#1b4b77;stop-opacity:1;"
-         offset="1"
-         id="stop3771-8-3-6-3" />
-    </linearGradient>
-    <linearGradient
-       y2="289.19193"
-       x2="330.96988"
-       y1="289.19193"
-       x1="205.42113"
-       gradientTransform="translate(199.1667,-827.04909)"
-       gradientUnits="userSpaceOnUse"
-       id="linearGradient4077"
-       xlink:href="#linearGradient3767-1-0-4-1"
-       inkscape:collect="always" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="5.6"
-     inkscape:cx="50.5723"
-     inkscape:cy="70.745335"
-     inkscape:document-units="px"
-     inkscape:current-layer="g3197"
-     showgrid="false"
-     inkscape:window-width="1920"
-     inkscape:window-height="1023"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1"
-     fit-margin-top="0"
-     fit-margin-left="0"
-     fit-margin-right="0"
-     fit-margin-bottom="0" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     inkscape:label="Calque 1"
-     inkscape:groupmode="layer"
-     id="layer1"
-     transform="translate(-315.1676,-72.803581)">
-    <g
-       id="g3197"
-       transform="matrix(1.0301914,0,0,1.0301914,-9.5153501,-6.0625407)">
-      <rect
-         inkscape:export-ydpi="90.544151"
-         inkscape:export-xdpi="90.544151"
-         inkscape:export-filename="/home/ldestail/git/foundation/logo/dolibarr_124x124.png"
-         transform="rotate(90)"
-         y="-439.41635"
-         x="76.554825"
-         height="124.24876"
-         width="124.24876"
-         id="rect3765"
-         style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none" />
-      <g
-         aria-label="D"
-         transform="matrix(1.0073139,0,0,0.99273916,-0.13867046,0.34667621)"
-         style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none"
-         id="text3775">
-        <path
-           d="m 361.99432,122.6877 v 56.9749 h -23.7737 V 99.733777 h 30.97607 q 20.37746,0 31.91298,9.251833 13.70208,11.06707 13.70208,30.03918 0,18.15234 -11.71118,29.6293 -11.71119,11.47695 -30.1563,11.47695 -2.16657,0 -7.08526,-0.23422 V 156.4159 h 3.80613 q 20.78735,0 20.78735,-17.39111 0,-16.33709 -20.43601,-16.33709 z"
-           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:119.92250824px;line-height:1.25;font-family:'Bauhaus 93';-inkscape-font-specification:'Bauhaus 93,';fill:#fbfbfb;fill-opacity:1"
-           id="path854"
-           inkscape:connector-curvature="0" />
-      </g>
-      <ellipse
-         style="display:inline;fill:#a1cccf;fill-opacity:1;stroke:none;stroke-width:0.65291774;stroke-opacity:1"
-         id="path957"
-         cx="412.50858"
-         cy="112.0897"
-         rx="11.512888"
-         ry="11.040191" />
-    </g>
-  </g>
-</svg>
diff --git a/doc/images/dolibarr_512x512_color.png b/doc/images/dolibarr_512x512_color.png
deleted file mode 100644 (file)
index 71c2b0c..0000000
Binary files a/doc/images/dolibarr_512x512_color.png and /dev/null differ
diff --git a/doc/images/dolibarr_favicon.ico b/doc/images/dolibarr_favicon.ico
deleted file mode 100644 (file)
index b0cba0f..0000000
Binary files a/doc/images/dolibarr_favicon.ico and /dev/null differ
diff --git a/doc/images/dolibarr_logo.jpg b/doc/images/dolibarr_logo.jpg
deleted file mode 100644 (file)
index a4a0611..0000000
Binary files a/doc/images/dolibarr_logo.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_logo.png b/doc/images/dolibarr_logo.png
deleted file mode 100644 (file)
index 63bd8ac..0000000
Binary files a/doc/images/dolibarr_logo.png and /dev/null differ
diff --git a/doc/images/dolibarr_logo.svg b/doc/images/dolibarr_logo.svg
deleted file mode 100644 (file)
index 9c9259d..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:xlink="http://www.w3.org/1999/xlink"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="720"
-   height="200"
-   id="svg3450"
-   version="1.1"
-   inkscape:version="0.92.3 (2405546, 2018-03-11)"
-   sodipodi:docname="dolibarr_logo.svg"
-   inkscape:export-filename="/home/ldestailleur/git/dolibarr-foundation/logo-cliparts/dolibarr_logo.png"
-   inkscape:export-xdpi="77.362831"
-   inkscape:export-ydpi="77.362831">
-  <title
-     id="title3072">Logo Dolibarr ERP-CRM</title>
-  <defs
-     id="defs3452">
-    <linearGradient
-       id="linearGradient3734-3-6">
-      <stop
-         style="stop-color:#49496f;stop-opacity:1"
-         offset="0"
-         id="stop3736" />
-      <stop
-         style="stop-color:#45455a;stop-opacity:1"
-         offset="1"
-         id="stop3738" />
-    </linearGradient>
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3734-3-6"
-       id="linearGradient4636"
-       gradientUnits="userSpaceOnUse"
-       x1="75.697441"
-       y1="310.53391"
-       x2="742.98004"
-       y2="310.53391" />
-    <linearGradient
-       inkscape:collect="always"
-       xlink:href="#linearGradient3734-3-6"
-       id="linearGradient899"
-       gradientUnits="userSpaceOnUse"
-       x1="75.697441"
-       y1="310.53391"
-       x2="742.98004"
-       y2="310.53391" />
-  </defs>
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="1.4142136"
-     inkscape:cx="391.6782"
-     inkscape:cy="-50.366015"
-     inkscape:current-layer="g4648"
-     inkscape:document-units="px"
-     showgrid="false"
-     inkscape:window-width="1920"
-     inkscape:window-height="1023"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1"
-     inkscape:showpageshadow="false"
-     showborder="true"
-     borderlayer="false"
-     fit-margin-top="24"
-     fit-margin-left="24"
-     fit-margin-right="0"
-     fit-margin-bottom="0"
-     showguides="true"
-     inkscape:guide-bbox="true"
-     inkscape:measure-start="0,0"
-     inkscape:measure-end="0,0"
-     inkscape:pagecheckerboard="true">
-    <inkscape:grid
-       type="xygrid"
-       id="grid1458" />
-  </sodipodi:namedview>
-  <metadata
-     id="metadata3455">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title>Logo Dolibarr ERP-CRM</dc:title>
-        <cc:license
-           rdf:resource="http://creativecommons.org/licenses/by-nd/4.0/" />
-        <dc:creator>
-          <cc:Agent>
-            <dc:title>Laurent Destailleur</dc:title>
-          </cc:Agent>
-        </dc:creator>
-        <dc:rights>
-          <cc:Agent>
-            <dc:title>Laurent Destailleur</dc:title>
-          </cc:Agent>
-        </dc:rights>
-      </cc:Work>
-      <cc:License
-         rdf:about="http://creativecommons.org/licenses/by-nd/4.0/">
-        <cc:permits
-           rdf:resource="http://creativecommons.org/ns#Reproduction" />
-        <cc:permits
-           rdf:resource="http://creativecommons.org/ns#Distribution" />
-        <cc:requires
-           rdf:resource="http://creativecommons.org/ns#Notice" />
-        <cc:requires
-           rdf:resource="http://creativecommons.org/ns#Attribution" />
-      </cc:License>
-    </rdf:RDF>
-  </metadata>
-  <g
-     id="layer1"
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     style="display:inline"
-     transform="translate(-51.413681,-199.60957)">
-    <g
-       id="g4592">
-      <g
-         style="fill:url(#linearGradient4636);fill-opacity:1"
-         id="g4626">
-        <g
-           style="fill:url(#linearGradient899)"
-           id="g4648">
-          <path
-             sodipodi:nodetypes="cccccscsssccsssc"
-             d="m 112.32913,280.29476 v 98.02589 l -36.631688,-0.40123 v 0.40123 -137.35672 h 47.729468 c 20.93239,0 37.32341,5.28424 49.17307,15.85272 14.07523,12.64204 21.11285,29.7991 21.11285,51.47117 0,20.73563 -6.01506,37.65857 -18.04517,50.76884 -12.03011,13.11027 -27.20637,19.35291 -46.1538,19.35291 -2.22557,0 -6.23968,-0.0713 -11.22982,-0.0888 v -40.23379 l 10.08954,-0.0542 c 21.35314,-0.11469 27.8053,-9.87885 27.8053,-29.74492 0,-18.66206 -10.49627,-27.99309 -31.48881,-27.99309 z"
-             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:194.85823059px;line-height:125%;font-family:'Bauhaus 93';-inkscape-font-specification:'Bauhaus 93';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#263c5c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.7072947;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.18431373"
-             id="path8463"
-             inkscape:connector-curvature="0" />
-          <path
-             d="m 251.18669,274.26322 q 19.12787,0 32.75197,15.35106 13.71432,15.25071 13.71432,36.62179 0,21.67206 -13.89478,36.92279 -13.80455,15.25071 -33.38356,15.25071 -19.57899,0 -33.47377,-15.25071 -13.89479,-15.35105 -13.89479,-36.92279 0,-21.97308 13.89479,-36.9228 13.89478,-15.05005 34.28582,-15.05005 z m -0.90227,37.02313 q -5.41355,0 -9.20303,4.41468 -3.78949,4.31435 -3.78949,10.63537 0,6.22068 3.78949,10.63537 3.87971,4.41468 9.20303,4.41468 5.41356,0 9.20304,-4.41468 3.8797,-4.41469 3.8797,-10.63537 0,-6.32102 -3.78947,-10.63537 -3.78949,-4.41468 -9.29327,-4.41468 z"
-             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:194.85823059px;line-height:125%;font-family:'Bauhaus 93';-inkscape-font-specification:'Bauhaus 93';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#263c5c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.7072947;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.18431373"
-             id="path8465"
-             inkscape:connector-curvature="0" />
-          <path
-             sodipodi:nodetypes="ccccc"
-             d="M 345.47268,241.05287 V 378.40956 H 311.72822 V 241.05287 Z"
-             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:194.85823059px;line-height:125%;font-family:'Bauhaus 93';-inkscape-font-specification:'Bauhaus 93';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#263c5c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.7072947;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.18431373"
-             id="path8467"
-             inkscape:connector-curvature="0" />
-          <path
-             sodipodi:nodetypes="csscscsccscsssccscc"
-             d="m 450.676,239.98458 v 81.97261 c 0,13.31093 4.30076,19.9664 12.90229,19.9664 3.66918,0 6.76693,-1.37123 9.29326,-4.11368 2.58647,-2.80935 3.87971,-6.18725 3.87971,-10.1337 0,-4.08023 -1.20301,-7.49158 -3.60903,-10.23403 -2.40603,-2.80935 -5.3534,-4.21402 -8.84213,-4.21402 -2.46617,0 -8.23123,-0.013 -8.23123,-0.013 l -0.25,-38.08747 c 0,0 6.97747,-0.22701 9.02258,-0.22701 12.69177,0 23.54895,5.08358 32.57153,15.25073 9.08273,10.16714 13.6241,22.40785 13.6241,36.72212 0,14.64872 -5.14562,26.5166 -13.80455,37.02313 -8.57803,10.40836 -22.98621,14.59993 -33.92491,14.51154 -6.73664,-0.0544 -13.32335,-1.10024 -19.75947,-4.37784 -6.37595,-3.27757 -11.63912,-7.69225 -15.78951,-13.24404 -7.21807,-9.63203 -10.8271,-22.10686 -10.8271,-37.42447 v -83.37728 z"
-             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:194.85823059px;line-height:125%;font-family:'Bauhaus 93';-inkscape-font-specification:'Bauhaus 93';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#263c5c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.7072947;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.18431373"
-             id="path8471"
-             inkscape:connector-curvature="0" />
-          <path
-             sodipodi:nodetypes="ccssscscsccscscscscc"
-             d="m 575.66649,342.98354 -0.15625,35.42602 c 0,0 -5.0745,0 -7.36022,0 -13.53387,0 -24.8121,-3.24403 -33.83468,-13.14362 -9.02259,-9.89959 -13.53388,-22.30753 -13.53388,-37.2238 0,-14.51494 4.54137,-26.82254 13.6241,-36.92279 9.14289,-10.10026 20.24066,-15.15039 33.29333,-15.15039 14.55643,0 26.01511,4.74913 34.37604,14.24739 8.42108,9.43136 12.63162,22.34096 12.63162,38.72879 l -0.0625,49.46442 h -33.80696 l 0.125,-46.75541 c 0.0141,-5.28421 -1.17293,-9.49824 -3.5188,-12.64203 -2.28573,-3.14379 -5.38348,-4.71569 -9.29327,-4.71569 -3.54889,0 -6.61657,1.43811 -9.20304,4.31434 -2.58647,2.87623 -3.87971,6.28758 -3.87971,10.23405 0,4.14712 1.17294,7.55846 3.51881,10.23403 2.34587,2.67556 5.32333,4.01334 8.93236,4.01334 2.94737,0 8.14805,-0.10867 8.14805,-0.10867 z"
-             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:194.85823059px;line-height:125%;font-family:'Bauhaus 93';-inkscape-font-specification:'Bauhaus 93';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#263c5c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.7072947;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.18431373"
-             id="path8473"
-             inkscape:connector-curvature="0" />
-          <path
-             sodipodi:nodetypes="ccssccscsc"
-             d="m 683.66305,275.87667 0.004,38.91662 c 0,0 -4.41872,0.10517 -6.34353,0.10517 -6.13535,0 -9.20303,5.21735 -9.20303,15.65204 v 47.85906 h -33.74447 v -55.08308 c 0,-14.44805 3.54888,-25.95298 10.64665,-34.51479 7.09777,-8.62869 16.57148,-12.94304 28.42114,-12.94304 2.64662,0 10.21945,0.008 10.21945,0.008 z"
-             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:194.85823059px;line-height:125%;font-family:'Bauhaus 93';-inkscape-font-specification:'Bauhaus 93';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#263c5c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.7072947;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.18431373"
-             id="path8475"
-             inkscape:connector-curvature="0" />
-          <path
-             sodipodi:nodetypes="ccssccscscc"
-             d="m 742.97999,275.87857 -0.0312,38.94597 c 0,0 -4.51247,0.0739 -6.43728,0.0739 -6.13537,0 -9.20305,5.21735 -9.20305,15.65204 v 47.85906 h -33.74445 v -55.08308 c 0,-14.44805 3.54888,-25.95298 10.64664,-34.51479 7.09777,-8.62869 16.57149,-12.94304 28.42114,-12.94304 2.64663,0 10.34825,0.01 10.34825,0.01 z"
-             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:194.85823059px;line-height:125%;font-family:'Bauhaus 93';-inkscape-font-specification:'Bauhaus 93';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#263c5c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.7072947;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.18431373"
-             id="path8477"
-             inkscape:connector-curvature="0" />
-          <path
-             sodipodi:nodetypes="ccccc"
-             d="m 398.91378,276.40957 v 102 h -33.74446 v -102 z"
-             style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:194.85823059px;line-height:125%;font-family:'Bauhaus 93';-inkscape-font-specification:'Bauhaus 93';text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#263c5c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.47124052;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.18431373"
-             id="path8467-5"
-             inkscape:connector-curvature="0" />
-        </g>
-      </g>
-    </g>
-    <text
-       xml:space="preserve"
-       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:Arial;-inkscape-font-specification:Arial;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#007b8c;fill-opacity:1;fill-rule:nonzero;stroke:none;"
-       x="643.31146"
-       y="229.77211"
-       id="text5484"
-       transform="scale(0.88533213,1.1295196)"><tspan
-         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:42.95219803px;line-height:100%;font-family:Arial;-inkscape-font-specification:Arial;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#007b8c;fill-opacity:1;fill-rule:nonzero;stroke:none;"
-         sodipodi:role="line"
-         id="tspan5486"
-         x="643.31146"
-         y="229.77211">ERP/CRM</tspan></text>
-    <ellipse
-       style="fill:#007b8c;fill-opacity:1;stroke:none;stroke-width:1.02999127;stroke-opacity:1"
-       id="path957"
-       cx="381.94193"
-       cy="247.58162"
-       rx="17.456699"
-       ry="18.119612" />
-  </g>
-</svg>
diff --git a/doc/images/dolibarr_screenshot10_1920x1080.jpg b/doc/images/dolibarr_screenshot10_1920x1080.jpg
deleted file mode 100644 (file)
index 6197475..0000000
Binary files a/doc/images/dolibarr_screenshot10_1920x1080.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot11_1024x768.jpg b/doc/images/dolibarr_screenshot11_1024x768.jpg
deleted file mode 100644 (file)
index 8e8c013..0000000
Binary files a/doc/images/dolibarr_screenshot11_1024x768.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot12_1920x1080.jpg b/doc/images/dolibarr_screenshot12_1920x1080.jpg
deleted file mode 100644 (file)
index c063cca..0000000
Binary files a/doc/images/dolibarr_screenshot12_1920x1080.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot1_1280x800.jpg b/doc/images/dolibarr_screenshot1_1280x800.jpg
deleted file mode 100644 (file)
index ac238d3..0000000
Binary files a/doc/images/dolibarr_screenshot1_1280x800.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot1_1920x1080.jpg b/doc/images/dolibarr_screenshot1_1920x1080.jpg
deleted file mode 100644 (file)
index 19a8090..0000000
Binary files a/doc/images/dolibarr_screenshot1_1920x1080.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot2_1280x800.jpg b/doc/images/dolibarr_screenshot2_1280x800.jpg
deleted file mode 100644 (file)
index 2956a55..0000000
Binary files a/doc/images/dolibarr_screenshot2_1280x800.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot3_1280x800.png b/doc/images/dolibarr_screenshot3_1280x800.png
deleted file mode 100644 (file)
index 00d57fc..0000000
Binary files a/doc/images/dolibarr_screenshot3_1280x800.png and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot4_1920x1080.jpg b/doc/images/dolibarr_screenshot4_1920x1080.jpg
deleted file mode 100644 (file)
index d41dd87..0000000
Binary files a/doc/images/dolibarr_screenshot4_1920x1080.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot5_1280x800.jpg b/doc/images/dolibarr_screenshot5_1280x800.jpg
deleted file mode 100644 (file)
index 6eea0a2..0000000
Binary files a/doc/images/dolibarr_screenshot5_1280x800.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot5_1920x1080.jpg b/doc/images/dolibarr_screenshot5_1920x1080.jpg
deleted file mode 100644 (file)
index 8f14c34..0000000
Binary files a/doc/images/dolibarr_screenshot5_1920x1080.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot6_1920x1080.jpg b/doc/images/dolibarr_screenshot6_1920x1080.jpg
deleted file mode 100644 (file)
index cc2f2e6..0000000
Binary files a/doc/images/dolibarr_screenshot6_1920x1080.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot7_1920x1080.jpg b/doc/images/dolibarr_screenshot7_1920x1080.jpg
deleted file mode 100644 (file)
index fcf4cac..0000000
Binary files a/doc/images/dolibarr_screenshot7_1920x1080.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot8_1920x1080.jpg b/doc/images/dolibarr_screenshot8_1920x1080.jpg
deleted file mode 100644 (file)
index e09a1b3..0000000
Binary files a/doc/images/dolibarr_screenshot8_1920x1080.jpg and /dev/null differ
diff --git a/doc/images/dolibarr_screenshot9_1920x1080.jpg b/doc/images/dolibarr_screenshot9_1920x1080.jpg
deleted file mode 100644 (file)
index a280fe6..0000000
Binary files a/doc/images/dolibarr_screenshot9_1920x1080.jpg and /dev/null differ
diff --git a/doc/images/dolihelp.ico b/doc/images/dolihelp.ico
deleted file mode 100644 (file)
index 82ee717..0000000
Binary files a/doc/images/dolihelp.ico and /dev/null differ
diff --git a/doc/images/doliwampoff.ico b/doc/images/doliwampoff.ico
deleted file mode 100644 (file)
index 2b19b2a..0000000
Binary files a/doc/images/doliwampoff.ico and /dev/null differ
diff --git a/doc/images/doliwampon.ico b/doc/images/doliwampon.ico
deleted file mode 100644 (file)
index 4aa3ba9..0000000
Binary files a/doc/images/doliwampon.ico and /dev/null differ
diff --git a/doc/images/invoice.png b/doc/images/invoice.png
deleted file mode 100644 (file)
index 2200fd1..0000000
Binary files a/doc/images/invoice.png and /dev/null differ
diff --git a/doc/index.html b/doc/index.html
deleted file mode 100644 (file)
index 333f960..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>Dolibarr doc directory</title>
-</head>
-<body>
-
-This directory contains several subdirectories with entries for informations on Dolibarr.<br>
-But if you are looking for other resources (downloads, documentation, addons, ...), you can find this on Internet on web following sites:<br>
-
-<br>
-* <a href="https://www.dolibarr.org">Dolibarr portal (official website)</a><br>
-<br>
-* <a href="https://wiki.dolibarr.org">Dolibarr wiki (documentation)</a><br>
-<br>
-* <a href="https://demo.dolibarr.org">Dolibarr demo (online)</a><br>
-<br>
-* <a href="https://www.dolistore.com">DoliStore (official addons/plugins market place)</a><br>
-
-</body>
-</html>
\ No newline at end of file
diff --git a/doc/install/README b/doc/install/README
deleted file mode 100644 (file)
index 0192ff2..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-README (english)
---------------------------------
-
-
---------------------------------
-Download
---------------------------------
-
-* Dolibarr ERP/CRM can be downloaded at sourceforge:
-    https://sourceforge.net/projects/dolibarr/files
-  or from Dolibarr official web site:
-    https://www.dolibarr.org
-
-* Most external modules are only available on DoliStore:
-    https://www.dolistore.com 
-
-
---------------------------------
-Install
---------------------------------
-
-* For a Quick guide, take a look at README.md file into root directory.
-
-* More complete documentations are also available on line on the Dolibarr Wiki:
-    https://wiki.dolibarr.org
diff --git a/doc/install/README-DE b/doc/install/README-DE
deleted file mode 100644 (file)
index f4cb3c1..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-README (deutsch / german / allemand)
-------------------------------------
-
-
-------------------------------------
-Download / Herunterladen
-------------------------------------
-
-* Dolibarr ERP/CRM kann man Ã¼ber die offizielle Dolibarr Website
-
-    https://www.dolibarr.org/downloads 
-    
-  oder direkt bei Sourceforge
-  
-    https://sourceforge.net/projects/dolibarr/files/
-  
-  herunterladen.
-  
-
-
-
-------------------------------------
-Installation / Hilfe
-------------------------------------
-
-* Für eine kurze Einleitung schau in die README.md Datei im Hauptverzeichnis.
-
-* Umfangreiche Dokumentationen sind im Dolibarr Wiki zu finden:
-    https://wiki.dolibarr.org/index.php/Hauptseite 
-    
-* eine Deutsche Community bietet der Dolibarr e.V. unter 
-    https://www.dolibarr.de/ 
-
-
-
-
-------------------------------------
-Zusatzmodule
-------------------------------------
-
-* Die meisten externen Module/Themen sind Ã¼ber den offiziellen DoliStore verfügbar: 
-
-    https://www.dolistore.com/de/
-    
-
diff --git a/doc/install/README-FR b/doc/install/README-FR
deleted file mode 100644 (file)
index c362316..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-README (french)
---------------------------------
-
-
---------------------------------
-Téléchargement
---------------------------------
-
-* Dolibarr ERP/CRM peut Ãªtre téléchargé sur sourceforge:
-https://sourceforge.net/projects/dolibarr/files
-
-ou sur le site officiel de Dolibarr:
-https://www.dolibarr.org
-
-* La plupart des modules externes ne sont disponibles que sur le DoliStore officiel:
-https://www.dolistore.com
-
-
---------------------------------
-Documentation utilisateur
---------------------------------
-
-* Pour une prise en main et installation rapide, consultez le fichier README-FR.md Ã  la racine.
-
-* Une documentation utilisateur francophone plus consistante est disponible en ligne sur le wiki de Dolibarr Ã  l'adresse:
-    https://wiki.dolibarr.org
diff --git a/doc/user/README b/doc/user/README
deleted file mode 100644 (file)
index ecde765..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-README (english)
---------------------------------
-User guide
---------------------------------
-
-* All Dolibarr guides are available, on line, on the Dolibarr Web site:
-
-https://www.dolibarr.org
diff --git a/doc/user/README-DE b/doc/user/README-DE
deleted file mode 100644 (file)
index 336e7ab..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-README (german)
-LiesMich (deutsch)
-
---------------------------------
-Benutzeranleitung
---------------------------------
-
-Alle Dolibarr-Informationen sind online verfuegbar ueber die Webseiten:
-
-https://www.dolibarr.de (de)   oder   https://www.dolibarr.org   (intl)
-
-
-https://wiki.dolibarr.org/index.php/Hauptseite (de)
diff --git a/doc/user/README-FR b/doc/user/README-FR
deleted file mode 100644 (file)
index f5cb72e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-README (french)
---------------------------------
-Documentation utilisateur
---------------------------------
-
-La documentation utilisateur francophone est disponible en ligne sur le site Web de Dolibarr Ã  l'adresse:
-
-https://www.dolibarr.fr
index fb69ab5..a5b894d 100644 (file)
@@ -531,7 +531,7 @@ if ($mode == 'common' || $mode == 'commonkanban') {
        }
        print '<input type="hidden" name="mode" value="'.$mode.'">';
 
-       print dol_get_fiche_head($head, 'modules', '', -1);
+       //print dol_get_fiche_head($head, 'modules', '', -1);
 
        print $deschelp;
 
@@ -995,7 +995,7 @@ if ($mode == 'common' || $mode == 'commonkanban') {
                print '<br><span class="opacitymedium">'.$langs->trans("NoDeployedModulesFoundWithThisSearchCriteria").'</span><br><br>';
        }
 
-       print dol_get_fiche_end();
+       //print dol_get_fiche_end();
 
        print '<br>';
 
@@ -1006,7 +1006,7 @@ if ($mode == 'common' || $mode == 'commonkanban') {
 }
 
 if ($mode == 'marketplace') {
-       print dol_get_fiche_head($head, $mode, '', -1);
+       //print dol_get_fiche_head($head, $mode, '', -1);
 
        print $deschelp;
 
@@ -1031,7 +1031,7 @@ if ($mode == 'marketplace') {
        // print "</table>\n";
        // print '</div>';
 
-       print dol_get_fiche_end();
+       //print dol_get_fiche_end();
 
        print '<br>';
 
@@ -1041,7 +1041,7 @@ if ($mode == 'marketplace') {
 // Install external module
 
 if ($mode == 'deploy') {
-       print dol_get_fiche_head($head, $mode, '', -1);
+       //print dol_get_fiche_head($head, $mode, '', -1);
 
        print $deschelp;
 
@@ -1219,11 +1219,11 @@ if ($mode == 'deploy') {
                }
        }
 
-       print dol_get_fiche_end();
+       //print dol_get_fiche_end();
 }
 
 if ($mode == 'develop') {
-       print dol_get_fiche_head($head, $mode, '', -1);
+       //print dol_get_fiche_head($head, $mode, '', -1);
 
        print $deschelp;
 
@@ -1262,7 +1262,7 @@ if ($mode == 'develop') {
 
        print "</table>\n";
 
-       print dol_get_fiche_end();
+       //print dol_get_fiche_end();
 }
 
 // End of page
diff --git a/htdocs/asterisk/wrapper.php b/htdocs/asterisk/wrapper.php
deleted file mode 100644 (file)
index 2f5096f..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-<?php
-/* Copyright (C) 2009-2010 Laurent Destailleur  <eldy@users.sourceforge.net>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file       htdocs/asterisk/wrapper.php
- *  \brief      File that is entry point to call an Asterisk server
- *     \remarks        To be used, an Asterisk user must be created by adding this
- *                             in /etc/asterisk/manager.conf
- *                             [dolibarr]
- *                             secret = dolibarr
- *                             deny=0.0.0.0/0.0.0.0
- *                             permit=127.0.0.1/255.255.255.0
- *                             read = system,call,log,verbose,command,agent,user
- *                             write = system,call,log,verbose,command,agent,user
- */
-
-if (!defined('NOREQUIRESOC')) {
-       define('NOREQUIRESOC', '1');
-}
-if (!defined('NOREQUIRETRAN')) {
-       define('NOREQUIRETRAN', '1');
-}
-if (!defined('NOTOKENRENEWAL')) {
-       define('NOTOKENRENEWAL', '1');
-}
-if (!defined('NOREQUIREMENU')) {
-       define('NOREQUIREMENU', '1');
-}
-if (!defined('NOREQUIREHTML')) {
-       define('NOREQUIREHTML', '1');
-}
-if (!defined('NOREQUIREAJAX')) {
-       define('NOREQUIREAJAX', '1');
-}
-
-/**
- * Empty header
- *
- * @ignore
- * @return     void
- */
-function llxHeader()
-{
-       print '<html>'."\n";
-       print '<head>'."\n";
-       print '<title>Asterisk redirection from Dolibarr...</title>'."\n";
-       print '</head>'."\n";
-}
-
-/**
- * Empty footer
- *
- * @ignore
- * @return     void
- */
-function llxFooter()
-{
-       print "\n".'</html>'."\n";
-}
-
-require_once '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-
-
-// Security check
-if (empty($conf->clicktodial->enabled)) {
-       accessforbidden();
-       exit;
-}
-
-
-// Define Asterisk setup
-if (!isset($conf->global->ASTERISK_HOST)) {
-       $conf->global->ASTERISK_HOST = "127.0.0.1";
-}
-if (!isset($conf->global->ASTERISK_TYPE)) {
-       $conf->global->ASTERISK_TYPE = "SIP/";
-}
-if (!isset($conf->global->ASTERISK_INDICATIF)) {
-       $conf->global->ASTERISK_INDICATIF = "0";
-}
-if (!isset($conf->global->ASTERISK_PORT)) {
-       $conf->global->ASTERISK_PORT = 5038;
-}
-if ($conf->global->ASTERISK_INDICATIF == 'NONE') {
-       $conf->global->ASTERISK_INDICATIF = '';
-}
-if (!isset($conf->global->ASTERISK_CONTEXT)) {
-       $conf->global->ASTERISK_CONTEXT = "from-internal";
-}
-if (!isset($conf->global->ASTERISK_WAIT_TIME)) {
-       $conf->global->ASTERISK_WAIT_TIME = "30";
-}
-if (!isset($conf->global->ASTERISK_PRIORITY)) {
-       $conf->global->ASTERISK_PRIORITY = "1";
-}
-if (!isset($conf->global->ASTERISK_MAX_RETRY)) {
-       $conf->global->ASTERISK_MAX_RETRY = "2";
-}
-
-
-$login = GETPOST('login', 'alphanohtml');
-$password = GETPOST('password', 'none');
-$caller = GETPOST('caller', 'alphanohtml');
-$called = GETPOST('called', 'alphanohtml');
-
-// IP address of Asterisk server
-$strHost = $conf->global->ASTERISK_HOST;
-// Spécifiez le type d'extension par laquelle vous poste est connecte.
-// ex: SIP/, IAX2/, ZAP/, etc
-$channel = $conf->global->ASTERISK_TYPE;
-// Indicatif de la ligne sortante
-$prefix = $conf->global->ASTERISK_INDICATIF;
-// Port
-$port = $conf->global->ASTERISK_PORT;
-// Context ( generalement from-internal )
-$strContext = $conf->global->ASTERISK_CONTEXT;
-// Delai d'attente avant de raccrocher
-$strWaitTime = $conf->global->ASTERISK_WAIT_TIME;
-// Priority
-$strPriority = $conf->global->ASTERISK_PRIORITY;
-// Nomber of try
-$strMaxRetry = $conf->global->ASTERISK_MAX_RETRY;
-
-
-/*
- * View
- */
-
-llxHeader();
-
-$sql = "SELECT s.nom as name FROM ".MAIN_DB_PREFIX."societe as s";
-$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as sp ON sp.fk_soc = s.rowid";
-$sql .= " WHERE s.entity IN (".getEntity('societe').")";
-$sql .= " AND (s.phone='".$db->escape($called)."'";
-$sql .= " OR sp.phone='".$db->escape($called)."'";
-$sql .= " OR sp.phone_perso='".$db->escape($called)."'";
-$sql .= " OR sp.phone_mobile='".$db->escape($called)."')";
-$sql .= $db->plimit(1);
-
-dol_syslog('click to dial search information with phone '.$called, LOG_DEBUG);
-$resql = $db->query($sql);
-if ($resql) {
-       $obj = $db->fetch_object($resql);
-       if ($obj) {
-               $found = $obj->name;
-       } else {
-               $found = 'Not found';
-       }
-       $db->free($resql);
-} else {
-       dol_print_error($db, 'Error');
-       $found = 'Error';
-}
-
-$number = strtolower($called);
-$pos = strpos($number, "local");
-if (!empty($number)) {
-       if ($pos === false) {
-               $errno = 0;
-               $errstr = 0;
-               $strCallerId = "Dolibarr caller $found <".strtolower($number).">";
-               $oSocket = @fsockopen($strHost, $port, $errno, $errstr, 10);
-               if (!$oSocket) {
-                       print '<body>'."\n";
-                       $txt = "Failed to execute fsockopen($strHost, $port, \$errno, \$errstr, 10)<br>\n";
-                       print $txt;
-                       dol_syslog($txt, LOG_ERR);
-                       $txt = $errstr." (".$errno.")<br>\n";
-                       print $txt;
-                       dol_syslog($txt, LOG_ERR);
-                       print '</body>'."\n";
-               } else {
-                       $txt = "Call Asterisk dialer for caller: ".$caller.", called: ".$called." clicktodiallogin: ".$login;
-                       dol_syslog($txt);
-                       print '<body onload="javascript:history.go(-1);">'."\n";
-                       print '<!-- '.$txt.' -->';
-                       fputs($oSocket, "Action: login\r\n");
-                       fputs($oSocket, "Events: off\r\n");
-                       fputs($oSocket, "Username: $login\r\n");
-                       fputs($oSocket, "Secret: $password\r\n\r\n");
-                       fputs($oSocket, "Action: originate\r\n");
-                       fputs($oSocket, "Channel: ".$channel.$caller."\r\n");
-                       fputs($oSocket, "WaitTime: $strWaitTime\r\n");
-                       fputs($oSocket, "CallerId: $strCallerId\r\n");
-                       fputs($oSocket, "Exten: ".$prefix.$number."\r\n");
-                       fputs($oSocket, "Context: $strContext\r\n");
-                       fputs($oSocket, "Priority: $strPriority\r\n\r\n");
-                       fputs($oSocket, "Action: Logoff\r\n\r\n");
-                       sleep(2);
-                       fclose($oSocket);
-                       print '</body>'."\n";
-               }
-       }
-} else {
-       print 'Bad parameters in URL. Must be '.dol_escape_htmltag($_SERVER['PHP_SELF']).'?caller=99999&called=99999&login=xxxxx&password=xxxxx';
-}
-
-// End of page
-llxFooter();
-$db->close();
index 407fcc3..f7d5577 100644 (file)
@@ -5,11 +5,11 @@
 // Take a look at conf.php.example file for an example of conf.php file
 // and explanations for all possibles parameters.
 //
-$dolibarr_main_url_root='http://localhost/creorga';
+$dolibarr_main_url_root='http://dks-laptop/creorga';
 $dolibarr_main_document_root='D:/dksapps/htdocs/creorga';
 $dolibarr_main_url_root_alt='/custom';
 $dolibarr_main_document_root_alt='D:/dksapps/htdocs/creorga/custom';
-$dolibarr_main_data_root='Z:/documents';
+$dolibarr_main_data_root='D:/Workspace/dolibarr/documentsdev';
 $dolibarr_main_db_host='dksserver';
 $dolibarr_main_db_port='3306';
 $dolibarr_main_db_name='dolibarr_db';
@@ -21,7 +21,10 @@ $dolibarr_main_db_character_set='utf8';
 $dolibarr_main_db_collation='utf8_unicode_ci';
 // Authentication settings
 //$dolibarr_main_authentication='dolibarr';
-$dolibarr_main_authentication='mc';
+//$dolibarr_main_authentication='mc';
+$dolibarr_main_authentication='forceuser';
+$dolibarr_auto_user='ksaffran';
+
 //$dolibarr_main_demo='autologin,autopass';
 // Security settings
 $dolibarr_main_prod='0';
@@ -47,3 +50,4 @@ $dolibarr_mailing_limit_sendbycli='0';
 //$dolibarr_font_DOL_DEFAULT_TTF='';
 //$dolibarr_font_DOL_DEFAULT_TTF_BOLD='';
 $dolibarr_main_distrib='standard';
+$php_session_save_handler='db';
\ No newline at end of file
index 0eef42b..5338503 100644 (file)
@@ -115,18 +115,18 @@ class DoliDBMysqli extends DoliDB
                                        $clientmustbe = 'utf8';
                                }
 
-                               if ($this->db->character_set_name() != $clientmustbe) {
-                                       $this->db->set_charset($clientmustbe); // This set charset, but with a bad collation
-
-                                       $collation = $conf->db->dolibarr_main_db_collation;
-                                       if (preg_match('/latin1/', $collation)) {
-                                               $collation = 'utf8_unicode_ci';
-                                       }
-
-                                       if (!preg_match('/general/', $collation)) {
-                                               $this->db->query("SET collation_connection = ".$collation);
-                                       }
-                               }
+                               // if ($this->db->character_set_name() != $clientmustbe) {
+                               //      $this->db->set_charset($clientmustbe); // This set charset, but with a bad collation
+
+                               //      $collation = $conf->db->dolibarr_main_db_collation;
+                               //      if (preg_match('/latin1/', $collation)) {
+                               //              $collation = 'utf8_unicode_ci';
+                               //      }
+
+                               //      if (!preg_match('/general/', $collation)) {
+                               //              $this->db->query("SET collation_connection = ".$collation);
+                               //      }
+                               // }
                        } else {
                                $this->database_selected = false;
                                $this->database_name = '';
index ae98d46..5ead30f 100644 (file)
@@ -765,12 +765,13 @@ function ihm_prepare_head()
        $head[$h][1] = $langs->trans("Dashboard");
        $head[$h][2] = 'dashboard';
        $h++;
-
-       $head[$h][0] = DOL_URL_ROOT."/admin/ihm.php?mode=login";
-       $head[$h][1] = $langs->trans("LoginPage");
-       $head[$h][2] = 'login';
-       $h++;
-
+       
+       //DKS: Disabled because auth method: forceuser
+               // $head[$h][0] = DOL_URL_ROOT."/admin/ihm.php?mode=login";
+               // $head[$h][1] = $langs->trans("LoginPage");
+               // $head[$h][2] = 'login';
+               // $h++;
+       //DKS END : Disabled because auth method: forceuser
        complete_head_from_modules($conf, $langs, null, $head, $h, 'ihm_admin');
 
        complete_head_from_modules($conf, $langs, null, $head, $h, 'ihm_admin', 'remove');
index be31f99..2ce62b4 100644 (file)
@@ -154,10 +154,10 @@ function assetPrepareHead(Asset $object)
        $head[$h][2] = 'document';
        $h++;
 
-       $head[$h][0] = DOL_URL_ROOT . '/asset/agenda.php?id=' . $object->id;
-       $head[$h][1] = $langs->trans("Events");
-       $head[$h][2] = 'agenda';
-       $h++;
+       // $head[$h][0] = DOL_URL_ROOT . '/asset/agenda.php?id=' . $object->id;
+       // $head[$h][1] = $langs->trans("Events");
+       // $head[$h][2] = 'agenda';
+       // $h++;
 
        // Show more tabs from modules
        // Entries must be declared in modules descriptor with line
index 3285988..0b9985d 100644 (file)
@@ -373,38 +373,38 @@ function societe_prepare_head(Societe $object)
                $h++;
        }
 
-       $head[$h][0] = DOL_URL_ROOT.'/societe/agenda.php?socid='.$object->id;
-       $head[$h][1] = $langs->trans("Events");
-       if (isModEnabled('agenda')&& (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
-               $nbEvent = 0;
-               // Enable caching of thirdparty count actioncomm
-               require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
-               $cachekey = 'count_events_thirdparty_'.$object->id;
-               $dataretrieved = dol_getcache($cachekey);
-               if (!is_null($dataretrieved)) {
-                       $nbEvent = $dataretrieved;
-               } else {
-                       $sql = "SELECT COUNT(id) as nb";
-                       $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm";
-                       $sql .= " WHERE fk_soc = ".((int) $object->id);
-                       $resql = $db->query($sql);
-                       if ($resql) {
-                               $obj = $db->fetch_object($resql);
-                               $nbEvent = $obj->nb;
-                       } else {
-                               dol_syslog('Failed to count actioncomm '.$db->lasterror(), LOG_ERR);
-                       }
-                       dol_setcache($cachekey, $nbEvent, 120);         // If setting cache fails, this is not a problem, so we do not test result.
-               }
-
-               $head[$h][1] .= '/';
-               $head[$h][1] .= $langs->trans("Agenda");
-               if ($nbEvent > 0) {
-                       $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbEvent.'</span>';
-               }
-       }
-       $head[$h][2] = 'agenda';
-       $h++;
+       // $head[$h][0] = DOL_URL_ROOT.'/societe/agenda.php?socid='.$object->id;
+       // $head[$h][1] = $langs->trans("Events");
+       // if (isModEnabled('agenda')&& (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
+       //      $nbEvent = 0;
+       //      // Enable caching of thirdparty count actioncomm
+       //      require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
+       //      $cachekey = 'count_events_thirdparty_'.$object->id;
+       //      $dataretrieved = dol_getcache($cachekey);
+       //      if (!is_null($dataretrieved)) {
+       //              $nbEvent = $dataretrieved;
+       //      } else {
+       //              $sql = "SELECT COUNT(id) as nb";
+       //              $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm";
+       //              $sql .= " WHERE fk_soc = ".((int) $object->id);
+       //              $resql = $db->query($sql);
+       //              if ($resql) {
+       //                      $obj = $db->fetch_object($resql);
+       //                      $nbEvent = $obj->nb;
+       //              } else {
+       //                      dol_syslog('Failed to count actioncomm '.$db->lasterror(), LOG_ERR);
+       //              }
+       //              dol_setcache($cachekey, $nbEvent, 120);         // If setting cache fails, this is not a problem, so we do not test result.
+       //      }
+
+       //      $head[$h][1] .= '/';
+       //      $head[$h][1] .= $langs->trans("Agenda");
+       //      if ($nbEvent > 0) {
+       //              $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbEvent.'</span>';
+       //      }
+       // }
+       // $head[$h][2] = 'agenda';
+       // $h++;
 
        // Show more tabs from modules
        // Entries must be declared in modules descriptor with line
index 2dbf97d..766f3af 100644 (file)
@@ -132,14 +132,14 @@ function contact_prepare_head(Contact $object)
        $tab++;
 
        // Agenda / Events
-       $head[$tab][0] = DOL_URL_ROOT.'/contact/agenda.php?id='.$object->id;
-       $head[$tab][1] = $langs->trans("Events");
-       if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
-               $head[$tab][1] .= '/';
-               $head[$tab][1] .= $langs->trans("Agenda");
-       }
-       $head[$tab][2] = 'agenda';
-       $tab++;
+       // $head[$tab][0] = DOL_URL_ROOT.'/contact/agenda.php?id='.$object->id;
+       // $head[$tab][1] = $langs->trans("Events");
+       // if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
+       //      $head[$tab][1] .= '/';
+       //      $head[$tab][1] .= $langs->trans("Agenda");
+       // }
+       // $head[$tab][2] = 'agenda';
+       // $tab++;
 
        // Log
        /*
index 6404075..de1448c 100644 (file)
@@ -87,14 +87,14 @@ function contract_prepare_head(Contrat $object)
        $head[$h][2] = 'documents';
        $h++;
 
-       $head[$h][0] = DOL_URL_ROOT.'/contrat/agenda.php?id='.$object->id;
-       $head[$h][1] = $langs->trans("Events");
-       if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
-               $head[$h][1] .= '/';
-               $head[$h][1] .= $langs->trans("Agenda");
-       }
-       $head[$h][2] = 'agenda';
-       $h++;
+       // $head[$h][0] = DOL_URL_ROOT.'/contrat/agenda.php?id='.$object->id;
+       // $head[$h][1] = $langs->trans("Events");
+       // if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
+       //      $head[$h][1] .= '/';
+       //      $head[$h][1] .= $langs->trans("Agenda");
+       // }
+       // $head[$h][2] = 'agenda';
+       // $h++;
 
        complete_head_from_modules($conf, $langs, $object, $head, $h, 'contract', 'add', 'external');
 
index c658916..650aa26 100644 (file)
@@ -116,10 +116,10 @@ function facturefourn_prepare_head($object)
        $head[$h][2] = 'documents';
        $h++;
 
-       $head[$h][0] = DOL_URL_ROOT.'/fourn/facture/info.php?facid='.$object->id;
-       $head[$h][1] = $langs->trans('Info');
-       $head[$h][2] = 'info';
-       $h++;
+       // $head[$h][0] = DOL_URL_ROOT.'/fourn/facture/info.php?facid='.$object->id;
+       // $head[$h][1] = $langs->trans('Info');
+       // $head[$h][2] = 'info';
+       // $h++;
 
        complete_head_from_modules($conf, $langs, $object, $head, $h, 'supplier_invoice', 'add', 'external');
 
index cf02832..efc8d17 100644 (file)
@@ -118,10 +118,10 @@ function facture_prepare_head($object)
        $head[$h][2] = 'documents';
        $h++;
 
-       $head[$h][0] = DOL_URL_ROOT.'/compta/facture/info.php?facid='.$object->id;
-       $head[$h][1] = $langs->trans('Info');
-       $head[$h][2] = 'info';
-       $h++;
+       // $head[$h][0] = DOL_URL_ROOT.'/compta/facture/info.php?facid='.$object->id;
+       // $head[$h][1] = $langs->trans('Info');
+       // $head[$h][2] = 'info';
+       // $h++;
 
        complete_head_from_modules($conf, $langs, $object, $head, $h, 'invoice', 'add', 'external');
 
index 49e0672..511c57c 100644 (file)
@@ -139,7 +139,7 @@ function pdf_getInstance($format = '', $metric = 'mm', $pagetype = 'P')
                define('PDF_CREATOR', 'TCPDF');
                define('PDF_AUTHOR', 'TCPDF');
                define('PDF_HEADER_TITLE', 'TCPDF Example');
-               define('PDF_HEADER_STRING', "by Dolibarr ERP CRM");
+               define('PDF_HEADER_STRING', "by Creorga ");
                define('PDF_UNIT', 'mm');
                define('PDF_MARGIN_HEADER', 5);
                define('PDF_MARGIN_FOOTER', 10);
index 4b0b487..cf89752 100644 (file)
@@ -216,15 +216,15 @@ function product_prepare_head($object)
        $head[$h][2] = 'documents';
        $h++;
 
-       // Log
-       $head[$h][0] = DOL_URL_ROOT.'/product/agenda.php?id='.$object->id;
-       $head[$h][1] = $langs->trans("Events");
-       if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
-               $head[$h][1] .= '/';
-               $head[$h][1] .= $langs->trans("Agenda");
-       }
-       $head[$h][2] = 'agenda';
-       $h++;
+       // // Log
+       // $head[$h][0] = DOL_URL_ROOT.'/product/agenda.php?id='.$object->id;
+       // $head[$h][1] = $langs->trans("Events");
+       // if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
+       //      $head[$h][1] .= '/';
+       //      $head[$h][1] .= $langs->trans("Agenda");
+       // }
+       // $head[$h][2] = 'agenda';
+       // $h++;
 
        complete_head_from_modules($conf, $langs, $object, $head, $h, 'product', 'add', 'external');
 
index ebfbaf2..9b69cf6 100644 (file)
@@ -85,14 +85,14 @@ function resource_prepare_head($object)
        $head[$h][2] = 'documents';
        $h++;
 
-       $head[$h][0] = DOL_URL_ROOT.'/resource/agenda.php?id='.$object->id;
-       $head[$h][1] = $langs->trans("Events");
-       if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
-               $head[$h][1] .= '/';
-               $head[$h][1] .= $langs->trans("Agenda");
-       }
-       $head[$h][2] = 'agenda';
-       $h++;
+       // $head[$h][0] = DOL_URL_ROOT.'/resource/agenda.php?id='.$object->id;
+       // $head[$h][1] = $langs->trans("Events");
+       // if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
+       //      $head[$h][1] .= '/';
+       //      $head[$h][1] .= $langs->trans("Agenda");
+       // }
+       // $head[$h][2] = 'agenda';
+       // $h++;
 
        /*$head[$h][0] = DOL_URL_ROOT.'/resource/info.php?id='.$object->id;
        $head[$h][1] = $langs->trans('Info');
index 64747c1..f0506f8 100644 (file)
@@ -379,70 +379,70 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false)
                print $form->textwithpicto($langs->trans("DefaultSkin"), $langs->trans("ThemeDir").' : '.$dirthemestring);
                print '</th>';
                print '<th class="right">';
-               $url = 'https://www.dolistore.com/9-skins';
-               print '<a href="'.$url.'" target="_blank" rel="noopener noreferrer external">';
-               print $langs->trans('DownloadMoreSkins');
-               print img_picto('', 'globe', 'class="paddingleft"');
-               print '</a>';
+               // $url = 'https://www.dolistore.com/9-skins';
+               // print '<a href="'.$url.'" target="_blank" rel="noopener noreferrer external">';
+               // print $langs->trans('DownloadMoreSkins');
+               // print img_picto('', 'globe', 'class="paddingleft"');
+               // print '</a>';
                print '</th></tr>';
        }
 
        print '<tr><td colspan="'.$colspan.'" class="center">';
 
-       if (!empty($conf->global->MAIN_FORCETHEME)) {
-               $langs->load("errors");
-               print $langs->trans("WarningThemeForcedTo", $conf->global->MAIN_FORCETHEME);
-       }
+       // if (!empty($conf->global->MAIN_FORCETHEME)) {
+       //      $langs->load("errors");
+       //      print $langs->trans("WarningThemeForcedTo", $conf->global->MAIN_FORCETHEME);
+       // }
 
        print '<table class="nobordernopadding" width="100%"><tr><td><div class="center">';
 
        $i = 0;
-       foreach ($dirthemes as $dir) {
-               //print $dirroot.$dir;exit;
-               $dirtheme = dol_buildpath($dir, 0); // This include loop on $conf->file->dol_document_root
-               $urltheme = dol_buildpath($dir, 1);
-
-               if (is_dir($dirtheme)) {
-                       $handle = opendir($dirtheme);
-                       if (is_resource($handle)) {
-                               while (($subdir = readdir($handle)) !== false) {
-                                       if (is_dir($dirtheme."/".$subdir) && substr($subdir, 0, 1) <> '.'
-                                                       && substr($subdir, 0, 3) <> 'CVS' && !preg_match('/common|phones/i', $subdir)) {
-                                               // Disable not stable themes (dir ends with _exp or _dev)
-                                               if ($conf->global->MAIN_FEATURES_LEVEL < 2 && preg_match('/_dev$/i', $subdir)) {
-                                                       continue;
-                                               }
-                                               if ($conf->global->MAIN_FEATURES_LEVEL < 1 && preg_match('/_exp$/i', $subdir)) {
-                                                       continue;
-                                               }
-
-                                               print '<div class="inline-block" style="margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;">';
-                                               $file = $dirtheme."/".$subdir."/thumb.png";
-                                               $url = $urltheme."/".$subdir."/thumb.png";
-                                               if (!file_exists($file)) {
-                                                       $url = DOL_URL_ROOT.'/public/theme/common/nophoto.png';
-                                               }
-                                               print '<a href="'.$_SERVER["PHP_SELF"].($edit ? '?action=edit&token='.newToken().'&mode=template&theme=' : '?theme=').$subdir.(GETPOST('optioncss', 'alpha', 1) ? '&optioncss='.GETPOST('optioncss', 'alpha', 1) : '').($fuser ? '&id='.$fuser->id : '').'" style="font-weight: normal;" alt="'.$langs->trans("Preview").'">';
-                                               if ($subdir == $conf->global->MAIN_THEME) {
-                                                       $title = $langs->trans("ThemeCurrentlyActive");
-                                               } else {
-                                                       $title = $langs->trans("ShowPreview");
-                                               }
-                                               print '<img class="img-skinthumb shadow" src="'.$url.'" alt="'.dol_escape_htmltag($title).'" title="'.dol_escape_htmltag($title).'" style="border: none; margin-bottom: 5px;">';
-                                               print '</a><br>';
-                                               if ($subdir == $selected_theme) {
-                                                       print '<input '.($edit ? '' : 'disabled').' type="radio" class="themethumbs" style="border: 0px;" id="main_theme'.$subdir.'" checked name="main_theme" value="'.$subdir.'"><label for="main_theme'.$subdir.'"> <b>'.$subdir.'</b></label>';
-                                               } else {
-                                                       print '<input '.($edit ? '' : 'disabled').' type="radio" class="themethumbs" style="border: 0px;" id="main_theme'.$subdir.'" name="main_theme" value="'.$subdir.'"><label for="main_theme'.$subdir.'"> '.$subdir.'</label>';
-                                               }
-                                               print '</div>';
-
-                                               $i++;
-                                       }
-                               }
-                       }
-               }
-       }
+       // foreach ($dirthemes as $dir) {
+       //      //print $dirroot.$dir;exit;
+       //      $dirtheme = dol_buildpath($dir, 0); // This include loop on $conf->file->dol_document_root
+       //      $urltheme = dol_buildpath($dir, 1);
+
+       //      if (is_dir($dirtheme)) {
+       //              $handle = opendir($dirtheme);
+       //              if (is_resource($handle)) {
+       //                      while (($subdir = readdir($handle)) !== false) {
+       //                              if (is_dir($dirtheme."/".$subdir) && substr($subdir, 0, 1) <> '.'
+       //                                              && substr($subdir, 0, 3) <> 'CVS' && !preg_match('/common|phones/i', $subdir)) {
+       //                                      // Disable not stable themes (dir ends with _exp or _dev)
+       //                                      if ($conf->global->MAIN_FEATURES_LEVEL < 2 && preg_match('/_dev$/i', $subdir)) {
+       //                                              continue;
+       //                                      }
+       //                                      if ($conf->global->MAIN_FEATURES_LEVEL < 1 && preg_match('/_exp$/i', $subdir)) {
+       //                                              continue;
+       //                                      }
+
+       //                                      print '<div class="inline-block" style="margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;">';
+       //                                      $file = $dirtheme."/".$subdir."/thumb.png";
+       //                                      $url = $urltheme."/".$subdir."/thumb.png";
+       //                                      if (!file_exists($file)) {
+       //                                              $url = DOL_URL_ROOT.'/public/theme/common/nophoto.png';
+       //                                      }
+       //                                      print '<a href="'.$_SERVER["PHP_SELF"].($edit ? '?action=edit&token='.newToken().'&mode=template&theme=' : '?theme=').$subdir.(GETPOST('optioncss', 'alpha', 1) ? '&optioncss='.GETPOST('optioncss', 'alpha', 1) : '').($fuser ? '&id='.$fuser->id : '').'" style="font-weight: normal;" alt="'.$langs->trans("Preview").'">';
+       //                                      if ($subdir == $conf->global->MAIN_THEME) {
+       //                                              $title = $langs->trans("ThemeCurrentlyActive");
+       //                                      } else {
+       //                                              $title = $langs->trans("ShowPreview");
+       //                                      }
+       //                                      print '<img class="img-skinthumb shadow" src="'.$url.'" alt="'.dol_escape_htmltag($title).'" title="'.dol_escape_htmltag($title).'" style="border: none; margin-bottom: 5px;">';
+       //                                      print '</a><br>';
+       //                                      if ($subdir == $selected_theme) {
+       //                                              print '<input '.($edit ? '' : 'disabled').' type="radio" class="themethumbs" style="border: 0px;" id="main_theme'.$subdir.'" checked name="main_theme" value="'.$subdir.'"><label for="main_theme'.$subdir.'"> <b>'.$subdir.'</b></label>';
+       //                                      } else {
+       //                                              print '<input '.($edit ? '' : 'disabled').' type="radio" class="themethumbs" style="border: 0px;" id="main_theme'.$subdir.'" name="main_theme" value="'.$subdir.'"><label for="main_theme'.$subdir.'"> '.$subdir.'</label>';
+       //                                      }
+       //                                      print '</div>';
+
+       //                                      $i++;
+       //                              }
+       //                      }
+       //              }
+       //      }
+       // }
 
        print '</div></td></tr></table>';
 
index 1624542..1ccdb4b 100644 (file)
@@ -805,65 +805,65 @@ function getSocialNetworkHeaderCards($params = null)
 
        $out = '';
 
-       if ($website->virtualhost) {
-               $pageurl = $websitepage->pageurl;
-               $title = $websitepage->title;
-               $image = $websitepage->image;
-               $companyname = $mysoc->name;
-               $description = $websitepage->description;
-
-               $pageurl = str_replace('__WEBSITE_KEY__', $website->ref, $pageurl);
-               $title = str_replace('__WEBSITE_KEY__', $website->ref, $title);
-               $image = '/medias'.(preg_match('/^\//', $image) ? '' : '/').str_replace('__WEBSITE_KEY__', $website->ref, $image);
-               $companyname = str_replace('__WEBSITE_KEY__', $website->ref, $companyname);
-               $description = str_replace('__WEBSITE_KEY__', $website->ref, $description);
-
-               $shortlangcode = '';
-               if ($websitepage->lang) {
-                       $shortlangcode = substr($websitepage->lang, 0, 2); // en_US or en-US -> en
-               }
-               if (empty($shortlangcode)) {
-                       $shortlangcode = substr($website->lang, 0, 2); // en_US or en-US -> en
-               }
-
-               $fullurl = $website->virtualhost.'/'.$websitepage->pageurl.'.php';
-               $canonicalurl = $website->virtualhost.(($websitepage->id == $website->fk_default_home) ? '/' : (($shortlangcode != substr($website->lang, 0, 2) ? '/'.$shortlangcode : '').'/'.$websitepage->pageurl.'.php'));
-               $hashtags = trim(join(' #', array_map('trim', explode(',', $websitepage->keywords))));
-
-               // Open Graph
-               $out .= '<meta name="og:type" content="website">'."\n"; // TODO If blogpost, use type article
-               $out .= '<meta name="og:title" content="'.$websitepage->title.'">'."\n";
-               if ($websitepage->image) {
-                       $out .= '<meta name="og:image" content="'.$website->virtualhost.$image.'">'."\n";
-               }
-               $out .= '<meta name="og:url" content="'.$canonicalurl.'">'."\n";
-
-               // Twitter
-               $out .= '<meta name="twitter:card" content="summary">'."\n";
-               if (!empty($params) && !empty($params['twitter_account'])) {
-                       $out .= '<meta name="twitter:site" content="@'.$params['twitter_account'].'">'."\n";
-                       $out .= '<meta name="twitter:creator" content="@'.$params['twitter_account'].'">'."\n";
-               }
-               $out .= '<meta name="twitter:title" content="'.$websitepage->title.'">'."\n";
-               if ($websitepage->description) {
-                       $out .= '<meta name="twitter:description" content="'.$websitepage->description.'">'."\n";
-               }
-               if ($websitepage->image) {
-                       $out .= '<meta name="twitter:image" content="'.$website->virtualhost.$image.'">'."\n";
-               }
-               //$out .= '<meta name="twitter:domain" content="'.getDomainFromURL($website->virtualhost, 1).'">';
-               /*
-                $out .= '<meta name="twitter:app:name:iphone" content="">';
-                $out .= '<meta name="twitter:app:name:ipad" content="">';
-                $out .= '<meta name="twitter:app:name:googleplay" content="">';
-                $out .= '<meta name="twitter:app:url:iphone" content="">';
-                $out .= '<meta name="twitter:app:url:ipad" content="">';
-                $out .= '<meta name="twitter:app:url:googleplay" content="">';
-                $out .= '<meta name="twitter:app:id:iphone" content="">';
-                $out .= '<meta name="twitter:app:id:ipad" content="">';
-                $out .= '<meta name="twitter:app:id:googleplay" content="">';
-                */
-       }
+       // if ($website->virtualhost) {
+       //      $pageurl = $websitepage->pageurl;
+       //      $title = $websitepage->title;
+       //      $image = $websitepage->image;
+       //      $companyname = $mysoc->name;
+       //      $description = $websitepage->description;
+
+       //      $pageurl = str_replace('__WEBSITE_KEY__', $website->ref, $pageurl);
+       //      $title = str_replace('__WEBSITE_KEY__', $website->ref, $title);
+       //      $image = '/medias'.(preg_match('/^\//', $image) ? '' : '/').str_replace('__WEBSITE_KEY__', $website->ref, $image);
+       //      $companyname = str_replace('__WEBSITE_KEY__', $website->ref, $companyname);
+       //      $description = str_replace('__WEBSITE_KEY__', $website->ref, $description);
+
+       //      $shortlangcode = '';
+       //      if ($websitepage->lang) {
+       //              $shortlangcode = substr($websitepage->lang, 0, 2); // en_US or en-US -> en
+       //      }
+       //      if (empty($shortlangcode)) {
+       //              $shortlangcode = substr($website->lang, 0, 2); // en_US or en-US -> en
+       //      }
+
+       //      $fullurl = $website->virtualhost.'/'.$websitepage->pageurl.'.php';
+       //      $canonicalurl = $website->virtualhost.(($websitepage->id == $website->fk_default_home) ? '/' : (($shortlangcode != substr($website->lang, 0, 2) ? '/'.$shortlangcode : '').'/'.$websitepage->pageurl.'.php'));
+       //      $hashtags = trim(join(' #', array_map('trim', explode(',', $websitepage->keywords))));
+
+       //      // Open Graph
+       //      // $out .= '<meta name="og:type" content="website">'."\n";      // TODO If blogpost, use type article
+       //      // $out .= '<meta name="og:title" content="'.$websitepage->title.'">'."\n";
+       //      // if ($websitepage->image) {
+       //      //      $out .= '<meta name="og:image" content="'.$website->virtualhost.$image.'">'."\n";
+       //      // }
+       //      // $out .= '<meta name="og:url" content="'.$canonicalurl.'">'."\n";
+
+       //      // Twitter
+       //      // $out .= '<meta name="twitter:card" content="summary">'."\n";
+       //      // if (!empty($params) && !empty($params['twitter_account'])) {
+       //      //      $out .= '<meta name="twitter:site" content="@'.$params['twitter_account'].'">'."\n";
+       //      //      $out .= '<meta name="twitter:creator" content="@'.$params['twitter_account'].'">'."\n";
+       //      // }
+       //      // $out .= '<meta name="twitter:title" content="'.$websitepage->title.'">'."\n";
+       //      // if ($websitepage->description) {
+       //      //      $out .= '<meta name="twitter:description" content="'.$websitepage->description.'">'."\n";
+       //      // }
+       //      // if ($websitepage->image) {
+       //      //      $out .= '<meta name="twitter:image" content="'.$website->virtualhost.$image.'">'."\n";
+       //      // }
+       //      //$out .= '<meta name="twitter:domain" content="'.getDomainFromURL($website->virtualhost, 1).'">';
+       //      /*
+       //       $out .= '<meta name="twitter:app:name:iphone" content="">';
+       //       $out .= '<meta name="twitter:app:name:ipad" content="">';
+       //       $out .= '<meta name="twitter:app:name:googleplay" content="">';
+       //       $out .= '<meta name="twitter:app:url:iphone" content="">';
+       //       $out .= '<meta name="twitter:app:url:ipad" content="">';
+       //       $out .= '<meta name="twitter:app:url:googleplay" content="">';
+       //       $out .= '<meta name="twitter:app:id:iphone" content="">';
+       //       $out .= '<meta name="twitter:app:id:ipad" content="">';
+       //       $out .= '<meta name="twitter:app:id:googleplay" content="">';
+       //       */
+       // }
 
        return $out;
 }
@@ -876,53 +876,53 @@ function getSocialNetworkHeaderCards($params = null)
 function getSocialNetworkSharingLinks()
 {
        global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $websitepage, $weblangs; // Very important. Required to have var available when running inluded containers.
-
-       $out = '<!-- section for social network sharing of page -->'."\n";
-
-       if ($website->virtualhost) {
-               $fullurl = $website->virtualhost.'/'.$websitepage->pageurl.'.php';
-               $hashtags = trim(join(' #', array_map('trim', explode(',', $websitepage->keywords))));
-
-               $out .= '<div class="dol-social-share">'."\n";
-
-               // Twitter
-               $out .= '<div class="dol-social-share-tw">'."\n";
-               $out .= '<a href="https://twitter.com/share" class="twitter-share-button" data-url="'.$fullurl.'" data-text="'.dol_escape_htmltag($websitepage->description).'" data-lang="'.$websitepage->lang.'" data-size="small" data-related="" data-hashtags="'.preg_replace('/^#/', '', $hashtags).'" data-count="horizontal">Tweet</a>';
-               $out .= '<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?\'http\':\'https\';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+\'://platform.twitter.com/widgets.js\';fjs.parentNode.insertBefore(js,fjs);}}(document, \'script\', \'twitter-wjs\');</script>';
-               $out .= '</div>'."\n";
-
-               // Reddit
-               $out .= '<div class="dol-social-share-reddit">'."\n";
-               $out .= '<a href="https://www.reddit.com/submit" target="_blank" rel="noopener noreferrer external" onclick="window.location = \'https://www.reddit.com/submit?url='.$fullurl.'\'; return false">';
-               $out .= '<span class="dol-social-share-reddit-span">Reddit</span>';
-               $out .= '</a>';
-               $out .= '</div>'."\n";
-
-               // Facebook
-               $out .= '<div class="dol-social-share-fbl">'."\n";
-               $out .= '<div id="fb-root"></div>'."\n";
-               $out .= '<script>(function(d, s, id) {
-                                 var js, fjs = d.getElementsByTagName(s)[0];
-                                 if (d.getElementById(id)) return;
-                                 js = d.createElement(s); js.id = id;
-                                 js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.0&amp;appId=dolibarr.org";
-                                 fjs.parentNode.insertBefore(js, fjs);
-                               }(document, \'script\', \'facebook-jssdk\'));</script>
-                                       <fb:like
-                                       href="'.$fullurl.'"
-                                       layout="button_count"
-                                       show_faces="false"
-                                       width="90"
-                                       colorscheme="light"
-                                       share="1"
-                                       action="like" ></fb:like>'."\n";
-               $out .= '</div>'."\n";
-
-               $out .= "\n</div>\n";
-       } else {
-               $out .= '<!-- virtual host not defined in CMS. No way to add sharing buttons -->'."\n";
-       }
-       $out .= '<!-- section end for social network sharing of page -->'."\n";
+       $out="";
+       // $out = '<!-- section for social network sharing of page -->'."\n";
+
+       // if ($website->virtualhost) {
+       //      $fullurl = $website->virtualhost.'/'.$websitepage->pageurl.'.php';
+       //      $hashtags = trim(join(' #', array_map('trim', explode(',', $websitepage->keywords))));
+
+       //      $out .= '<div class="dol-social-share">'."\n";
+
+       //      // Twitter
+       //      $out .= '<div class="dol-social-share-tw">'."\n";
+       //      $out .= '<a href="https://twitter.com/share" class="twitter-share-button" data-url="'.$fullurl.'" data-text="'.dol_escape_htmltag($websitepage->description).'" data-lang="'.$websitepage->lang.'" data-size="small" data-related="" data-hashtags="'.preg_replace('/^#/', '', $hashtags).'" data-count="horizontal">Tweet</a>';
+       //      $out .= '<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?\'http\':\'https\';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+\'://platform.twitter.com/widgets.js\';fjs.parentNode.insertBefore(js,fjs);}}(document, \'script\', \'twitter-wjs\');</script>';
+       //      $out .= '</div>'."\n";
+
+       //      // Reddit
+       //      $out .= '<div class="dol-social-share-reddit">'."\n";
+       //      $out .= '<a href="https://www.reddit.com/submit" target="_blank" rel="noopener noreferrer external" onclick="window.location = \'https://www.reddit.com/submit?url='.$fullurl.'\'; return false">';
+       //      $out .= '<span class="dol-social-share-reddit-span">Reddit</span>';
+       //      $out .= '</a>';
+       //      $out .= '</div>'."\n";
+
+       //      // Facebook
+       //      $out .= '<div class="dol-social-share-fbl">'."\n";
+       //      $out .= '<div id="fb-root"></div>'."\n";
+       //      $out .= '<script>(function(d, s, id) {
+       //                        var js, fjs = d.getElementsByTagName(s)[0];
+       //                        if (d.getElementById(id)) return;
+       //                        js = d.createElement(s); js.id = id;
+       //                        js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.0&amp;appId=dolibarr.org";
+       //                        fjs.parentNode.insertBefore(js, fjs);
+       //                      }(document, \'script\', \'facebook-jssdk\'));</script>
+       //                              <fb:like
+       //                              href="'.$fullurl.'"
+       //                              layout="button_count"
+       //                              show_faces="false"
+       //                              width="90"
+       //                              colorscheme="light"
+       //                              share="1"
+       //                              action="like" ></fb:like>'."\n";
+       //      $out .= '</div>'."\n";
+
+       //      $out .= "\n</div>\n";
+       // } else {
+       //      $out .= '<!-- virtual host not defined in CMS. No way to add sharing buttons -->'."\n";
+       // }
+       // $out .= '<!-- section end for social network sharing of page -->'."\n";
 
        return $out;
 }
index 5fbe998..d645aaf 100644 (file)
@@ -1456,21 +1456,21 @@ function get_left_menu_billing($mainmenu, &$newmenu, $usemenuhider = 1, $leftmen
                        $newmenu->add("/fourn/facture/card.php?leftmenu=suppliers_bills&amp;action=create", $langs->trans("NewBill"), 1, ($user->hasRight('fournisseur',  'facture', 'creer') || $user->hasRight('supplier_invoice',  'creer')), '', $mainmenu, 'suppliers_bills_create');
                        $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills", $langs->trans("List"), 1, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'suppliers_bills_list');
 
-                       if ($usemenuhider || empty($leftmenu) || preg_match('/suppliers_bills/', $leftmenu)) {
-                               $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_draft&amp;search_status=0", $langs->trans("BillShortStatusDraft"), 2, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'suppliers_bills_draft');
-                               $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_notpaid&amp;search_status=1", $langs->trans("BillShortStatusNotPaid"), 2, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'suppliers_bills_notpaid');
-                               $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_paid&amp;search_status=2", $langs->trans("BillShortStatusPaid"), 2, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'suppliers_bills_paid');
-                       }
+                       // if ($usemenuhider || empty($leftmenu) || preg_match('/suppliers_bills/', $leftmenu)) {
+                       //      $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_draft&amp;search_status=0", $langs->trans("BillShortStatusDraft"), 2, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'suppliers_bills_draft');
+                       //      $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_notpaid&amp;search_status=1", $langs->trans("BillShortStatusNotPaid"), 2, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'suppliers_bills_notpaid');
+                       //      $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills_paid&amp;search_status=2", $langs->trans("BillShortStatusPaid"), 2, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'suppliers_bills_paid');
+                       // }
 
-                       $newmenu->add("/fourn/facture/list-rec.php?leftmenu=supplierinvoicestemplate_list", $langs->trans("ListOfTemplates"), 1, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'supplierinvoicestemplate_list');
+                       // $newmenu->add("/fourn/facture/list-rec.php?leftmenu=supplierinvoicestemplate_list", $langs->trans("ListOfTemplates"), 1, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'supplierinvoicestemplate_list');
 
                        $newmenu->add("/fourn/paiement/list.php?leftmenu=suppliers_bills_payment", $langs->trans("Payments"), 1, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'suppliers_bills_payment');
 
-                       if ($usemenuhider || empty($leftmenu) || preg_match('/suppliers_bills/', $leftmenu)) {
-                               $newmenu->add("/fourn/facture/rapport.php?leftmenu=suppliers_bills_payment_report", $langs->trans("Reportings"), 2, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'suppliers_bills_payment_report');
-                       }
+                       // if ($usemenuhider || empty($leftmenu) || preg_match('/suppliers_bills/', $leftmenu)) {
+                       //      $newmenu->add("/fourn/facture/rapport.php?leftmenu=suppliers_bills_payment_report", $langs->trans("Reportings"), 2, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'suppliers_bills_payment_report');
+                       // }
 
-                       $newmenu->add("/compta/facture/stats/index.php?mode=supplier&amp;leftmenu=suppliers_bills_stats", $langs->trans("Statistics"), 1, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'suppliers_bills_stats');
+                       // $newmenu->add("/compta/facture/stats/index.php?mode=supplier&amp;leftmenu=suppliers_bills_stats", $langs->trans("Statistics"), 1, $user->hasRight('fournisseur',  'facture', 'lire'), '', $mainmenu, 'suppliers_bills_stats');
                }
 
                // Orders
@@ -1,48 +1,46 @@
 <?php
 /* Copyright (C) 2010-2012     Laurent Destailleur <eldy@users.sourceforge.net>
  * Copyright (C) 2012          Juanjo Menent           <jmenent@2byte.es>
- * Copyright (C) 2014          Marcos García          <marcosgdf@gmail.com>
  * Copyright (C) 2016          Charlie Benke           <charlie@patas-monkey.com>
- * Copyright (C) 2018-2021  Philippe Grand      <philippe.grand@atoo-net.com>
- * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
+ * Copyright (C) 2018-2019  Frédéric France         <frederic.france@netlogic.fr>
  *
- * 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 <https://www.gnu.org/licenses/>.
- * or see https://www.gnu.org/
- */
+* 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 <https://www.gnu.org/licenses/>.
+* or see https://www.gnu.org/
+*/
 
 /**
- *     \file       htdocs/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php
- *     \ingroup    mymodule
- *     \brief      File of class to build ODT documents for myobjects
+ *     \file       htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
+ *     \ingroup    societe
+ *     \brief      File of class to build ODT documents for third parties
  */
 
-dol_include_once('/mymodule/core/modules/mymodule/modules_myobject.php');
+require_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php';
 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php';
 
 
 /**
  *     Class to build documents using ODF templates generator
  */
-class doc_generic_myobject_odt extends ModelePDFMyObject
+class doc_generic_proposal_odt extends ModelePDFPropales
 {
        /**
-        * Issuer
-        * @var Societe
+        * @var Societe Issuer object that emits
         */
        public $emetteur;
 
@@ -71,12 +69,13 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                $langs->loadLangs(array("main", "companies"));
 
                $this->db = $db;
-               $this->name = "ODT templates";
-               $this->description = $langs->trans("DocumentModelOdt");
-               $this->scandir = 'MYMODULE_MYOBJECT_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan
+               $this->name = "HTML templates";
+               $this->description = $langs->trans("DocumentModelHTML");
+               $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
+               $this->scandir = 'PROPALE_ADDON_PDF_HTML_PATH'; // Name of constant that is used to save list of directories to scan
 
                // Page size for A4 format
-               $this->type = 'odt';
+               $this->type = 'html';
                $this->page_largeur = 0;
                $this->page_hauteur = 0;
                $this->format = array($this->page_largeur, $this->page_hauteur);
@@ -86,7 +85,7 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                $this->marge_basse = 0;
 
                $this->option_logo = 1; // Display logo
-               $this->option_tva = 0; // Manage the vat option FACTURE_TVAOPTION
+               $this->option_tva = 0; // Manage the vat option PROPALE_TVAOPTION
                $this->option_modereg = 0; // Display payment mode
                $this->option_condreg = 0; // Display payment terms
                $this->option_multilang = 1; // Available in several languages
@@ -118,18 +117,26 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
 
                $form = new Form($this->db);
 
+               $odtChosen = getDolGlobalInt('MAIN_PROPAL_CHOOSE_HTML_DOCUMENT') > 0;
+               $odtPath = trim(getDolGlobalString('PROPALE_ADDON_PDF_HTML_PATH'));
+
                $texte = $this->description.".<br>\n";
                $texte .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" enctype="multipart/form-data">';
                $texte .= '<input type="hidden" name="token" value="'.newToken().'">';
                $texte .= '<input type="hidden" name="page_y" value="">';
                $texte .= '<input type="hidden" name="action" value="setModuleOptions">';
-               $texte .= '<input type="hidden" name="param1" value="MYMODULE_MYOBJECT_ADDON_PDF_ODT_PATH">';
+               $texte .= '<input type="hidden" name="param1" value="PROPALE_ADDON_PDF_HTML_PATH">';
+               if ($odtChosen) {
+                       $texte .= '<input type="hidden" name="param2" value="PROPALE_ADDON_PDF_HTML_DEFAULT">';
+                       $texte .= '<input type="hidden" name="param3" value="PROPALE_ADDON_PDF_HTML_TOBILL">';
+                       $texte .= '<input type="hidden" name="param4" value="PROPALE_ADDON_PDF_HTML_CLOSED">';
+               }
                $texte .= '<table class="nobordernopadding centpercent">';
 
                // List of directories area
                $texte .= '<tr><td>';
                $texttitle = $langs->trans("ListOfDirectories");
-               $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->MYMODULE_MYOBJECT_ADDON_PDF_ODT_PATH)));
+               $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', $odtPath));
                $listoffiles = array();
                foreach ($listofdir as $key => $tmpdir) {
                        $tmpdir = trim($tmpdir);
@@ -141,7 +148,7 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                        if (!is_dir($tmpdir)) {
                                $texttitle .= img_warning($langs->trans("ErrorDirNotFound", $tmpdir), 0);
                        } else {
-                               $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.(ods|odt)');
+                               $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.html');
                                if (count($tmpfiles)) {
                                        $listoffiles = array_merge($listoffiles, $tmpfiles);
                                }
@@ -155,15 +162,15 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                $texte .= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1);
                $texte .= '<div><div style="display: inline-block; min-width: 100px; vertical-align: middle;">';
                $texte .= '<textarea class="flat" cols="60" name="value1">';
-               $texte .= $conf->global->MYMODULE_MYOBJECT_ADDON_PDF_ODT_PATH;
+               $texte .= $odtPath;
                $texte .= '</textarea>';
                $texte .= '</div><div style="display: inline-block; vertical-align: middle;">';
-               $texte .= '<input type="submit" class="button small reposition" name="modify" value="'.dol_escape_htmltag($langs->trans("Modify")).'">';
+               $texte .= '<input type="submit" class="button small reposition" name="modify" value="'.$langs->trans("Modify").'">';
                $texte .= '<br></div></div>';
 
                // Scan directories
                $nbofiles = count($listoffiles);
-               if (!empty($conf->global->MYMODULE_MYOBJECT_ADDON_PDF_ODT_PATH)) {
+               if (!empty($odtPath)) {
                        $texte .= $langs->trans("NumberOfModelFilesFound").': <b>';
                        //$texte.=$nbofiles?'<a id="a_'.get_class($this).'" href="#">':'';
                        $texte .= count($listoffiles);
@@ -175,13 +182,38 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                        $texte .= '<div id="div_'.get_class($this).'" class="hiddenx">';
                        // Show list of found files
                        foreach ($listoffiles as $file) {
-                               $texte .= '- '.$file['name'].' <a href="'.DOL_URL_ROOT.'/document.php?modulepart=doctemplates&file=mymodule_myobject/'.urlencode(basename($file['name'])).'">'.img_picto('', 'listlight').'</a>';
-                               $texte .= ' &nbsp; <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?modulepart=doctemplates&keyforuploaddir=MYMODULE_MYOBJECT_ADDON_PDF_ODT_PATH&action=deletefile&token='.newToken().'&file='.urlencode(basename($file['name'])).'">'.img_picto('', 'delete').'</a>';
+                               $texte .= '- '.$file['name'];
+                               $texte .= ' <a href="'.DOL_URL_ROOT.'/document.php?modulepart=doctemplates&file=proposals/'.urlencode(basename($file['name'])).'">'.img_picto('', 'listlight').'</a>';
+                               $texte .= ' &nbsp; <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?modulepart=doctemplates&keyforuploaddir=PROPALE_ADDON_PDF_HTML_PATH&action=deletefile&token='.newToken().'&file='.urlencode(basename($file['name'])).'">'.img_picto('', 'delete').'</a>';
                                $texte .= '<br>';
                        }
                        $texte .= '</div>';
-               }
 
+                       // Set default template for different status of proposal
+                       if ($odtChosen) {
+                               // Model for creation
+                               $list = ModelePDFPropales::liste_modeles($this->db);
+                               $texte .= '<table width="50%;">';
+                               $texte .= '<tr>';
+                               $texte .= '<td width="60%;">'.$langs->trans("DefaultModelPropalCreate").'</td>';
+                               $texte .= '<td colspan="">';
+                               $texte .= $form->selectarray('value2', $list, getDolGlobalString('PROPALE_ADDON_PDF_HTML_DEFAULT'));
+                               $texte .= "</td></tr>";
+
+                               $texte .= '<tr>';
+                               $texte .= '<td width="60%;">'.$langs->trans("DefaultModelPropalToBill").'</td>';
+                               $texte .= '<td colspan="">';
+                               $texte .= $form->selectarray('value3', $list, getDolGlobalString('PROPALE_ADDON_PDF_HTML_TOBILL'));
+                               $texte .= "</td></tr>";
+                               $texte .= '<tr>';
+
+                               $texte .= '<td width="60%;">'.$langs->trans("DefaultModelPropalClosed").'</td>';
+                               $texte .= '<td colspan="">';
+                               $texte .= $form->selectarray('value4', $list, getDolGlobalString('PROPALE_ADDON_PDF_HTML_CLOSED'));
+                               $texte .= "</td></tr>";
+                               $texte .= '</table>';
+                       }
+               }
                // Add input to upload a new template file.
                $texte .= '<div>'.$langs->trans("UploadNewTemplate");
                $maxfilesizearray = getMaxFileSizeArray();
@@ -190,10 +222,9 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                        $texte .= '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">';    // MAX_FILE_SIZE must precede the field type=file
                }
                $texte .= ' <input type="file" name="uploadfile">';
-               $texte .= '<input type="hidden" value="MYMODULE_MYOBJECT_ADDON_PDF_ODT_PATH" name="keyforuploaddir">';
+               $texte .= '<input type="hidden" value="PROPALE_ADDON_PDF_HTML_PATH" name="keyforuploaddir">';
                $texte .= '<input type="submit" class="button small reposition" value="'.dol_escape_htmltag($langs->trans("Upload")).'" name="upload">';
                $texte .= '</div>';
-
                $texte .= '</td>';
 
                $texte .= '<td rowspan="2" class="tdtop hideonsmartphone">';
@@ -211,9 +242,9 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
 
        // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
        /**
-        *  Function to build a document on disk using the generic odt module.
+        *      Function to build a document on disk using the generic odt module.
         *
-        *      @param          MyObject        $object                         Object source to build document
+        *      @param          Propal          $object                         Object source to build document
         *      @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
@@ -245,13 +276,14 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                $sav_charset_output = $outputlangs->charset_output;
                $outputlangs->charset_output = 'UTF-8';
 
+               // Load translation files required by the page
                $outputlangs->loadLangs(array("main", "dict", "companies", "bills"));
 
-               if ($conf->mymodule->dir_output) {
+               if ($conf->propal->multidir_output[$conf->entity]) {
                        // If $object is id instead of object
                        if (!is_object($object)) {
                                $id = $object;
-                               $object = new MyObject($this->db);
+                               $object = new Propal($this->db);
                                $result = $object->fetch($id);
                                if ($result < 0) {
                                        dol_print_error($this->db, $object->error);
@@ -261,7 +293,7 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
 
                        $object->fetch_thirdparty();
 
-                       $dir = $conf->mymodule->multidir_output[isset($object->entity) ? $object->entity : 1];
+                       $dir = $conf->propal->multidir_output[$object->entity];
                        $objectref = dol_sanitizeFileName($object->ref);
                        if (!preg_match('/specimen/i', $objectref)) {
                                $dir .= "/".$objectref;
@@ -283,7 +315,6 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                                $newfiletmp = preg_replace('/modele_/i', '', $newfiletmp);
 
                                $newfiletmp = $objectref . '_' . $newfiletmp;
-                               //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt';
 
                                // Get extension (ods or odt)
                                $newfileformat = substr($newfile, strrpos($newfile, '.') + 1);
@@ -300,16 +331,16 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                                //print "newdir=".$dir;
                                //print "newfile=".$newfile;
                                //print "file=".$file;
-                               //print "conf->societe->dir_temp=".$conf->societe->dir_temp;
+                               //print "conf->propal->dir_temp=".$conf->propal->dir_temp;
 
-                               dol_mkdir($conf->mymodule->dir_temp);
-                               if (!is_writable($conf->mymodule->dir_temp)) {
-                                       $this->error = $langs->transnoentities("ErrorFailedToWriteInTempDirectory", $conf->mymodule->dir_temp);
+                               dol_mkdir($conf->propal->multidir_temp[$object->entity]);
+                               if (!is_writable($conf->propal->dir_temp)) {
+                                       $this->error = $langs->transnoentities("ErrorFailedToWriteInTempDirectory", $conf->propal->dir_temp);
                                        dol_syslog('Error in write_file: ' . $this->error, LOG_ERR);
                                        return -1;
                                }
 
-                               // If CUSTOMER contact defined on object, we use it
+                               // If CUSTOMER contact defined on proposal, we use it
                                $usecontact = false;
                                $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
                                if (count($arrayidcontact) > 0) {
@@ -333,14 +364,13 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                                } else {
                                        $socobject = $object->thirdparty;
                                }
-
                                // Make substitution
                                $substitutionarray = array(
-                                       '__FROM_NAME__' => $this->emetteur->name,
-                                       '__FROM_EMAIL__' => $this->emetteur->email,
-                                       '__TOTAL_TTC__' => $object->total_ttc,
-                                       '__TOTAL_HT__' => $object->total_ht,
-                                       '__TOTAL_VAT__' => $object->total_tva
+                               '__FROM_NAME__' => $this->emetteur->name,
+                               '__FROM_EMAIL__' => $this->emetteur->email,
+                               '__TOTAL_TTC__' => $object->total_ttc,
+                               '__TOTAL_HT__' => $object->total_ht,
+                               '__TOTAL_VAT__' => $object->total_tva
                                );
                                complete_substitutions_array($substitutionarray, $langs, $object);
                                // Call the ODTSubstitution hook
@@ -349,7 +379,7 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
 
                                // Line of free text
                                $newfreetext = '';
-                               $paramfreetext = 'MYMODULE_MYOBJECT_FREE_TEXT';
+                               $paramfreetext = 'PROPOSAL_FREE_TEXT';
                                if (!empty($conf->global->$paramfreetext)) {
                                        $newfreetext = make_substitutions($conf->global->$paramfreetext, $substitutionarray);
                                }
@@ -360,7 +390,7 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                                        $odfHandler = new odf(
                                                $srctemplatepath,
                                                array(
-                                               'PATH_TO_TMP'     => $conf->mymodule->dir_temp,
+                                               'PATH_TO_TMP'     => $conf->propal->multidir_temp[$object->entity],
                                                'ZIP_PROXY'               => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
                                                'DELIMITER_LEFT'  => '{',
                                                'DELIMITER_RIGHT' => '}'
@@ -377,6 +407,7 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                                //print html_entity_decode($odfHandler->__toString());
                                //print exit;
 
+                               $object->fetch_optionals();
 
                                // Make substitutions into odt of freetext
                                try {
@@ -408,15 +439,14 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
 
                                foreach ($tmparray as $key => $value) {
                                        try {
-                                               if (preg_match('/logo$/', $key)) {
-                                                       // Image
+                                               if (preg_match('/logo$/', $key)) { // Image
                                                        if (file_exists($value)) {
                                                                $odfHandler->setImage($key, $value);
                                                        } else {
                                                                $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
                                                        }
-                                               } else {
-                                                       // Text
+                                               } else // Text
+                                               {
                                                        $odfHandler->setVars($key, $value, true, 'UTF-8');
                                                }
                                        } catch (OdfException $e) {
@@ -472,12 +502,11 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                                }
 
                                // Call the beforeODTSave hook
-
                                $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
                                $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
 
                                // Write new file
-                               if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
+                               if (!empty($conf->global->MAIN_HTML_AS_PDF)) {
                                        try {
                                                $odfHandler->exportAsAttachedPDF($file);
                                        } catch (Exception $e) {
@@ -494,7 +523,6 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
                                                return -1;
                                        }
                                }
-
                                $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
                                $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
 
diff --git a/htdocs/core/modules/propale/doc/pdf_peitureteufela.modules.php b/htdocs/core/modules/propale/doc/pdf_peitureteufela.modules.php
new file mode 100644 (file)
index 0000000..797e9dd
--- /dev/null
@@ -0,0 +1,2080 @@
+<?php
+/* Copyright (C) 2004-2014 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@inodbox.com>
+ * Copyright (C) 2008      Raphael Bertrand     <raphael.bertrand@resultic.fr>
+ * Copyright (C) 2010-2015 Juanjo Menent           <jmenent@2byte.es>
+ * Copyright (C) 2012      Christophe Battarel   <christophe.battarel@altairis.fr>
+ * Copyright (C) 2012      Cedric Salvador      <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2015      Marcos García        <marcosgdf@gmail.com>
+ * Copyright (C) 2017      Ferran Marcet        <fmarcet@2byte.es>
+ * Copyright (C) 2018      Frédéric France      <frederic.france@netlogic.fr>
+ *
+ * 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 <https://www.gnu.org/licenses/>.
+ * or see https://www.gnu.org/
+ */
+
+/**
+ *     \file       htdocs/core/modules/propale/doc/pdf_cyan.modules.php
+ *     \ingroup    propale
+ *     \brief      File of Class to generate PDF proposal with Cyan template
+ */
+require_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php';
+require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
+
+
+/**
+ *     Class to generate PDF proposal Cyan
+ */
+class pdf_peitureteufela extends ModelePDFPropales
+{
+       /**
+        * @var DoliDb Database handler
+        */
+       public $db;
+
+       /**
+        * @var string model name
+        */
+       public $name;
+
+       /**
+        * @var string model description (short text)
+        */
+       public $description;
+
+       /**
+        * @var int    Save the name of generated file as the main doc when generating a doc with this template
+        */
+       public $update_main_doc_field;
+
+       /**
+        * @var string document type
+        */
+       public $type;
+
+       /**
+        * @var array Minimum version of PHP required by module.
+        * e.g.: PHP â‰¥ 7.0 = array(7, 0)
+        */
+       public $phpmin = array(7, 0);
+
+       /**
+        * Dolibarr version of the loaded document
+        * @var string
+        */
+       public $version = 'dolibarr';
+
+       /**
+        * @var int page_largeur
+        */
+       public $page_largeur;
+
+       /**
+        * @var int page_hauteur
+        */
+       public $page_hauteur;
+
+       /**
+        * @var array format
+        */
+       public $format;
+
+       /**
+        * @var int marge_gauche
+        */
+       public $marge_gauche;
+
+       /**
+        * @var int marge_droite
+        */
+       public $marge_droite;
+
+       /**
+        * @var int marge_haute
+        */
+       public $marge_haute;
+
+       /**
+        * @var int marge_basse
+        */
+       public $marge_basse;
+
+       /**
+        * Issuer
+        * @var Societe Object that emits
+        */
+       public $emetteur;
+
+       /**
+        * @var array of document table columns
+        */
+       public $cols;
+
+
+       /**
+        *      Constructor
+        *
+        *  @param              DoliDB          $db      Database handler
+        */
+       public function __construct($db)
+       {
+               global $conf, $langs, $mysoc;
+
+               // Translations
+               $langs->loadLangs(array("main", "bills"));
+
+               $this->db = $db;
+               $this->name = "Peinture Teufel Angebot";
+               $this->description = $langs->trans('DocModelCyanDescription');
+               $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
+
+               // Dimension page
+               $this->type = 'pdf';
+               $formatarray = pdf_getFormat();
+               $this->page_largeur = $formatarray['width'];
+               $this->page_hauteur = $formatarray['height'];
+               $this->format = array($this->page_largeur, $this->page_hauteur);
+               $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
+               $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
+               $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
+               $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
+
+               $this->option_logo = 1; // Display logo
+               $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
+               $this->option_modereg = 1; // Display payment mode
+               $this->option_condreg = 1; // Display payment terms
+               $this->option_multilang = 1; // Available in several languages
+               $this->option_escompte = 0; // Displays if there has been a discount
+               $this->option_credit_note = 0; // Support credit notes
+               $this->option_freetext = 1; // Support add of a personalised text
+               $this->option_draft_watermark = 1; // Support add of a watermark on drafts
+               $this->watermark = '';
+
+               // Get source company
+               $this->emetteur = $mysoc;
+               if (empty($this->emetteur->country_code)) {
+                       $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
+               }
+
+               // Define position of columns
+               $this->posxdesc = $this->marge_gauche + 1; // used for notes ans other stuff
+
+
+               $this->tabTitleHeight = 5; // default height
+
+               //  Use new system for position of columns, view  $this->defineColumnField()
+
+               $this->tva = array();
+               $this->tva_array = array();
+               $this->localtax1 = array();
+               $this->localtax2 = array();
+               $this->atleastoneratenotnull = 0;
+               $this->atleastonediscount = 0;
+       }
+
+       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+       /**
+        *  Function to build pdf onto disk
+        *
+        *  @param              Propal          $object                         Object to generate
+        *  @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
+        *  @param              int                     $hidedesc                       Do not show desc
+        *  @param              int                     $hideref                        Do not show ref
+        *  @return     int                                             1=OK, 0=KO
+        */
+       public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
+       {
+         // phpcs:enable
+               global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines;
+
+               dol_syslog("write_file outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null'));
+
+               if (!is_object($outputlangs)) {
+                       $outputlangs = $langs;
+               }
+               // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
+               if (!empty($conf->global->MAIN_USE_FPDF)) {
+                       $outputlangs->charset_output = 'ISO-8859-1';
+               }
+
+               // Load translation files required by page
+               $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "propal"));
+
+               //  Show Draft Watermark
+               if ($object->statut == $object::STATUS_DRAFT && getDolGlobalString('PROPALE_DRAFT_WATERMARK')) {
+                       $this->watermark = getDolGlobalString('PROPALE_DRAFT_WATERMARK');
+               }
+
+               global $outputlangsbis;
+               $outputlangsbis = null;
+               if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
+                       $outputlangsbis = new Translate('', $conf);
+                       $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
+                       $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "propal"));
+               }
+
+               $nblines = count($object->lines);
+
+               $hidetop = 0;
+               if (!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)) {
+                       $hidetop = $conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE;
+               }
+
+               // Loop on each lines to detect if there is at least one image to show
+               $realpatharray = array();
+               $this->atleastonephoto = false;
+               if (!empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE)) {
+                       $objphoto = new Product($this->db);
+
+                       for ($i = 0; $i < $nblines; $i++) {
+                               if (empty($object->lines[$i]->fk_product)) {
+                                       continue;
+                               }
+
+                               $objphoto->fetch($object->lines[$i]->fk_product);
+                               //var_dump($objphoto->ref);exit;
+                               if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
+                                       $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/";
+                                       $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/';
+                               } else {
+                                       $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product'); // default
+                                       $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative
+                               }
+
+                               $arephoto = false;
+                               foreach ($pdir as $midir) {
+                                       if (!$arephoto) {
+                                               if ($conf->entity != $objphoto->entity) {
+                                                       $dir = $conf->product->multidir_output[$objphoto->entity].'/'.$midir; //Check repertories of current entities
+                                               } else {
+                                                       $dir = $conf->product->dir_output.'/'.$midir; //Check repertory of the current product
+                                               }
+
+                                               foreach ($objphoto->liste_photos($dir, 1) as $key => $obj) {
+                                                       if (!getDolGlobalInt('CAT_HIGH_QUALITY_IMAGES')) {              // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
+                                                               if ($obj['photo_vignette']) {
+                                                                       $filename = $obj['photo_vignette'];
+                                                               } else {
+                                                                       $filename = $obj['photo'];
+                                                               }
+                                                       } else {
+                                                               $filename = $obj['photo'];
+                                                       }
+
+                                                       $realpath = $dir.$filename;
+                                                       $arephoto = true;
+                                                       $this->atleastonephoto = true;
+                                               }
+                                       }
+                               }
+
+                               if ($realpath && $arephoto) {
+                                       $realpatharray[$i] = $realpath;
+                               }
+                       }
+               }
+
+               if (count($realpatharray) == 0) {
+                       $this->posxpicture = $this->posxtva;
+               }
+
+               if ($conf->propal->multidir_output[$conf->entity]) {
+                       $object->fetch_thirdparty();
+
+                       $deja_regle = 0;
+
+                       // Definition of $dir and $file
+                       if ($object->specimen) {
+                               $dir = $conf->propal->multidir_output[$conf->entity];
+                               $file = $dir."/SPECIMEN.pdf";
+                       } else {
+                               $objectref = dol_sanitizeFileName($object->ref);
+                               $dir = $conf->propal->multidir_output[$object->entity]."/".$objectref;
+                               $file = $dir."/".$objectref.".pdf";
+                       }
+
+                       if (!file_exists($dir)) {
+                               if (dol_mkdir($dir) < 0) {
+                                       $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
+                                       return 0;
+                               }
+                       }
+
+                       if (file_exists($dir)) {
+                               // Add pdfgeneration hook
+                               if (!is_object($hookmanager)) {
+                                       include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
+                                       $hookmanager = new HookManager($this->db);
+                               }
+                               $hookmanager->initHooks(array('pdfgeneration'));
+                               $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
+                               global $action;
+                               $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
+
+                               // Set nblines with the new content of lines after hook
+                               $nblines = count($object->lines);
+                               //$nbpayments = count($object->getListOfPayments());
+
+                               // Create pdf instance
+                               $pdf = pdf_getInstance($this->format);
+                               $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
+                               $pdf->SetAutoPageBreak(1, 0);
+
+                               if (class_exists('TCPDF')) {
+                                       $pdf->setPrintHeader(false);
+                                       $pdf->setPrintFooter(false);
+                               }
+                               $pdf->SetFont(pdf_getPDFFont($outputlangs));
+                               // Set path to the background PDF File
+                               if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) {
+                                       $logodir = $conf->mycompany->dir_output;
+                                       if (!empty($conf->mycompany->multidir_output[$object->entity])) {
+                                               $logodir = $conf->mycompany->multidir_output[$object->entity];
+                                       }
+                                       $pagecount = $pdf->setSourceFile($logodir.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
+                                       $tplidx = $pdf->importPage(1);
+                               }
+
+                               $pdf->Open();
+                               $pagenb = 0;
+                               $pdf->SetDrawColor(128, 128, 128);
+
+                               $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
+                               $pdf->SetSubject($outputlangs->transnoentities("PdfCommercialProposalTitle"));
+                               $pdf->SetCreator("Dolibarr ".DOL_VERSION);
+                               $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
+                               $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfCommercialProposalTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
+                               if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
+                                       $pdf->SetCompression(false);
+                               }
+
+                               $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
+
+                               // Set $this->atleastonediscount if you have at least one discount
+                               for ($i = 0; $i < $nblines; $i++) {
+                                       if ($object->lines[$i]->remise_percent) {
+                                               $this->atleastonediscount++;
+                                       }
+                               }
+
+
+                               // New page
+                               $pdf->AddPage();
+                               if (!empty($tplidx)) {
+                                       $pdf->useTemplate($tplidx);
+                               }
+                               $pagenb++;
+
+                               $heightforinfotot = 40; // Height reserved to output the info and total part
+                               $heightforsignature = empty($conf->global->PROPAL_DISABLE_SIGNATURE) ? (pdfGetHeightForHtmlContent($pdf, $outputlangs->transnoentities("ProposalCustomerSignature")) + 10) : 0;
+                               $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page
+                               $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 12 : 22); // Height reserved to output the footer (value include bottom margin)
+                               //print $heightforinfotot + $heightforsignature + $heightforfreetext + $heightforfooter;exit;
+
+                               $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, $outputlangsbis);
+                               $pdf->SetFont('', '', $default_font_size - 1);
+                               $pdf->MultiCell(0, 3, ''); // Set interline to 3
+                               $pdf->SetTextColor(0, 0, 0);
+
+
+                               $tab_top = 90 + $top_shift;
+                               $tab_top_newpage = (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD') ? 42 + $top_shift : 10);
+
+
+                               // Incoterm
+                               $height_incoterms = 0;
+                               if (isModEnabled('incoterm')) {
+                                       $desc_incoterms = $object->getIncotermsForPDF();
+                                       if ($desc_incoterms) {
+                                               $tab_top -= 2;
+
+                                               $pdf->SetFont('', '', $default_font_size - 1);
+                                               $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top - 1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
+                                               $nexY = max($pdf->GetY(), $nexY);
+                                               $height_incoterms = $nexY - $tab_top;
+
+                                               // Rect takes a length in 3rd parameter
+                                               $pdf->SetDrawColor(192, 192, 192);
+                                               $pdf->Rect($this->marge_gauche, $tab_top - 1, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $height_incoterms + 1);
+
+                                               $tab_top = $nexY + 6;
+                                               $height_incoterms += 4;
+                                       }
+                               }
+
+                               // Displays notes
+                               $notetoshow = empty($object->note_public) ? '' : $object->note_public;
+                               if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) {
+                                       // Get first sale rep
+                                       if (is_object($object->thirdparty)) {
+                                               $salereparray = $object->thirdparty->getSalesRepresentatives($user);
+                                               $salerepobj = new User($this->db);
+                                               $salerepobj->fetch($salereparray[0]['id']);
+                                               if (!empty($salerepobj->signature)) {
+                                                       $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature);
+                                               }
+                                       }
+                               }
+
+                               // Extrafields in note
+                               $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
+                               // if (!empty($extranote)) {
+                               //      $notetoshow = dol_concatdesc($notetoshow, $extranote);
+                               // }
+
+                               if (!empty($conf->global->MAIN_ADD_CREATOR_IN_NOTE) && $object->user_author_id > 0) {
+                                       $tmpuser = new User($this->db);
+                                       $tmpuser->fetch($object->user_author_id);
+
+                                       $creator_info = $langs->trans("CaseFollowedBy").' '.$tmpuser->getFullName($langs);
+                                       if ($tmpuser->email) $creator_info .= ',  '.$langs->trans("EMail").': '.$tmpuser->email;
+                                       if ($tmpuser->office_phone) $creator_info .= ', '.$langs->trans("Phone").': '.$tmpuser->office_phone;
+
+                                       $notetoshow = dol_concatdesc($notetoshow, $creator_info);
+                               }
+
+                               $tab_height = $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter;
+
+                               $pagenb = $pdf->getPage();
+                               if ($notetoshow) {
+                                       $tab_top -= 2;
+
+                                       $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
+                                       $pageposbeforenote = $pagenb;
+
+                                       $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
+                                       complete_substitutions_array($substitutionarray, $outputlangs, $object);
+                                       $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
+                                       $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
+
+                                       $pdf->startTransaction();
+
+                                       $pdf->SetFont('', '', $default_font_size - 1);
+                                       $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
+                                       // Description
+                                       $pageposafternote = $pdf->getPage();
+                                       $posyafter = $pdf->GetY();
+
+                                       if ($pageposafternote > $pageposbeforenote) {
+                                               $pdf->rollbackTransaction(true);
+
+                                               // prepare pages to receive notes
+                                               while ($pagenb < $pageposafternote) {
+                                                       $pdf->AddPage();
+                                                       $pagenb++;
+                                                       if (!empty($tplidx)) {
+                                                               $pdf->useTemplate($tplidx);
+                                                       }
+                                                       if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
+                                                               $this->_pagehead($pdf, $object, 0, $outputlangs);
+                                                       }
+                                                       // $this->_pagefoot($pdf,$object,$outputlangs,1);
+                                                       $pdf->setTopMargin($tab_top_newpage);
+                                                       // The only function to edit the bottom margin of current page to set it.
+                                                       $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
+                                               }
+
+                                               // back to start
+                                               $pdf->setPage($pageposbeforenote);
+                                               $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
+                                               $pdf->SetFont('', '', $default_font_size - 1);
+                                               $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
+                                               $pageposafternote = $pdf->getPage();
+
+                                               $posyafter = $pdf->GetY();
+
+                                               if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {        // There is no space left for total+free text
+                                                       $pdf->AddPage('', '', true);
+                                                       $pagenb++;
+                                                       $pageposafternote++;
+                                                       $pdf->setPage($pageposafternote);
+                                                       $pdf->setTopMargin($tab_top_newpage);
+                                                       // The only function to edit the bottom margin of current page to set it.
+                                                       $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
+                                                       //$posyafter = $tab_top_newpage;
+                                               }
+
+
+                                               // apply note frame to previous pages
+                                               $i = $pageposbeforenote;
+                                               while ($i < $pageposafternote) {
+                                                       $pdf->setPage($i);
+
+
+                                                       $pdf->SetDrawColor(128, 128, 128);
+                                                       // Draw note frame
+                                                       if ($i > $pageposbeforenote) {
+                                                               $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
+                                                               $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
+                                                       } else {
+                                                               $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
+                                                               $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
+                                                       }
+
+                                                       // Add footer
+                                                       $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
+                                                       $this->_pagefoot($pdf, $object, $outputlangs, 1);
+
+                                                       $i++;
+                                               }
+
+                                               // apply note frame to last page
+                                               $pdf->setPage($pageposafternote);
+                                               if (!empty($tplidx)) {
+                                                       $pdf->useTemplate($tplidx);
+                                               }
+                                               if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
+                                                       $this->_pagehead($pdf, $object, 0, $outputlangs);
+                                               }
+                                               $height_note = $posyafter - $tab_top_newpage;
+                                               $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
+                                       } else {
+                                               // No pagebreak
+                                               $pdf->commitTransaction();
+                                               $posyafter = $pdf->GetY();
+                                               $height_note = $posyafter - $tab_top;
+                                               $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
+
+
+                                               if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {
+                                                       // not enough space, need to add page
+                                                       $pdf->AddPage('', '', true);
+                                                       $pagenb++;
+                                                       $pageposafternote++;
+                                                       $pdf->setPage($pageposafternote);
+                                                       if (!empty($tplidx)) {
+                                                               $pdf->useTemplate($tplidx);
+                                                       }
+                                                       if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
+                                                               $this->_pagehead($pdf, $object, 0, $outputlangs);
+                                                       }
+
+                                                       $posyafter = $tab_top_newpage;
+                                               }
+                                       }
+                                       $tab_height = $tab_height - $height_note;
+                                       $tab_top = $posyafter + 6;
+                               } else {
+                                       $height_note = 0;
+                               }
+
+                               // Use new auto column system
+                               $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
+
+                               // Table simulation to know the height of the title line
+                               $pdf->startTransaction();
+                               $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
+                               $pdf->rollbackTransaction(true);
+
+                               $nexY = $tab_top + $this->tabTitleHeight;
+
+                               // Loop on each lines
+                               $pageposbeforeprintlines = $pdf->getPage();
+                               $pagenb = $pageposbeforeprintlines;
+                               for ($i = 0; $i < $nblines; $i++) {
+                                       $curY = $nexY;
+                                       $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
+                                       $pdf->SetTextColor(0, 0, 0);
+
+                                       // Define size of image if we need it
+                                       $imglinesize = array();
+                                       if (!empty($realpatharray[$i])) {
+                                               $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
+                                       }
+
+                                       $pdf->setTopMargin($tab_top_newpage);
+                                       $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
+                                       $pageposbefore = $pdf->getPage();
+
+                                       $showpricebeforepagebreak = 1;
+                                       $posYAfterImage = 0;
+                                       $posYAfterDescription = 0;
+
+                                       if ($this->getColumnStatus('photo')) {
+                                               // We start with Photo of product line
+                                               if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot))) {    // If photo too high, we moved completely on new page
+                                                       $pdf->AddPage('', '', true);
+                                                       if (!empty($tplidx)) {
+                                                               $pdf->useTemplate($tplidx);
+                                                       }
+                                                       $pdf->setPage($pageposbefore + 1);
+
+                                                       $curY = $tab_top_newpage;
+
+                                                       // Allows data in the first page if description is long enough to break in multiples pages
+                                                       if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
+                                                               $showpricebeforepagebreak = 1;
+                                                       } else {
+                                                               $showpricebeforepagebreak = 0;
+                                                       }
+                                               }
+
+
+                                               if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) {
+                                                       $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY + 1, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
+                                                       // $pdf->Image does not increase value return by getY, so we save it manually
+                                                       $posYAfterImage = $curY + $imglinesize['height'];
+                                               }
+                                       }
+
+                                       // Description of product line
+                                       if ($this->getColumnStatus('desc')) {
+                                               $pdf->startTransaction();
+
+                                               $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
+                                               $pageposafter = $pdf->getPage();
+
+                                               if ($pageposafter > $pageposbefore) {   // There is a pagebreak
+                                                       $pdf->rollbackTransaction(true);
+
+                                                       $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
+
+                                                       $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
+
+                                                       $pageposafter = $pdf->getPage();
+                                                       $posyafter = $pdf->GetY();
+                                                       //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
+                                                       if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforsignature + $heightforinfotot))) {   // There is no space left for total+free text
+                                                               if ($i == ($nblines - 1)) {     // No more lines, and no space left to show total, so we create a new page
+                                                                       $pdf->AddPage('', '', true);
+                                                                       if (!empty($tplidx)) {
+                                                                               $pdf->useTemplate($tplidx);
+                                                                       }
+                                                                       $pdf->setPage($pageposafter + 1);
+                                                               }
+                                                       } else {
+                                                               // We found a page break
+                                                               // Allows data in the first page if description is long enough to break in multiples pages
+                                                               if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
+                                                                       $showpricebeforepagebreak = 1;
+                                                               } else {
+                                                                       $showpricebeforepagebreak = 0;
+                                                               }
+                                                       }
+                                               } else // No pagebreak
+                                               {
+                                                       $pdf->commitTransaction();
+                                               }
+                                               $posYAfterDescription = $pdf->GetY();
+                                       }
+
+                                       $nexY = $pdf->GetY();
+                                       $pageposafter = $pdf->getPage();
+
+                                       $pdf->setPage($pageposbefore);
+                                       $pdf->setTopMargin($this->marge_haute);
+                                       $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
+
+                                       // We suppose that a too long description or photo were moved completely on next page
+                                       if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
+                                               $pdf->setPage($pageposafter);
+                                               $curY = $tab_top_newpage;
+                                       }
+
+                                       $pdf->SetFont('', '', $default_font_size - 1); // We reposition the default font
+
+                                       // VAT Rate
+                                       if ($this->getColumnStatus('vat')) {
+                                               $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
+                                               $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
+                                               $nexY = max($pdf->GetY(), $nexY);
+                                       }
+
+                                       // Unit price before discount
+                                       if ($this->getColumnStatus('subprice')) {
+                                               $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
+                                               $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
+                                               $nexY = max($pdf->GetY(), $nexY);
+                                       }
+
+                                       // Quantity
+                                       // Enough for 6 chars
+                                       if ($this->getColumnStatus('qty')) {
+                                               $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
+                                               $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
+                                               $nexY = max($pdf->GetY(), $nexY);
+                                       }
+
+
+                                       // Unit
+                                       if ($this->getColumnStatus('unit')) {
+                                               $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
+                                               $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
+                                               $nexY = max($pdf->GetY(), $nexY);
+                                       }
+
+                                       // Discount on line
+                                       if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) {
+                                               $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
+                                               $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
+                                               $nexY = max($pdf->GetY(), $nexY);
+                                       }
+
+                                       // Total excl tax line (HT)
+                                       if ($this->getColumnStatus('totalexcltax')) {
+                                               $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
+                                               $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
+                                               $nexY = max($pdf->GetY(), $nexY);
+                                       }
+
+                                       // Total with tax line (TTC)
+                                       if ($this->getColumnStatus('totalincltax')) {
+                                               $total_incl_tax = pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails);
+                                               $this->printStdColumnContent($pdf, $curY, 'totalincltax', $total_incl_tax);
+                                               $nexY = max($pdf->GetY(), $nexY);
+                                       }
+
+                                       // Extrafields
+                                       if (!empty($object->lines[$i]->array_options)) {
+                                               foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) {
+                                                       if ($this->getColumnStatus($extrafieldColKey)) {
+                                                               $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs);
+                                                               $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
+                                                               $nexY = max($pdf->GetY(), $nexY);
+                                                       }
+                                               }
+                                       }
+
+                                       $parameters = array(
+                                               'object' => $object,
+                                               'i' => $i,
+                                               'pdf' =>& $pdf,
+                                               'curY' =>& $curY,
+                                               'nexY' =>& $nexY,
+                                               'outputlangs' => $outputlangs,
+                                               'hidedetails' => $hidedetails
+                                       );
+                                       $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook
+
+
+                                       // Collection of totals by value of vat in $this->tva["rate"] = total_tva
+                                       if (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) {
+                                               $tvaligne = $object->lines[$i]->multicurrency_total_tva;
+                                       } else {
+                                               $tvaligne = $object->lines[$i]->total_tva;
+                                       }
+
+                                       $localtax1ligne = $object->lines[$i]->total_localtax1;
+                                       $localtax2ligne = $object->lines[$i]->total_localtax2;
+                                       $localtax1_rate = $object->lines[$i]->localtax1_tx;
+                                       $localtax2_rate = $object->lines[$i]->localtax2_tx;
+                                       $localtax1_type = $object->lines[$i]->localtax1_type;
+                                       $localtax2_type = $object->lines[$i]->localtax2_type;
+
+                                       if ($object->remise_percent) {
+                                               $tvaligne -= ($tvaligne * $object->remise_percent) / 100;
+                                       }
+                                       if ($object->remise_percent) {
+                                               $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100;
+                                       }
+                                       if ($object->remise_percent) {
+                                               $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
+                                       }
+
+                                       $vatrate = (string) $object->lines[$i]->tva_tx;
+
+                                       // Retrieve type from database for backward compatibility with old records
+                                       if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
+                                       && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
+                                               $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
+                                               $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
+                                               $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
+                                       }
+
+                                       // retrieve global local tax
+                                       if ($localtax1_type && $localtax1ligne != 0) {
+                                               $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
+                                       }
+                                       if ($localtax2_type && $localtax2ligne != 0) {
+                                               $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
+                                       }
+
+                                       if (($object->lines[$i]->info_bits & 0x01) == 0x01) {
+                                               $vatrate .= '*';
+                                       }
+
+                                       // Fill $this->tva and $this->tva_array
+                                       if (!isset($this->tva[$vatrate])) {
+                                               $this->tva[$vatrate] = 0;
+                                       }
+                                       $this->tva[$vatrate] += $tvaligne;
+                                       $vatcode = $object->lines[$i]->vat_src_code;
+                                       if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) {
+                                               $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0;
+                                       }
+                                       $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate'=>$vatrate, 'vatcode'=>$vatcode, 'amount'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne);
+
+                                       if ($posYAfterImage > $posYAfterDescription) {
+                                               $nexY = max($nexY, $posYAfterImage);
+                                       }
+
+                                       // Add line
+                                       if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) {
+                                               $pdf->setPage($pageposafter);
+                                               $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
+                                               //$pdf->SetDrawColor(190,190,200);
+                                               $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1);
+                                               $pdf->SetLineStyle(array('dash'=>0));
+                                       }
+
+                                       $nexY += 2; // Add space between lines
+
+                                       // Detect if some page were added automatically and output _tableau for past pages
+                                       while ($pagenb < $pageposafter) {
+                                               $pdf->setPage($pagenb);
+                                               if ($pagenb == $pageposbeforeprintlines) {
+                                                       $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
+                                               } else {
+                                                       $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
+                                               }
+                                               $this->_pagefoot($pdf, $object, $outputlangs, 1);
+                                               $pagenb++;
+                                               $pdf->setPage($pagenb);
+                                               $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
+                                               if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
+                                                       $this->_pagehead($pdf, $object, 0, $outputlangs);
+                                               }
+                                               if (!empty($tplidx)) {
+                                                       $pdf->useTemplate($tplidx);
+                                               }
+                                       }
+
+                                       if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
+                                               if ($pagenb == $pageposafter) {
+                                                       $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
+                                               } else {
+                                                       $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
+                                               }
+                                               $this->_pagefoot($pdf, $object, $outputlangs, 1);
+                                               // New page
+                                               $pdf->AddPage();
+                                               if (!empty($tplidx)) {
+                                                       $pdf->useTemplate($tplidx);
+                                               }
+                                               $pagenb++;
+                                               if (!getDolGlobalInt('MAIN_PDF_DONOTREPEAT_HEAD')) {
+                                                       $this->_pagehead($pdf, $object, 0, $outputlangs);
+                                               }
+                                       }
+                               }
+
+                               // Show square
+                               if ($pagenb == $pageposbeforeprintlines) {
+                                       $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis);
+                                       $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1;
+                               } else {
+                                       $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis);
+                                       $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1;
+                               }
+
+                               // Display infos area
+                               $posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
+
+                               // Display total zone
+                               $posy = $this->drawTotalTable($pdf, $object, 0, $bottomlasttab, $outputlangs);
+
+                               // Display payment area
+                               /*
+                               if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included)
+                               {
+                                       $posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
+                               }
+                               */
+
+                               // Customer signature area
+                               if (empty($conf->global->PROPAL_DISABLE_SIGNATURE)) {
+                                       $posy = $this->drawSignatureArea($pdf, $object, $posy, $outputlangs);
+                               }
+
+                               // Pagefoot
+                               $this->_pagefoot($pdf, $object, $outputlangs);
+                               if (method_exists($pdf, 'AliasNbPages')) {
+                                       $pdf->AliasNbPages();
+                               }
+
+                               //If propal merge product PDF is active
+                               if (!empty($conf->global->PRODUIT_PDF_MERGE_PROPAL)) {
+                                       require_once DOL_DOCUMENT_ROOT.'/product/class/propalmergepdfproduct.class.php';
+
+                                       $already_merged = array();
+                                       foreach ($object->lines as $line) {
+                                               if (!empty($line->fk_product) && !(in_array($line->fk_product, $already_merged))) {
+                                                       // Find the desire PDF
+                                                       $filetomerge = new Propalmergepdfproduct($this->db);
+
+                                                       if (getDolGlobalInt('MAIN_MULTILANGS')) {
+                                                               $filetomerge->fetch_by_product($line->fk_product, $outputlangs->defaultlang);
+                                                       } else {
+                                                               $filetomerge->fetch_by_product($line->fk_product);
+                                                       }
+
+                                                       $already_merged[] = $line->fk_product;
+
+                                                       $product = new Product($this->db);
+                                                       $product->fetch($line->fk_product);
+
+                                                       if ($product->entity != $conf->entity) {
+                                                               $entity_product_file = $product->entity;
+                                                       } else {
+                                                               $entity_product_file = $conf->entity;
+                                                       }
+
+                                                       // If PDF is selected and file is not empty
+                                                       if (count($filetomerge->lines) > 0) {
+                                                               foreach ($filetomerge->lines as $linefile) {
+                                                                       if (!empty($linefile->id) && !empty($linefile->file_name)) {
+                                                                               if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
+                                                                                       if (isModEnabled("product")) {
+                                                                                               $filetomerge_dir = $conf->product->multidir_output[$entity_product_file].'/'.get_exdir($product->id, 2, 0, 0, $product, 'product').$product->id."/photos";
+                                                                                       } elseif (isModEnabled("service")) {
+                                                                                               $filetomerge_dir = $conf->service->multidir_output[$entity_product_file].'/'.get_exdir($product->id, 2, 0, 0, $product, 'product').$product->id."/photos";
+                                                                                       }
+                                                                               } else {
+                                                                                       if (isModEnabled("product")) {
+                                                                                               $filetomerge_dir = $conf->product->multidir_output[$entity_product_file].'/'.get_exdir(0, 0, 0, 0, $product, 'product');
+                                                                                       } elseif (isModEnabled("service")) {
+                                                                                               $filetomerge_dir = $conf->service->multidir_output[$entity_product_file].'/'.get_exdir(0, 0, 0, 0, $product, 'product');
+                                                                                       }
+                                                                               }
+
+                                                                               dol_syslog(get_class($this).':: upload_dir='.$filetomerge_dir, LOG_DEBUG);
+
+                                                                               $infile = $filetomerge_dir.'/'.$linefile->file_name;
+                                                                               if (file_exists($infile) && is_readable($infile)) {
+                                                                                       $pagecount = $pdf->setSourceFile($infile);
+                                                                                       for ($i = 1; $i <= $pagecount; $i++) {
+                                                                                               $tplIdx = $pdf->importPage($i);
+                                                                                               if ($tplIdx !== false) {
+                                                                                                       $s = $pdf->getTemplatesize($tplIdx);
+                                                                                                       $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
+                                                                                                       $pdf->useTemplate($tplIdx);
+                                                                                               } else {
+                                                                                                       setEventMessages(null, array($infile.' cannot be added, probably protected PDF'), 'warnings');
+                                                                                               }
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               $pdf->Close();
+
+                               $pdf->Output($file, 'F');
+
+                               //Add pdfgeneration hook
+                               $hookmanager->initHooks(array('pdfgeneration'));
+                               $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) {
+                                       $this->error = $hookmanager->error;
+                                       $this->errors = $hookmanager->errors;
+                               }
+
+                               if (!empty($conf->global->MAIN_UMASK)) {
+                                       @chmod($file, octdec($conf->global->MAIN_UMASK));
+                               }
+
+                               $this->result = array('fullpath'=>$file);
+
+                               return 1; // No error
+                       } else {
+                               $this->error = $langs->trans("ErrorCanNotCreateDir", $dir);
+                               return 0;
+                       }
+               } else {
+                       $this->error = $langs->trans("ErrorConstantNotDefined", "PROP_OUTPUTDIR");
+                       return 0;
+               }
+       }
+
+       /**
+        *  Show payments table
+        *
+        *  @param      TCPDF           $pdf            Object PDF
+        *  @param  Propal              $object         Object proposal
+        *  @param  int                 $posy           Position y in PDF
+        *  @param  Translate   $outputlangs    Object langs for output
+        *  @return int                                 <0 if KO, >0 if OK
+        */
+       protected function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
+       {
+       }
+
+       /**
+        *   Show miscellaneous information (payment mode, payment term, ...)
+        *
+        *   @param             TCPDF           $pdf                    Object PDF
+        *   @param             Propal          $object                 Object to show
+        *   @param             int                     $posy                   Y
+        *   @param             Translate       $outputlangs    Langs object
+        *   @return    int                                                     Pos y
+        */
+       public function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
+       {
+               global $conf, $mysoc;
+               $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+               $pdf->SetFont('', '', $default_font_size - 1);
+
+               // If France, show VAT mention if not applicable
+               if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
+                       $pdf->SetFont('', 'B', $default_font_size - 2);
+                       $pdf->SetXY($this->marge_gauche, $posy);
+                       $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
+
+                       $posy = $pdf->GetY() + 4;
+               }
+
+               $posxval = 52;
+               if (!empty($conf->global->MAIN_PDF_DATE_TEXT)) {
+                       $displaydate = "daytext";
+               } else {
+                       $displaydate = "day";
+               }
+
+               // Show shipping date
+               if (!empty($object->delivery_date)) {
+                       $outputlangs->load("sendings");
+                       $pdf->SetFont('', 'B', $default_font_size - 2);
+                       $pdf->SetXY($this->marge_gauche, $posy);
+                       $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':';
+                       $pdf->MultiCell(80, 4, $titre, 0, 'L');
+                       $pdf->SetFont('', '', $default_font_size - 2);
+                       $pdf->SetXY($posxval, $posy);
+                       $dlp = dol_print_date($object->delivery_date, $displaydate, false, $outputlangs, true);
+                       $pdf->MultiCell(80, 4, $dlp, 0, 'L');
+
+                       $posy = $pdf->GetY() + 1;
+               } elseif ($object->availability_code || $object->availability) {    // Show availability conditions
+                       $pdf->SetFont('', 'B', $default_font_size - 2);
+                       $pdf->SetXY($this->marge_gauche, $posy);
+                       $titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
+                       $pdf->MultiCell(80, 4, $titre, 0, 'L');
+                       $pdf->SetTextColor(0, 0, 0);
+                       $pdf->SetFont('', '', $default_font_size - 2);
+                       $pdf->SetXY($posxval, $posy);
+                       $lib_availability = $outputlangs->transnoentities("AvailabilityType".$object->availability_code) != ('AvailabilityType'.$object->availability_code) ? $outputlangs->transnoentities("AvailabilityType".$object->availability_code) : $outputlangs->convToOutputCharset($object->availability);
+                       $lib_availability = str_replace('\n', "\n", $lib_availability);
+                       $pdf->MultiCell(80, 4, $lib_availability, 0, 'L');
+
+                       $posy = $pdf->GetY() + 1;
+               }
+
+               // Show delivery mode
+               if (empty($conf->global->PROPOSAL_PDF_HIDE_DELIVERYMODE) && $object->shipping_method_id > 0) {
+                       $outputlangs->load("sendings");
+
+                       $shipping_method_id = $object->shipping_method_id;
+                       if (!empty($conf->global->SOCIETE_ASK_FOR_SHIPPING_METHOD) && !empty($this->emetteur->shipping_method_id)) {
+                               $shipping_method_id = $this->emetteur->shipping_method_id;
+                       }
+                       $shipping_method_code = dol_getIdFromCode($this->db, $shipping_method_id, 'c_shipment_mode', 'rowid', 'code');
+                       $shipping_method_label = dol_getIdFromCode($this->db, $shipping_method_id, 'c_shipment_mode', 'rowid', 'libelle');
+
+                       $pdf->SetFont('', 'B', $default_font_size - 2);
+                       $pdf->SetXY($this->marge_gauche, $posy);
+                       $titre = $outputlangs->transnoentities("SendingMethod").':';
+                       $pdf->MultiCell(43, 4, $titre, 0, 'L');
+
+                       $pdf->SetFont('', '', $default_font_size - 2);
+                       $pdf->SetXY($posxval, $posy);
+                       $lib_condition_paiement = ($outputlangs->transnoentities("SendingMethod".strtoupper($shipping_method_code)) != "SendingMethod".strtoupper($shipping_method_code)) ? $outputlangs->trans("SendingMethod".strtoupper($shipping_method_code)) : $shipping_method_label;
+                       $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
+                       $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
+
+                       $posy = $pdf->GetY() + 1;
+               }
+
+               // Show payments conditions
+               if (empty($conf->global->PROPOSAL_PDF_HIDE_PAYMENTTERM) && $object->cond_reglement_code) {
+                       $pdf->SetFont('', 'B', $default_font_size - 2);
+                       $pdf->SetXY($this->marge_gauche, $posy);
+                       $titre = $outputlangs->transnoentities("PaymentConditions").':';
+                       $pdf->MultiCell(43, 4, $titre, 0, 'L');
+
+                       $pdf->SetFont('', '', $default_font_size - 2);
+                       $pdf->SetXY($posxval, $posy);
+                       $lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != ('PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement_label);
+                       $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement);
+                       if ($object->deposit_percent > 0) {
+                               $lib_condition_paiement = str_replace('__DEPOSIT_PERCENT__', $object->deposit_percent, $lib_condition_paiement);
+                       }
+                       $pdf->MultiCell(67, 4, $lib_condition_paiement, 0, 'L');
+
+                       $posy = $pdf->GetY() + 3;
+               }
+
+               if (empty($conf->global->PROPOSAL_PDF_HIDE_PAYMENTMODE)) {
+                       // Show payment mode
+                       if ($object->mode_reglement_code
+                       && $object->mode_reglement_code != 'CHQ'
+                       && $object->mode_reglement_code != 'VIR') {
+                               $pdf->SetFont('', 'B', $default_font_size - 2);
+                               $pdf->SetXY($this->marge_gauche, $posy);
+                               $titre = $outputlangs->transnoentities("PaymentMode").':';
+                               $pdf->MultiCell(80, 5, $titre, 0, 'L');
+                               $pdf->SetFont('', '', $default_font_size - 2);
+                               $pdf->SetXY($posxval, $posy);
+                               $lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement);
+                               $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L');
+
+                               $posy = $pdf->GetY() + 2;
+                       }
+
+                       // Show payment mode CHQ
+                       if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') {
+                               // Si mode reglement non force ou si force a CHQ
+                               if (!empty($conf->global->FACTURE_CHQ_NUMBER)) {
+                                       $diffsizetitle = (empty($conf->global->PDF_DIFFSIZE_TITLE) ? 3 : $conf->global->PDF_DIFFSIZE_TITLE);
+
+                                       if ($conf->global->FACTURE_CHQ_NUMBER > 0) {
+                                               $account = new Account($this->db);
+                                               $account->fetch($conf->global->FACTURE_CHQ_NUMBER);
+
+                                               $pdf->SetXY($this->marge_gauche, $posy);
+                                               $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
+                                               $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $account->proprio), 0, 'L', 0);
+                                               $posy = $pdf->GetY() + 1;
+
+                                               if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) {
+                                                       $pdf->SetXY($this->marge_gauche, $posy);
+                                                       $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
+                                                       $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
+                                                       $posy = $pdf->GetY() + 2;
+                                               }
+                                       }
+                                       if ($conf->global->FACTURE_CHQ_NUMBER == -1) {
+                                               $pdf->SetXY($this->marge_gauche, $posy);
+                                               $pdf->SetFont('', 'B', $default_font_size - $diffsizetitle);
+                                               $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo', $this->emetteur->name), 0, 'L', 0);
+                                               $posy = $pdf->GetY() + 1;
+
+                                               if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) {
+                                                       $pdf->SetXY($this->marge_gauche, $posy);
+                                                       $pdf->SetFont('', '', $default_font_size - $diffsizetitle);
+                                                       $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
+                                                       $posy = $pdf->GetY() + 2;
+                                               }
+                                       }
+                               }
+                       }
+
+                       // If payment mode not forced or forced to VIR, show payment with BAN
+                       if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') {
+                               if ($object->fk_account > 0 || $object->fk_bank > 0 || getDolGlobalInt('FACTURE_RIB_NUMBER')) {
+                                       $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account);
+                                       if ($object->fk_bank > 0) {
+                                               $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
+                                       }
+                                       $account = new Account($this->db);
+                                       $account->fetch($bankid);
+
+                                       $curx = $this->marge_gauche;
+                                       $cury = $posy;
+
+                                       $posy = pdf_bank($pdf, $outputlangs, $curx, $cury, $account, 0, $default_font_size);
+
+                                       $posy += 2;
+                               }
+                       }
+               }
+
+               return $posy;
+       }
+
+
+       /**
+        *      Show total to pay
+        *
+        *      @param  TCPDF           $pdf            Object PDF
+        *      @param  Propal          $object         Object proposal
+        *      @param  int                     $deja_regle     Amount already paid (in the currency of invoice)
+        *      @param  int                     $posy                   Position depart
+        *      @param  Translate       $outputlangs    Objet langs
+        *  @param  Translate   $outputlangsbis Object lang for output bis
+        *      @return int                                                     Position pour suite
+        */
+       protected function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs, $outputlangsbis = null)
+       {
+               global $conf, $mysoc, $hookmanager;
+
+               $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+               if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
+                       $outputlangsbis = new Translate('', $conf);
+                       $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
+                       $outputlangsbis->loadLangs(array("main", "dict", "companies", "bills", "products", "propal"));
+                       $default_font_size--;
+               }
+
+               $tab2_top = $posy;
+               $tab2_hl = 4;
+               $pdf->SetFont('', '', $default_font_size - 1);
+
+               // Total table
+               $col1x = 120;
+               $col2x = 170;
+               if ($this->page_largeur < 210) { // To work with US executive format
+                       $col2x -= 20;
+               }
+               $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
+
+               $useborder = 0;
+               $index = 0;
+
+               // Total HT
+               $pdf->SetFillColor(255, 255, 255);
+               $pdf->SetXY($col1x, $tab2_top + 0);
+               $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalHT") : ''), 0, 'L', 1);
+
+               $total_ht = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ht : $object->total_ht);
+               $pdf->SetXY($col2x, $tab2_top + 0);
+               $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (!empty($object->remise) ? $object->remise : 0), 0, $outputlangs), 0, 'R', 1);
+
+               // Show VAT by rates and total
+               $pdf->SetFillColor(248, 248, 248);
+
+               $total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
+
+               $this->atleastoneratenotnull = 0;
+               if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) {
+                       $tvaisnull = ((!empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
+                       if (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull) {
+                               // Nothing to do
+                       } else {
+                               //Local tax 1 before VAT
+                               //if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
+                               //{
+                               foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
+                                       if (in_array((string) $localtax_type, array('1', '3', '5'))) {
+                                               continue;
+                                       }
+
+                                       foreach ($localtax_rate as $tvakey => $tvaval) {
+                                               if ($tvakey != 0) {    // On affiche pas taux 0
+                                                       //$this->atleastoneratenotnull++;
+
+                                                       $index++;
+                                                       $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+                                                       $tvacompl = '';
+                                                       if (preg_match('/\*/', $tvakey)) {
+                                                               $tvakey = str_replace('*', '', $tvakey);
+                                                               $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+                                                       }
+                                                       $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
+                                                       $totalvat .= ' ';
+                                                       $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
+                                                       $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+                                                       $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+                                                       $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+                                               }
+                                       }
+                               }
+                               //}
+                               //Local tax 2 before VAT
+                               //if (!empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
+                               //{
+                               foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
+                                       if (in_array((string) $localtax_type, array('1', '3', '5'))) {
+                                               continue;
+                                       }
+
+                                       foreach ($localtax_rate as $tvakey => $tvaval) {
+                                               if ($tvakey != 0) {    // On affiche pas taux 0
+                                                       //$this->atleastoneratenotnull++;
+
+
+
+                                                       $index++;
+                                                       $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+                                                       $tvacompl = '';
+                                                       if (preg_match('/\*/', $tvakey)) {
+                                                               $tvakey = str_replace('*', '', $tvakey);
+                                                               $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+                                                       }
+                                                       $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
+                                                       $totalvat .= ' ';
+                                                       $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
+                                                       $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+                                                       $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+                                                       $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+                                               }
+                                       }
+                               }
+                               //}
+
+                               // VAT
+                               foreach ($this->tva as $tvakey => $tvaval) {
+                                       if ($tvakey != 0) {    // On affiche pas taux 0
+                                               $this->atleastoneratenotnull++;
+
+                                               $index++;
+                                               $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+                                               $tvacompl = '';
+                                               if (preg_match('/\*/', $tvakey)) {
+                                                       $tvakey = str_replace('*', '', $tvakey);
+                                                       $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+                                               }
+                                               $totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalVAT", $mysoc->country_code) : '');
+                                               $totalvat .= ' ';
+                                               $totalvat .= vatrate($tvakey, 1).$tvacompl;
+                                               $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+                                               $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+                                               $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+                                       }
+                               }
+
+                               //Local tax 1 after VAT
+                               //if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
+                               //{
+                               foreach ($this->localtax1 as $localtax_type => $localtax_rate) {
+                                       if (in_array((string) $localtax_type, array('2', '4', '6'))) {
+                                               continue;
+                                       }
+
+                                       foreach ($localtax_rate as $tvakey => $tvaval) {
+                                               if ($tvakey != 0) {    // On affiche pas taux 0
+                                                       //$this->atleastoneratenotnull++;
+
+                                                       $index++;
+                                                       $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+                                                       $tvacompl = '';
+                                                       if (preg_match('/\*/', $tvakey)) {
+                                                               $tvakey = str_replace('*', '', $tvakey);
+                                                               $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+                                                       }
+                                                       $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT1", $mysoc->country_code) : '');
+                                                       $totalvat .= ' ';
+
+                                                       $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
+                                                       $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+                                                       $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+                                                       $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+                                               }
+                                       }
+                               }
+                               //}
+                               //Local tax 2 after VAT
+                               //if (!empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
+                               //{
+                               foreach ($this->localtax2 as $localtax_type => $localtax_rate) {
+                                       if (in_array((string) $localtax_type, array('2', '4', '6'))) {
+                                               continue;
+                                       }
+
+                                       foreach ($localtax_rate as $tvakey => $tvaval) {
+                                               // retrieve global local tax
+                                               if ($tvakey != 0) {    // On affiche pas taux 0
+                                                       //$this->atleastoneratenotnull++;
+
+                                                       $index++;
+                                                       $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+                                                       $tvacompl = '';
+                                                       if (preg_match('/\*/', $tvakey)) {
+                                                               $tvakey = str_replace('*', '', $tvakey);
+                                                               $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+                                                       }
+                                                       $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalLT2", $mysoc->country_code) : '');
+                                                       $totalvat .= ' ';
+
+                                                       $totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
+                                                       $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+                                                       $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+                                                       $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+                                               }
+                                       }
+                               }
+                               //}
+
+                               // Total TTC
+                               $index++;
+                               $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+                               $pdf->SetTextColor(0, 0, 60);
+                               $pdf->SetFillColor(224, 224, 224);
+                               $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("TotalTTC") : ''), $useborder, 'L', 1);
+
+                               $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+                               $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1);
+                       }
+               }
+
+               $pdf->SetTextColor(0, 0, 0);
+
+               $resteapayer = 0;
+               /*
+               $resteapayer = $object->total_ttc - $deja_regle;
+               if (!empty($object->paye)) $resteapayer=0;
+               */
+
+               if ($deja_regle > 0) {
+                       // Already paid + Deposits
+                       $index++;
+
+                       $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+                       $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("AlreadyPaid") : ''), 0, 'L', 0);
+
+                       $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+                       $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0);
+
+                       /*
+                       if ($object->close_code == 'discount_vat')
+                       {
+                               $index++;
+                               $pdf->SetFillColor(255,255,255);
+
+                               $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+                               $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort"), $useborder, 'L', 1);
+
+                               $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+                               $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle, 0, $outputlangs), $useborder, 'R', 1);
+
+                               $resteapayer=0;
+                       }
+                       */
+
+                       $index++;
+                       $pdf->SetTextColor(0, 0, 60);
+                       $pdf->SetFillColor(224, 224, 224);
+                       $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+                       $pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay").(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transnoentities("RemainderToPay") : ''), $useborder, 'L', 1);
+
+                       $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+                       $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
+
+                       $pdf->SetFont('', '', $default_font_size - 1);
+                       $pdf->SetTextColor(0, 0, 0);
+               }
+
+               $index++;
+               return ($tab2_top + ($tab2_hl * $index));
+       }
+
+       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
+       /**
+        *   Show table for lines
+        *
+        *   @param             TCPDF           $pdf                    Object PDF
+        *   @param             string          $tab_top                Top position of table
+        *   @param             string          $tab_height             Height of table (rectangle)
+        *   @param             int                     $nexY                   Y (not used)
+        *   @param             Translate       $outputlangs    Langs object
+        *   @param             int                     $hidetop                1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
+        *   @param             int                     $hidebottom             Hide bottom bar of array
+        *   @param             string          $currency               Currency code
+        *   @param             Translate       $outputlangsbis Langs object bis
+        *   @return    void
+        */
+       protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
+       {
+               global $conf;
+
+               // Force to disable hidetop and hidebottom
+               $hidebottom = 0;
+               if ($hidetop) {
+                       $hidetop = -1;
+               }
+
+               $currency = !empty($currency) ? $currency : $conf->currency;
+               $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+               // Amount in (at tab_top - 1)
+               $pdf->SetTextColor(0, 0, 0);
+               $pdf->SetFont('', '', $default_font_size - 2);
+
+               if (empty($hidetop)) {
+                       $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
+                       if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
+                               $titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency));
+                       }
+
+                       $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
+                       $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
+
+                       //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
+                       if (!empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) {
+                               $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, 'F', null, explode(',', $conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
+                       }
+               }
+
+               $pdf->SetDrawColor(128, 128, 128);
+               $pdf->SetFont('', '', $default_font_size - 1);
+
+               // Output Rect
+               if (empty($conf->global->MAIN_PDF_PROPAL_NOLINES)){
+                       $this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect takes a length in 3rd parameter and 4th parameter
+               }       
+               $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
+
+               if (empty($hidetop)) {
+                       $pdf->line($this->marge_gauche, $tab_top + $this->tabTitleHeight, $this->page_largeur - $this->marge_droite, $tab_top + $this->tabTitleHeight); // line takes a position y in 2nd parameter and 4th parameter
+               }
+       }
+
+       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
+       /**
+        *  Show top header of page.
+        *
+        *  @param      TCPDF           $pdf                    Object PDF
+        *  @param  Propal              $object         Object to show
+        *  @param  int         $showaddress    0=no, 1=yes
+        *  @param  Translate   $outputlangs    Object lang for output
+        *  @param  Translate   $outputlangsbis Object lang for output bis
+        *  @return     void
+        */
+       protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null)
+       {
+               global $conf, $langs;
+
+               $ltrdirection = 'L';
+               if ($outputlangs->trans("DIRECTION") == 'rtl') $ltrdirection = 'R';
+
+               // Load traductions files required by page
+               $outputlangs->loadLangs(array("main", "propal", "companies", "bills"));
+
+               $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+               pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
+
+               $pdf->SetTextColor(0, 0, 60);
+               $pdf->SetFont('', 'B', $default_font_size + 3);
+
+               $w = 100;
+
+               $posy = $this->marge_haute;
+               $posx = $this->page_largeur - $this->marge_droite - $w;
+
+               $pdf->SetXY($this->marge_gauche, $posy);
+
+               // Logo
+               if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) {
+                       if ($this->emetteur->logo) {
+                               $logodir = $conf->mycompany->dir_output;
+                               if (!empty($conf->mycompany->multidir_output[$object->entity])) {
+                                       $logodir = $conf->mycompany->multidir_output[$object->entity];
+                               }
+                               if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) {
+                                       $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
+                               } else {
+                                       $logo = $logodir.'/logos/'.$this->emetteur->logo;
+                               }
+                               if (is_readable($logo)) {
+                                       $height = pdf_getHeightForLogo($logo);
+                                       $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
+                               } else {
+                                       $pdf->SetTextColor(200, 0, 0);
+                                       $pdf->SetFont('', 'B', $default_font_size - 2);
+                                       $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
+                                       $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
+                               }
+                       } else {
+                               $text = $this->emetteur->name;
+                               $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, $ltrdirection);
+                       }
+               }
+
+               $pdf->SetFont('', 'B', $default_font_size + 3);
+               $pdf->SetXY($posx, $posy);
+               //$pdf->SetTextColor(0, 0, 60);
+               $title = $outputlangs->transnoentities("PdfCommercialProposalTitle");
+               $title .= ' '.$outputlangs->convToOutputCharset($object->ref);
+               // if ($object->statut == $object::STATUS_DRAFT) {
+               //      $pdf->SetTextColor(128, 0, 0);
+               //      $title .= ' - '.$outputlangs->transnoentities("NotValidated");
+               // }
+
+               $pdf->MultiCell($w, 4, $title, '', 'R');
+
+               $pdf->SetFont('', 'B', $default_font_size);
+
+               /*
+               $posy += 5;
+               $pdf->SetXY($posx, $posy);
+               $pdf->SetTextColor(0, 0, 60);
+               $textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref);
+               if ($object->statut == $object::STATUS_DRAFT) {
+                       $pdf->SetTextColor(128, 0, 0);
+                       $textref .= ' - '.$outputlangs->transnoentities("NotValidated");
+               }
+               $pdf->MultiCell($w, 4, $textref, '', 'R');
+               */
+
+               $posy += 3;
+               $pdf->SetFont('', '', $default_font_size - 2);
+
+               if ($object->ref_client) {
+                       $posy += 4;
+                       $pdf->SetXY($posx, $posy);
+                       $pdf->SetTextColor(0, 0, 60);
+                       $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".dol_trunc($outputlangs->convToOutputCharset($object->ref_client), 65), '', 'R');
+               }
+
+               if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) {
+                       $object->fetch_projet();
+                       if (!empty($object->project->ref)) {
+                               $posy += 3;
+                               $pdf->SetXY($posx, $posy);
+                               $pdf->SetTextColor(0, 0, 60);
+                               $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->project->title), '', 'R');
+                       }
+               }
+
+               if (!empty($conf->global->PDF_SHOW_PROJECT)) {
+                       $object->fetch_projet();
+                       if (!empty($object->project->ref)) {
+                               $outputlangs->load("projects");
+                               $posy += 3;
+                               $pdf->SetXY($posx, $posy);
+                               $pdf->SetTextColor(0, 0, 60);
+                               $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
+                       }
+               }
+
+               if (!empty($conf->global->MAIN_PDF_DATE_TEXT)) {
+                       $displaydate = "daytext";
+               } else {
+                       $displaydate = "day";
+               }
+
+               $posy += 4;
+               $pdf->SetXY($posx, $posy);
+               $pdf->SetTextColor(0, 0, 60);
+               $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Date")." : ".dol_print_date($object->date, $displaydate, false, $outputlangs, true), '', 'R');
+
+               $posy += 4;
+               $pdf->SetXY($posx, $posy);
+               $pdf->SetTextColor(0, 0, 60);
+
+               $title = $outputlangs->transnoentities("DateEndPropal");
+               if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
+                       $title .= ' - '.$outputlangsbis->transnoentities("DateEndPropal");
+               }
+               $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->fin_validite, $displaydate, false, $outputlangs, true), '', 'R');
+
+               if (empty($conf->global->MAIN_PDF_HIDE_CUSTOMER_CODE) && $object->thirdparty->code_client) {
+                       $posy += 4;
+                       $pdf->SetXY($posx, $posy);
+                       $pdf->SetTextColor(0, 0, 60);
+                       $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
+               }
+
+               // Get contact
+               if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) {
+                       $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
+                       if (count($arrayidcontact) > 0) {
+                               $usertmp = new User($this->db);
+                               $usertmp->fetch($arrayidcontact[0]);
+                               $posy += 4;
+                               $pdf->SetXY($posx, $posy);
+                               $pdf->SetTextColor(0, 0, 60);
+                               $pdf->MultiCell($w, 3, $langs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
+                       }
+               }
+
+               $posy += 2;
+
+               $top_shift = 0;
+               // Show list of linked objects
+               $current_y = $pdf->getY();
+               $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
+               if ($current_y < $pdf->getY()) {
+                       $top_shift = $pdf->getY() - $current_y;
+               }
+
+               if ($showaddress) {
+                       // Sender properties
+                       $carac_emetteur = '';
+                       // Add internal contact of proposal if defined
+                       $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
+                       if (count($arrayidcontact) > 0) {
+                               $object->fetch_user($arrayidcontact[0]);
+                               $labelbeforecontactname = ($outputlangs->transnoentities("FromContactName") != 'FromContactName' ? $outputlangs->transnoentities("FromContactName") : $outputlangs->transnoentities("Name"));
+                               $carac_emetteur .= ($carac_emetteur ? "\n" : '').$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";
+                       }
+
+                       $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
+
+                       // Show sender
+                       $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
+                       $posy += $top_shift;
+                       $posx = $this->marge_gauche;
+                       if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
+                               $posx = $this->page_largeur - $this->marge_droite - 80;
+                       }
+
+                       $hautcadre = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40;
+                       $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82;
+
+                       // Show sender frame
+                       if (empty($conf->global->MAIN_PDF_NO_SENDER_FRAME)) {
+                               $pdf->SetTextColor(0, 0, 0);
+                               $pdf->SetFont('', '', $default_font_size - 2);
+                               $pdf->SetXY($posx, $posy - 5);
+                               $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillFrom"), 0, $ltrdirection);
+                               $pdf->SetXY($posx, $posy);
+                               $pdf->SetFillColor(230, 230, 230);
+                               $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1);
+                               $pdf->SetTextColor(0, 0, 60);
+                       }
+
+                       // Show sender name
+                       if (empty($conf->global->MAIN_PDF_HIDE_SENDER_NAME)) {
+                               $pdf->SetXY($posx + 2, $posy + 3);
+                               $pdf->SetFont('', 'B', $default_font_size);
+                               $pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, $ltrdirection);
+                               $posy = $pdf->getY();
+                       }
+
+                       // Show sender information
+                       $pdf->SetXY($posx + 2, $posy);
+                       $pdf->SetFont('', '', $default_font_size - 1);
+                       //$pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, $ltrdirection);
+
+
+                       // If CUSTOMER contact defined, we use it
+                       $usecontact = false;
+                       $arrayidcontact = $object->getIdContact('external', 'CUSTOMER');
+                       if (count($arrayidcontact) > 0) {
+                               $usecontact = true;
+                               $result = $object->fetch_contact($arrayidcontact[0]);
+                       }
+
+                       // Recipient name
+                       if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) {
+                               $thirdparty = $object->contact;
+                       } else {
+                               $thirdparty = $object->thirdparty;
+                       }
+
+                       $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
+
+                       $mode = 'target';
+                       $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, $mode, $object);
+
+                       // Show recipient
+                       $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100;
+                       if ($this->page_largeur < 210) {
+                               $widthrecbox = 84; // To work with US executive format
+                       }
+                       $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
+                       $posy += $top_shift;
+                       $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
+                       if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
+                               $posx = $this->marge_gauche;
+                       }
+
+                       // Show recipient frame
+                       if (empty($conf->global->MAIN_PDF_NO_RECIPENT_FRAME)) {
+                               $pdf->SetTextColor(0, 0, 0);
+                               $pdf->SetFont('', '', $default_font_size - 2);
+                               $pdf->SetXY($posx + 2, $posy - 5);
+                               $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo"), 0, $ltrdirection);
+                               $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
+                       }
+
+                       // Show recipient name
+                       $pdf->SetXY($posx + 2, $posy + 3);
+                       $pdf->SetFont('', 'B', $default_font_size);
+                       $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, $ltrdirection);
+
+                       $posy = $pdf->getY();
+
+                       // Show recipient information
+                       $pdf->SetFont('', '', $default_font_size - 1);
+                       $pdf->SetXY($posx + 2, $posy);
+                       $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, $ltrdirection);
+               }
+
+               $pdf->SetTextColor(0, 0, 0);
+               return $top_shift;
+       }
+
+       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
+       /**
+        *      Show footer of page. Need this->emetteur object
+        *
+        *      @param  TCPDF           $pdf                            PDF
+        *              @param  Propal          $object                         Object to show
+        *      @param  Translate       $outputlangs            Object lang for output
+        *      @param  int                     $hidefreetext           1=Hide free text
+        *      @return int                                                             Return height of bottom margin including footer text
+        */
+       protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
+       {
+               global $conf;
+               if (empty($conf->global->MAIN_PDF_PROPAL_NOFOOT)){
+                       $showdetails = getDolGlobalInt('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', 0);
+                       return pdf_pagefoot($pdf, $outputlangs, 'PROPOSAL_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext, $this->page_largeur, $this->watermark);
+               }
+       }
+
+       /**
+        *      Show area for the customer to sign
+        *
+        *      @param  TCPDF           $pdf            Object PDF
+        *      @param  Propal          $object         Object proposal
+        *      @param  int                     $posy                   Position depart
+        *      @param  Translate       $outputlangs    Objet langs
+        *      @return int                                                     Position pour suite
+        */
+       protected function drawSignatureArea(&$pdf, $object, $posy, $outputlangs)
+       {
+               global $conf;
+               $default_font_size = pdf_getPDFFontSize($outputlangs);
+               $tab_top = $posy + 4;
+               $tab_hl = 4;
+
+               $posx = 120;
+               $largcol = ($this->page_largeur - $this->marge_droite - $posx);
+               $useborder = 0;
+               $index = 0;
+               // Total HT
+               $pdf->SetFillColor(255, 255, 255);
+               $pdf->SetXY($posx, $tab_top + 0);
+               $pdf->SetFont('', '', $default_font_size - 2);
+               $pdf->MultiCell($largcol, $tab_hl, $outputlangs->transnoentities("ProposalCustomerSignature"), 0, 'L', 1);
+
+               $pdf->SetXY($posx, $tab_top + $tab_hl);
+               $pdf->MultiCell($largcol, $tab_hl * 3, '', 1, 'R');
+               if (!empty($conf->global->MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING)) {
+                       $pdf->addEmptySignatureAppearance($posx, $tab_top + $tab_hl, $largcol, $tab_hl * 3);
+               }
+
+               return ($tab_hl * 7);
+       }
+
+
+       /**
+        *      Define Array Column Field
+        *
+        *      @param  Propal                  $object                 object proposal
+        *      @param  Translate               $outputlangs    langs
+        *      @param  int                             $hidedetails    Do not show line details
+        *      @param  int                             $hidedesc               Do not show desc
+        *      @param  int                             $hideref                Do not show ref
+        *      @return null
+        */
+       public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
+       {
+               global $conf, $hookmanager;
+
+               // Default field style for content
+               $this->defaultContentsFieldsStyle = array(
+                       'align' => 'R', // R,C,L
+                       'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+               );
+
+               // Default field style for content
+               $this->defaultTitlesFieldsStyle = array(
+                       'align' => 'C', // R,C,L
+                       'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+               );
+
+               /*
+                * For exemple
+                $this->cols['theColKey'] = array(
+                'rank' => $rank, // int : use for ordering columns
+                'width' => 20, // the column width in mm
+                'title' => array(
+                'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
+                'label' => ' ', // the final label : used fore final generated text
+                'align' => 'L', // text alignement :  R,C,L
+                'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+                ),
+                'content' => array(
+                'align' => 'L', // text alignement :  R,C,L
+                'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+                ),
+                );
+                */
+
+               $rank = 0; // do not use negative rank
+               $this->cols['desc'] = array(
+                       'rank' => $rank,
+                       'width' => false, // only for desc
+                       'status' => true,
+                       'title' => array(
+                               'textkey' => 'Designation', // use lang key is usefull in somme case with module
+                               'align' => 'L',
+                               // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
+                               // 'label' => ' ', // the final label
+                               'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+                       ),
+                       'content' => array(
+                               'align' => 'L',
+                               'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+                       ),
+               );
+
+               // Image of product
+               $rank = $rank + 10;
+               $this->cols['photo'] = array(
+                       'rank' => $rank,
+                       'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
+                       'status' => false,
+                       'title' => array(
+                               'textkey' => 'Photo',
+                               'label' => ' '
+                       ),
+                       'content' => array(
+                               'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+                       ),
+                       'border-left' => false, // remove left line separator
+               );
+
+               if (!empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE) && !empty($this->atleastonephoto)) {
+                       $this->cols['photo']['status'] = true;
+                       $this->cols['photo']['border-left'] = true;
+               }
+
+
+               $rank = $rank + 10;
+               $this->cols['vat'] = array(
+                       'rank' => $rank,
+                       'status' => false,
+                       'width' => 16, // in mm
+                       'title' => array(
+                               'textkey' => 'VAT'
+                       ),
+                       'border-left' => true, // add left line separator
+               );
+
+               if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) {
+                       $this->cols['vat']['status'] = true;
+               }
+
+               $rank = $rank + 10;
+               $this->cols['subprice'] = array(
+                       'rank' => $rank,
+                       'width' => 19, // in mm
+                       'status' => true,
+                       'title' => array(
+                               'textkey' => 'PriceUHT'
+                       ),
+                       'border-left' => true, // add left line separator
+               );
+
+               // Adapt dynamically the width of subprice, if text is too long.
+               $tmpwidth = 0;
+               $nblines = count($object->lines);
+               for ($i = 0; $i < $nblines; $i++) {
+                       $tmpwidth2 = dol_strlen(dol_string_nohtmltag(pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails)));
+                       $tmpwidth = max($tmpwidth, $tmpwidth2);
+               }
+               if ($tmpwidth > 10) {
+                       $this->cols['subprice']['width'] += (2 * ($tmpwidth - 10));
+               }
+
+               $rank = $rank + 10;
+               $this->cols['qty'] = array(
+                       'rank' => $rank,
+                       'width' => 16, // in mm
+                       'status' => true,
+                       'title' => array(
+                               'textkey' => 'Qty'
+                       ),
+                       'border-left' => true, // add left line separator
+               );
+
+               $rank = $rank + 10;
+               $this->cols['unit'] = array(
+                       'rank' => $rank,
+                       'width' => 11, // in mm
+                       'status' => false,
+                       'title' => array(
+                               'textkey' => 'Unit'
+                       ),
+                       'border-left' => true, // add left line separator
+               );
+               if (!empty($conf->global->PRODUCT_USE_UNITS)) {
+                       $this->cols['unit']['status'] = true;
+               }
+
+               $rank = $rank + 10;
+               $this->cols['discount'] = array(
+                       'rank' => $rank,
+                       'width' => 13, // in mm
+                       'status' => false,
+                       'title' => array(
+                               'textkey' => 'ReductionShort'
+                       ),
+                       'border-left' => true, // add left line separator
+               );
+               if ($this->atleastonediscount) {
+                       $this->cols['discount']['status'] = true;
+               }
+
+               $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
+               $this->cols['totalexcltax'] = array(
+                       'rank' => $rank,
+                       'width' => 26, // in mm
+                       'status' => empty($conf->global->PDF_PROPAL_HIDE_PRICE_EXCL_TAX) ? true : false,
+                       'title' => array(
+                               'textkey' => 'TotalHT'
+                       ),
+                       'border-left' => true, // add left line separator
+               );
+
+               $rank = $rank + 1010; // add a big offset to be sure is the last col because default extrafield rank is 100
+               $this->cols['totalincltax'] = array(
+                       'rank' => $rank,
+                       'width' => 26, // in mm
+                       'status' => empty($conf->global->PDF_PROPAL_SHOW_PRICE_INCL_TAX) ? false : true,
+                       'title' => array(
+                               'textkey' => 'TotalTTC'
+                       ),
+                       'border-left' => true, // add left line separator
+               );
+
+               // Add extrafields cols
+               if (!empty($object->lines)) {
+                       $line = reset($object->lines);
+                       $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
+               }
+
+               $parameters = array(
+                       'object' => $object,
+                       'outputlangs' => $outputlangs,
+                       'hidedetails' => $hidedetails,
+                       'hidedesc' => $hidedesc,
+                       'hideref' => $hideref
+               );
+
+               $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
+               if ($reshook < 0) {
+                       setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+               } elseif (empty($reshook)) {
+                       $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
+               } else {
+                       $this->cols = $hookmanager->resArray;
+               }
+       }
+}
index 5e517bc..f9a6c38 100644 (file)
@@ -956,9 +956,9 @@ class Emails extends CommonObject
                        foreach ($filter as $key => $value) {
                                if ($key == 't.rowid') {
                                        $sqlwhere[] = $key . '=' . $value;
-                               } elseif (in_array($this->fields[$key]['type'], ['date', 'datetime', 'timestamp'])) {
+                               } elseif (isset($this->fields[$key]['type']) && in_array($this->fields[$key]['type'], ['date', 'datetime', 'timestamp'])) {
                                        $sqlwhere[] = $key . ' = \'' . $this->db->idate($value) . '\'';
-                               } elseif ($key == 'customsql') {
+                               } elseif (isset($key) && $key == 'customsql') {
                                        $sqlwhere[] = $value;
                                } elseif (strpos($value, '%') === false) {
                                        $sqlwhere[] = $key . ' IN (' . $this->db->sanitize($this->db->escape($value)) . ')';
index f3d1d89..4981537 100644 (file)
@@ -216,6 +216,7 @@ class modEmailTracker extends DolibarrModules
                }
 
                // Array to add new pages in new tabs
+               
                $this->tabs = [];
                $this->tabs[] = ['data' => 'propal:+emailtracker:EmailTracker:emailtracker@emailtracker:$user->rights->emailtracker->emails->read:/emailtracker/tab_propal.php?id=__ID__'];
                $this->tabs[] = ['data' => 'order:+emailtracker:EmailTracker:emailtracker@emailtracker:$user->rights->emailtracker->emails->read:/emailtracker/tab_order.php?id=__ID__'];
@@ -224,6 +225,7 @@ class modEmailTracker extends DolibarrModules
                $this->tabs[] = ['data' => 'supplier_proposal:+emailtracker:EmailTracker:emailtracker@emailtracker:$user->rights->emailtracker->emails->read:/emailtracker/tab_supplier_proposal.php?id=__ID__'];
                $this->tabs[] = ['data' => 'supplier_order:+emailtracker:EmailTracker:emailtracker@emailtracker:$user->rights->emailtracker->emails->read:/emailtracker/tab_order_supplier.php?id=__ID__'];
                $this->tabs[] = ['data' => 'supplier_invoice:+emailtracker:EmailTracker:emailtracker@emailtracker:$user->rights->emailtracker->emails->read:/emailtracker/tab_invoice_supplier.php?id=__ID__'];
+               
                // Example:
                // $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@emailtracker:$user->rights->emailtracker->read:/emailtracker/mynewtab1.php?id=__ID__');                                        // To add a new tab identified by code tabname1
                // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@emailtracker:$user->rights->othermodule->read:/emailtracker/mynewtab2.php?id=__ID__',     // To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
index a952f52..f73517a 100644 (file)
@@ -109,7 +109,7 @@ if ($object->id > 0) {
 
        $head = facturefourn_prepare_head($object);
        $titre = $langs->trans('SupplierInvoice');
-       print dol_get_fiche_head($head, 'emailtracker', $titre, -1, 'supplier_invoice');
+       //print dol_get_fiche_head($head, 'emailtracker', $titre, -1, 'supplier_invoice');
 
        // Supplier invoice card
        $linkback = '<a href="' . DOL_URL_ROOT . '/fourn/facture/list.php?restore_lastsearch_values=1' . (!empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans('BackToList') . '</a>';
@@ -160,9 +160,9 @@ if ($object->id > 0) {
        $object->totalpaye = $alreadypaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status
 
        dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
-
+       print dol_get_fiche_head($head, 'emailtracker', $titre, -1, 'supplier_invoice');
        print dol_get_fiche_end();
-
+       
        print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
        print '<table class="tagtable nobottomiftotal liste">' . "\n";
        ?>
diff --git a/htdocs/debugbar/class/DataCollector/DolConfigCollector.php b/htdocs/debugbar/class/DataCollector/DolConfigCollector.php
deleted file mode 100644 (file)
index 715d20a..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-<?php
-
-use \DebugBar\DataCollector\ConfigCollector;
-
-/**
- * DolConfigCollector class
- */
-
-class DolConfigCollector extends ConfigCollector
-{
-       /**
-        *      Return widget settings
-        *
-        *  @return array      Array
-        */
-       public function getWidgets()
-       {
-               global $langs;
-
-               return array(
-                       $langs->transnoentities('Config') => array(
-                               "icon" => "gear",
-                               "widget" => "PhpDebugBar.Widgets.VariableListWidget",
-                               "map" => $this->getName(),
-                               "default" => "{}"
-                       )
-               );
-       }
-
-       /**
-        *      Return collected data
-        *
-        *  @return    array   Array
-        */
-       public function collect()
-       {
-               $this->data = $this->getConfig();
-
-               return parent::collect();
-       }
-
-       /**
-        * Returns an array with config data
-        *
-        * @return array       Array of config
-        */
-       protected function getConfig()
-       {
-               global $conf, $user;
-
-               // Get constants
-               $const = get_defined_constants(true);
-
-               $config = array(
-                       'Dolibarr' => array(
-                               'const' => $const['user'],
-                               '$conf' => $this->objectToArray($conf),
-                               '$user' => $this->objectToArray($user)
-                       ),
-                       'PHP' => array(
-                               'version'   => PHP_VERSION,
-                               'interface' => PHP_SAPI,
-                               'os'        => PHP_OS
-                       )
-               );
-
-               return $config;
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        * Convert an object to array
-        *
-        * @param  mixed   $obj        Object
-        * @return array               Array
-        */
-       protected function objectToArray($obj)
-       {
-               // phpcs:enable
-               $arr = array();
-               $_arr = is_object($obj) ? get_object_vars($obj) : $obj;
-               foreach ($_arr as $key => $val) {
-                       $val = (is_array($val) || is_object($val)) ? $this->objectToArray($val) : $val;
-                       $arr[$key] = $val;
-               }
-
-               return $arr;
-       }
-}
diff --git a/htdocs/debugbar/class/DataCollector/DolExceptionsCollector.php b/htdocs/debugbar/class/DataCollector/DolExceptionsCollector.php
deleted file mode 100644 (file)
index 15d433f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-use \DebugBar\DataCollector\ExceptionsCollector;
-
-/**
- * DolExceptionsCollector class
- */
-
-class DolExceptionsCollector extends ExceptionsCollector
-{
-       /**
-        *      Return widget settings
-        *
-        *  @return    array       Array
-        */
-       public function getWidgets()
-       {
-               global $langs;
-
-               $title = $langs->transnoentities('Exceptions');
-
-               return array(
-                       "$title" => array(
-                               'icon' => 'bug',
-                               'widget' => 'PhpDebugBar.Widgets.ExceptionsWidget',
-                               'map' => 'exceptions.exceptions',
-                               'default' => '[]'
-                       ),
-                       "$title:badge" => array(
-                               'map' => 'exceptions.count',
-                               'default' => 'null'
-                       )
-               );
-       }
-}
diff --git a/htdocs/debugbar/class/DataCollector/DolLogsCollector.php b/htdocs/debugbar/class/DataCollector/DolLogsCollector.php
deleted file mode 100644 (file)
index 893804a..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-<?php
-
-use DebugBar\DataCollector\MessagesCollector;
-use Psr\Log\LogLevel;
-
-//use ReflectionClass;
-
-/**
- * DolLogsCollector class
- */
-
-class DolLogsCollector extends MessagesCollector
-{
-       /**
-        * @var string default logs file path
-        */
-       protected $path;
-       /**
-        * @var int number of lines to show
-        */
-       protected $maxnboflines;
-
-       /**
-        * @var int number of lines
-        */
-       protected $nboflines;
-
-       /**
-        * Constructor
-        *
-        * @param string $path     Path
-        * @param string $name     Name
-        */
-       public function __construct($path = null, $name = 'logs')
-       {
-               global $conf;
-
-               parent::__construct($name);
-
-               $this->nboflines = 0;
-               $this->maxnboflines = getDolGlobalInt('DEBUGBAR_LOGS_LINES_NUMBER', 250); // High number slows seriously output
-
-               $this->path = $path ?: $this->getLogsFile();
-       }
-
-       /**
-        *      Return widget settings
-        *
-        *  @return array  Array
-        */
-       public function getWidgets()
-       {
-               global $langs;
-
-               $title = $langs->transnoentities('Logs');
-               $name = $this->getName();
-
-               return array(
-                       "$title" => array(
-                               "icon" => "list-alt",
-                               "widget" => "PhpDebugBar.Widgets.MessagesWidget",
-                               "map" => "$name.messages",
-                               "default" => "[]"
-                       ),
-                       "$title:badge" => array(
-                               "map" => "$name.count",
-                               "default" => "null"
-                       )
-               );
-       }
-
-       /**
-        *      Return collected data
-        *
-        *  @return array  Array
-        */
-       public function collect()
-       {
-               global $conf;
-
-               $uselogfile =  getDolGlobalInt('DEBUGBAR_USE_LOG_FILE');
-
-               if ($uselogfile) {
-                       $this->getStorageLogs($this->path);
-               } else {
-                       $log_levels = $this->getLevels();
-
-                       foreach ($conf->logbuffer as $line) {
-                               if ($this->nboflines >= $this->maxnboflines) {
-                                       break;
-                               }
-                               foreach ($log_levels as $level_key => $level) {
-                                       if (strpos(strtolower($line), strtolower($level_key)) == 20) {
-                                               $this->nboflines++;
-                                               $this->addMessage($line, $level, false);
-                                       }
-                               }
-                       }
-               }
-
-               return parent::collect();
-       }
-
-       /**
-        * Get the path to the logs file
-        *
-        * @return string
-        */
-       public function getLogsFile()
-       {
-               // default dolibarr log file
-               $path = DOL_DATA_ROOT.'/dolibarr.log';
-               return $path;
-       }
-
-       /**
-        * Get logs
-        *
-        * @param string $path     Path
-        * @return array
-        */
-       public function getStorageLogs($path)
-       {
-               if (!file_exists($path)) {
-                       return;
-               }
-
-               // Load the latest lines
-               $file = implode("", $this->tailFile($path, $this->maxnboflines));
-
-               foreach ($this->getLogs($file) as $log) {
-                       $this->addMessage($log['line'], $log['level'], false);
-               }
-       }
-
-       /**
-        * Get latest file lines
-        *
-        * @param string       $file       File
-        * @param int          $lines      Lines
-        * @return array       Array
-        */
-       protected function tailFile($file, $lines)
-       {
-               $handle = fopen($file, "r");
-               $linecounter = $lines;
-               $pos = -2;
-               $beginning = false;
-               $text = array();
-               while ($linecounter > 0) {
-                       $t = " ";
-                       while ($t != "\n") {
-                               if (fseek($handle, $pos, SEEK_END) == -1) {
-                                       $beginning = true;
-                                       break;
-                               }
-                               $t = fgetc($handle);
-                               $pos--;
-                       }
-                       $linecounter--;
-                       if ($beginning) {
-                               rewind($handle);
-                       }
-                       $text[$lines - $linecounter - 1] = fgets($handle);
-                       if ($beginning) {
-                               break;
-                       }
-               }
-               fclose($handle);
-               return array_reverse($text);
-       }
-
-       /**
-        * Search a string for log entries
-        *
-        * @param  string  $file       File
-        * @return array               Lines of logs
-        */
-       public function getLogs($file)
-       {
-               $pattern = "/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.*/";
-               $log_levels = $this->getLevels();
-               preg_match_all($pattern, $file, $matches);
-               $log = array();
-               foreach ($matches as $lines) {
-                       foreach ($lines as $line) {
-                               foreach ($log_levels as $level_key => $level) {
-                                       if (strpos(strtolower($line), strtolower($level_key)) == 20) {
-                                               $log[] = array('level' => $level, 'line' => $line);
-                                       }
-                               }
-                       }
-               }
-               $log = array_reverse($log);
-               return $log;
-       }
-
-       /**
-        * Get the log levels from psr/log.
-        *
-        * @return array       Array of log level
-        */
-       public function getLevels()
-       {
-               $class = new ReflectionClass(new LogLevel());
-               $levels = $class->getConstants();
-               $levels['ERR'] = 'error';
-               $levels['WARN'] = 'warning';
-
-               return $levels;
-       }
-}
diff --git a/htdocs/debugbar/class/DataCollector/DolMemoryCollector.php b/htdocs/debugbar/class/DataCollector/DolMemoryCollector.php
deleted file mode 100644 (file)
index b52ac8f..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-use \DebugBar\DataCollector\MemoryCollector;
-
-/**
- * DolMemoryCollector class
- */
-
-class DolMemoryCollector extends MemoryCollector
-{
-       /**
-        *      Return value of indicator
-        *
-        *  @return void
-        */
-       public function collect()
-       {
-               global $conf, $langs;
-
-               $this->updatePeakUsage();
-               return array(
-                       'peak_usage' => $this->peakUsage,
-                       //'peak_usage_str' => $this->getDataFormatter()->formatBytes($this->peakUsage, 2)
-                       'peak_usage_str' => (empty($conf->dol_optimize_smallscreen) ? dol_print_size($this->peakUsage, 0) : dol_print_size($this->peakUsage, 1))
-               );
-       }
-
-       /**
-        *      Return widget settings
-        *
-        *  @return void
-        */
-       public function getWidgets()
-       {
-               global $langs;
-
-               $langs->load("other");
-
-               return array(
-                       "memory" => array(
-                               "icon" => "cogs",
-                               "tooltip" => $langs->transnoentities('MemoryUsage'),
-                               "map" => "memory.peak_usage_str",
-                               "default" => "'0B'"
-                       )
-               );
-       }
-}
diff --git a/htdocs/debugbar/class/DataCollector/DolMessagesCollector.php b/htdocs/debugbar/class/DataCollector/DolMessagesCollector.php
deleted file mode 100644 (file)
index 1fcf60c..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-use \DebugBar\DataCollector\MessagesCollector;
-
-/**
- * DolMessagesCollector class
- */
-
-class DolMessagesCollector extends MessagesCollector
-{
-       /**
-        *      Return widget settings
-        *
-        *  @return array  Array
-        */
-       public function getWidgets()
-       {
-               global $langs;
-
-               $title = $langs->transnoentities('Messages');
-               $name = $this->getName();
-
-               return array(
-                       "$title" => array(
-                               "icon" => "list-alt",
-                               "widget" => "PhpDebugBar.Widgets.MessagesWidget",
-                               "map" => "$name.messages",
-                               "default" => "[]"
-                       ),
-                       "$title:badge" => array(
-                               "map" => "$name.count",
-                               "default" => "null"
-                       )
-               );
-       }
-}
diff --git a/htdocs/debugbar/class/DataCollector/DolPhpCollector.php b/htdocs/debugbar/class/DataCollector/DolPhpCollector.php
deleted file mode 100644 (file)
index 3d6536b..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-<?php
-
-use DebugBar\DataCollector\DataCollector;
-use DebugBar\DataCollector\Renderable;
-
-/**
- * Class PhpCollector
- *
- * This class collects all PHP errors, notice, advices, trigger_error,...
- * Supports 15 different types included.
- */
-class PhpCollector extends DataCollector implements Renderable
-{
-       /**
-        * Collector name.
-        *
-        * @var string
-        */
-       protected $name;
-
-       /**
-        * List of messages. Each item includes:
-        *  'message', 'message_html', 'is_string', 'label', 'time'.
-        *
-        * @var array
-        */
-       protected $messages = [];
-
-       /**
-        * PHPCollector constructor.
-        *
-        * @param string $name The name used by this collector widget.
-        */
-       public function __construct($name = 'Error handler')
-       {
-               $this->name = $name;
-               set_error_handler([$this, 'errorHandler'], E_ALL);
-       }
-
-       /**
-        * Called by the DebugBar when data needs to be collected.
-        *
-        * @return array Collected data.
-        */
-       public function collect()
-       {
-               $messages = $this->getMessages();
-               return [
-                       'count' => count($messages),
-                       'messages' => $messages,
-               ];
-       }
-
-       /**
-        * Returns a list of messages ordered by their timestamp.
-        *
-        * @return array A list of messages ordered by time.
-        */
-       public function getMessages()
-       {
-               $messages = $this->messages;
-
-               usort($messages, function ($itemA, $itemB) {
-                       if ($itemA['time'] === $itemB['time']) {
-                               return 0;
-                       }
-                       return $itemA['time'] < $itemB['time'] ? -1 : 1;
-               });
-
-               return $messages;
-       }
-
-       /**
-        * Returns a hash where keys are control names and their values an array of options as defined in
-        * {@see DebugBar\JavascriptRenderer::addControl()}
-        *
-        * @return array Needed details to render the widget.
-        */
-       public function getWidgets()
-       {
-               $name = $this->getName();
-               return [
-                       $name => [
-                               'icon' => 'list',
-                               'widget' => 'PhpDebugBar.Widgets.MessagesWidget',
-                               'map' => "$name.messages",
-                               'default' => '[]',
-                       ],
-                       "$name:badge" => [
-                               'map' => "$name.count",
-                               'default' => 'null',
-                       ],
-               ];
-       }
-
-       /**
-        * Returns the unique name of the collector.
-        *
-        * @return string The widget name.
-        */
-       public function getName()
-       {
-               return $this->name;
-       }
-
-       /**
-        * Exception error handler. Called from constructor with set_error_handler to add all details.
-        *
-        * @param int    $severity Error type.
-        * @param string $message  Message of error.
-        * @param string $fileName File where error is generated.
-        * @param int    $line     Line number where error is generated.
-        *
-        * @return void
-        */
-       public function errorHandler($severity, $message, $fileName, $line)
-       {
-               for ($i = 0; $i < 15; $i++) {
-                       if ($type = $severity & (2 ** $i)) {
-                               $label = $this->friendlyErrorType($type);
-                               $this->messages[] = [
-                                       'message' => $message . ' (' . $fileName . ':' . $line . ')',
-                                       'message_html' => null,
-                                       'is_string' => true,
-                                       'label' => $label,
-                                       'time' => microtime(true),
-                               ];
-                       }
-               }
-       }
-
-       /**
-        * Return error name from error code.
-        *
-        * @info http://php.net/manual/es/errorfunc.constants.php
-        *
-        * @param int $type Error code.
-        *
-        * @return string Error name.
-        */
-       private function friendlyErrorType($type)
-       {
-               $errors = [
-                       E_ERROR => 'ERROR',
-                       E_WARNING => 'WARNING',
-                       E_PARSE => 'PARSE',
-                       E_NOTICE => 'NOTICE',
-                       E_CORE_ERROR => 'CORE_ERROR',
-                       E_CORE_WARNING => 'CORE_WARNING',
-                       E_COMPILE_ERROR => 'COMPILE_ERROR',
-                       E_COMPILE_WARNING => 'COMPILE_WARNING',
-                       E_USER_ERROR => 'USER_ERROR',
-                       E_USER_WARNING => 'USER_WARNING',
-                       E_USER_NOTICE => 'USER_NOTICE',
-                       E_STRICT => 'STRICT',
-                       E_RECOVERABLE_ERROR => 'RECOVERABLE_ERROR',
-                       E_DEPRECATED => 'DEPRECATED',
-                       E_USER_DEPRECATED => 'USER_DEPRECATED',
-               ];
-
-               $result = '';
-               if (isset($errors[$type])) {
-                       $result = $errors[$type];
-               }
-
-               return $result;
-       }
-}
diff --git a/htdocs/debugbar/class/DataCollector/DolQueryCollector.php b/htdocs/debugbar/class/DataCollector/DolQueryCollector.php
deleted file mode 100644 (file)
index ca5aa28..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-
-use DebugBar\DataCollector\AssetProvider;
-use DebugBar\DataCollector\DataCollector;
-use DebugBar\DataCollector\Renderable;
-use DebugBar\DebugBarException;
-
-dol_include_once('/debugbar/class/TraceableDB.php');
-
-/**
- * DolQueryCollector class
- */
-class DolQueryCollector extends DataCollector implements Renderable, AssetProvider
-{
-       /**
-        * @var object Database handler
-        */
-       protected $db;
-
-       /**
-        * Constructor
-        */
-       public function __construct()
-       {
-               global $db;
-
-               // Replace $db handler with new handler override by TraceableDB
-               $db = new TraceableDB($db);
-
-               $this->db = $db;
-       }
-
-       /**
-        * Return collected data
-        *
-        * @return array  Array
-        */
-       public function collect()
-       {
-               $queries = array();
-               $totalExecTime = 0;
-               $totalMemoryUsage = 0;
-               $totalFailed = 0;
-               foreach ($this->db->queries as $query) {
-                       $queries[] = array(
-                               'sql' => $query['sql'],
-                               'duration' => $query['duration'],
-                               'duration_str' => round($query['duration'] * 1000, 2),
-                               'memory' => $query['memory_usage'],
-                               'is_success' => $query['is_success'],
-                               'error_code' => $query['error_code'],
-                               'error_message' => $query['error_message']
-                       );
-                       $totalExecTime += $query['duration'];
-                       $totalMemoryUsage += $query['memory_usage'];
-                       if (!$query['is_success']) {
-                               $totalFailed += 1;
-                       }
-               }
-
-               return array(
-                       'nb_statements' => count($queries),
-                       'nb_failed_statements' => $totalFailed,
-                       'accumulated_duration' => $totalExecTime,
-                       'memory_usage' => $totalMemoryUsage,
-                       'statements' => $queries
-               );
-       }
-
-       /**
-        *      Return collector name
-        *
-        *  @return string  Name
-        */
-       public function getName()
-       {
-               return 'query';
-       }
-
-       /**
-        *      Return widget settings
-        *
-        *  @return array      Array
-        */
-       public function getWidgets()
-       {
-               global $langs;
-
-               $title = $langs->transnoentities('Database');
-
-               return array(
-                       "$title" => array(
-                               "icon" => "arrow-right",
-                               "widget" => "PhpDebugBar.Widgets.SQLQueriesWidget",
-                               "map" => "query",
-                               "default" => "[]"
-                       ),
-                       "$title:badge" => array(
-                               "map" => "query.nb_statements",
-                               "default" => 0
-                       )
-               );
-       }
-
-       /**
-        *      Return assets
-        *
-        *  @return array   Array
-        */
-       public function getAssets()
-       {
-               return array(
-                       'css' => 'widgets/sqlqueries/widget.css',
-                       'js' => 'widgets/sqlqueries/widget.js'
-               );
-       }
-}
diff --git a/htdocs/debugbar/class/DataCollector/DolRequestDataCollector.php b/htdocs/debugbar/class/DataCollector/DolRequestDataCollector.php
deleted file mode 100644 (file)
index 9386438..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-
-use \DebugBar\DataCollector\RequestDataCollector;
-
-/**
- * DolRequestDataCollector class
- */
-
-class DolRequestDataCollector extends RequestDataCollector
-{
-       /**
-        * Collects the data from the collectors
-        *
-        * @return array
-        */
-       public function collect()
-       {
-               $vars = array('_GET', '_POST', '_SESSION', '_COOKIE', '_SERVER');
-               $data = array();
-
-               foreach ($vars as $var) {
-                       if (isset($GLOBALS[$var])) {
-                               $arrayofvalues = $GLOBALS[$var];
-
-                               if ($var == '_COOKIE') {
-                                       foreach ($arrayofvalues as $key => $val) {
-                                               if (preg_match('/^DOLSESSID_/', $key)) {
-                                                       $arrayofvalues[$key] = '*****hidden*****';
-                                               }
-                                       }
-                                       //var_dump($arrayofvalues);
-                               }
-
-                               $data["$".$var] = $this->getDataFormatter()->formatVar($arrayofvalues);
-                       }
-               }
-
-               return $data;
-       }
-
-       /**
-        *      Return widget settings
-        *
-        *  @return void
-        */
-       public function getWidgets()
-       {
-               global $langs;
-
-               $langs->load("other");
-
-               return array(
-                       $langs->transnoentities('Variables') => array(
-                               "icon" => "tags",
-                               "widget" => "PhpDebugBar.Widgets.VariableListWidget",
-                               "map" => "request",
-                               "default" => "{}"
-                       )
-               );
-       }
-}
diff --git a/htdocs/debugbar/class/DataCollector/DolTimeDataCollector.php b/htdocs/debugbar/class/DataCollector/DolTimeDataCollector.php
deleted file mode 100644 (file)
index ed5e979..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-use \DebugBar\DataCollector\TimeDataCollector;
-
-/**
- * DolTimeDataCollector class
- */
-class DolTimeDataCollector extends TimeDataCollector
-{
-       /**
-        *      Return widget settings
-        *
-        *  @return array  Array
-        */
-       public function getWidgets()
-       {
-               global $langs;
-
-               return array(
-                       "time" => array(
-                               "icon" => "clock-o",
-                               "tooltip" => $langs->transnoentities('RequestDuration'),
-                               "map" => "time.duration_str",
-                               "default" => "'0ms'"
-                       ),
-                       $langs->transnoentities('Timeline') => array(
-                               "icon" => "tasks",
-                               "widget" => "PhpDebugBar.Widgets.TimelineWidget",
-                               "map" => "time",
-                               "default" => "{}"
-                       )
-               );
-       }
-}
diff --git a/htdocs/debugbar/class/DataCollector/DolibarrCollector.php b/htdocs/debugbar/class/DataCollector/DolibarrCollector.php
deleted file mode 100644 (file)
index 3193fe2..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-<?php
-
-use DebugBar\DataCollector\AssetProvider;
-use DebugBar\DataCollector\DataCollector;
-use DebugBar\DataCollector\Renderable;
-use DebugBar\DebugBarException;
-
-/**
- * DolibarrCollector class
- */
-
-class DolibarrCollector extends DataCollector implements Renderable, AssetProvider
-{
-       /**
-        *      Return collector name
-        *
-        *  @return string     Name
-        */
-       public function getName()
-       {
-               return 'dolibarr';
-       }
-
-       /**
-        *      Return collected data
-        *
-        * @return array       Array
-        */
-       public function collect()
-       {
-               return array();
-       }
-
-       /**
-        *      Return database info as an HTML string
-        *
-        *  @return string         HTML string
-        */
-       protected function getDatabaseInfo()
-       {
-               global $conf, $langs;
-
-               $info  = $langs->trans('Host').': <strong>'.$conf->db->host.'</strong><br>';
-               $info .= $langs->trans('Port').': <strong>'.$conf->db->port.'</strong><br>';
-               $info .= $langs->trans('Name').': <strong>'.$conf->db->name.'</strong><br>';
-               $info .= $langs->trans('User').': <strong>'.$conf->db->user.'</strong><br>';
-               $info .= $langs->trans('Type').': <strong>'.$conf->db->type.'</strong><br>';
-               $info .= $langs->trans('Prefix').': <strong>'.$conf->db->prefix.'</strong><br>';
-               $info .= $langs->trans('Charset').': <strong>'.$conf->db->character_set.'</strong>';
-
-               return $info;
-       }
-
-       /**
-        *      Return dolibarr info as an HTML string
-        *
-        * @return string      HTML string
-        */
-       protected function getDolibarrInfo()
-       {
-               global $conf, $langs;
-               global $dolibarr_main_prod, $dolibarr_nocsrfcheck;
-
-               $info  = $langs->trans('Version').': <strong>'.DOL_VERSION.'</strong><br>';
-               $info .= $langs->trans('Theme').': <strong>'.$conf->theme.'</strong><br>';
-               $info .= $langs->trans('Locale').': <strong>'.$conf->global->MAIN_LANG_DEFAULT.'</strong><br>';
-               $info .= $langs->trans('Currency').': <strong>'.$conf->currency.'</strong><br>';
-               $info .= $langs->trans('Entity').': <strong>'.$conf->entity.'</strong><br>';
-               $info .= $langs->trans('MaxSizeList').': <strong>'.($conf->liste_limit ?: $conf->global->MAIN_SIZE_LISTE_LIMIT).'</strong><br>';
-               $info .= $langs->trans('MaxSizeForUploadedFiles').': <strong>'.$conf->global->MAIN_UPLOAD_DOC.'</strong><br>';
-               $info .= '$dolibarr_main_prod = <strong>'.$dolibarr_main_prod.'</strong><br>';
-               $info .= '$dolibarr_nocsrfcheck = <strong>'.$dolibarr_nocsrfcheck.'</strong><br>';
-               $info .= 'MAIN_SECURITY_CSRF_WITH_TOKEN = <strong>'.$conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN.'</strong><br>';
-               $info .= 'MAIN_FEATURES_LEVEL = <strong>'.$conf->global->MAIN_FEATURES_LEVEL.'</strong><br>';
-
-               return $info;
-       }
-
-       /**
-        *      Return mail info as an HTML string
-        *
-        * @return string      HTML string
-        */
-       protected function getMailInfo()
-       {
-               global $conf, $langs;
-               global $dolibarr_mailing_limit_sendbyweb, $dolibarr_mailing_limit_sendbycli, $dolibarr_mailing_limit_sendbyday;
-
-               $info  = $langs->trans('Method').': <strong>'.getDolGlobalString("MAIN_MAIL_SENDMODE").'</strong><br>';
-               $info .= $langs->trans('Server').': <strong>'.getDolGlobalString("MAIN_MAIL_SMTP_SERVER").'</strong><br>';
-               $info .= $langs->trans('Port').': <strong>'.getDolGlobalString("MAIN_MAIL_SMTP_PORT").'</strong><br>';
-               $info .= $langs->trans('ID').': <strong>'.getDolGlobalString("MAIN_MAIL_SMTPS_IDT").'</strong><br>';
-               $info .= $langs->trans('Pwd').': <strong>'.preg_replace('/./', '*', getDolGlobalString("MAIN_MAIL_SMTPS_PW")).'</strong><br>';
-               $info .= $langs->trans('TLS/STARTTLS').': <strong>'.getDolGlobalString("MAIN_MAIL_EMAIL_TLS").'</strong> / <strong>'.getDolGlobalString("MAIN_MAIL_EMAIL_STARTTLS").'</strong><br>';
-               $info .= $langs->trans('MAIN_DISABLE_ALL_MAILS').': <strong>'.(empty($conf->global->MAIN_DISABLE_ALL_MAILS) ? $langs->trans('No') : $langs->trans('Yes')).'</strong><br>';
-               $info .= 'dolibarr_mailing_limit_sendbyweb = <strong>'.$dolibarr_mailing_limit_sendbyweb.'</strong><br>';
-               $info .= 'dolibarr_mailing_limit_sendbycli = <strong>'.$dolibarr_mailing_limit_sendbycli.'</strong><br>';
-               $info .= 'dolibarr_mailing_limit_sendbyday = <strong>'.$dolibarr_mailing_limit_sendbyday.'</strong><br>';
-
-               return $info;
-       }
-
-       /**
-        *      Return widget settings
-        *
-        * @return array       Array
-        */
-       public function getWidgets()
-       {
-               return array(
-                       "database_info" => array(
-                               "icon" => "database",
-                               "indicator" => "PhpDebugBar.DebugBar.TooltipIndicator",
-                               "tooltip" => array(
-                                       "html" => $this->getDatabaseInfo(),
-                                       "class" => "tooltip-wide"
-                               ),
-                               "map" => "",
-                               "default" => ""
-                       ),
-                       "dolibarr_info" => array(
-                               "icon" => "desktop",
-                               "indicator" => "PhpDebugBar.DebugBar.TooltipIndicator",
-                               "tooltip" => array(
-                                       "html" => $this->getDolibarrInfo(),
-                                       "class" => "tooltip-wide"
-                               ),
-                               "map" => "",
-                               "default" => ""
-                       ),
-                       "mail_info" => array(
-                               "icon" => "envelope",
-                               "indicator" => "PhpDebugBar.DebugBar.TooltipIndicator",
-                               "tooltip" => array(
-                                       "html" => $this->getMailInfo(),
-                                       "class" => "tooltip-extra-wide"
-                               ),
-                               "map" => "",
-                               "default" => ""
-                       )
-               );
-       }
-
-       /**
-        *      Return collector assests
-        *
-        * @return array       Array
-        */
-       public function getAssets()
-       {
-               return array(
-                       'base_url' => dol_buildpath('/debugbar', 1),
-                       'js' => 'js/widgets.js'
-               );
-       }
-}
diff --git a/htdocs/debugbar/class/DebugBar.php b/htdocs/debugbar/class/DebugBar.php
deleted file mode 100644 (file)
index bf797e6..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-<?php
-
-dol_include_once('/debugbar/class/autoloader.php');
-
-use \DebugBar\DebugBar;
-use \DebugBar\DataCollector\PhpInfoCollector;
-
-dol_include_once('/debugbar/class/DataCollector/DolMessagesCollector.php');
-dol_include_once('/debugbar/class/DataCollector/DolRequestDataCollector.php');
-dol_include_once('/debugbar/class/DataCollector/DolConfigCollector.php');
-dol_include_once('/debugbar/class/DataCollector/DolTimeDataCollector.php');
-dol_include_once('/debugbar/class/DataCollector/DolMemoryCollector.php');
-dol_include_once('/debugbar/class/DataCollector/DolPhpCollector.php');
-dol_include_once('/debugbar/class/DataCollector/DolExceptionsCollector.php');
-dol_include_once('/debugbar/class/DataCollector/DolQueryCollector.php');
-dol_include_once('/debugbar/class/DataCollector/DolibarrCollector.php');
-dol_include_once('/debugbar/class/DataCollector/DolLogsCollector.php');
-
-/**
- * DolibarrDebugBar class
- *
- * @see http://phpdebugbar.com/docs/base-collectors.html#base-collectors
- */
-
-class DolibarrDebugBar extends DebugBar
-{
-       /**
-        * Constructor
-        *
-        */
-       public function __construct()
-       {
-               global $conf;
-
-               //$this->addCollector(new PhpInfoCollector());
-               //$this->addCollector(new DolMessagesCollector());
-               $this->addCollector(new DolRequestDataCollector());
-               //$this->addCollector(new DolConfigCollector());      // Disabled for security purpose
-               $this->addCollector(new DolTimeDataCollector());
-               $this->addCollector(new PhpCollector());
-               $this->addCollector(new DolMemoryCollector());
-               //$this->addCollector(new DolExceptionsCollector());
-               $this->addCollector(new DolQueryCollector());
-               $this->addCollector(new DolibarrCollector());
-               if (isModEnabled('syslog')) {
-                       $this->addCollector(new DolLogsCollector());
-               }
-       }
-
-       /**
-        * Returns a JavascriptRenderer for this instance
-        *
-        * @return string      String content
-        */
-       public function getRenderer()
-       {
-               $renderer = parent::getJavascriptRenderer(DOL_URL_ROOT.'/includes/maximebf/debugbar/src/DebugBar/Resources');
-               $renderer->disableVendor('jquery');                     // We already have jquery loaded globally by the main.inc.php
-               $renderer->disableVendor('fontawesome');        // We already have fontawesome loaded globally by the main.inc.php
-               $renderer->disableVendor('highlightjs');        // We don't need this
-               $renderer->setEnableJqueryNoConflict(false);    // We don't need no conflict
-               return $renderer;
-       }
-}
diff --git a/htdocs/debugbar/class/TraceableDB.php b/htdocs/debugbar/class/TraceableDB.php
deleted file mode 100644 (file)
index 5863f1d..0000000
+++ /dev/null
@@ -1,723 +0,0 @@
-<?php
-
-require_once DOL_DOCUMENT_ROOT.'/core/db/DoliDB.class.php';
-
-/**
- * TraceableDB class
- *
- * Used to log queries into DebugBar
- */
-class TraceableDB extends DoliDB
-{
-       /**
-        * @var DoliDb Database handler
-        */
-       public $db; // cannot be protected because of parent declaration
-       /**
-        * @var array Queries array
-        */
-       public $queries;
-       /**
-        * @var int Request start time
-        */
-       protected $startTime;
-       /**
-        * @var int Request start memory
-        */
-       protected $startMemory;
-       /**
-        * @var string type
-        */
-       public $type;
-       /**
-        * @const Database label
-        */
-       const LABEL = ''; // TODO: the right value should be $this->db::LABEL (but this is a constant? o_O)
-       /**
-        * @const Version min database
-        */
-       const VERSIONMIN = ''; // TODO: the same thing here, $this->db::VERSIONMIN is the right value
-
-       /**
-        * Constructor
-        *
-        * @param               DoliDB          $db      Database handler
-        */
-       public function __construct($db)
-       {
-               $this->db      = $db;
-               $this->type    = $this->db->type;
-               $this->queries = array();
-       }
-
-       /**
-        * Format a SQL IF
-        *
-        * @param   string $test Test string (example: 'cd.statut=0', 'field IS NULL')
-        * @param   string $resok resultat si test egal
-        * @param   string $resko resultat si test non egal
-        * @return      string                SQL string
-        */
-       public function ifsql($test, $resok, $resko)
-       {
-               return $this->db->ifsql($test, $resok, $resko);
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        * Return datas as an array
-        *
-        * @param   resource $resultset    Resultset of request
-        * @return  array                  Array
-        */
-       public function fetch_row($resultset)
-       {
-               // phpcs:enable
-               return $this->db->fetch_row($resultset);
-       }
-
-       /**
-        * Convert (by PHP) a GM Timestamp date into a string date with PHP server TZ to insert into a date field.
-        * Function to use to build INSERT, UPDATE or WHERE predica
-        *
-        *   @param         int         $param      Date TMS to convert
-        *       @param         mixed   $gm                     'gmt'=Input informations are GMT values, 'tzserver'=Local to server TZ
-        *   @return    string                  Date in a string YYYY-MM-DD HH:MM:SS
-        */
-       public function idate($param, $gm = 'tzserver')
-       {
-               return $this->db->idate($param, $gm);
-       }
-
-       /**
-        * Return last error code
-        *
-        * @return  string    lasterrno
-        */
-       public function lasterrno()
-       {
-               return $this->db->lasterrno();
-       }
-
-       /**
-        * Start transaction
-        *
-        * @param       string  $textinlog              Add a small text into log. '' by default.
-        * @return  int                                 1 if transaction successfuly opened or already opened, 0 if error
-        */
-       public function begin($textinlog = '')
-       {
-               return $this->db->begin($textinlog);
-       }
-
-       /**
-        * Create a new database
-        * Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated
-        * We force to create database with charset this->forcecharset and collate this->forcecollate
-        *
-        * @param   string              $database               Database name to create
-        * @param   string              $charset                Charset used to store data
-        * @param   string              $collation              Charset used to sort data
-        * @param   string              $owner                  Username of database owner
-        * @return  resource                    resource defined if OK, null if KO
-        */
-       public function DDLCreateDb($database, $charset = '', $collation = '', $owner = '')
-       {
-               return $this->db->DDLCreateDb($database, $charset, $collation, $owner);
-       }
-
-       /**
-        * Return version of database server into an array
-        *
-        * @return      array        Version array
-        */
-       public function getVersionArray()
-       {
-               return $this->db->getVersionArray();
-       }
-
-       /**
-        *  Convert a SQL request in Mysql syntax to native syntax
-        *
-        * @param   string $line   SQL request line to convert
-        * @param   string $type   Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...)
-        * @return  string         SQL request line converted
-        */
-       public static function convertSQLFromMysql($line, $type = 'ddl')
-       {
-               return self::$db->convertSQLFromMysql($line);
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        * Return the number o flines into the result of a request INSERT, DELETE or UPDATE
-        *
-        * @param   resource $resultset    Curseur de la requete voulue
-        * @return      int                    Number of lines
-        * @see         num_rows()
-        */
-       public function affected_rows($resultset)
-       {
-               // phpcs:enable
-               return $this->db->affected_rows($resultset);
-       }
-
-       /**
-        * Return description of last error
-        *
-        * @return  string        Error text
-        */
-       public function error()
-       {
-               return $this->db->error();
-       }
-
-       /**
-        *  List tables into a database
-        *
-        *  @param      string          $database       Name of database
-        *  @param      string          $table          Nmae of table filter ('xxx%')
-        *  @return     array                                   List of tables in an array
-        */
-       public function DDLListTables($database, $table = '')
-       {
-               return $this->db->DDLListTables($database, $table);
-       }
-
-       /**
-        * Return last request executed with query()
-        *
-        * @return      string                    Last query
-        */
-       public function lastquery()
-       {
-               return $this->db->lastquery();
-       }
-
-       /**
-        * Define sort criteria of request
-        *
-        * @param   string $sortfield List of sort fields
-        * @param   string $sortorder Sort order
-        * @return  string            String to provide syntax of a sort sql string
-        */
-       public function order($sortfield = null, $sortorder = null)
-       {
-               return $this->db->order($sortfield, $sortorder);
-       }
-
-       /**
-        * Decrypt sensitive data in database
-        *
-        * @param    string $value Value to decrypt
-        * @return   string                    Decrypted value if used
-        */
-       public function decrypt($value)
-       {
-               return $this->db->decrypt($value);
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        * Return datas as an array
-        *
-        * @param   resource $resultset    Resultset of request
-        * @return  array                  Array
-        */
-       public function fetch_array($resultset)
-       {
-               // phpcs:enable
-               return $this->db->fetch_array($resultset);
-       }
-
-       /**
-        * Return last error label
-        *
-        * @return      string    lasterror
-        */
-       public function lasterror()
-       {
-               return $this->db->lasterror();
-       }
-
-       /**
-        * Escape a string to insert data
-        *
-        * @param   string $stringtoencode String to escape
-        * @return  string                        String escaped
-        */
-       public function escape($stringtoencode)
-       {
-               return $this->db->escape($stringtoencode);
-       }
-
-       /**
-        * Escape a string to insert data
-        *
-        * @param   string $stringtoencode String to escape
-        * @return  string                        String escaped
-        * @deprecated
-        */
-       public function escapeunderscore($stringtoencode)
-       {
-               return $this->db->escapeunderscore($stringtoencode);
-       }
-
-       /**
-        *      Escape a string to insert data into a like
-        *
-        *      @param  string  $stringtoencode         String to escape
-        *      @return string                                          String escaped
-        */
-       public function escapeforlike($stringtoencode)
-       {
-               return str_replace(array('_', '\\', '%'), array('\_', '\\\\', '\%'), (string) $stringtoencode);
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        * Get last ID after an insert INSERT
-        *
-        * @param       string  $tab            Table name concerned by insert. Ne sert pas sous MySql mais requis pour compatibilite avec Postgresql
-        * @param   string      $fieldid        Field name
-        * @return  int                 Id of row
-        */
-       public function last_insert_id($tab, $fieldid = 'rowid')
-       {
-               // phpcs:enable
-               return $this->db->last_insert_id($tab, $fieldid);
-       }
-
-       /**
-        * Return full path of restore program
-        *
-        * @return        string        Full path of restore program
-        */
-       public function getPathOfRestore()
-       {
-               return $this->db->getPathOfRestore();
-       }
-
-       /**
-        *      Cancel a transaction and go back to initial data values
-        *
-        *      @param  string                  $log            Add more log to default log line
-        *      @return resource|int                    1 if cancelation is ok or transaction not open, 0 if error
-        */
-       public function rollback($log = '')
-       {
-               return $this->db->rollback($log);
-       }
-
-       /**
-        * Execute a SQL request and return the resultset
-        *
-        * @param   string      $query          SQL query string
-        * @param   int         $usesavepoint   0=Default mode, 1=Run a savepoint before and a rollback to savepoint if error (this allow to have some request with errors inside global transactions).
-        *                                      Note that with Mysql, this parameter is not used as Myssql can already commit a transaction even if one request is in error, without using savepoints.
-        * @param   string      $type           Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...)
-        * @param       int             $result_mode    Result mode
-        * @return  resource                    Resultset of answer
-        */
-       public function query($query, $usesavepoint = 0, $type = 'auto', $result_mode = 0)
-       {
-               $this->startTracing();
-
-               $resql = $this->db->query($query, $usesavepoint, $type, $result_mode);
-
-               $this->endTracing($query, $resql);
-
-               return $resql;
-       }
-
-       /**
-        * Start query tracing
-        *
-        * @return     void
-        */
-       protected function startTracing()
-       {
-               $this->startTime   = microtime(true);
-               $this->startMemory = memory_get_usage(true);
-       }
-
-       /**
-        * End query tracing
-        *
-        * @param      string   $sql       query string
-        * @param      string   $resql     query result
-        * @return     void
-        */
-       protected function endTracing($sql, $resql)
-       {
-               $endTime     = microtime(true);
-               $duration    = $endTime - $this->startTime;
-               $endMemory   = memory_get_usage(true);
-               $memoryDelta = $endMemory - $this->startMemory;
-
-               $this->queries[] = array(
-                       'sql'           => $sql,
-                       'duration'      => $duration,
-                       'memory_usage'  => $memoryDelta,
-                       'is_success'    => $resql ? true : false,
-                       'error_code'    => $resql ? null : $this->db->lasterrno(),
-                       'error_message' => $resql ? null : $this->db->lasterror()
-               );
-       }
-
-       /**
-        * Connexion to server
-        *
-        * @param   string $host database server host
-        * @param   string $login login
-        * @param   string $passwd password
-        * @param   string $name name of database (not used for mysql, used for pgsql)
-        * @param   int    $port Port of database server
-        * @return  resource            Database access handler
-        * @see     close()
-        */
-       public function connect($host, $login, $passwd, $name, $port = 0)
-       {
-               return $this->db->connect($host, $login, $passwd, $name, $port);
-       }
-
-       /**
-        *    Define limits and offset of request
-        *
-        * @param   int $limit Maximum number of lines returned (-1=conf->liste_limit, 0=no limit)
-        * @param   int $offset Numero of line from where starting fetch
-        * @return  string            String with SQL syntax to add a limit and offset
-        */
-       public function plimit($limit = 0, $offset = 0)
-       {
-               return $this->db->plimit($limit, $offset);
-       }
-
-       /**
-        * Return value of server parameters
-        *
-        * @param   string      $filter         Filter list on a particular value
-        * @return  array                               Array of key-values (key=>value)
-        */
-       public function getServerParametersValues($filter = '')
-       {
-               return $this->db->getServerParametersValues($filter);
-       }
-
-       /**
-        * Return value of server status
-        *
-        * @param   string $filter              Filter list on a particular value
-        * @return  array                               Array of key-values (key=>value)
-        */
-       public function getServerStatusValues($filter = '')
-       {
-               return $this->db->getServerStatusValues($filter);
-       }
-
-       /**
-        * Return collation used in database
-        *
-        * @return  string        Collation value
-        */
-       public function getDefaultCollationDatabase()
-       {
-               return $this->db->getDefaultCollationDatabase();
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        * Return number of lines for result of a SELECT
-        *
-        * @param   resource $resultset    Resulset of requests
-        * @return      int                    Nb of lines
-        * @see         affected_rows()
-        */
-       public function num_rows($resultset)
-       {
-               // phpcs:enable
-               return $this->db->num_rows($resultset);
-       }
-
-       /**
-        * Return full path of dump program
-        *
-        * @return        string        Full path of dump program
-        */
-       public function getPathOfDump()
-       {
-               return $this->db->getPathOfDump();
-       }
-
-       /**
-        * Return version of database client driver
-        *
-        * @return            string      Version string
-        */
-       public function getDriverInfo()
-       {
-               return $this->db->getDriverInfo();
-       }
-
-       /**
-        * Return generic error code of last operation.
-        *
-        * @return    string        Error code (Exemples: DB_ERROR_TABLE_ALREADY_EXISTS, DB_ERROR_RECORD_ALREADY_EXISTS...)
-        */
-       public function errno()
-       {
-               return $this->db->errno();
-       }
-
-       /**
-        * Create a table into database
-        *
-        * @param        string $table                  Name of table
-        * @param        array  $fields                 Tableau associatif [nom champ][tableau des descriptions]
-        * @param        string $primary_key    Nom du champ qui sera la clef primaire
-        * @param        string $type                   Type de la table
-        * @param        array  $unique_keys    Tableau associatifs Nom de champs qui seront clef unique => valeur
-        * @param        array  $fulltext_keys  Tableau des Nom de champs qui seront indexes en fulltext
-        * @param        array $keys                    Tableau des champs cles noms => valeur
-        * @return       int                    <0 if KO, >=0 if OK
-        */
-       public function DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys = null, $fulltext_keys = null, $keys = null)
-       {
-               return $this->db->DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys, $fulltext_keys, $keys);
-       }
-
-       /**
-        * Drop a table into database
-        *
-        * @param        string $table                  Name of table
-        * @return       int                    <0 if KO, >=0 if OK
-        */
-       public function DDLDropTable($table)
-       {
-               return $this->db->DDLDropTable($table);
-       }
-
-       /**
-        * Return list of available charset that can be used to store data in database
-        *
-        * @return        array        List of Charset
-        */
-       public function getListOfCharacterSet()
-       {
-               return $this->db->getListOfCharacterSet();
-       }
-
-       /**
-        * Create a new field into table
-        *
-        * @param    string $table                              Name of table
-        * @param    string $field_name                 Name of field to add
-        * @param    string $field_desc                 Tableau associatif de description du champ a inserer[nom du parametre][valeur du parametre]
-        * @param    string $field_position     Optionnel ex.: "after champtruc"
-        * @return   int                        <0 if KO, >0 if OK
-        */
-       public function DDLAddField($table, $field_name, $field_desc, $field_position = "")
-       {
-               return $this->db->DDLAddField($table, $field_name, $field_desc, $field_position);
-       }
-
-       /**
-        * Drop a field from table
-        *
-        * @param    string $table                              Name of table
-        * @param    string $field_name                 Name of field to drop
-        * @return   int                        <0 if KO, >0 if OK
-        */
-       public function DDLDropField($table, $field_name)
-       {
-               return $this->db->DDLDropField($table, $field_name);
-       }
-
-       /**
-        * Update format of a field into a table
-        *
-        * @param    string     $table                  Name of table
-        * @param    string     $field_name     Name of field to modify
-        * @param    string     $field_desc     Array with description of field format
-        * @return   int                        <0 if KO, >0 if OK
-        */
-       public function DDLUpdateField($table, $field_name, $field_desc)
-       {
-               return $this->db->DDLUpdateField($table, $field_name, $field_desc);
-       }
-
-       /**
-        * Return list of available collation that can be used for database
-        *
-        * @return        array                         List of Collation
-        */
-       public function getListOfCollation()
-       {
-               return $this->db->getListOfCollation();
-       }
-
-       /**
-        * Return a pointer of line with description of a table or field
-        *
-        * @param    string     $table                  Name of table
-        * @param    string     $field                  Optionnel : Name of field if we want description of field
-        * @return   resource                           Resource
-        */
-       public function DDLDescTable($table, $field = "")
-       {
-               return $this->db->DDLDescTable($table, $field);
-       }
-
-       /**
-        * Return version of database server
-        *
-        * @return            string                    Version string
-        */
-       public function getVersion()
-       {
-               return $this->db->getVersion();
-       }
-
-       /**
-        * Return charset used to store data in database
-        *
-        * @return        string                        Charset
-        */
-       public function getDefaultCharacterSetDatabase()
-       {
-               return $this->db->getDefaultCharacterSetDatabase();
-       }
-
-       /**
-        * Create a user and privileges to connect to database (even if database does not exists yet)
-        *
-        * @param    string $dolibarr_main_db_host      Ip serveur
-        * @param    string $dolibarr_main_db_user      Nom user a creer
-        * @param    string $dolibarr_main_db_pass      Mot de passe user a creer
-        * @param    string $dolibarr_main_db_name      Database name where user must be granted
-        * @return   int                            <0 if KO, >=0 if OK
-        */
-       public function DDLCreateUser($dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_pass, $dolibarr_main_db_name)
-       {
-               return $this->db->DDLCreateUser($dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_pass, $dolibarr_main_db_name);
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        * Convert (by PHP) a PHP server TZ string date into a Timestamps date (GMT if gm=true)
-        * 19700101020000 -> 3600 with TZ+1 and gmt=0
-        * 19700101020000 -> 7200 whaterver is TZ if gmt=1
-        *
-        * @param       string                  $string         Date in a string (YYYYMMDDHHMMSS, YYYYMMDD, YYYY-MM-DD HH:MM:SS)
-        * @param       bool                    $gm                     1=Input informations are GMT values, otherwise local to server TZ
-        * @return      int|string                                      Date TMS or ''
-        */
-       public function jdate($string, $gm = false)
-       {
-               // phpcs:enable
-               return $this->db->jdate($string, $gm);
-       }
-
-       /**
-        * Encrypt sensitive data in database
-        * Warning: This function includes the escape and add the SQL simple quotes on strings.
-        *
-        * @param       string  $fieldorvalue   Field name or value to encrypt
-        * @param       int             $withQuotes             Return string including the SQL simple quotes. This param must always be 1 (Value 0 is bugged and deprecated).
-        * @return      string                                  XXX(field) or XXX('value') or field or 'value'
-        */
-       public function encrypt($fieldorvalue, $withQuotes = 1)
-       {
-               return $this->db->encrypt($fieldorvalue, $withQuotes);
-       }
-
-       /**
-        * Validate a database transaction
-        *
-        * @param   string                      $log                    Add more log to default log line
-        * @return      int                                             1 if validation is OK or transaction level no started, 0 if ERROR
-        */
-       public function commit($log = '')
-       {
-               return $this->db->commit($log);
-       }
-
-       /**
-        * List information of columns into a table.
-        *
-        * @param   string                      $table                  Name of table
-        * @return  array                                       Array with inforation on table
-        */
-       public function DDLInfoTable($table)
-       {
-               return $this->db->DDLInfoTable($table);
-       }
-
-       /**
-        * Free last resultset used.
-        *
-        * @param       resource                $resultset              Fre cursor
-        * @return  void
-        */
-       public function free($resultset = null)
-       {
-               $this->db->free($resultset);
-       }
-
-       /**
-        * Close database connexion
-        *
-        * @return  boolean                                             True if disconnect successfull, false otherwise
-        * @see     connect()
-        */
-       public function close()
-       {
-               return $this->db->close();
-       }
-
-       /**
-        * Return last query in error
-        *
-        * @return  string    lastqueryerror
-        */
-       public function lastqueryerror()
-       {
-               return $this->db->lastqueryerror();
-       }
-
-       /**
-        * Return connexion ID
-        *
-        * @return  string      Id connexion
-        */
-       public function DDLGetConnectId()
-       {
-               return $this->db->DDLGetConnectId();
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        * Returns the current line (as an object) for the resultset cursor
-        *
-        * @param   resource|Connection                 $resultset      Handler of the desired SQL request
-        * @return  Object                                                              Object result line or false if KO or end of cursor
-        */
-       public function fetch_object($resultset)
-       {
-               // phpcs:enable
-               return $this->db->fetch_object($resultset);
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        * Select a database
-        *
-        * @param       string $database     Name of database
-        * @return  boolean              true if OK, false if KO
-        */
-       public function select_db($database)
-       {
-               // phpcs:enable
-               return $this->db->select_db($database);
-       }
-}
diff --git a/htdocs/debugbar/class/autoloader.php b/htdocs/debugbar/class/autoloader.php
deleted file mode 100644 (file)
index a093315..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/**
- * Simple autoloader, so we don't need Composer just for this.
- */
-
-spl_autoload_register(function ($class) {
-       if (preg_match('/^DebugBar/', $class)) {
-               $file = DOL_DOCUMENT_ROOT.'/includes/maximebf/debugbar/src/'.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
-               //var_dump($class.' - '.file_exists($file).' - '.$file);
-               if (file_exists($file)) {
-                       require_once $file;
-                       return true;
-               }
-               return false;
-       }
-       if (preg_match('/^'.preg_quote('Psr\Log', '/').'/', $class)) {
-               $file = DOL_DOCUMENT_ROOT.'/includes/'.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
-               //var_dump($class.' - '.file_exists($file).' - '.$file);
-               if (file_exists($file)) {
-                       require_once $file;
-                       return true;
-               }
-               return false;
-       }
-       if (preg_match('/^'.preg_quote('Symfony\Component\VarDumper', '/').'/', $class)) {
-               $class = preg_replace('/'.preg_quote('Symfony\Component\VarDumper', '/').'/', '', $class);
-               $file = DOL_DOCUMENT_ROOT.'/includes/symfony/var-dumper/'.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
-               if (file_exists($file)) {
-                       require_once $file;
-                       return true;
-               }
-               return false;
-       }
-       return true;
-});
diff --git a/htdocs/debugbar/js/widgets.js b/htdocs/debugbar/js/widgets.js
deleted file mode 100644 (file)
index 7c10555..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-(function ($) {
-
-    var csscls = PhpDebugBar.utils.makecsscls('phpdebugbar-');
-
-    /**
-     * TooltipIndicator
-     *
-     * A customised indicator class that will provide a better tooltip.
-     *
-     * Options:
-     *  - icon
-     *  - title
-     *  - tooltip: array('html' => '', 'class' => '')
-     *  - data: alias of title
-     */
-    var TooltipIndicator = PhpDebugBar.DebugBar.TooltipIndicator = PhpDebugBar.DebugBar.Indicator.extend({
-
-        render: function() {
-            this.$icon = $('<i />').appendTo(this.$el);
-            this.bindAttr('icon', function(icon) {
-                if (icon) {
-                    this.$icon.attr('class', 'fa fa-' + icon);
-                } else {
-                    this.$icon.attr('class', '');
-                }
-            });
-
-            this.bindAttr(['title', 'data'], $('<span />').addClass(csscls('text')).appendTo(this.$el));
-
-            this.$tooltip = $('<span />').addClass(csscls('tooltip disabled')).appendTo(this.$el);
-            this.bindAttr('tooltip', function(tooltip) {
-                if (tooltip['html']) {
-                    tooltipHTML = $('<span />').html(tooltip['html']).addClass(csscls('tooltip-html'));
-                    this.$tooltip.html(tooltipHTML).removeClass(csscls('disabled'));
-                    if (tooltip['class']) {
-                        this.$tooltip.addClass(csscls(tooltip['class']));
-                    }
-                } else {
-                    this.$tooltip.addClass(csscls('disabled'));
-                }
-            });
-        }
-
-    });
-
-    /**
-     * LinkIndicator
-     *
-     * A customised indicator class that will allow "click" behaviour.
-     *
-     * Options:
-     *  - icon
-     *  - title
-     *  - tooltip
-     *  - data: alias of title
-     *  - href
-     *  - target
-     */
-    var LinkIndicator = PhpDebugBar.DebugBar.LinkIndicator = PhpDebugBar.DebugBar.Indicator.extend({
-
-        tagName: 'a',
-
-        render: function() {
-            LinkIndicator.__super__.render.apply(this);
-            this.bindAttr('href', function(href) {
-                this.$el.attr('href', href);
-            });
-            this.bindAttr('target', function(target) {
-                this.$el.attr('target', target);
-            });
-        }
-
-    });
-
-})(PhpDebugBar.$);
\ No newline at end of file
index cf337ab..8ccbd7c 100644 (file)
@@ -197,13 +197,14 @@ if ($object->id > 0) {
         * Show tabs
         */
        $head = societe_prepare_head($object);
-
-       print dol_get_fiche_head($head, 'supplier', $langs->trans("ThirdParty"), -1, 'company');
-
        $linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
 
        dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom');
 
+       print dol_get_fiche_head($head, 'supplier', $langs->trans("ThirdParty"), -1, 'company');
+
+       
+
        print '<div class="fichecenter"><div class="fichehalfleft">';
 
        print '<div class="underbanner clearboth"></div>';
index bc0c7b9..56e230e 100644 (file)
@@ -2795,17 +2795,17 @@ class FactureFournisseur extends CommonInvoice
                        $label .= ' - '.$moretitle;
                }
 
-               $ref = $this->ref;
+               $ref = $this->ref_supplier;
                if (empty($ref)) {
                        $ref = $this->id;
                }
 
                $linkclose = '';
                if (empty($notooltip)) {
-                       if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
-                               $label = $langs->trans("ShowSupplierInvoice");
-                               $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
-                       }
+                       // if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
+                       //      $label = $langs->trans("ShowSupplierInvoice");
+                       //      $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
+                       // }
                        $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
                        $linkclose .= ' class="classfortooltip"';
                }
index e330446..d8211ea 100644 (file)
@@ -2713,7 +2713,7 @@ if ($action == 'create') {
                $head = facturefourn_prepare_head($object);
                $titre = $langs->trans('SupplierInvoice');
 
-               print dol_get_fiche_head($head, 'card', $titre, -1, 'supplier_invoice');
+               //print dol_get_fiche_head($head, 'card', $titre, -1, 'supplier_invoice');
 
                $formconfirm = '';
 
@@ -2955,6 +2955,8 @@ if ($action == 'create') {
 
                dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
 
+               print dol_get_fiche_head($head, 'card', $titre, -1, 'supplier_invoice');
+               
                print '<div class="fichecenter">';
                print '<div class="fichehalfleft">';
                print '<div class="underbanner clearboth"></div>';
index cff4a30..ea6f1b5 100644 (file)
@@ -101,7 +101,7 @@ llxHeader('', $title, $helpurl);
 
 if ($object->id > 0) {
        $head = facturefourn_prepare_head($object);
-       print dol_get_fiche_head($head, 'documents', $langs->trans('SupplierInvoice'), -1, 'supplier_invoice');
+       //print dol_get_fiche_head($head, 'documents', $langs->trans('SupplierInvoice'), -1, 'supplier_invoice');
 
        $totalpaid = $object->getSommePaiement();
 
@@ -142,7 +142,7 @@ if ($object->id > 0) {
        $object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status
 
        dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0);
-
+       print dol_get_fiche_head($head, 'documents', $langs->trans('SupplierInvoice'), -1, 'supplier_invoice');
        print '<div class="fichecenter">';
        print '<div class="underbanner clearboth"></div>';
 
index ad03c48..3eac81a 100644 (file)
@@ -949,37 +949,37 @@ if ($search_all) {
 
 // If the user can view prospects other than his'
 $moreforfilter = '';
-if ($user->rights->user->user->lire) {
-       $langs->load("commercial");
-       $moreforfilter .= '<div class="divsearchfield">';
-       $tmptitle = $langs->trans('ThirdPartiesOfSaleRepresentative');
-       $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, $tmptitle, 'maxwidth200');
-       $moreforfilter .= '</div>';
-}
+// if ($user->rights->user->user->lire) {
+//     $langs->load("commercial");
+//     $moreforfilter .= '<div class="divsearchfield">';
+//     $tmptitle = $langs->trans('ThirdPartiesOfSaleRepresentative');
+//     $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, $tmptitle, 'maxwidth200');
+//     $moreforfilter .= '</div>';
+// }
 // If the user can view prospects other than his'
-if ($user->rights->user->user->lire) {
-       $moreforfilter .= '<div class="divsearchfield">';
-       $tmptitle = $langs->trans('LinkedToSpecificUsers');
-       $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form->select_dolusers($search_user, 'search_user', $tmptitle, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth200');
-       $moreforfilter .= '</div>';
-}
+// if ($user->rights->user->user->lire) {
+//     $moreforfilter .= '<div class="divsearchfield">';
+//     $tmptitle = $langs->trans('LinkedToSpecificUsers');
+//     $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form->select_dolusers($search_user, 'search_user', $tmptitle, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth200');
+//     $moreforfilter .= '</div>';
+// }
 // If the user can view prospects other than his'
-if (isModEnabled('categorie') && $user->rights->categorie->lire && ($user->rights->produit->lire || $user->rights->service->lire)) {
-       include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
-       $moreforfilter .= '<div class="divsearchfield">';
-       $tmptitle = $langs->trans('IncludingProductWithTag');
-       $cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT, null, 'parent', null, null, 1);
-       $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"').$form->selectarray('search_product_category', $cate_arbo, $search_product_category, $tmptitle, 0, 0, '', 0, 0, 0, 0, 'maxwidth300 widthcentpercentminusx', 1);
-       $moreforfilter .= '</div>';
-}
-
-if (isModEnabled('categorie')) {
-       require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
-       $moreforfilter .= '<div class="divsearchfield">';
-       $tmptitle = $langs->trans('SuppliersCategoriesShort');
-       $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"').$formother->select_categories('supplier', $search_categ_sup, 'search_categ_sup', 1, $tmptitle);
-       $moreforfilter .= '</div>';
-}
+// if (isModEnabled('categorie') && $user->rights->categorie->lire && ($user->rights->produit->lire || $user->rights->service->lire)) {
+//     include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+//     $moreforfilter .= '<div class="divsearchfield">';
+//     $tmptitle = $langs->trans('IncludingProductWithTag');
+//     $cate_arbo = $form->select_all_categories(Categorie::TYPE_PRODUCT, null, 'parent', null, null, 1);
+//     $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"').$form->selectarray('search_product_category', $cate_arbo, $search_product_category, $tmptitle, 0, 0, '', 0, 0, 0, 0, 'maxwidth300 widthcentpercentminusx', 1);
+//     $moreforfilter .= '</div>';
+// }
+
+// if (isModEnabled('categorie')) {
+//     require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+//     $moreforfilter .= '<div class="divsearchfield">';
+//     $tmptitle = $langs->trans('SuppliersCategoriesShort');
+//     $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"').$formother->select_categories('supplier', $search_categ_sup, 'search_categ_sup', 1, $tmptitle);
+//     $moreforfilter .= '</div>';
+// }
 $parameters = array();
 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
 if (empty($reshook)) {
@@ -1245,9 +1245,9 @@ print '<tr class="liste_titre">';
 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
        print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
 }
-if (!empty($arrayfields['f.ref']['checked'])) {
-       print_liste_field_titre($arrayfields['f.ref']['label'], $_SERVER['PHP_SELF'], 'f.ref,f.rowid', '', $param, '', $sortfield, $sortorder);
-}
+// if (!empty($arrayfields['f.ref']['checked'])) {
+//     print_liste_field_titre($arrayfields['f.ref']['label'], $_SERVER['PHP_SELF'], 'f.ref,f.rowid', '', $param, '', $sortfield, $sortorder);
+// }
 if (!empty($arrayfields['f.ref_supplier']['checked'])) {
        print_liste_field_titre($arrayfields['f.ref_supplier']['label'], $_SERVER["PHP_SELF"], 'f.ref_supplier', '', $param, '', $sortfield, $sortorder);
 }
@@ -1444,30 +1444,31 @@ if ($num > 0) {
                        }
                        print '</td>';
                }
-               if (!empty($arrayfields['f.ref']['checked'])) {
-                       print '<td class="nowraponall">';
-
-                       print '<table class="nobordernopadding"><tr class="nocellnopadd">';
-                       // Picto + Ref
-                       print '<td class="nobordernopadding nowraponall">';
-                       print $facturestatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1);
-
-                       $filename = dol_sanitizeFileName($obj->ref);
-                       $filedir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($obj->facid, 2, 0, 0, $facturestatic, 'invoice_supplier').dol_sanitizeFileName($obj->ref);
-                       $subdir = get_exdir($obj->facid, 2, 0, 0, $facturestatic, 'invoice_supplier').dol_sanitizeFileName($obj->ref);
-                       print $formfile->getDocumentsLink('facture_fournisseur', $subdir, $filedir);
-                       print '</td></tr></table>';
-
-                       print "</td>\n";
-                       if (!$i) {
-                               $totalarray['nbfield']++;
-                       }
-               }
+               // if (!empty($arrayfields['f.ref']['checked'])) {
+               //      print '<td class="nowraponall">';
+
+               //      print '<table class="nobordernopadding"><tr class="nocellnopadd">';
+               //      // Picto + Ref
+               //      print '<td class="nobordernopadding nowraponall">';
+               //      print $facturestatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1);
+
+               //      //$filename = dol_sanitizeFileName($obj->ref);
+               //      //$filedir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($obj->facid, 2, 0, 0, $facturestatic, 'invoice_supplier').dol_sanitizeFileName($obj->ref);
+               //      //$subdir = get_exdir($obj->facid, 2, 0, 0, $facturestatic, 'invoice_supplier').dol_sanitizeFileName($obj->ref);
+               //      //print $formfile->getDocumentsLink('facture_fournisseur', $subdir, $filedir);
+               //      print '</td></tr></table>';
+
+               //      print "</td>\n";
+               //      if (!$i) {
+               //              $totalarray['nbfield']++;
+               //      }
+               // }
 
                // Supplier ref
                if (!empty($arrayfields['f.ref_supplier']['checked'])) {
                        print '<td class="nowrap tdoverflowmax150" title="'.dol_escape_htmltag($obj->ref_supplier).'">';
-                       print $obj->ref_supplier;
+                       print $facturestatic->getNomUrl(1, '', 0, 0, '', 1, -1, 1);
+                       // print $obj->ref_supplier;
                        print '</td>';
                        if (!$i) {
                                $totalarray['nbfield']++;
diff --git a/htdocs/includes/html2pdf/Segment.php b/htdocs/includes/html2pdf/Segment.php
new file mode 100644 (file)
index 0000000..9ff3951
--- /dev/null
@@ -0,0 +1,273 @@
+<?php
+require 'SegmentIterator.php';
+class SegmentException extends Exception
+{
+}
+
+/**
+ * Class for handling templating segments with odt files
+ * You need PHP 5.2 at least
+ * You need Zip Extension or PclZip library
+ *
+ * @copyright  2008 - Julien Pauli - Cyril PIERRE de GEYER - Anaska (http://www.anaska.com)
+ * @copyright  2012 - Stephen Larroque - lrq3000@gmail.com
+ * @license    https://www.gnu.org/copyleft/gpl.html  GPL License
+ * @version 1.4.5 (last update 2013-04-07)
+ */
+class Segment implements IteratorAggregate, Countable
+{
+       protected $xml;
+       protected $xmlParsed = '';
+       protected $name;
+       protected $children = array();
+       protected $vars = array();
+       protected $images = array();
+       protected $odf;
+       protected $file;
+       
+
+       /**
+        * Constructor
+        *
+        * @param string $name  name of the segment to construct
+        * @param string $xml   XML tree of the segment
+        * @param string $odf   odf
+        */
+       public function __construct($name, $xml, $odf)
+       {
+               $this->name = (string) $name;
+               $this->xml = (string) $xml;
+               $this->odf = $odf;
+               $zipHandler = $this->odf->getConfig('ZIP_PROXY');
+               $this->file = new $zipHandler($this->odf->getConfig('PATH_TO_TMP'));
+               $this->_analyseChildren($this->xml);
+       }
+       /**
+        * Returns the name of the segment
+        *
+        * @return string
+        */
+       public function getName()
+       {
+               return $this->name;
+       }
+       /**
+        * Does the segment have children ?
+        *
+        * @return bool
+        */
+       public function hasChildren()
+       {
+               return $this->getIterator()->hasChildren();
+       }
+       /**
+        * Countable interface
+        *
+        * @return int
+        */
+  #[\ReturnTypeWillChange]
+       public function count()
+       {
+               return count($this->children);
+       }
+       /**
+        * IteratorAggregate interface
+        *
+        * @return Iterator
+        */
+  #[\ReturnTypeWillChange]
+       public function getIterator()
+       {
+               return new RecursiveIteratorIterator(new SegmentIterator($this->children), 1);
+       }
+       /**
+        * Replace variables of the template in the XML code
+        * All the children are also called
+        * Complete the current segment with new line
+        *
+        * @return string
+        */
+       public function merge()
+       {
+               // To provide debug information on line number processed
+               global $count;
+               if (empty($count)) $count=1;
+               else $count++;
+               
+               if (empty($this->savxml)) $this->savxml = $this->xml;       // Sav content of line at first line merged, so we will reuse original for next steps
+               $this->xml = $this->savxml;
+               $tmpvars = $this->vars;                                     // Store into $tmpvars so we won't modify this->vars when completing data with empty values
+               if(isset($this->xml)){
+                       $reg='/\{\{\#(\w+)\}\}(.+)\{\{\/(\w+)\}\}/smU';
+                       $matches = array();
+                       preg_match_all($reg, $this->xml, $matches, PREG_SET_ORDER);
+                       foreach ($matches as $match) {  
+                                       if (isset($tmpvars[$match[1]])){
+                                               $this->xml = str_replace($match[0],$match[2],$this->xml);
+                                       } else {
+                                               $this->xml = str_replace($match[0],'',$this->xml);
+                                       }
+                       }
+               
+                       $reg='/\{(\w+)\}/';
+                       $matches = array();
+                       preg_match_all($reg, $this->xml, $matches, PREG_SET_ORDER);
+                       foreach ($matches as $match) {
+                               if (isset($tmpvars[$match[1]])){
+                                       $this->xml = str_replace($match[0],$tmpvars[$match[1]],$this->xml);
+                               } else {
+                                       $this->xml= str_replace($match[0],'',$this->xml);
+                               }
+                       }
+                       $this->xmlParsed .= $this->xml;
+               }
+               return $this->xmlParsed;
+       }
+
+       /**
+       * Function to replace macros for invoice short and long month, invoice year
+       *
+       * Substitution occur when the invoice is generated, not considering the invoice date
+       * so do not (re)generate in a diferent date than the one that the invoice belongs to
+       * Perhaps it would be better to use the invoice issued date but I still do not know
+       * how to get it here
+       *
+       * Miguel Erill 09/04/2017
+       *
+       * @param        string  $value  String to convert
+       */
+       public function macroReplace($text)
+       {
+               include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+               global $langs;
+
+               $hoy = dol_getdate(dol_now('tzuser'));
+               $dateinonemontharray = dol_get_next_month($hoy['mon'], $hoy['year']);
+               $nextMonth = $dateinonemontharray['month'];
+
+               $patterns=array( '/__CURRENTDAY__/u','/__CURENTWEEKDAY__/u',
+                                                '/__CURRENTMONTH__/u','/__CURRENTMONTHLONG__/u',
+                                                '/__NEXTMONTH__/u','/__NEXTMONTHLONG__/u',
+                                                '/__CURRENTYEAR__/u','/__NEXTYEAR__/u' );
+               $values=array( $hoy['mday'], $langs->transnoentitiesnoconv($hoy['weekday']),
+                                          $hoy['mon'], $langs->transnoentitiesnoconv($hoy['month']),
+                                          $nextMonth, monthArray($langs)[$nextMonth],
+                                          $hoy['year'], $hoy['year']+1 );
+
+               $text=preg_replace($patterns, $values, $text);
+
+               return $text;
+       }
+
+       /**
+        * Analyse the XML code in order to find children
+        *
+        * @param string $xml   Xml
+        * @return Segment
+        */
+       protected function _analyseChildren($xml)
+       {
+               // $reg2 = "#\[!--\sBEGIN\s([\S]*)\s--\](?:<\/text:p>)?(.*)(?:<text:p\s.*>)?\[!--\sEND\s(\\1)\s--\]#sm";
+               $reg2 = "#\[!--\sBEGIN\s([\S]*)\s--\](.*)\[!--\sEND\s(\\1)\s--\]#sm";
+               preg_match_all($reg2, $xml, $matches);
+               for ($i = 0, $size = count($matches[0]); $i < $size; $i++) {
+                       if ($matches[1][$i] != $this->name) {
+                               $this->children[$matches[1][$i]] = new self($matches[1][$i], $matches[0][$i], $this->odf);
+                       } else {
+                               $this->_analyseChildren($matches[2][$i]);
+                       }
+               }
+               return $this;
+       }
+
+       /**
+        * Assign a template variable to replace
+        *
+        * @param string $key       Key
+        * @param string $value     Value
+        * @param string $encode    Encode
+        * @param string $charset   Charset
+        * @throws SegmentException
+        * @return Segment
+        */
+       public function setVars($key, $value, $encode = true, $charset = 'ISO-8859')
+       {
+               $tag = $this->odf->getConfig('DELIMITER_LEFT') . $key . $this->odf->getConfig('DELIMITER_RIGHT');
+
+
+               $this->vars[$key] = $this->odf->convertVarToOdf($value, $encode, $charset);
+
+               return $this;
+       }
+
+       /**
+        * Assign a template variable as a picture
+        *
+        * @param string $key name of the variable within the template
+        * @param string $value path to the picture
+        * @throws OdfException
+        * @return Segment
+        */
+       public function setImage($key, $value)
+       {
+               $filename = strtok(strrchr($value, '/'), '/.');
+               $file = substr(strrchr($value, '/'), 1);
+               $size = @getimagesize($value);
+               if ($size === false) {
+                       throw new OdfException("Invalid image");
+               }
+               // Set the width and height of the page
+               list ($width, $height) = $size;
+               $width *= Odf::PIXEL_TO_CM;
+               $height *= Odf::PIXEL_TO_CM;
+               // Fix local-aware issues (eg: 12,10 -> 12.10)
+               $width = sprintf("%F", $width);
+               $height = sprintf("%F", $height);
+
+               $xml = <<<IMG
+<draw:frame draw:style-name="fr1" draw:name="$filename" text:anchor-type="aschar" svg:width="{$width}cm" svg:height="{$height}cm" draw:z-index="3"><draw:image xlink:href="Pictures/$file" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/></draw:frame>
+IMG;
+               $this->images[$value] = $file;
+               $this->setVars($key, $xml, false);
+               return $this;
+       }
+       /**
+        * Shortcut to retrieve a child
+        *
+        * @param string $prop      Prop
+        * @return Segment
+        * @throws SegmentException
+        */
+       public function __get($prop)
+       {
+               if (array_key_exists($prop, $this->children)) {
+                       return $this->children[$prop];
+               } else {
+                       throw new SegmentException('child ' . $prop . ' does not exist');
+               }
+       }
+       /**
+        * Proxy for setVars
+        *
+        * @param string $meth      Meth
+        * @param array $args       Args
+        * @return Segment
+        */
+       public function __call($meth, $args)
+       {
+               try {
+                       return $this->setVars($meth, $args[0]);
+               } catch (SegmentException $e) {
+                       throw new SegmentException("method $meth nor var $meth exist");
+               }
+       }
+       /**
+        * Returns the parsed XML
+        *
+        * @return string
+        */
+       public function getXmlParsed()
+       {
+               return $this->xmlParsed;
+       }
+}
diff --git a/htdocs/includes/html2pdf/SegmentIterator.php b/htdocs/includes/html2pdf/SegmentIterator.php
new file mode 100644 (file)
index 0000000..cb6b352
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Segments iterator
+ * You need PHP 5.2 at least
+ * You need Zip Extension or PclZip library
+ *
+ * @copyright  GPL License 2008 - Julien Pauli - Cyril PIERRE de GEYER - Anaska (http://www.anaska.com)
+ * @license    https://www.gnu.org/copyleft/gpl.html  GPL License
+ * @version 1.3
+ */
+class SegmentIterator implements RecursiveIterator
+{
+    
+    private $ref;
+    private $key;
+    public function __construct(array $ref)
+    {
+        $this->ref = $ref;
+        $this->key = 0;
+        $this->keys = array_keys($this->ref);
+    }
+    #[\ReturnTypeWillChange]
+    public function hasChildren()
+    {
+        return $this->valid() && $this->current() instanceof Segment;
+    }
+    #[\ReturnTypeWillChange]
+    public function current()
+    {
+        return $this->ref[$this->keys[$this->key]];
+    }
+    #[\ReturnTypeWillChange]
+    function getChildren()
+    {
+        return new self($this->current()->children);
+    }
+    #[\ReturnTypeWillChange]
+    public function key()
+    {
+        return $this->key;
+    }
+    #[\ReturnTypeWillChange]
+    public function valid()
+    {
+        return array_key_exists($this->key, $this->keys);
+    }
+    #[\ReturnTypeWillChange]
+    public function rewind()
+    {
+        $this->key = 0;
+    }
+    #[\ReturnTypeWillChange]
+    public function next()
+    {
+        $this->key ++;
+    }
+}
+
diff --git a/htdocs/includes/html2pdf/html2pdf.php b/htdocs/includes/html2pdf/html2pdf.php
new file mode 100644 (file)
index 0000000..89ae023
--- /dev/null
@@ -0,0 +1,1012 @@
+<?php
+
+require 'Segment.php';
+
+/**
+ * Class of ODT Exception
+ */
+class OdfException extends Exception
+{
+}
+
+/**
+ * Templating class for odt file
+ * You need PHP 5.2 at least
+ * You need Zip Extension or PclZip library
+ *
+ * @copyright  2008 - Julien Pauli - Cyril PIERRE de GEYER - Anaska (http://www.anaska.com)
+ * @copyright  2010-2015 - Laurent Destailleur - eldy@users.sourceforge.net
+ * @copyright  2010 - Vikas Mahajan - http://vikasmahajan.wordpress.com
+ * @copyright  2012 - Stephen Larroque - lrq3000@gmail.com
+ * @license    https://www.gnu.org/copyleft/gpl.html  GPL License
+ * @version 1.5.0
+ */
+class html2pdf
+{
+       protected $config = array(
+               'ZIP_PROXY' => 'PclZipProxy',   // PclZipProxy, PhpZipProxy
+               'DELIMITER_LEFT' => '{',
+               'DELIMITER_RIGHT' => '}',
+               'PATH_TO_TMP' => '/tmp'
+       );
+       protected $file;
+       protected $contentXml;                  // To store content of content.xml file
+       protected $metaXml;                         // To store content of meta.xml file
+       protected $stylesXml;                   // To store content of styles.xml file
+       protected $manifestXml;                 // To store content of META-INF/manifest.xml file
+       protected $tmpfile;
+       protected $tmpdir='';
+       protected $images = array();
+       protected $vars = array();
+       protected $segments = array();
+
+       public $creator;
+       public $title;
+       public $subject;
+       public $userdefined=array();
+
+       const PIXEL_TO_CM = 0.026458333;
+
+       /**
+        * Class constructor
+        *
+        * @param string $filename     The name of the odt file
+        * @param string $config       Array of config data
+        * @throws OdfException
+        */
+       public function __construct($filename, $config = array())
+       {
+               clearstatcache();
+
+               if (! is_array($config)) {
+                       throw new OdfException('Configuration data must be provided as array');
+               }
+               foreach ($config as $configKey => $configValue) {
+                       if (array_key_exists($configKey, $this->config)) {
+                               $this->config[$configKey] = $configValue;
+                       }
+               }
+
+               $md5uniqid = md5(uniqid());
+               if ($this->config['PATH_TO_TMP']) $this->tmpdir = preg_replace('|[\/]$|', '', $this->config['PATH_TO_TMP']);    // Remove last \ or /
+               $this->tmpdir .= ($this->tmpdir?'/':'').$md5uniqid;
+               $this->tmpfile = $this->tmpdir.'/'.$md5uniqid.'.odt';   // We keep .odt extension to allow OpenOffice usage during debug.
+
+               // A working directory is required for some zip proxy like PclZipProxy
+               if (in_array($this->config['ZIP_PROXY'], array('PclZipProxy')) && ! is_dir($this->config['PATH_TO_TMP'])) {
+                       throw new OdfException('Temporary directory '.$this->config['PATH_TO_TMP'].' must exists');
+               }
+
+               // Create tmp direcoty (will be deleted in destructor)
+               if (!file_exists($this->tmpdir)) {
+                       $result = mkdir($this->tmpdir);
+               }
+
+               // Load zip proxy
+               $zipHandler = $this->config['ZIP_PROXY'];
+               if (!defined('PCLZIP_TEMPORARY_DIR')) define('PCLZIP_TEMPORARY_DIR', $this->tmpdir);
+               include_once 'zip/'.$zipHandler.'.php';
+               if (! class_exists($this->config['ZIP_PROXY'])) {
+                       throw new OdfException($this->config['ZIP_PROXY'] . ' class not found - check your php settings');
+               }
+               $this->file = new $zipHandler($this->tmpdir);
+
+
+               if ($this->file->open($filename) !== true) {    // This also create the tmpdir directory
+                       throw new OdfException("Error while Opening the file '$filename' - Check your odt filename");
+               }
+               if (($this->contentXml = $this->file->getFromName('content.xml')) === false) {
+                       throw new OdfException("Nothing to parse - Check that the content.xml file is correctly formed in source file '$filename'");
+               }
+               if (($this->manifestXml = $this->file->getFromName('META-INF/manifest.xml')) === false) {
+                       throw new OdfException("Something is wrong with META-INF/manifest.xml in source file '$filename'");
+               }
+               if (($this->metaXml = $this->file->getFromName('meta.xml')) === false) {
+                       throw new OdfException("Nothing to parse - Check that the meta.xml file is correctly formed in source file '$filename'");
+               }
+               if (($this->stylesXml = $this->file->getFromName('styles.xml')) === false) {
+                       throw new OdfException("Nothing to parse - Check that the styles.xml file is correctly formed in source file '$filename'");
+               }
+               $this->file->close();
+
+
+               //print "tmpdir=".$tmpdir;
+               //print "filename=".$filename;
+               //print "tmpfile=".$tmpfile;
+
+               copy($filename, $this->tmpfile);
+
+               // Now file has been loaded, we must move the [!-- BEGIN and [!-- END tags outside the
+               // <table:table-row tag and clean bad lines tags.
+               //$this->_moveRowSegments();
+       }
+
+       /**
+        * Assing a template variable into ->vars.
+        * For example, key is {object_date} and value is '2021-01-01'
+        *
+        * @param string   $key        Name of the variable within the template
+        * @param string   $value      Replacement value
+        * @param bool     $encode     If true, special XML characters are encoded
+        * @param string   $charset    Charset
+        * @throws OdfException
+        * @return odf
+        */
+       public function setVars($key, $value, $encode = true, $charset = 'ISO-8859')
+       {
+               $tag = $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT'];
+
+               // TODO Warning string may be:
+               // <text:span text:style-name="T13">{</text:span><text:span text:style-name="T12">aaa</text:span><text:span text:style-name="T13">}</text:span>
+               // instead of {aaa} so we should enhance this function.
+               //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'<br>';
+               // if (strpos($this->contentXml, $tag) === false && strpos($this->stylesXml, $tag) === false) {
+               //      // Add the throw only for development. In most cases, it is normal to not having the key into the document (only few keys are presents).
+               //      //throw new OdfException("var $key not found in the document");
+               //      return $this;
+               // }
+    if (dol_textishtml($value)){
+      $value=preg_replace('/(\r\n|\r|\n)/i', '', $value);
+    }
+               $this->vars[$key] = $this->convertVarToOdf($value, $encode, $charset);
+
+               return $this;
+       }
+
+       /**
+        * Replaces html tags found into the $value with ODT compatible tags and return the converted compatible string
+        *
+        * @param string   $value       Replacement value
+        * @param bool     $encode      If true, special XML characters are encoded
+        * @param string   $charset     Charset
+        * @return string                               String in ODTsyntax format
+        */
+       public function convertVarToOdf($value, $encode = true, $charset = 'ISO-8859')
+       {
+    if ($value != null){
+                 $value = $encode ? html_entity_decode($value) : $value;
+    }
+               $value = ($charset == 'ISO-8859') ? utf8_encode($value) : $value;
+               $convertedValue = $value;
+               
+               // Check if the value includes html tags
+               if ($this->_hasHtmlTag($value) === true) {
+                       // Default styles for strong/b, i/em, u, s, sub & sup
+                       $automaticStyles = array(
+                               '<style:style style:name="boldText" style:family="text"><style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold" /></style:style>',
+                               '<style:style style:name="italicText" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>',
+                               '<style:style style:name="underlineText" style:family="text"><style:text-properties style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color" /></style:style>',
+                               '<style:style style:name="strikethroughText" style:family="text"><style:text-properties style:text-line-through-style="solid" style:text-line-through-type="single" /></style:style>',
+                               '<style:style style:name="subText" style:family="text"><style:text-properties style:text-position="sub 58%" /></style:style>',
+                               '<style:style style:name="supText" style:family="text"><style:text-properties style:text-position="super 58%" /></style:style>'
+                       );
+
+                       $customStyles = array();
+                       $fontDeclarations = array();
+
+                       $convertedValue = $this->_replaceHtmlWithOdtTag($this->_getDataFromHtml($value), $customStyles, $fontDeclarations);
+
+                       foreach ($customStyles as $key => $val) {
+                               array_push($automaticStyles, '<style:style style:name="customStyle' . $key . '" style:family="text">' . $val . '</style:style>');
+                       }
+
+                       // Join the styles and add them to the content xml
+                       $styles = '';
+                       foreach ($automaticStyles as $style) {
+                               if (strpos($this->contentXml, $style) === false) {
+                                       $styles .= $style;
+                               }
+                       }
+                       $this->contentXml = str_replace('</office:automatic-styles>', $styles . '</office:automatic-styles>', $this->contentXml);
+
+                       // Join the font declarations and add them to the content xml
+                       $fonts = '';
+                       foreach ($fontDeclarations as $font) {
+                               if (strpos($this->contentXml, 'style:name="' . $font . '"') === false) {
+                                       $fonts .= '<style:font-face style:name="' . $font . '" svg:font-family="\'' . $font . '\'" />';
+                               }
+                       }
+                       $this->contentXml = str_replace('</office:font-face-decls>', $fonts . '</office:font-face-decls>', $this->contentXml);
+               } else {
+      if ($value){
+                         $convertedValue = preg_replace('/(\r\n|\r|\n)/i', "<text:line-break/>", $value);
+      }
+    }
+
+               return $convertedValue;
+       }
+
+       /**
+        * Replaces html tags in with odt tags and returns an odt string
+        *
+        * @param array $tags                           An array with html tags generated by the getDataFromHtml() function
+        * @param array $customStyles           An array of style defenitions that should be included inside the odt file
+        * @param array $fontDeclarations   An array of font declarations that should be included inside the odt file
+        * @return string
+        */
+       private function _replaceHtmlWithOdtTag($tags, &$customStyles, &$fontDeclarations)
+       {
+               if ($customStyles == null) $customStyles = array();
+               if ($fontDeclarations == null) $fontDeclarations = array();
+
+               $odtResult = '';
+
+               foreach ((array) $tags as $tag) {
+                       // Check if the current item is a tag or just plain text
+                       if (isset($tag['text'])) {
+                               $odtResult .= $tag['text'];
+                       } elseif (isset($tag['name'])) {
+                               switch ($tag['name']) {
+                                       case 'br':
+                                               $odtResult .= '<text:line-break/>';
+                                               break;
+                                       case 'strong':
+                                       case 'b':
+                                               $odtResult .= '<text:span text:style-name="boldText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
+                                               break;
+                                       case 'i':
+                                       case 'em':
+                                               $odtResult .= '<text:span text:style-name="italicText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
+                                               break;
+                                       case 'u':
+                                               $odtResult .= '<text:span text:style-name="underlineText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
+                                               break;
+                                       case 's':
+                                               $odtResult .= '<text:span text:style-name="strikethroughText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
+                                               break;
+                                       case 'sub':
+                                               $odtResult .= '<text:span text:style-name="subText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
+                                               break;
+                                       case 'sup':
+                                               $odtResult .= '<text:span text:style-name="supText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
+                                               break;
+                                       case 'span':
+                                               if (isset($tag['attributes']['style'])) {
+                                                       $odtStyles = '';
+                                                       foreach ($tag['attributes']['style'] as $styleName => $styleValue) {
+                                                               switch ($styleName) {
+                                                                       case 'font-family':
+                                                                               $fontName = $styleValue;
+                                                                               if (strpos($fontName, ',') !== false) {
+                                                                                       $fontName = explode(',', $fontName)[0];
+                                                                               }
+                                                                               if (!in_array($fontName, $fontDeclarations)) {
+                                                                                       array_push($fontDeclarations, $fontName);
+                                                                               }
+                                                                               $odtStyles .= '<style:text-properties style:font-name="' . $fontName . '" />';
+                                                                               break;
+                                                                       case 'font-size':
+                                                                               if (preg_match('/([0-9]+)\s?(px|pt)/', $styleValue, $matches)) {
+                                                                                       $fontSize = intval($matches[1]);
+                                                                                       if ($matches[2] == 'px') {
+                                                                                               $fontSize = round($fontSize * 0.75);
+                                                                                       }
+                                                                                       $odtStyles .= '<style:text-properties fo:font-size="' . $fontSize . 'pt" style:font-size-asian="' . $fontSize . 'pt" style:font-size-complex="' . $fontSize . 'pt" />';
+                                                                               }
+                                                                               break;
+                                                                       case 'color':
+                                                                               if (preg_match('/#[0-9A-Fa-f]{3}(?:[0-9A-Fa-f]{3})?/', $styleValue)) {
+                                                                                       $odtStyles .= '<style:text-properties fo:color="' . $styleValue . '" />';
+                                                                               }
+                                                                               break;
+                                                               }
+                                                       }
+                                                       if (strlen($odtStyles) > 0) {
+                                                               // Generate a unique id for the style (using microtime and random because some CPUs are really fast...)
+                                                               $key = floatval(str_replace('.', '', microtime(true)))+rand(0, 10);
+                                                               $customStyles[$key] = $odtStyles;
+                                                               $odtResult .= '<text:span text:style-name="customStyle' . $key . '">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
+                                                       }
+                                               }
+                                               break;
+                                       default:
+                                               $odtResult .= $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations);
+                                               break;
+                               }
+                       }
+               }
+               return $odtResult;
+       }
+
+       /**
+        * Checks if the given text is a html string
+        * @param string    $text   The text to check
+        * @return bool
+        */
+       private function _isHtmlTag($text)
+       {
+               return preg_match('/<([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(.*)<\/\1>))/', $text);
+       }
+
+       /**
+        * Checks if the given text includes a html string
+        * @param string    $text   The text to check
+        * @return bool
+        */
+       private function _hasHtmlTag($text)
+       {
+               if ($text){
+      $result = preg_match_all('/<([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(.*)<\/\1>))/', $text);
+    } else {
+      $result = null;
+    }
+               return is_numeric($result) && $result > 0;
+       }
+
+       /**
+        * Returns an array of html elements
+        * @param string    $html   A string with html tags
+        * @return array
+        */
+       private function _getDataFromHtml($html)
+       {
+               $tags = array();
+               $tempHtml = $html;
+
+               while (strlen($tempHtml) > 0) {
+                       $matches = array();
+                       // Check if the string includes a html tag
+                       if (preg_match_all('/<([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(.*)<\/\1>))/', $tempHtml, $matches)) {
+                               $tagOffset = strpos($tempHtml, $matches[0][0]);
+                               // Check if the string starts with the html tag
+                               if ($tagOffset > 0) {
+                                       // Push the text infront of the html tag to the result array
+                                       array_push($tags, array(
+                                               'text' => substr($tempHtml, 0, $tagOffset)
+                                       ));
+                                       // Remove the text from the string
+                                       $tempHtml = substr($tempHtml, $tagOffset);
+                               }
+                               // Extract the attribute data from the html tag
+                               $explodedAttributes = array();
+                               preg_match_all('/([0-9A-Za-z]+(?:="[0-9A-Za-z\:\-\s\,\;\#]*")?)+/', $matches[2][0], $explodedAttributes);
+                               $explodedAttributes = array_filter($explodedAttributes[0]);
+                               $attributes = array();
+                               // Store each attribute with its name in the $attributes array
+                               $explodedAttributesCount = count($explodedAttributes);
+                               for ($i=0; $i<$explodedAttributesCount; $i++) {
+                                       $attribute = trim($explodedAttributes[$i]);
+                                       // Check if the attribute has a value (like style="") or has no value (like required)
+                                       if (strpos($attribute, '=') !== false) {
+                                               $splitAttribute = explode('=', $attribute);
+                                               $attrName = trim($splitAttribute[0]);
+                                               $attrValue = trim(str_replace('"', '', $splitAttribute[1]));
+                                               // check if the current attribute is a style attribute
+                                               if (strtolower($attrName) == 'style') {
+                                                       $attributes[$attrName] = array();
+                                                       if (strpos($attrValue, ';') !== false) {
+                                                               // Split the style properties and store them in an array
+                                                               $explodedStyles = explode(';', $attrValue);
+                                                               $explodedStylesCount = count($explodedStyles);
+                                                               for ($n=0; $n<$explodedStylesCount; $n++) {
+                                                                       $splitStyle = explode(':', $explodedStyles[$n]);
+                                                                       $attributes[$attrName][trim($splitStyle[0])] = trim($splitStyle[1]);
+                                                               }
+                                                       } else {
+                                                               $splitStyle = explode(':', $attrValue);
+                                                               $attributes[$attrName][trim($splitStyle[0])] = trim($splitStyle[1]);
+                                                       }
+                                               } else {
+                                                       // Store the value directly in the $attributes array if this is not the style attribute
+                                                       $attributes[$attrName] = $attrValue;
+                                               }
+                                       } else {
+                                               $attributes[trim($attribute)] = true;
+                                       }
+                               }
+                               // Push the html tag data to the result array
+                               array_push($tags, array(
+                                       'name' => $matches[1][0],
+                                       'attributes' => $attributes,
+                                       'innerText' => strip_tags($matches[3][0]),
+                                       'children' => $this->_hasHtmlTag($matches[3][0]) ? $this->_getDataFromHtml($matches[3][0]) : null
+                               ));
+                               // Remove the processed html tag from the html string
+                               $tempHtml = substr($tempHtml, strlen($matches[0][0]));
+                       } else {
+                               array_push($tags, array(
+                                       'text' => $tempHtml
+                               ));
+                               $tempHtml = '';
+                       }
+               }
+               return $tags;
+       }
+
+
+       /**
+        * Function to convert a HTML string into an ODT string
+        *
+        * @param       string  $value  String to convert
+        * @return      string                  String converted
+        */
+       public function htmlToUTFAndPreOdf($value)
+       {
+               // We decode into utf8, entities
+               $value=dol_html_entity_decode($value, ENT_QUOTES|ENT_HTML5);
+
+               // We convert html tags
+               $ishtml=dol_textishtml($value);
+               if ($ishtml) {
+                       // If string is "MYPODUCT - Desc <strong>bold</strong> with &eacute; accent<br />\n<br />\nUn texto en espa&ntilde;ol ?"
+                       // Result after clean must be "MYPODUCT - Desc bold with Ã© accent\n\nUn texto en espa&ntilde;ol ?"
+
+                       // We want to ignore \n and we want all <br> to be \n
+                       $value=preg_replace('/(\r\n|\r|\n)/i', '', $value);
+                       $value=preg_replace('/<br>/i', "\n", $value);
+                       $value=preg_replace('/<br\s+[^<>\/]*>/i', "\n", $value);
+                       $value=preg_replace('/<br\s+[^<>\/]*\/>/i', "\n", $value);
+
+                       //$value=preg_replace('/<strong>/','__lt__text:p text:style-name=__quot__bold__quot____gt__',$value);
+                       //$value=preg_replace('/<\/strong>/','__lt__/text:p__gt__',$value);
+
+                       $value=dol_string_nohtmltag($value, 0);
+               }
+
+               return $value;
+       }
+
+
+       /**
+        * Function to convert a HTML string into an ODT string
+        *
+        * @param       string  $value  String to convert
+        * @return      string                  String converted
+        */
+       // public function preOdfToOdf($value)
+       // {
+       //      $value = str_replace("\n", "<text:line-break/>", $value);
+
+       //      //$value = str_replace("__lt__", "<", $value);
+       //      //$value = str_replace("__gt__", ">", $value);
+       //      //$value = str_replace("__quot__", '"', $value);
+
+       //      return $value;
+       // }
+
+       /**
+        * Assign a template variable as a picture
+        *
+        * @param string $key name of the variable within the template
+        * @param string $value path to the picture
+        * @throws OdfException
+        * @return odf
+        */
+       public function setImage($key, $value)
+       {
+               $filename = strtok(strrchr($value, '/'), '/.');
+               $file = substr(strrchr($value, '/'), 1);
+               $size = @getimagesize($value);
+               if ($size === false) {
+                       throw new OdfException("Invalid image");
+               }
+               list ($width, $height) = $size;
+               $width *= self::PIXEL_TO_CM;
+               $height *= self::PIXEL_TO_CM;
+               $xml = <<<IMG
+                       <draw:frame draw:style-name="fr1" draw:name="$filename" text:anchor-type="aschar" svg:width="{$width}cm" svg:height="{$height}cm" draw:z-index="3"><draw:image xlink:href="Pictures/$file" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"/></draw:frame>
+IMG;
+               $this->images[$value] = $file;
+               $this->setVars($key, $xml, false);
+               return $this;
+       }
+
+       /**
+        * Move segment tags for lines of tables
+        * This function is called automatically within the constructor, so this->contentXml is clean before any other thing
+        *
+        * @return void
+        */
+       private function _moveRowSegments()
+       {
+               // Replace BEGIN<text:s/>xxx into BEGIN xxx
+               $this->contentXml = preg_replace('/\[!--\sBEGIN<text:s[^>]>(row.[\S]*)\s--\]/sm', '[!-- BEGIN \\1 --]', $this->contentXml);
+               // Replace END<text:s/>xxx into END xxx
+               $this->contentXml = preg_replace('/\[!--\sEND<text:s[^>]>(row.[\S]*)\s--\]/sm', '[!-- END \\1 --]', $this->contentXml);
+
+               // Search all possible rows in the document
+               $reg1 = "#<table:table-row[^>]*>(.*)</table:table-row>#smU";
+               $matches = array();
+               preg_match_all($reg1, $this->contentXml, $matches);
+               for ($i = 0, $size = count($matches[0]); $i < $size; $i++) {
+                       // Check if the current row contains a segment row.*
+                       $reg2 = '#\[!--\sBEGIN\s(row.[\S]*)\s--\](.*)\[!--\sEND\s\\1\s--\]#sm';
+                       $matches2 = array();
+                       if (preg_match($reg2, $matches[0][$i], $matches2)) {
+                               $balise = str_replace('row.', '', $matches2[1]);
+                               // Move segment tags around the row
+                               $replace = array(
+                               '[!-- BEGIN ' . $matches2[1] . ' --]'   => '',
+                               '[!-- END ' . $matches2[1] . ' --]'             => '',
+                               '<table:table-row'                                                      => '[!-- BEGIN ' . $balise . ' --]<table:table-row',
+                               '</table:table-row>'                                            => '</table:table-row>[!-- END ' . $balise . ' --]'
+                               );
+                               $replacedXML = str_replace(array_keys($replace), array_values($replace), $matches[0][$i]);
+                               $this->contentXml = str_replace($matches[0][$i], $replacedXML, $this->contentXml);
+                       }
+               }
+       }
+
+       /**
+        * Merge template variables
+        * Called at the beginning of the _save function
+        *
+        * @param  string       $type           'content', 'styles' or 'meta'
+        * @return void
+        */
+       private function _parse($type = 'content')
+       {
+               // Search all tags found into condition to complete $this->vars, so we will proceed all tests even if not defined
+               $reg='/\{\{\#(\w+)\}\}(.+)\{\{\/(\w+)\}\}/smU';
+               $matches = array();
+               preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER);
+               foreach ($matches as $match) {  
+                       if (($match[1] !== "lines") && (strpos($match[1],"line_") !== 0)){
+                               if (isset($this->vars[$match[1]])){
+                                       $this->contentXml = str_replace($match[0],$match[2],$this->contentXml);
+                               } else {
+                                       $this->contentXml = str_replace($match[0],'',$this->contentXml);
+                               }
+                       }
+                       
+               }
+               // $this->contentXml = str_replace('<br/>','<text:line-break/>',$this->contentXml);
+               // $this->contentXml = str_replace('<br>','<text:line-break/>',$this->contentXml);
+               // $this->contentXml = str_replace('<br />','<text:line-break/>',$this->contentXml);
+               $reg='/\{(\w+)\}/';
+               $matches = array();
+               preg_match_all($reg, $this->contentXml, $matches, PREG_SET_ORDER);
+               foreach ($matches as $match) {
+                       if (strpos($match[1],"line_") !== 0){ 
+                               if (isset($this->vars[$match[1]])){
+                                       $this->contentXml = str_replace($match[0],$this->vars[$match[1]],$this->contentXml);
+                               } else {
+                                       $this->contentXml = str_replace($match[0],'',$this->contentXml);
+                               }
+                       }
+               }
+               $this->contentXml = preg_replace('/\xc2\xa0/', '', $this->contentXml);
+               preg_match_all($reg, $this->stylesXml, $matches, PREG_SET_ORDER);
+               foreach ($matches as $match) { 
+                       if (strpos($match[1],"line_") !== 0){ 
+                               if (isset($this->vars[$match[1]])){
+                                       $this->stylesXml = str_replace($match[0],$this->vars[$match[1]],$this->stylesXml);
+                               } else {
+                                       $this->stylesXml = str_replace($match[0],'',$this->stylesXml);
+                               }
+                       }
+               }
+               preg_match_all($reg, $this->metaXml, $matches, PREG_SET_ORDER);
+               foreach ($matches as $match) { 
+                       if (strpos($match[1],"line_") !== 0){ 
+                               if (isset($this->vars[$match[1]])){
+                                       $this->metaXml = str_replace($match[0],$this->vars[$match[1]],$this->metaXml);
+                               } else {
+                                       $this->metaXml = str_replace($match[0],'',$this->metaXml);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Add the merged segment to the document
+        *
+        * @param Segment $segment     Segment
+        * @throws OdfException
+        * @return odf
+        */
+       public function mergeSegment(Segment $segment)
+       {
+               if (! array_key_exists($segment->getName(), $this->segments)) {
+                       throw new OdfException($segment->getName() . 'cannot be parsed, has it been set yet ?');
+               }
+               $string = $segment->getName();
+               $reg='/\{\{\#' . $string . '\}\}(.+)\{\{\/' . $string . '\}\}/smU';
+               $this->contentXml = preg_replace($reg, $segment->getXmlParsed(), $this->contentXml);
+               return $this;
+       }
+
+       /**
+        * Display all the current template variables
+        *
+        * @return string
+        */
+       public function printVars()
+       {
+               return print_r('<pre>' . print_r($this->vars, true) . '</pre>', true);
+       }
+
+       /**
+        * Display the XML content of the file from odt document
+        * as it is at the moment
+        *
+        * @return string
+        */
+       public function __toString()
+       {
+               return $this->contentXml;
+       }
+
+       /**
+        * Display loop segments declared with setSegment()
+        *
+        * @return string
+        */
+       public function printDeclaredSegments()
+       {
+               return '<pre>' . print_r(implode(' ', array_keys($this->segments)), true) . '</pre>';
+       }
+
+       /**
+        * Declare a segment in order to use it in a loop.
+        * Extract the segment and store it into $this->segments[]. Return it for next call.
+        *
+        * @param  string      $segment        Segment
+        * @throws OdfException
+        * @return Segment
+        */
+       public function setSegment($segment)
+       {
+               if (array_key_exists($segment, $this->segments)) {
+                       return $this->segments[$segment];
+               }
+               $reg='/\{\{\#('.$segment.')\}\}(.+)\{\{\/('.$segment.')\}\}/smU';
+               $m = array();
+               preg_match($reg, $this->contentXml, $m);
+               if (preg_match($reg, $this->contentXml, $m) == 0) {
+                       throw new OdfException("'".$segment."' segment not found in the document. The tag {{#segment}} and {{/segment}} is not present into content file.");
+               }
+               $this->segments[$segment] = new Segment($segment, $m[2], $this);
+               return $this->segments[$segment];
+       }
+       /**
+        * Save the odt file on the disk
+        *
+        * @param string $file name of the desired file
+        * @throws OdfException
+        * @return void
+        */
+       public function saveToDisk($file = null)
+       {
+               if ($file !== null && is_string($file)) {
+                       if (file_exists($file) && !(is_file($file) && is_writable($file))) {
+                               throw new OdfException('Permission denied : can\'t create ' . $file);
+                       }
+                       $this->_save();
+                       copy($this->tmpfile, $file);
+               } else {
+                       $this->_save();
+               }
+       }
+
+       /**
+        * Write output file onto disk
+        *
+        * @throws OdfException
+        * @return void
+        */
+       private function _save()
+       {
+               $res=$this->file->open($this->tmpfile);    // tmpfile is odt template
+               $this->_parse('content');
+               //$this->_parse('styles');
+               //$this->_parse('meta');
+
+               $this->setMetaData();
+               //print $this->metaXml;exit;
+
+               if (! $this->file->addFromString('content.xml', $this->contentXml)) {
+                       throw new OdfException('Error during file export addFromString content');
+               }
+               if (! $this->file->addFromString('meta.xml', $this->metaXml)) {
+                       throw new OdfException('Error during file export addFromString meta');
+               }
+               if (! $this->file->addFromString('styles.xml', $this->stylesXml)) {
+                       throw new OdfException('Error during file export addFromString styles');
+               }
+
+               foreach ($this->images as $imageKey => $imageValue) {
+                       // Add the image inside the ODT document
+                       $this->file->addFile($imageKey, 'Pictures/' . $imageValue);
+                       // Add the image to the Manifest (which maintains a list of images, necessary to avoid "Corrupt ODT file. Repair?" when opening the file with LibreOffice)
+                       $this->addImageToManifest($imageValue);
+               }
+               if (! $this->file->addFromString('./META-INF/manifest.xml', $this->manifestXml)) {
+                       throw new OdfException('Error during file export: manifest.xml');
+               }
+               $this->file->close();
+       }
+
+       /**
+        * Update Meta information
+        * <dc:date>2013-03-16T14:06:25</dc:date>
+        *
+        * @return void
+        */
+       public function setMetaData()
+       {
+               if (empty($this->creator)) $this->creator='';
+
+               $this->metaXml = preg_replace('/<dc:date>.*<\/dc:date>/', '<dc:date>'.gmdate("Y-m-d\TH:i:s").'</dc:date>', $this->metaXml);
+               $this->metaXml = preg_replace('/<dc:creator>.*<\/dc:creator>/', '<dc:creator>'.(($this->title)?htmlspecialchars($this->creator):"").'</dc:creator>', $this->metaXml);
+               $this->metaXml = preg_replace('/<dc:title>.*<\/dc:title>/', '<dc:title>'.(($this->title)?htmlspecialchars($this->title):"").'</dc:title>', $this->metaXml);
+               $this->metaXml = preg_replace('/<dc:subject>.*<\/dc:subject>/', '<dc:subject>'.(($this->title)?htmlspecialchars($this->subject):"").'</dc:subject>', $this->metaXml);
+
+               if (count($this->userdefined)) {
+                       foreach ($this->userdefined as $key => $val) {
+                               $this->metaXml = preg_replace('<meta:user-defined meta:name="'.$key.'"/>', '', $this->metaXml);
+                               $this->metaXml = preg_replace('/<meta:user-defined meta:name="'.$key.'">.*<\/meta:user-defined>/', '', $this->metaXml);
+                               $this->metaXml = str_replace('</office:meta>', '<meta:user-defined meta:name="'.$key.'">'.(($this->title)?htmlspecialchars($val):"").'</meta:user-defined></office:meta>', $this->metaXml);
+                       }
+               }
+       }
+
+       /**
+        * Update Manifest file according to added image files
+        *
+        * @param string        $file           Image file to add into manifest content
+        * @return void
+        */
+       public function addImageToManifest($file)
+       {
+               // Get the file extension
+               $ext = substr(strrchr($file, '.'), 1);
+               // Create the correct image XML entry to add to the manifest (this is necessary because ODT format requires that we keep a list of the images in the manifest.xml)
+               $add = ' <manifest:file-entry manifest:media-type="image/'.$ext.'" manifest:full-path="Pictures/'.$file.'"/>'."\n";
+               // Append the image to the manifest
+               $this->manifestXml = str_replace('</manifest:manifest>', $add.'</manifest:manifest>', $this->manifestXml); // we replace the manifest closing tag by the image XML entry + manifest closing tag (this results in appending the data, we do not overwrite anything)
+       }
+
+       /**
+        * Export the file as attached file by HTTP
+        *
+        * @param string $name (optional)
+        * @throws OdfException
+        * @return void
+        */
+       public function exportAsAttachedFile($name = "")
+       {
+               $this->_save();
+               if (headers_sent($filename, $linenum)) {
+                       throw new OdfException("headers already sent ($filename at $linenum)");
+               }
+
+               if ( $name == "" ) {
+                       $name = md5(uniqid()) . ".odt";
+               }
+
+               header('Content-type: application/vnd.oasis.opendocument.text');
+               header('Content-Disposition: attachment; filename="'.$name.'"');
+               header('Content-Length: '.filesize($this->tmpfile));
+               readfile($this->tmpfile);
+       }
+
+       /**
+        * Convert the ODT file to PDF and export the file as attached file by HTTP
+        * Note: you need to have JODConverter and OpenOffice or LibreOffice installed and executable on the same system as where this php script will be executed. You also need to chmod +x odt2pdf.sh
+        *
+        * @param       string  $name   Name of ODT file to generate before generating PDF
+        * @throws OdfException
+        * @return void
+        */
+       public function exportAsAttachedPDF($name = "")
+       {
+               global $conf;
+
+               if ( $name == "" ) $name = "temp".md5(uniqid());
+
+               dol_syslog(get_class($this).'::exportAsAttachedPDF $name='.$name, LOG_DEBUG);
+               $this->saveToDisk($name);
+
+               $execmethod=(empty($conf->global->MAIN_EXEC_USE_POPEN)?1:2);    // 1 or 2
+               // Method 1 sometimes hang the server.
+
+
+               // Export to PDF using LibreOffice
+               if (getDolGlobalString('MAIN_ODT_AS_PDF') == 'libreoffice') {
+                       dol_mkdir($conf->user->dir_temp);       // We must be sure the directory exists and is writable
+
+                       // We delete and recreate a subdir because the soffice may have change pemrissions on it
+                       dol_delete_dir_recursive($conf->user->dir_temp.'/odtaspdf');
+                       dol_mkdir($conf->user->dir_temp.'/odtaspdf');
+
+                       // Install prerequisites: apt install soffice libreoffice-common libreoffice-writer
+                       // using windows libreoffice that must be in path
+                       // using linux/mac libreoffice that must be in path
+                       // Note PHP Config "fastcgi.impersonate=0" must set to 0 - Default is 1
+
+
+                       if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'){
+                               $command ='soffice.exe --headless -env:UserInstallation=file:///'.$conf->user->dir_temp.'/odtaspdf --convert-to pdf pdf:writer_pdf_Export --outdir '. escapeshellarg(dirname($name)). " ".escapeshellarg($name);
+                       } else {
+                               $command ='soffice --headless -env:UserInstallation=file:///'.$conf->user->dir_temp.'/odtaspdf --convert-to pdf:writer_pdf_Export --outdir '. escapeshellarg(dirname($name)). " ".escapeshellarg($name);
+                       }
+               } elseif (getDolGlobalString('MAIN_ODT_AS_PDF') == 'curl') {
+                               $finfo = pathinfo($name);
+                               $dksapikey=getDolGlobalString('MAIN_DKS_API_KEY');
+                               //$copyname = preg_replace('/[^A-Za-z0-9\-\_\.]/', '', $finfo['filename']);
+                               //copy($name,dirname($name).'/'.$copyname.".odt");
+                               $command ='curl -q -A "DKS Tools" --header "HTTP_API_KEY: '.$dksapikey.'" -X POST -F '.escapeshellarg('odtfile=@'.$name).' -o '.escapeshellarg(dirname($name).'/'.$finfo['filename'].'.pdf').' https://service.dks.lu/odt2pdf/';
+                               file_put_contents("curl.log",$command."\n",FILE_APPEND);
+               } elseif (preg_match('/unoconv/', getDolGlobalString('MAIN_ODT_AS_PDF'))) {
+                       // If issue with unoconv, see https://github.com/dagwieers/unoconv/issues/87
+
+                       // MAIN_ODT_AS_PDF should be   "sudo -u unoconv /usr/bin/unoconv" and userunoconv must have sudo to be root by adding file /etc/sudoers.d/unoconv with content  www-data ALL=(unoconv) NOPASSWD: /usr/bin/unoconv .
+
+                       // Try this with www-data user:    /usr/bin/unoconv -vvvv -f pdf /tmp/document-example.odt
+                       // It must return:
+                       //Verbosity set to level 4
+                       //Using office base path: /usr/lib/libreoffice
+                       //Using office binary path: /usr/lib/libreoffice/program
+                       //DEBUG: Connection type: socket,host=127.0.0.1,port=2002;urp;StarOffice.ComponentContext
+                       //DEBUG: Existing listener not found.
+                       //DEBUG: Launching our own listener using /usr/lib/libreoffice/program/soffice.bin.
+                       //LibreOffice listener successfully started. (pid=9287)
+                       //Input file: /tmp/document-example.odt
+                       //unoconv: file `/tmp/document-example.odt' does not exist.
+                       //unoconv: RuntimeException during import phase:
+                       //Office probably died. Unsupported URL <file:///tmp/document-example.odt>: "type detection failed"
+                       //DEBUG: Terminating LibreOffice instance.
+                       //DEBUG: Waiting for LibreOffice instance to exit
+
+                       // If it fails:
+                       // - set shell of user to bash instead of nologin.
+                       // - set permission to read/write to user on home directory /var/www so user can create the libreoffice , dconf and .cache dir and files then set permission back
+
+                       $command = getDolGlobalString('MAIN_ODT_AS_PDF').' '.escapeshellcmd($name);
+                       //$command = '/usr/bin/unoconv -vvv '.escapeshellcmd($name);
+               } else {
+                       // deprecated old method using odt2pdf.sh (native, jodconverter, ...)
+                       $tmpname=preg_replace('/\.odt/i', '', $name);
+
+                       if (getDolGlobalString('MAIN_DOL_SCRIPTS_ROOT')) {
+                               $command = getDolGlobalString('MAIN_DOL_SCRIPTS_ROOT').'/scripts/odt2pdf/odt2pdf.sh '.escapeshellcmd($tmpname).' '.(is_numeric(getDolGlobalString('MAIN_ODT_AS_PDF'))?'jodconverter':getDolGlobalString('MAIN_ODT_AS_PDF'));
+                       } else {
+                               dol_syslog(get_class($this).'::exportAsAttachedPDF is used but the constant MAIN_DOL_SCRIPTS_ROOT with path to script directory was not defined.', LOG_WARNING);
+                               $command = '../../scripts/odt2pdf/odt2pdf.sh '.escapeshellcmd($tmpname).' '.(is_numeric(getDolGlobalString('MAIN_ODT_AS_PDF'))?'jodconverter':getDolGlobalString('MAIN_ODT_AS_PDF'));
+                       }
+               }
+
+               //$dirname=dirname($name);
+               //$command = DOL_DOCUMENT_ROOT.'/includes/odtphp/odt2pdf.sh '.$name.' '.$dirname;
+
+               dol_syslog(get_class($this).'::exportAsAttachedPDF $execmethod='.$execmethod.' Run command='.$command, LOG_DEBUG);
+               // TODO Use:
+               // $outputfile = DOL_DATA_ROOT.'/odt2pdf.log';
+               // $result = $utils->executeCLI($command, $outputfile);  and replace test on $execmethod.
+               // $retval will be $result['result']
+               // $errorstring will be $result['output']
+               $retval=0; $output_arr=array();
+               if ($execmethod == 1) {
+                       exec($command, $output_arr, $retval);
+               }
+               if ($execmethod == 2) {
+                       $outputfile = DOL_DATA_ROOT.'/odt2pdf.log';
+
+                       $ok=0;
+                       $handle = fopen($outputfile, 'w');
+                       if ($handle) {
+                               dol_syslog(get_class($this)."Run command ".$command, LOG_DEBUG);
+                               fwrite($handle, $command."\n");
+                               $handlein = popen($command, 'r');
+                               while (!feof($handlein)) {
+                                       $read = fgets($handlein);
+                                       fwrite($handle, $read);
+                                       $output_arr[]=$read;
+                               }
+                               pclose($handlein);
+                               fclose($handle);
+                       }
+                       if (! empty($conf->global->MAIN_UMASK)) @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
+               }
+               if ($retval == 0) {
+                       dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG);
+                       $filename=''; $linenum=0;
+
+                       if (php_sapi_name() != 'cli') { // If we are in a web context (not into CLI context)
+                               if (headers_sent($filename, $linenum)) {
+                                       throw new OdfException("headers already sent ($filename at $linenum)");
+                               }
+
+                               if (!empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
+                                       $name=preg_replace('/\.od(x|t)/i', '', $name);
+                                       header('Content-type: application/pdf');
+                                       header('Content-Disposition: attachment; filename="'.$name.'.pdf"');
+                                       readfile($name.".pdf");
+                               }
+                       }
+
+                       if (!empty($conf->global->MAIN_ODT_AS_PDF_DEL_SOURCE)) {
+                               unlink($name);
+                       }
+               } else {
+                       dol_syslog(get_class($this).'::exportAsAttachedPDF $ret_val='.$retval, LOG_DEBUG);
+                       dol_syslog(get_class($this).'::exportAsAttachedPDF $output_arr='.var_export($output_arr, true), LOG_DEBUG);
+                       if ($retval == 126) {
+                               throw new OdfException('Permission execute convert script : ' . $command);
+                       } else {
+                               $errorstring='';
+                               foreach ($output_arr as $line) {
+                                       $errorstring.= $line."<br>";
+                               }
+                               throw new OdfException('ODT to PDF convert fail (option MAIN_ODT_AS_PDF is '.$conf->global->MAIN_ODT_AS_PDF.', command was '.$command.', retval='.$retval.') : ' . $errorstring);
+                       }
+               }
+       }
+
+       /**
+        * Returns a variable of configuration
+        *
+        * @param  string  $configKey  Config key
+        * @return string              The requested variable of configuration
+        */
+       public function getConfig($configKey)
+       {
+               if (array_key_exists($configKey, $this->config)) {
+                       return $this->config[$configKey];
+               }
+               return false;
+       }
+       /**
+        * Returns the temporary working file
+        *
+        * @return string le chemin vers le fichier temporaire de travail
+        */
+       public function getTmpfile()
+       {
+               return $this->tmpfile;
+       }
+
+       /**
+        * Delete the temporary file when the object is destroyed
+        */
+       public function __destruct()
+       {
+               if (file_exists($this->tmpfile)) {
+                       unlink($this->tmpfile);
+               }
+
+               if (file_exists($this->tmpdir)) {
+                       $this->_rrmdir($this->tmpdir);
+                       rmdir($this->tmpdir);
+               }
+       }
+
+       /**
+        * Empty the temporary working directory recursively
+        *
+        * @param  string  $dir    The temporary working directory
+        * @return void
+        */
+       private function _rrmdir($dir)
+       {
+               if ($handle = opendir($dir)) {
+                       while (($file = readdir($handle)) !== false) {
+                               if ($file != '.' && $file != '..') {
+                                       if (is_dir($dir . '/' . $file)) {
+                                               $this->_rrmdir($dir . '/' . $file);
+                                               rmdir($dir . '/' . $file);
+                                       } else {
+                                               unlink($dir . '/' . $file);
+                                       }
+                               }
+                       }
+                       closedir($handle);
+               }
+       }
+
+       /**
+        * return the value present on odt in [valuename][/valuename]
+        *
+        * @param  string $valuename   Balise in the template
+        * @return string              The value inside the balise
+        */
+       public function getvalue($valuename)
+       {
+               $searchreg="/\\[".$valuename."\\](.*)\\[\\/".$valuename."\\]/";
+               $matches = array();
+               preg_match($searchreg, $this->contentXml, $matches);
+               $this->contentXml = preg_replace($searchreg, "", $this->contentXml);
+               return  $matches[1];
+       }
+}
diff --git a/htdocs/includes/html2pdf/zip/PclZipProxy.php b/htdocs/includes/html2pdf/zip/PclZipProxy.php
new file mode 100644 (file)
index 0000000..45ea50d
--- /dev/null
@@ -0,0 +1,160 @@
+<?php
+if (! defined('ODTPHP_PATHTOPCLZIP')) define('ODTPHP_PATHTOPCLZIP','pclzip/');
+require_once ODTPHP_PATHTOPCLZIP.'pclzip.lib.php';
+require_once 'ZipInterface.php';
+class PclZipProxyException extends Exception
+{ }
+/**
+ * Proxy class for the PclZip library
+ * You need PHP 5.2 at least
+ * You need Zip Extension or PclZip library
+ * Encoding : ISO-8859-1
+ *
+ * @copyright  GPL License 2008 - Julien Pauli - Cyril PIERRE de GEYER - Anaska (http://www.anaska.com)
+ * @copyright  GPL License 2010 - Laurent Destailleur - eldy@users.sourceforge.net
+ * @license    https://www.gnu.org/copyleft/gpl.html  GPL License
+ * @version 1.4
+ */
+class PclZipProxy implements ZipInterface
+{
+       protected $tmpdir = '/tmp';
+       protected $openned = false;
+       protected $filename;
+       protected $pclzip;
+    /**
+     * Class constructor
+     *
+     * @throws PclZipProxyException
+     */
+       public function __construct($forcedir='')
+       {
+               if (! class_exists('PclZip')) {
+                       throw new PclZipProxyException('PclZip class not loaded - PclZip library
+                        is required for using PclZipProxy'); ;
+               }
+               if ($forcedir) $this->tmpdir=preg_replace('|[//\/]$|','',$forcedir);    // $this->tmpdir must not contains / at the end
+       }
+
+       /**
+        * Open a Zip archive
+        *
+        * @param string $filename the name of the archive to open
+        * @return true if openning has succeeded
+        */
+       public function open($filename)
+       {
+               if (true === $this->openned) {
+                       $this->close();
+               }
+               $this->filename = $filename;
+               $this->pclzip = new PclZip($this->filename);
+               $this->openned = true;
+               return true;
+       }
+
+       /**
+        * Retrieve the content of a file within the archive from its name
+        *
+        * @param string $name the name of the file to extract
+        * @return the content of the file in a string
+        */
+       public function getFromName($name)
+       {
+               if (false === $this->openned) {
+                       return false;
+               }
+               $name = preg_replace("/(?:\.|\/)*(.*)/", "\\1", $name);
+               $extraction = $this->pclzip->extract(PCLZIP_OPT_BY_NAME, $name,
+                       PCLZIP_OPT_EXTRACT_AS_STRING);
+               if (!empty($extraction)) {
+                       return $extraction[0]['content'];
+               }
+               return false;
+       }
+
+       /**
+        * Add a file within the archive from a string
+        *
+        * @param string $localname the local path to the file in the archive
+        * @param string $contents the content of the file
+        * @return true if the file has been successful added
+        */
+       public function addFromString($localname, $contents)
+       {
+               if (false === $this->openned) {
+                       return false;
+               }
+               if (file_exists($this->filename) && !is_writable($this->filename)) {
+                       return false;
+               }
+               $localname = preg_replace("/(?:\.|\/)*(.*)/", "\\1", $localname);
+               $localpath = dirname($localname);
+               $tmpfilename = $this->tmpdir . '/' . basename($localname);
+               if (false !== file_put_contents($tmpfilename, $contents)) {
+                       //print "tmpfilename=".$tmpfilename;
+                       //print "localname=".$localname;
+                       $res=$this->pclzip->delete(PCLZIP_OPT_BY_NAME, $localname);
+                       $add = $this->pclzip->add($tmpfilename,
+                               PCLZIP_OPT_REMOVE_PATH, $this->tmpdir,
+                               PCLZIP_OPT_ADD_PATH, $localpath);
+                       unlink($tmpfilename);
+                       if (!empty($add)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Add a file within the archive from a file
+        *
+        * @param string $filename the path to the file we want to add
+        * @param string $localname the local path to the file in the archive
+        * @return true if the file has been successful added
+        */
+       public function addFile($filename, $localname = null)
+       {
+               if (false === $this->openned) {
+                       return false;
+               }
+               if ((file_exists($this->filename) && !is_writable($this->filename))
+                       || !file_exists($filename)) {
+                       return false;
+               }
+               if (isSet($localname)) {
+                       $localname = preg_replace("/(?:\.|\/)*(.*)/", "\\1", $localname);
+                       $localpath = dirname($localname);
+                       $tmpfilename = $this->tmpdir . '/' . basename($localname);
+               } else {
+                       $localname = basename($filename);
+                       $tmpfilename = $this->tmpdir . '/' . $localname;
+                       $localpath = '';
+               }
+               if (file_exists($filename)) {
+                       copy($filename, $tmpfilename);
+                       $this->pclzip->delete(PCLZIP_OPT_BY_NAME, $localname);
+                       $this->pclzip->add($tmpfilename,
+                               PCLZIP_OPT_REMOVE_PATH, $this->tmpdir,
+                               PCLZIP_OPT_ADD_PATH, $localpath);
+                       unlink($tmpfilename);
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * Close the Zip archive
+        * @return true
+        */
+       public function close()
+       {
+               if (false === $this->openned) {
+                       return false;
+               }
+               $this->pclzip = $this->filename = null;
+               $this->openned = false;
+               return true;
+       }
+}
+
+?>
diff --git a/htdocs/includes/html2pdf/zip/PhpZipProxy.php b/htdocs/includes/html2pdf/zip/PhpZipProxy.php
new file mode 100644 (file)
index 0000000..0035858
--- /dev/null
@@ -0,0 +1,92 @@
+<?php
+require_once 'ZipInterface.php';
+class PhpZipProxyException extends Exception
+{ }
+/**
+ * Proxy class for the PHP Zip Extension
+ * You need PHP 5.2 at least
+ * You need Zip Extension or PclZip library
+ * Encoding : ISO-8859-1
+ *
+ * @copyright  GPL License 2008 - Julien Pauli - Cyril PIERRE de GEYER - Anaska (http://www.anaska.com)
+ * @license    https://www.gnu.org/copyleft/gpl.html  GPL License
+ * @version 1.3
+ */
+
+class PhpZipProxy implements ZipInterface
+{
+       protected $zipArchive;
+       protected $filename;
+    /**
+     * Class constructor
+     *
+     * @throws PhpZipProxyException
+     */        
+       public function __construct()
+       {
+               if (! class_exists('ZipArchive')) {
+                       throw new PhpZipProxyException('Zip extension not loaded - check your php settings, PHP5.2 minimum with zip extension
+                        is required for using PhpZipProxy'); ;
+               }
+               $this->zipArchive = new ZipArchive();
+       }
+       /**
+        * Open a Zip archive
+        * 
+        * @param string $filename the name of the archive to open
+        * @return true if openning has succeeded
+        */             
+       public function open($filename)
+       {
+               $this->filename = $filename;
+               return $this->zipArchive->open($filename, ZIPARCHIVE::CREATE);
+       }
+       /**
+        * Retrieve the content of a file within the archive from its name
+        * 
+        * @param string $name the name of the file to extract
+        * @return the content of the file in a string
+        */     
+       public function getFromName($name)
+       {
+               return $this->zipArchive->getFromName($name);
+       }
+       /**
+        * Add a file within the archive from a string
+        * 
+        * @param string $localname the local path to the file in the archive
+        * @param string $contents the content of the file
+        * @return true if the file has been successful added
+        */             
+       public function addFromString($localname, $contents)
+       {
+               if (file_exists($this->filename) && !is_writable($this->filename)) {
+                       return false;
+               }
+               return $this->zipArchive->addFromString($localname, $contents);
+       }
+       /**
+        * Add a file within the archive from a file
+        * 
+        * @param string $filename the path to the file we want to add
+        * @param string $localname the local path to the file in the archive
+        * @return true if the file has been successful added
+        */
+       public function addFile($filename, $localname = null)
+       {
+               if ((file_exists($this->filename) && !is_writable($this->filename))
+                       || !file_exists($filename)) {
+                       return false;
+               }
+               return $this->zipArchive->addFile($filename, $localname);
+       }
+       /**
+        * Close the Zip archive
+        * @return true
+        */     
+       public function close()
+       {
+               return $this->zipArchive->close();
+       }
+}
+?>
diff --git a/htdocs/includes/html2pdf/zip/ZipInterface.php b/htdocs/includes/html2pdf/zip/ZipInterface.php
new file mode 100644 (file)
index 0000000..6b72485
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Interface for Zip libraries used in odtPHP
+ * You need PHP 5.2 at least
+ * You need Zip Extension or PclZip library
+ * Encoding : ISO-8859-1
+ *
+ * @copyright  GPL License 2008 - Julien Pauli - Cyril PIERRE de GEYER - Anaska (http://www.anaska.com)
+ * @license    https://www.gnu.org/copyleft/gpl.html  GPL License
+ * @version 1.3
+ */
+interface ZipInterface
+{
+       /**
+        * Open a Zip archive
+        *
+        * @param string $filename the name of the archive to open
+        * @return true if openning has succeeded
+        */
+       public function open($filename);
+       /**
+        * Retrieve the content of a file within the archive from its name
+        *
+        * @param string $name the name of the file to extract
+        * @return the content of the file in a string
+        */
+       public function getFromName($name);
+       /**
+        * Add a file within the archive from a string
+        *
+        * @param string $localname the local path to the file in the archive
+        * @param string $contents the content of the file
+        * @return true if the file has been successful added
+        */
+       public function addFromString($localname, $contents);
+       /**
+        * Add a file within the archive from a file
+        *
+        * @param string $filename the path to the file we want to add
+        * @param string $localname the local path to the file in the archive
+        * @return true if the file has been successful added
+        */
+       public function addFile($filename, $localname = null);
+       /**
+        * Close the Zip archive
+        * @return true
+        */
+       public function close();
+}
+?>
similarity index 84%
rename from htdocs/modulebuilder/template/COPYING
rename to htdocs/includes/html2pdf/zip/pclzip/LICENSE
index 94a0453..dbbe355 100644 (file)
@@ -1,5 +1,5 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
+                    GNU AFFERO GENERAL PUBLIC LICENSE
+                       Version 3, 19 November 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
  Everyone is permitted to copy and distribute verbatim copies
@@ -7,17 +7,15 @@
 
                             Preamble
 
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
+  The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
 
   The licenses for most software and other practical works are designed
 to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
+our General Public Licenses are intended to guarantee your freedom to
 share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
+software for all its users.
 
   When we speak of free software, we are referring to freedom, not
 price.  Our General Public Licenses are designed to make sure that you
@@ -26,44 +24,34 @@ them if you wish), that you receive source code or can get it if you
 want it, that you can change the software or use pieces of it in new
 free programs, and that you know you can do these things.
 
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
+  Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+  A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate.  Many developers of free software are heartened and
+encouraged by the resulting cooperation.  However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+  The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community.  It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server.  Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+  An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals.  This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
 
   The precise terms and conditions for copying, distribution and
 modification follow.
@@ -72,7 +60,7 @@ modification follow.
 
   0. Definitions.
 
-  "This License" refers to version 3 of the GNU General Public License.
+  "This License" refers to version 3 of the GNU Affero General Public License.
 
   "Copyright" also means copyright-like laws that apply to other kinds of
 works, such as semiconductor masks.
@@ -549,35 +537,45 @@ to collect a royalty for further conveying from those to whom you convey
 the Program, the only way you could satisfy both those terms and this
 License would be to refrain entirely from conveying the Program.
 
-  13. Use with the GNU Affero General Public License.
+  13. Remote Network Interaction; Use with the GNU General Public License.
+
+  Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software.  This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
 
   Notwithstanding any other provision of this License, you have
 permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
+under version 3 of the GNU General Public License into a single
 combined work, and to convey the resulting work.  The terms of this
 License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
 
   14. Revised Versions of this License.
 
   The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
+the GNU Affero General Public License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in detail to
 address new problems or concerns.
 
   Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
+Program specifies that a certain numbered version of the GNU Affero General
 Public License "or any later version" applies to it, you have the
 option of following the terms and conditions either of that numbered
 version or of any later version published by the Free Software
 Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
+GNU Affero General Public License, you may choose any version ever published
 by the Free Software Foundation.
 
   If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
+versions of the GNU Affero General Public License can be used, that proxy's
 public statement of acceptance of a version permanently authorizes you
 to choose that version for the Program.
 
@@ -619,3 +617,45 @@ Program, unless a warranty or assumption of liability accompanies a
 copy of the Program in return for a fee.
 
                      END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source.  For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code.  There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<http://www.gnu.org/licenses/>.
diff --git a/htdocs/includes/html2pdf/zip/pclzip/composer.json b/htdocs/includes/html2pdf/zip/pclzip/composer.json
new file mode 100644 (file)
index 0000000..fd36bfb
--- /dev/null
@@ -0,0 +1,20 @@
+{
+    "name": "chamilo/pclzip",
+    "type": "library",
+    "description": "A PHP library that offers compression and extraction functions for Zip formatted archives",
+    "keywords": ["php", "zip"],
+    "homepage": "https://github.com/chamilo/pclzip",
+    "license": ["LGPL-2.1"],
+    "authors": [
+        {
+            "name": "Vincent Blavet"
+        }
+    ],
+    "replace": {
+        "pclzip/pclzip": "^2.8"
+    },
+    "autoload": {
+        "classmap": ["pclzip.lib.php"]
+    }
+}
+
diff --git a/htdocs/includes/html2pdf/zip/pclzip/gnu-lgpl.txt b/htdocs/includes/html2pdf/zip/pclzip/gnu-lgpl.txt
new file mode 100644 (file)
index 0000000..583509c
--- /dev/null
@@ -0,0 +1,504 @@
+          GNU LESSER GENERAL PUBLIC LICENSE
+               Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+          GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+             END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/htdocs/includes/html2pdf/zip/pclzip/pclzip.lib.php b/htdocs/includes/html2pdf/zip/pclzip/pclzip.lib.php
new file mode 100644 (file)
index 0000000..2a1a2b8
--- /dev/null
@@ -0,0 +1,5415 @@
+<?php
+// --------------------------------------------------------------------------------
+// PhpConcept Library - Zip Module 2.8.4
+// --------------------------------------------------------------------------------
+// License GNU/LGPL - Vincent Blavet - August 2009
+// Originaly http://www.phpconcept.net
+// Now       https://github.com/chamilo/pclzip
+// --------------------------------------------------------------------------------
+//
+// Presentation :
+//   PclZip is a PHP library that manage ZIP archives.
+//   So far tests show that archives generated by PclZip are readable by
+//   WinZip application and other tools.
+//
+// Description :
+//   See readme.txt and http://www.phpconcept.net
+//
+// Warning :
+//   This library and the associated files are non commercial, non professional
+//   work.
+//   It should not have unexpected results. However if any damage is caused by
+//   this software the author can not be responsible.
+//   The use of this software is at the risk of the user.
+//
+// --------------------------------------------------------------------------------
+// --------------------------------------------------------------------------------
+
+// ----- Constants
+if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
+    define('PCLZIP_READ_BLOCK_SIZE', 2048);
+}
+
+// ----- File list separator
+// In version 1.x of PclZip, the separator for file list is a space
+// (which is not a very smart choice, specifically for windows paths !).
+// A better separator should be a comma (,). This constant gives you the
+// abilty to change that.
+// However notice that changing this value, may have impact on existing
+// scripts, using space separated filenames.
+// Recommanded values for compatibility with older versions :
+//define( 'PCLZIP_SEPARATOR', ' ' );
+// Recommanded values for smart separation of filenames.
+if (!defined('PCLZIP_SEPARATOR')) {
+    define('PCLZIP_SEPARATOR', ',');
+}
+
+// ----- Error configuration
+// 0 : PclZip Class integrated error handling
+// 1 : PclError external library error handling. By enabling this
+//     you must ensure that you have included PclError library.
+// [2,...] : reserved for futur use
+if (!defined('PCLZIP_ERROR_EXTERNAL')) {
+    define('PCLZIP_ERROR_EXTERNAL', 0);
+}
+
+// ----- Optional static temporary directory
+//       By default temporary files are generated in the script current
+//       path.
+//       If defined :
+//       - MUST BE terminated by a '/'.
+//       - MUST be a valid, already created directory
+//       Samples :
+// define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
+// define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
+if (!defined('PCLZIP_TEMPORARY_DIR')) {
+    define('PCLZIP_TEMPORARY_DIR', '');
+}
+
+// ----- Optional threshold ratio for use of temporary files
+//       Pclzip sense the size of the file to add/extract and decide to
+//       use or not temporary file. The algorythm is looking for
+//       memory_limit of PHP and apply a ratio.
+//       threshold = memory_limit * ratio.
+//       Recommended values are under 0.5. Default 0.47.
+//       Samples :
+// define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 );
+if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
+    define('PCLZIP_TEMPORARY_FILE_RATIO', 0.47);
+}
+
+// --------------------------------------------------------------------------------
+// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
+// --------------------------------------------------------------------------------
+
+// ----- Global variables
+$g_pclzip_version = "2.8.2";
+
+// ----- Error codes
+//   -1 : Unable to open file in binary write mode
+//   -2 : Unable to open file in binary read mode
+//   -3 : Invalid parameters
+//   -4 : File does not exist
+//   -5 : Filename is too long (max. 255)
+//   -6 : Not a valid zip file
+//   -7 : Invalid extracted file size
+//   -8 : Unable to create directory
+//   -9 : Invalid archive extension
+//  -10 : Invalid archive format
+//  -11 : Unable to delete file (unlink)
+//  -12 : Unable to rename file (rename)
+//  -13 : Invalid header checksum
+//  -14 : Invalid archive size
+define('PCLZIP_ERR_USER_ABORTED', 2);
+define('PCLZIP_ERR_NO_ERROR', 0);
+define('PCLZIP_ERR_WRITE_OPEN_FAIL', -1);
+define('PCLZIP_ERR_READ_OPEN_FAIL', -2);
+define('PCLZIP_ERR_INVALID_PARAMETER', -3);
+define('PCLZIP_ERR_MISSING_FILE', -4);
+define('PCLZIP_ERR_FILENAME_TOO_LONG', -5);
+define('PCLZIP_ERR_INVALID_ZIP', -6);
+define('PCLZIP_ERR_BAD_EXTRACTED_FILE', -7);
+define('PCLZIP_ERR_DIR_CREATE_FAIL', -8);
+define('PCLZIP_ERR_BAD_EXTENSION', -9);
+define('PCLZIP_ERR_BAD_FORMAT', -10);
+define('PCLZIP_ERR_DELETE_FILE_FAIL', -11);
+define('PCLZIP_ERR_RENAME_FILE_FAIL', -12);
+define('PCLZIP_ERR_BAD_CHECKSUM', -13);
+define('PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14);
+define('PCLZIP_ERR_MISSING_OPTION_VALUE', -15);
+define('PCLZIP_ERR_INVALID_OPTION_VALUE', -16);
+define('PCLZIP_ERR_ALREADY_A_DIRECTORY', -17);
+define('PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18);
+define('PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19);
+define('PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20);
+define('PCLZIP_ERR_DIRECTORY_RESTRICTION', -21);
+
+// ----- Options values
+define('PCLZIP_OPT_PATH', 77001);
+define('PCLZIP_OPT_ADD_PATH', 77002);
+define('PCLZIP_OPT_REMOVE_PATH', 77003);
+define('PCLZIP_OPT_REMOVE_ALL_PATH', 77004);
+define('PCLZIP_OPT_SET_CHMOD', 77005);
+define('PCLZIP_OPT_EXTRACT_AS_STRING', 77006);
+define('PCLZIP_OPT_NO_COMPRESSION', 77007);
+define('PCLZIP_OPT_BY_NAME', 77008);
+define('PCLZIP_OPT_BY_INDEX', 77009);
+define('PCLZIP_OPT_BY_EREG', 77010);
+define('PCLZIP_OPT_BY_PREG', 77011);
+define('PCLZIP_OPT_COMMENT', 77012);
+define('PCLZIP_OPT_ADD_COMMENT', 77013);
+define('PCLZIP_OPT_PREPEND_COMMENT', 77014);
+define('PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015);
+define('PCLZIP_OPT_REPLACE_NEWER', 77016);
+define('PCLZIP_OPT_STOP_ON_ERROR', 77017);
+// Having big trouble with crypt. Need to multiply 2 long int
+// which is not correctly supported by PHP ...
+//define( 'PCLZIP_OPT_CRYPT', 77018 );
+define('PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019);
+define('PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020);
+define('PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020); // alias
+define('PCLZIP_OPT_TEMP_FILE_ON', 77021);
+define('PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021); // alias
+define('PCLZIP_OPT_TEMP_FILE_OFF', 77022);
+define('PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022); // alias
+
+// ----- File description attributes
+define('PCLZIP_ATT_FILE_NAME', 79001);
+define('PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002);
+define('PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003);
+define('PCLZIP_ATT_FILE_MTIME', 79004);
+define('PCLZIP_ATT_FILE_CONTENT', 79005);
+define('PCLZIP_ATT_FILE_COMMENT', 79006);
+
+// ----- Call backs values
+define('PCLZIP_CB_PRE_EXTRACT', 78001);
+define('PCLZIP_CB_POST_EXTRACT', 78002);
+define('PCLZIP_CB_PRE_ADD', 78003);
+define('PCLZIP_CB_POST_ADD', 78004);
+/* For futur use
+define( 'PCLZIP_CB_PRE_LIST', 78005 );
+define( 'PCLZIP_CB_POST_LIST', 78006 );
+define( 'PCLZIP_CB_PRE_DELETE', 78007 );
+define( 'PCLZIP_CB_POST_DELETE', 78008 );
+*/
+
+// --------------------------------------------------------------------------------
+// Class : PclZip
+// Description :
+//   PclZip is the class that represent a Zip archive.
+//   The public methods allow the manipulation of the archive.
+// Attributes :
+//   Attributes must not be accessed directly.
+// Methods :
+//   PclZip() : Object creator
+//   create() : Creates the Zip archive
+//   listContent() : List the content of the Zip archive
+//   extract() : Extract the content of the archive
+//   properties() : List the properties of the archive
+// --------------------------------------------------------------------------------
+class PclZip
+{
+    // ----- Filename of the zip file
+    public $zipname = '';
+
+    // ----- File descriptor of the zip file
+    public $zip_fd = 0;
+
+    // ----- Internal error handling
+    public $error_code = 1;
+    public $error_string = '';
+
+    // ----- Current status of the magic_quotes_runtime
+    // This value store the php configuration for magic_quotes
+    // The class can then disable the magic_quotes and reset it after
+    public $magic_quotes_status;
+
+    // --------------------------------------------------------------------------------
+    // Function : PclZip()
+    // Description :
+    //   Creates a PclZip object and set the name of the associated Zip archive
+    //   filename.
+    //   Note that no real action is taken, if the archive does not exist it is not
+    //   created. Use create() for that.
+    // --------------------------------------------------------------------------------
+    public function __construct($p_zipname)
+    {
+
+        // ----- Tests the zlib
+        if (!function_exists('gzopen')) {
+            die('Abort ' . basename(__FILE__) . ' : Missing zlib extensions');
+        }
+
+        // ----- Set the attributes
+        $this->zipname             = $p_zipname;
+        $this->zip_fd              = 0;
+        $this->magic_quotes_status = -1;
+
+        // ----- Return
+        return;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function :
+    //   create($p_filelist, $p_add_dir="", $p_remove_dir="")
+    //   create($p_filelist, $p_option, $p_option_value, ...)
+    // Description :
+    //   This method supports two different synopsis. The first one is historical.
+    //   This method creates a Zip Archive. The Zip file is created in the
+    //   filesystem. The files and directories indicated in $p_filelist
+    //   are added in the archive. See the parameters description for the
+    //   supported format of $p_filelist.
+    //   When a directory is in the list, the directory and its content is added
+    //   in the archive.
+    //   In this synopsis, the function takes an optional variable list of
+    //   options. See bellow the supported options.
+    // Parameters :
+    //   $p_filelist : An array containing file or directory names, or
+    //                 a string containing one filename or one directory name, or
+    //                 a string containing a list of filenames and/or directory
+    //                 names separated by spaces.
+    //   $p_add_dir : A path to add before the real path of the archived file,
+    //                in order to have it memorized in the archive.
+    //   $p_remove_dir : A path to remove from the real path of the file to archive,
+    //                   in order to have a shorter path memorized in the archive.
+    //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
+    //                   is removed first, before $p_add_dir is added.
+    // Options :
+    //   PCLZIP_OPT_ADD_PATH :
+    //   PCLZIP_OPT_REMOVE_PATH :
+    //   PCLZIP_OPT_REMOVE_ALL_PATH :
+    //   PCLZIP_OPT_COMMENT :
+    //   PCLZIP_CB_PRE_ADD :
+    //   PCLZIP_CB_POST_ADD :
+    // Return Values :
+    //   0 on failure,
+    //   The list of the added files, with a status of the add action.
+    //   (see PclZip::listContent() for list entry format)
+    // --------------------------------------------------------------------------------
+    public function create($p_filelist)
+    {
+        $v_result = 1;
+
+        // ----- Reset the error handler
+        $this->privErrorReset();
+
+        // ----- Set default values
+        $v_options                            = array();
+        $v_options[PCLZIP_OPT_NO_COMPRESSION] = false;
+
+        // ----- Look for variable options arguments
+        $v_size = func_num_args();
+
+        // ----- Look for arguments
+        if ($v_size > 1) {
+            // ----- Get the arguments
+            $v_arg_list = func_get_args();
+
+            // ----- Remove from the options list the first argument
+            array_shift($v_arg_list);
+            $v_size--;
+
+            // ----- Look for first arg
+            if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+
+                // ----- Parse the options
+                $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array(
+                    PCLZIP_OPT_REMOVE_PATH => 'optional',
+                    PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+                    PCLZIP_OPT_ADD_PATH => 'optional',
+                    PCLZIP_CB_PRE_ADD => 'optional',
+                    PCLZIP_CB_POST_ADD => 'optional',
+                    PCLZIP_OPT_NO_COMPRESSION => 'optional',
+                    PCLZIP_OPT_COMMENT => 'optional',
+                    PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
+                    PCLZIP_OPT_TEMP_FILE_ON => 'optional',
+                    PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
+                    //, PCLZIP_OPT_CRYPT => 'optional'
+                ));
+                if ($v_result != 1) {
+                    return 0;
+                }
+
+            // ----- Look for 2 args
+            // Here we need to support the first historic synopsis of the
+            // method.
+            } else {
+
+                // ----- Get the first argument
+                $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
+
+                // ----- Look for the optional second argument
+                if ($v_size == 2) {
+                    $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
+                } elseif ($v_size > 2) {
+                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+                    return 0;
+                }
+            }
+        }
+
+        // ----- Look for default option values
+        $this->privOptionDefaultThreshold($v_options);
+
+        // ----- Init
+        $v_string_list    = array();
+        $v_att_list       = array();
+        $v_filedescr_list = array();
+        $p_result_list    = array();
+
+        // ----- Look if the $p_filelist is really an array
+        if (is_array($p_filelist)) {
+
+            // ----- Look if the first element is also an array
+            //       This will mean that this is a file description entry
+            if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
+                $v_att_list = $p_filelist;
+
+            // ----- The list is a list of string names
+            } else {
+                $v_string_list = $p_filelist;
+            }
+
+        // ----- Look if the $p_filelist is a string
+        } elseif (is_string($p_filelist)) {
+            // ----- Create a list from the string
+            $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
+
+        // ----- Invalid variable type for $p_filelist
+        } else {
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
+
+            return 0;
+        }
+
+        // ----- Reformat the string list
+        if (sizeof($v_string_list) != 0) {
+            foreach ($v_string_list as $v_string) {
+                if ($v_string != '') {
+                    $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
+                } else {
+                }
+            }
+        }
+
+        // ----- For each file in the list check the attributes
+        $v_supported_attributes = array(
+            PCLZIP_ATT_FILE_NAME => 'mandatory',
+            PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional',
+            PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional',
+            PCLZIP_ATT_FILE_MTIME => 'optional',
+            PCLZIP_ATT_FILE_CONTENT => 'optional',
+            PCLZIP_ATT_FILE_COMMENT => 'optional'
+        );
+        foreach ($v_att_list as $v_entry) {
+            $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes);
+            if ($v_result != 1) {
+                return 0;
+            }
+        }
+
+        // ----- Expand the filelist (expand directories)
+        $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
+        if ($v_result != 1) {
+            return 0;
+        }
+
+        // ----- Call the create fct
+        $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
+        if ($v_result != 1) {
+            return 0;
+        }
+
+        // ----- Return
+        return $p_result_list;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function :
+    //   add($p_filelist, $p_add_dir="", $p_remove_dir="")
+    //   add($p_filelist, $p_option, $p_option_value, ...)
+    // Description :
+    //   This method supports two synopsis. The first one is historical.
+    //   This methods add the list of files in an existing archive.
+    //   If a file with the same name already exists, it is added at the end of the
+    //   archive, the first one is still present.
+    //   If the archive does not exist, it is created.
+    // Parameters :
+    //   $p_filelist : An array containing file or directory names, or
+    //                 a string containing one filename or one directory name, or
+    //                 a string containing a list of filenames and/or directory
+    //                 names separated by spaces.
+    //   $p_add_dir : A path to add before the real path of the archived file,
+    //                in order to have it memorized in the archive.
+    //   $p_remove_dir : A path to remove from the real path of the file to archive,
+    //                   in order to have a shorter path memorized in the archive.
+    //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
+    //                   is removed first, before $p_add_dir is added.
+    // Options :
+    //   PCLZIP_OPT_ADD_PATH :
+    //   PCLZIP_OPT_REMOVE_PATH :
+    //   PCLZIP_OPT_REMOVE_ALL_PATH :
+    //   PCLZIP_OPT_COMMENT :
+    //   PCLZIP_OPT_ADD_COMMENT :
+    //   PCLZIP_OPT_PREPEND_COMMENT :
+    //   PCLZIP_CB_PRE_ADD :
+    //   PCLZIP_CB_POST_ADD :
+    // Return Values :
+    //   0 on failure,
+    //   The list of the added files, with a status of the add action.
+    //   (see PclZip::listContent() for list entry format)
+    // --------------------------------------------------------------------------------
+    public function add($p_filelist)
+    {
+        $v_result = 1;
+
+        // ----- Reset the error handler
+        $this->privErrorReset();
+
+        // ----- Set default values
+        $v_options                            = array();
+        $v_options[PCLZIP_OPT_NO_COMPRESSION] = false;
+
+        // ----- Look for variable options arguments
+        $v_size = func_num_args();
+
+        // ----- Look for arguments
+        if ($v_size > 1) {
+            // ----- Get the arguments
+            $v_arg_list = func_get_args();
+
+            // ----- Remove form the options list the first argument
+            array_shift($v_arg_list);
+            $v_size--;
+
+            // ----- Look for first arg
+            if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+
+                // ----- Parse the options
+                $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array(
+                    PCLZIP_OPT_REMOVE_PATH => 'optional',
+                    PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+                    PCLZIP_OPT_ADD_PATH => 'optional',
+                    PCLZIP_CB_PRE_ADD => 'optional',
+                    PCLZIP_CB_POST_ADD => 'optional',
+                    PCLZIP_OPT_NO_COMPRESSION => 'optional',
+                    PCLZIP_OPT_COMMENT => 'optional',
+                    PCLZIP_OPT_ADD_COMMENT => 'optional',
+                    PCLZIP_OPT_PREPEND_COMMENT => 'optional',
+                    PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
+                    PCLZIP_OPT_TEMP_FILE_ON => 'optional',
+                    PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
+                    //, PCLZIP_OPT_CRYPT => 'optional'
+                ));
+                if ($v_result != 1) {
+                    return 0;
+                }
+
+            // ----- Look for 2 args
+            // Here we need to support the first historic synopsis of the
+            // method.
+            } else {
+
+                // ----- Get the first argument
+                $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
+
+                // ----- Look for the optional second argument
+                if ($v_size == 2) {
+                    $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
+                } elseif ($v_size > 2) {
+                    // ----- Error log
+                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+                    // ----- Return
+                    return 0;
+                }
+            }
+        }
+
+        // ----- Look for default option values
+        $this->privOptionDefaultThreshold($v_options);
+
+        // ----- Init
+        $v_string_list    = array();
+        $v_att_list       = array();
+        $v_filedescr_list = array();
+        $p_result_list    = array();
+
+        // ----- Look if the $p_filelist is really an array
+        if (is_array($p_filelist)) {
+
+            // ----- Look if the first element is also an array
+            //       This will mean that this is a file description entry
+            if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
+                $v_att_list = $p_filelist;
+
+            // ----- The list is a list of string names
+            } else {
+                $v_string_list = $p_filelist;
+            }
+
+        // ----- Look if the $p_filelist is a string
+        } elseif (is_string($p_filelist)) {
+            // ----- Create a list from the string
+            $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
+
+        // ----- Invalid variable type for $p_filelist
+        } else {
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '" . gettype($p_filelist) . "' for p_filelist");
+
+            return 0;
+        }
+
+        // ----- Reformat the string list
+        if (sizeof($v_string_list) != 0) {
+            foreach ($v_string_list as $v_string) {
+                $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
+            }
+        }
+
+        // ----- For each file in the list check the attributes
+        $v_supported_attributes = array(
+            PCLZIP_ATT_FILE_NAME => 'mandatory',
+            PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional',
+            PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional',
+            PCLZIP_ATT_FILE_MTIME => 'optional',
+            PCLZIP_ATT_FILE_CONTENT => 'optional',
+            PCLZIP_ATT_FILE_COMMENT => 'optional'
+        );
+        foreach ($v_att_list as $v_entry) {
+            $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes);
+            if ($v_result != 1) {
+                return 0;
+            }
+        }
+
+        // ----- Expand the filelist (expand directories)
+        $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
+        if ($v_result != 1) {
+            return 0;
+        }
+
+        // ----- Call the create fct
+        $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
+        if ($v_result != 1) {
+            return 0;
+        }
+
+        // ----- Return
+        return $p_result_list;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : listContent()
+    // Description :
+    //   This public method, gives the list of the files and directories, with their
+    //   properties.
+    //   The properties of each entries in the list are (used also in other functions) :
+    //     filename : Name of the file. For a create or add action it is the filename
+    //                given by the user. For an extract function it is the filename
+    //                of the extracted file.
+    //     stored_filename : Name of the file / directory stored in the archive.
+    //     size : Size of the stored file.
+    //     compressed_size : Size of the file's data compressed in the archive
+    //                       (without the headers overhead)
+    //     mtime : Last known modification date of the file (UNIX timestamp)
+    //     comment : Comment associated with the file
+    //     folder : true | false
+    //     index : index of the file in the archive
+    //     status : status of the action (depending of the action) :
+    //              Values are :
+    //                ok : OK !
+    //                filtered : the file / dir is not extracted (filtered by user)
+    //                already_a_directory : the file can not be extracted because a
+    //                                      directory with the same name already exists
+    //                write_protected : the file can not be extracted because a file
+    //                                  with the same name already exists and is
+    //                                  write protected
+    //                newer_exist : the file was not extracted because a newer file exists
+    //                path_creation_fail : the file is not extracted because the folder
+    //                                     does not exist and can not be created
+    //                write_error : the file was not extracted because there was a
+    //                              error while writing the file
+    //                read_error : the file was not extracted because there was a error
+    //                             while reading the file
+    //                invalid_header : the file was not extracted because of an archive
+    //                                 format error (bad file header)
+    //   Note that each time a method can continue operating when there
+    //   is an action error on a file, the error is only logged in the file status.
+    // Return Values :
+    //   0 on an unrecoverable failure,
+    //   The list of the files in the archive.
+    // --------------------------------------------------------------------------------
+    public function listContent()
+    {
+        $v_result = 1;
+
+        // ----- Reset the error handler
+        $this->privErrorReset();
+
+        // ----- Check archive
+        if (!$this->privCheckFormat()) {
+            return (0);
+        }
+
+        // ----- Call the extracting fct
+        $p_list = array();
+        if (($v_result = $this->privList($p_list)) != 1) {
+            unset($p_list);
+
+            return (0);
+        }
+
+        // ----- Return
+        return $p_list;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function :
+    //   extract($p_path="./", $p_remove_path="")
+    //   extract([$p_option, $p_option_value, ...])
+    // Description :
+    //   This method supports two synopsis. The first one is historical.
+    //   This method extract all the files / directories from the archive to the
+    //   folder indicated in $p_path.
+    //   If you want to ignore the 'root' part of path of the memorized files
+    //   you can indicate this in the optional $p_remove_path parameter.
+    //   By default, if a newer file with the same name already exists, the
+    //   file is not extracted.
+    //
+    //   If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
+    //   are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
+    //   at the end of the path value of PCLZIP_OPT_PATH.
+    // Parameters :
+    //   $p_path : Path where the files and directories are to be extracted
+    //   $p_remove_path : First part ('root' part) of the memorized path
+    //                    (if any similar) to remove while extracting.
+    // Options :
+    //   PCLZIP_OPT_PATH :
+    //   PCLZIP_OPT_ADD_PATH :
+    //   PCLZIP_OPT_REMOVE_PATH :
+    //   PCLZIP_OPT_REMOVE_ALL_PATH :
+    //   PCLZIP_CB_PRE_EXTRACT :
+    //   PCLZIP_CB_POST_EXTRACT :
+    // Return Values :
+    //   0 or a negative value on failure,
+    //   The list of the extracted files, with a status of the action.
+    //   (see PclZip::listContent() for list entry format)
+    // --------------------------------------------------------------------------------
+    public function extract()
+    {
+        $v_result = 1;
+
+        // ----- Reset the error handler
+        $this->privErrorReset();
+
+        // ----- Check archive
+        if (!$this->privCheckFormat()) {
+            return (0);
+        }
+
+        // ----- Set default values
+        $v_options         = array();
+        //    $v_path = "./";
+        $v_path            = '';
+        $v_remove_path     = "";
+        $v_remove_all_path = false;
+
+        // ----- Look for variable options arguments
+        $v_size = func_num_args();
+
+        // ----- Default values for option
+        $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false;
+
+        // ----- Look for arguments
+        if ($v_size > 0) {
+            // ----- Get the arguments
+            $v_arg_list = func_get_args();
+
+            // ----- Look for first arg
+            if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+
+                // ----- Parse the options
+                $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array(
+                    PCLZIP_OPT_PATH => 'optional',
+                    PCLZIP_OPT_REMOVE_PATH => 'optional',
+                    PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+                    PCLZIP_OPT_ADD_PATH => 'optional',
+                    PCLZIP_CB_PRE_EXTRACT => 'optional',
+                    PCLZIP_CB_POST_EXTRACT => 'optional',
+                    PCLZIP_OPT_SET_CHMOD => 'optional',
+                    PCLZIP_OPT_BY_NAME => 'optional',
+                    PCLZIP_OPT_BY_EREG => 'optional',
+                    PCLZIP_OPT_BY_PREG => 'optional',
+                    PCLZIP_OPT_BY_INDEX => 'optional',
+                    PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
+                    PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
+                    PCLZIP_OPT_REPLACE_NEWER => 'optional',
+                    PCLZIP_OPT_STOP_ON_ERROR => 'optional',
+                    PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
+                    PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
+                    PCLZIP_OPT_TEMP_FILE_ON => 'optional',
+                    PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
+                ));
+                if ($v_result != 1) {
+                    return 0;
+                }
+
+                // ----- Set the arguments
+                if (isset($v_options[PCLZIP_OPT_PATH])) {
+                    $v_path = $v_options[PCLZIP_OPT_PATH];
+                }
+                if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
+                    $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
+                }
+                if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
+                    $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
+                }
+                if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
+                    // ----- Check for '/' in last path char
+                    if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
+                        $v_path .= '/';
+                    }
+                    $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
+                }
+
+            // ----- Look for 2 args
+            // Here we need to support the first historic synopsis of the
+            // method.
+            } else {
+
+                // ----- Get the first argument
+                $v_path = $v_arg_list[0];
+
+                // ----- Look for the optional second argument
+                if ($v_size == 2) {
+                    $v_remove_path = $v_arg_list[1];
+                } elseif ($v_size > 2) {
+                    // ----- Error log
+                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+                    // ----- Return
+                    return 0;
+                }
+            }
+        }
+
+        // ----- Look for default option values
+        $this->privOptionDefaultThreshold($v_options);
+
+        // ----- Trace
+
+        // ----- Call the extracting fct
+        $p_list   = array();
+        $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options);
+        if ($v_result < 1) {
+            unset($p_list);
+
+            return (0);
+        }
+
+        // ----- Return
+        return $p_list;
+    }
+    // --------------------------------------------------------------------------------
+
+
+    // --------------------------------------------------------------------------------
+    // Function :
+    //   extractByIndex($p_index, $p_path="./", $p_remove_path="")
+    //   extractByIndex($p_index, [$p_option, $p_option_value, ...])
+    // Description :
+    //   This method supports two synopsis. The first one is historical.
+    //   This method is doing a partial extract of the archive.
+    //   The extracted files or folders are identified by their index in the
+    //   archive (from 0 to n).
+    //   Note that if the index identify a folder, only the folder entry is
+    //   extracted, not all the files included in the archive.
+    // Parameters :
+    //   $p_index : A single index (integer) or a string of indexes of files to
+    //              extract. The form of the string is "0,4-6,8-12" with only numbers
+    //              and '-' for range or ',' to separate ranges. No spaces or ';'
+    //              are allowed.
+    //   $p_path : Path where the files and directories are to be extracted
+    //   $p_remove_path : First part ('root' part) of the memorized path
+    //                    (if any similar) to remove while extracting.
+    // Options :
+    //   PCLZIP_OPT_PATH :
+    //   PCLZIP_OPT_ADD_PATH :
+    //   PCLZIP_OPT_REMOVE_PATH :
+    //   PCLZIP_OPT_REMOVE_ALL_PATH :
+    //   PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
+    //     not as files.
+    //     The resulting content is in a new field 'content' in the file
+    //     structure.
+    //     This option must be used alone (any other options are ignored).
+    //   PCLZIP_CB_PRE_EXTRACT :
+    //   PCLZIP_CB_POST_EXTRACT :
+    // Return Values :
+    //   0 on failure,
+    //   The list of the extracted files, with a status of the action.
+    //   (see PclZip::listContent() for list entry format)
+    // --------------------------------------------------------------------------------
+    //function extractByIndex($p_index, options...)
+    public function extractByIndex($p_index)
+    {
+        $v_result = 1;
+
+        // ----- Reset the error handler
+        $this->privErrorReset();
+
+        // ----- Check archive
+        if (!$this->privCheckFormat()) {
+            return (0);
+        }
+
+        // ----- Set default values
+        $v_options         = array();
+        //    $v_path = "./";
+        $v_path            = '';
+        $v_remove_path     = "";
+        $v_remove_all_path = false;
+
+        // ----- Look for variable options arguments
+        $v_size = func_num_args();
+
+        // ----- Default values for option
+        $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false;
+
+        // ----- Look for arguments
+        if ($v_size > 1) {
+            // ----- Get the arguments
+            $v_arg_list = func_get_args();
+
+            // ----- Remove form the options list the first argument
+            array_shift($v_arg_list);
+            $v_size--;
+
+            // ----- Look for first arg
+            if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+
+                // ----- Parse the options
+                $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array(
+                    PCLZIP_OPT_PATH => 'optional',
+                    PCLZIP_OPT_REMOVE_PATH => 'optional',
+                    PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+                    PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
+                    PCLZIP_OPT_ADD_PATH => 'optional',
+                    PCLZIP_CB_PRE_EXTRACT => 'optional',
+                    PCLZIP_CB_POST_EXTRACT => 'optional',
+                    PCLZIP_OPT_SET_CHMOD => 'optional',
+                    PCLZIP_OPT_REPLACE_NEWER => 'optional',
+                    PCLZIP_OPT_STOP_ON_ERROR => 'optional',
+                    PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
+                    PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
+                    PCLZIP_OPT_TEMP_FILE_ON => 'optional',
+                    PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
+                ));
+                if ($v_result != 1) {
+                    return 0;
+                }
+
+                // ----- Set the arguments
+                if (isset($v_options[PCLZIP_OPT_PATH])) {
+                    $v_path = $v_options[PCLZIP_OPT_PATH];
+                }
+                if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
+                    $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
+                }
+                if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
+                    $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
+                }
+                if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
+                    // ----- Check for '/' in last path char
+                    if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
+                        $v_path .= '/';
+                    }
+                    $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
+                }
+                if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
+                    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false;
+                } else {
+                }
+
+            // ----- Look for 2 args
+            // Here we need to support the first historic synopsis of the
+            // method.
+            } else {
+
+                // ----- Get the first argument
+                $v_path = $v_arg_list[0];
+
+                // ----- Look for the optional second argument
+                if ($v_size == 2) {
+                    $v_remove_path = $v_arg_list[1];
+                } elseif ($v_size > 2) {
+                    // ----- Error log
+                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+                    // ----- Return
+                    return 0;
+                }
+            }
+        }
+
+        // ----- Trace
+
+        // ----- Trick
+        // Here I want to reuse extractByRule(), so I need to parse the $p_index
+        // with privParseOptions()
+        $v_arg_trick     = array(
+            PCLZIP_OPT_BY_INDEX,
+            $p_index
+        );
+        $v_options_trick = array();
+        $v_result        = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, array(
+            PCLZIP_OPT_BY_INDEX => 'optional'
+        ));
+        if ($v_result != 1) {
+            return 0;
+        }
+        $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
+
+        // ----- Look for default option values
+        $this->privOptionDefaultThreshold($v_options);
+
+        // ----- Call the extracting fct
+        if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
+            return (0);
+        }
+
+        // ----- Return
+        return $p_list;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function :
+    //   delete([$p_option, $p_option_value, ...])
+    // Description :
+    //   This method removes files from the archive.
+    //   If no parameters are given, then all the archive is emptied.
+    // Parameters :
+    //   None or optional arguments.
+    // Options :
+    //   PCLZIP_OPT_BY_INDEX :
+    //   PCLZIP_OPT_BY_NAME :
+    //   PCLZIP_OPT_BY_EREG :
+    //   PCLZIP_OPT_BY_PREG :
+    // Return Values :
+    //   0 on failure,
+    //   The list of the files which are still present in the archive.
+    //   (see PclZip::listContent() for list entry format)
+    // --------------------------------------------------------------------------------
+    public function delete()
+    {
+        $v_result = 1;
+
+        // ----- Reset the error handler
+        $this->privErrorReset();
+
+        // ----- Check archive
+        if (!$this->privCheckFormat()) {
+            return (0);
+        }
+
+        // ----- Set default values
+        $v_options = array();
+
+        // ----- Look for variable options arguments
+        $v_size = func_num_args();
+
+        // ----- Look for arguments
+        if ($v_size > 0) {
+            // ----- Get the arguments
+            $v_arg_list = func_get_args();
+
+            // ----- Parse the options
+            $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array(
+                PCLZIP_OPT_BY_NAME => 'optional',
+                PCLZIP_OPT_BY_EREG => 'optional',
+                PCLZIP_OPT_BY_PREG => 'optional',
+                PCLZIP_OPT_BY_INDEX => 'optional'
+            ));
+            if ($v_result != 1) {
+                return 0;
+            }
+        }
+
+        // ----- Magic quotes trick
+        $this->privDisableMagicQuotes();
+
+        // ----- Call the delete fct
+        $v_list = array();
+        if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
+            $this->privSwapBackMagicQuotes();
+            unset($v_list);
+
+            return (0);
+        }
+
+        // ----- Magic quotes trick
+        $this->privSwapBackMagicQuotes();
+
+        // ----- Return
+        return $v_list;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : deleteByIndex()
+    // Description :
+    //   ***** Deprecated *****
+    //   delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
+    // --------------------------------------------------------------------------------
+    public function deleteByIndex($p_index)
+    {
+
+        $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
+
+        // ----- Return
+        return $p_list;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : properties()
+    // Description :
+    //   This method gives the properties of the archive.
+    //   The properties are :
+    //     nb : Number of files in the archive
+    //     comment : Comment associated with the archive file
+    //     status : not_exist, ok
+    // Parameters :
+    //   None
+    // Return Values :
+    //   0 on failure,
+    //   An array with the archive properties.
+    // --------------------------------------------------------------------------------
+    public function properties()
+    {
+
+        // ----- Reset the error handler
+        $this->privErrorReset();
+
+        // ----- Magic quotes trick
+        $this->privDisableMagicQuotes();
+
+        // ----- Check archive
+        if (!$this->privCheckFormat()) {
+            $this->privSwapBackMagicQuotes();
+
+            return (0);
+        }
+
+        // ----- Default properties
+        $v_prop            = array();
+        $v_prop['comment'] = '';
+        $v_prop['nb']      = 0;
+        $v_prop['status']  = 'not_exist';
+
+        // ----- Look if file exists
+        if (@is_file($this->zipname)) {
+            // ----- Open the zip file
+            if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) {
+                $this->privSwapBackMagicQuotes();
+
+                // ----- Error log
+                PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in binary read mode');
+
+                // ----- Return
+                return 0;
+            }
+
+            // ----- Read the central directory informations
+            $v_central_dir = array();
+            if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
+                $this->privSwapBackMagicQuotes();
+
+                return 0;
+            }
+
+            // ----- Close the zip file
+            $this->privCloseFd();
+
+            // ----- Set the user attributes
+            $v_prop['comment'] = $v_central_dir['comment'];
+            $v_prop['nb']      = $v_central_dir['entries'];
+            $v_prop['status']  = 'ok';
+        }
+
+        // ----- Magic quotes trick
+        $this->privSwapBackMagicQuotes();
+
+        // ----- Return
+        return $v_prop;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : duplicate()
+    // Description :
+    //   This method creates an archive by copying the content of an other one. If
+    //   the archive already exist, it is replaced by the new one without any warning.
+    // Parameters :
+    //   $p_archive : The filename of a valid archive, or
+    //                a valid PclZip object.
+    // Return Values :
+    //   1 on success.
+    //   0 or a negative value on error (error code).
+    // --------------------------------------------------------------------------------
+    public function duplicate($p_archive)
+    {
+        $v_result = 1;
+
+        // ----- Reset the error handler
+        $this->privErrorReset();
+
+        // ----- Look if the $p_archive is a PclZip object
+        if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) {
+
+            // ----- Duplicate the archive
+            $v_result = $this->privDuplicate($p_archive->zipname);
+
+        // ----- Look if the $p_archive is a string (so a filename)
+        } elseif (is_string($p_archive)) {
+
+            // ----- Check that $p_archive is a valid zip file
+            // TBC : Should also check the archive format
+            if (!is_file($p_archive)) {
+                // ----- Error log
+                PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '" . $p_archive . "'");
+                $v_result = PCLZIP_ERR_MISSING_FILE;
+            } else {
+                // ----- Duplicate the archive
+                $v_result = $this->privDuplicate($p_archive);
+            }
+
+        // ----- Invalid variable
+        } else {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
+            $v_result = PCLZIP_ERR_INVALID_PARAMETER;
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : merge()
+    // Description :
+    //   This method merge the $p_archive_to_add archive at the end of the current
+    //   one ($this).
+    //   If the archive ($this) does not exist, the merge becomes a duplicate.
+    //   If the $p_archive_to_add archive does not exist, the merge is a success.
+    // Parameters :
+    //   $p_archive_to_add : It can be directly the filename of a valid zip archive,
+    //                       or a PclZip object archive.
+    // Return Values :
+    //   1 on success,
+    //   0 or negative values on error (see below).
+    // --------------------------------------------------------------------------------
+    public function merge($p_archive_to_add)
+    {
+        $v_result = 1;
+
+        // ----- Reset the error handler
+        $this->privErrorReset();
+
+        // ----- Check archive
+        if (!$this->privCheckFormat()) {
+            return (0);
+        }
+
+        // ----- Look if the $p_archive_to_add is a PclZip object
+        if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) {
+
+            // ----- Merge the archive
+            $v_result = $this->privMerge($p_archive_to_add);
+
+        // ----- Look if the $p_archive_to_add is a string (so a filename)
+        } elseif (is_string($p_archive_to_add)) {
+
+            // ----- Create a temporary archive
+            $v_object_archive = new PclZip($p_archive_to_add);
+
+            // ----- Merge the archive
+            $v_result = $this->privMerge($v_object_archive);
+
+        // ----- Invalid variable
+        } else {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
+            $v_result = PCLZIP_ERR_INVALID_PARAMETER;
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : errorCode()
+    // Description :
+    // Parameters :
+    // --------------------------------------------------------------------------------
+    public function errorCode()
+    {
+        if (PCLZIP_ERROR_EXTERNAL == 1) {
+            return (PclErrorCode());
+        } else {
+            return ($this->error_code);
+        }
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : errorName()
+    // Description :
+    // Parameters :
+    // --------------------------------------------------------------------------------
+    public function errorName($p_with_code = false)
+    {
+        $v_name = array(
+            PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
+            PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
+            PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
+            PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
+            PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
+            PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
+            PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
+            PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
+            PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
+            PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
+            PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
+            PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
+            PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
+            PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
+            PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
+            PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
+            PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
+            PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
+            PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION',
+            PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE',
+            PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
+        );
+
+        if (isset($v_name[$this->error_code])) {
+            $v_value = $v_name[$this->error_code];
+        } else {
+            $v_value = 'NoName';
+        }
+
+        if ($p_with_code) {
+            return ($v_value . ' (' . $this->error_code . ')');
+        } else {
+            return ($v_value);
+        }
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : errorInfo()
+    // Description :
+    // Parameters :
+    // --------------------------------------------------------------------------------
+    public function errorInfo($p_full = false)
+    {
+        if (PCLZIP_ERROR_EXTERNAL == 1) {
+            return (PclErrorString());
+        } else {
+            if ($p_full) {
+                return ($this->errorName(true) . " : " . $this->error_string);
+            } else {
+                return ($this->error_string . " [code " . $this->error_code . "]");
+            }
+        }
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
+    // *****                                                        *****
+    // *****       THESES FUNCTIONS MUST NOT BE USED DIRECTLY       *****
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privCheckFormat()
+    // Description :
+    //   This method check that the archive exists and is a valid zip archive.
+    //   Several level of check exists. (futur)
+    // Parameters :
+    //   $p_level : Level of check. Default 0.
+    //              0 : Check the first bytes (magic codes) (default value))
+    //              1 : 0 + Check the central directory (futur)
+    //              2 : 1 + Check each file header (futur)
+    // Return Values :
+    //   true on success,
+    //   false on error, the error code is set.
+    // --------------------------------------------------------------------------------
+    public function privCheckFormat($p_level = 0)
+    {
+        $v_result = true;
+
+        // ----- Reset the file system cache
+        clearstatcache();
+
+        // ----- Reset the error handler
+        $this->privErrorReset();
+
+        // ----- Look if the file exits
+        if (!is_file($this->zipname)) {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '" . $this->zipname . "'");
+
+            return (false);
+        }
+
+        // ----- Check that the file is readeable
+        if (!is_readable($this->zipname)) {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '" . $this->zipname . "'");
+
+            return (false);
+        }
+
+        // ----- Check the magic code
+        // TBC
+
+        // ----- Check the central header
+        // TBC
+
+        // ----- Check each file header
+        // TBC
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privParseOptions()
+    // Description :
+    //   This internal methods reads the variable list of arguments ($p_options_list,
+    //   $p_size) and generate an array with the options and values ($v_result_list).
+    //   $v_requested_options contains the options that can be present and those that
+    //   must be present.
+    //   $v_requested_options is an array, with the option value as key, and 'optional',
+    //   or 'mandatory' as value.
+    // Parameters :
+    //   See above.
+    // Return Values :
+    //   1 on success.
+    //   0 on failure.
+    // --------------------------------------------------------------------------------
+    public function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options = false)
+    {
+        $v_result = 1;
+
+        // ----- Read the options
+        $i = 0;
+        while ($i < $p_size) {
+
+            // ----- Check if the option is supported
+            if (!isset($v_requested_options[$p_options_list[$i]])) {
+                // ----- Error log
+                PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '" . $p_options_list[$i] . "' for this method");
+
+                // ----- Return
+                return PclZip::errorCode();
+            }
+
+            // ----- Look for next option
+            switch ($p_options_list[$i]) {
+                // ----- Look for options that request a path value
+                case PCLZIP_OPT_PATH:
+                case PCLZIP_OPT_REMOVE_PATH:
+                case PCLZIP_OPT_ADD_PATH:
+                    // ----- Check the number of parameters
+                    if (($i + 1) >= $p_size) {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Get the value
+                    $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i + 1], false);
+                    $i++;
+                    break;
+
+                case PCLZIP_OPT_TEMP_FILE_THRESHOLD:
+                    // ----- Check the number of parameters
+                    if (($i + 1) >= $p_size) {
+                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Check for incompatible options
+                    if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i]) . "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
+
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Check the value
+                    $v_value = $p_options_list[$i + 1];
+                    if ((!is_integer($v_value)) || ($v_value < 0)) {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Get the value (and convert it in bytes)
+                    $v_result_list[$p_options_list[$i]] = $v_value * 1048576;
+                    $i++;
+                    break;
+
+                case PCLZIP_OPT_TEMP_FILE_ON:
+                    // ----- Check for incompatible options
+                    if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i]) . "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
+
+                        return PclZip::errorCode();
+                    }
+
+                    $v_result_list[$p_options_list[$i]] = true;
+                    break;
+
+                case PCLZIP_OPT_TEMP_FILE_OFF:
+                    // ----- Check for incompatible options
+                    if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i]) . "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
+
+                        return PclZip::errorCode();
+                    }
+                    // ----- Check for incompatible options
+                    if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i]) . "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
+
+                        return PclZip::errorCode();
+                    }
+
+                    $v_result_list[$p_options_list[$i]] = true;
+                    break;
+
+                case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION:
+                    // ----- Check the number of parameters
+                    if (($i + 1) >= $p_size) {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Get the value
+                    if (is_string($p_options_list[$i + 1]) && ($p_options_list[$i + 1] != '')) {
+                        $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i + 1], false);
+                        $i++;
+                    } else {
+                    }
+                    break;
+
+                // ----- Look for options that request an array of string for value
+                case PCLZIP_OPT_BY_NAME:
+                    // ----- Check the number of parameters
+                    if (($i + 1) >= $p_size) {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Get the value
+                    if (is_string($p_options_list[$i + 1])) {
+                        $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i + 1];
+                    } elseif (is_array($p_options_list[$i + 1])) {
+                        $v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1];
+                    } else {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+                    $i++;
+                    break;
+
+                // ----- Look for options that request an EREG or PREG expression
+                case PCLZIP_OPT_BY_EREG:
+                    $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
+                    // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
+                    // to PCLZIP_OPT_BY_PREG
+                case PCLZIP_OPT_BY_PREG:
+                    //case PCLZIP_OPT_CRYPT :
+                    // ----- Check the number of parameters
+                    if (($i + 1) >= $p_size) {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Get the value
+                    if (is_string($p_options_list[$i + 1])) {
+                        $v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1];
+                    } else {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+                    $i++;
+                    break;
+
+                // ----- Look for options that takes a string
+                case PCLZIP_OPT_COMMENT:
+                case PCLZIP_OPT_ADD_COMMENT:
+                case PCLZIP_OPT_PREPEND_COMMENT:
+                    // ----- Check the number of parameters
+                    if (($i + 1) >= $p_size) {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Get the value
+                    if (is_string($p_options_list[$i + 1])) {
+                        $v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1];
+                    } else {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+                    $i++;
+                    break;
+
+                // ----- Look for options that request an array of index
+                case PCLZIP_OPT_BY_INDEX:
+                    // ----- Check the number of parameters
+                    if (($i + 1) >= $p_size) {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Get the value
+                    $v_work_list = array();
+                    if (is_string($p_options_list[$i + 1])) {
+
+                        // ----- Remove spaces
+                        $p_options_list[$i + 1] = strtr($p_options_list[$i + 1], ' ', '');
+
+                        // ----- Parse items
+                        $v_work_list = explode(",", $p_options_list[$i + 1]);
+                    } elseif (is_integer($p_options_list[$i + 1])) {
+                        $v_work_list[0] = $p_options_list[$i + 1] . '-' . $p_options_list[$i + 1];
+                    } elseif (is_array($p_options_list[$i + 1])) {
+                        $v_work_list = $p_options_list[$i + 1];
+                    } else {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Reduce the index list
+                    // each index item in the list must be a couple with a start and
+                    // an end value : [0,3], [5-5], [8-10], ...
+                    // ----- Check the format of each item
+                    $v_sort_flag  = false;
+                    $v_sort_value = 0;
+                    for ($j = 0; $j < sizeof($v_work_list); $j++) {
+                        // ----- Explode the item
+                        $v_item_list      = explode("-", $v_work_list[$j]);
+                        $v_size_item_list = sizeof($v_item_list);
+
+                        // ----- TBC : Here we might check that each item is a
+                        // real integer ...
+
+                        // ----- Look for single value
+                        if ($v_size_item_list == 1) {
+                            // ----- Set the option value
+                            $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
+                            $v_result_list[$p_options_list[$i]][$j]['end']   = $v_item_list[0];
+                        } elseif ($v_size_item_list == 2) {
+                            // ----- Set the option value
+                            $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
+                            $v_result_list[$p_options_list[$i]][$j]['end']   = $v_item_list[1];
+                        } else {
+                            // ----- Error log
+                            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                            // ----- Return
+                            return PclZip::errorCode();
+                        }
+
+                        // ----- Look for list sort
+                        if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
+                            $v_sort_flag = true;
+
+                            // ----- TBC : An automatic sort should be writen ...
+                            // ----- Error log
+                            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                            // ----- Return
+                            return PclZip::errorCode();
+                        }
+                        $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
+                    }
+
+                    // ----- Sort the items
+                    if ($v_sort_flag) {
+                        // TBC : To Be Completed
+                    }
+
+                    // ----- Next option
+                    $i++;
+                    break;
+
+                // ----- Look for options that request no value
+                case PCLZIP_OPT_REMOVE_ALL_PATH:
+                case PCLZIP_OPT_EXTRACT_AS_STRING:
+                case PCLZIP_OPT_NO_COMPRESSION:
+                case PCLZIP_OPT_EXTRACT_IN_OUTPUT:
+                case PCLZIP_OPT_REPLACE_NEWER:
+                case PCLZIP_OPT_STOP_ON_ERROR:
+                    $v_result_list[$p_options_list[$i]] = true;
+                    break;
+
+                // ----- Look for options that request an octal value
+                case PCLZIP_OPT_SET_CHMOD:
+                    // ----- Check the number of parameters
+                    if (($i + 1) >= $p_size) {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Get the value
+                    $v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1];
+                    $i++;
+                    break;
+
+                // ----- Look for options that request a call-back
+                case PCLZIP_CB_PRE_EXTRACT:
+                case PCLZIP_CB_POST_EXTRACT:
+                case PCLZIP_CB_PRE_ADD:
+                case PCLZIP_CB_POST_ADD:
+                    /* for futur use
+                    case PCLZIP_CB_PRE_DELETE :
+                    case PCLZIP_CB_POST_DELETE :
+                    case PCLZIP_CB_PRE_LIST :
+                    case PCLZIP_CB_POST_LIST :
+                    */
+                    // ----- Check the number of parameters
+                    if (($i + 1) >= $p_size) {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Get the value
+                    $v_function_name = $p_options_list[$i + 1];
+
+                    // ----- Check that the value is a valid existing function
+                    if (!function_exists($v_function_name)) {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '" . $v_function_name . "()' is not an existing function for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Set the attribute
+                    $v_result_list[$p_options_list[$i]] = $v_function_name;
+                    $i++;
+                    break;
+
+                default:
+                    // ----- Error log
+                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown parameter '" . $p_options_list[$i] . "'");
+
+                    // ----- Return
+                    return PclZip::errorCode();
+            }
+
+            // ----- Next options
+            $i++;
+        }
+
+        // ----- Look for mandatory options
+        if ($v_requested_options !== false) {
+            for ($key = reset($v_requested_options); $key = key($v_requested_options); $key = next($v_requested_options)) {
+                // ----- Look for mandatory option
+                if ($v_requested_options[$key] == 'mandatory') {
+                    // ----- Look if present
+                    if (!isset($v_result_list[$key])) {
+                        // ----- Error log
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter " . PclZipUtilOptionText($key) . "(" . $key . ")");
+
+                        // ----- Return
+                        return PclZip::errorCode();
+                    }
+                }
+            }
+        }
+
+        // ----- Look for default values
+        if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
+
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privOptionDefaultThreshold()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privOptionDefaultThreshold(&$p_options)
+    {
+        $v_result = 1;
+
+        if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
+            return $v_result;
+        }
+
+        // ----- Get 'memory_limit' configuration value
+        $v_memory_limit = ini_get('memory_limit');
+        $v_memory_limit = trim($v_memory_limit);
+        $last           = strtolower(substr($v_memory_limit, -1));
+        $v_memory_limit = preg_replace('/\s*[KkMmGg]$/', '', $v_memory_limit);
+
+        if ($last == 'g') {
+            //$v_memory_limit = $v_memory_limit*1024*1024*1024;
+            $v_memory_limit = $v_memory_limit * 1073741824;
+        }
+        if ($last == 'm') {
+            //$v_memory_limit = $v_memory_limit*1024*1024;
+            $v_memory_limit = $v_memory_limit * 1048576;
+        }
+        if ($last == 'k') {
+            $v_memory_limit = $v_memory_limit * 1024;
+        }
+
+        $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit * PCLZIP_TEMPORARY_FILE_RATIO);
+
+        // ----- Sanity check : No threshold if value lower than 1M
+        if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
+            unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privFileDescrParseAtt()
+    // Description :
+    // Parameters :
+    // Return Values :
+    //   1 on success.
+    //   0 on failure.
+    // --------------------------------------------------------------------------------
+    public function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options = false)
+    {
+        $v_result = 1;
+
+        // ----- For each file in the list check the attributes
+        foreach ($p_file_list as $v_key => $v_value) {
+
+            // ----- Check if the option is supported
+            if (!isset($v_requested_options[$v_key])) {
+                // ----- Error log
+                PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '" . $v_key . "' for this file");
+
+                // ----- Return
+                return PclZip::errorCode();
+            }
+
+            // ----- Look for attribute
+            switch ($v_key) {
+                case PCLZIP_ATT_FILE_NAME:
+                    if (!is_string($v_value)) {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". String expected for attribute '" . PclZipUtilOptionText($v_key) . "'");
+
+                        return PclZip::errorCode();
+                    }
+
+                    $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
+
+                    if ($p_filedescr['filename'] == '') {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '" . PclZipUtilOptionText($v_key) . "'");
+
+                        return PclZip::errorCode();
+                    }
+
+                    break;
+
+                case PCLZIP_ATT_FILE_NEW_SHORT_NAME:
+                    if (!is_string($v_value)) {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". String expected for attribute '" . PclZipUtilOptionText($v_key) . "'");
+
+                        return PclZip::errorCode();
+                    }
+
+                    $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
+
+                    if ($p_filedescr['new_short_name'] == '') {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '" . PclZipUtilOptionText($v_key) . "'");
+
+                        return PclZip::errorCode();
+                    }
+                    break;
+
+                case PCLZIP_ATT_FILE_NEW_FULL_NAME:
+                    if (!is_string($v_value)) {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". String expected for attribute '" . PclZipUtilOptionText($v_key) . "'");
+
+                        return PclZip::errorCode();
+                    }
+
+                    $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
+
+                    if ($p_filedescr['new_full_name'] == '') {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '" . PclZipUtilOptionText($v_key) . "'");
+
+                        return PclZip::errorCode();
+                    }
+                    break;
+
+                // ----- Look for options that takes a string
+                case PCLZIP_ATT_FILE_COMMENT:
+                    if (!is_string($v_value)) {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". String expected for attribute '" . PclZipUtilOptionText($v_key) . "'");
+
+                        return PclZip::errorCode();
+                    }
+
+                    $p_filedescr['comment'] = $v_value;
+                    break;
+
+                case PCLZIP_ATT_FILE_MTIME:
+                    if (!is_integer($v_value)) {
+                        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type " . gettype($v_value) . ". Integer expected for attribute '" . PclZipUtilOptionText($v_key) . "'");
+
+                        return PclZip::errorCode();
+                    }
+
+                    $p_filedescr['mtime'] = $v_value;
+                    break;
+
+                case PCLZIP_ATT_FILE_CONTENT:
+                    $p_filedescr['content'] = $v_value;
+                    break;
+
+                default:
+                    // ----- Error log
+                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown parameter '" . $v_key . "'");
+
+                    // ----- Return
+                    return PclZip::errorCode();
+            }
+
+            // ----- Look for mandatory options
+            if ($v_requested_options !== false) {
+                for ($key = reset($v_requested_options); $key = key($v_requested_options); $key = next($v_requested_options)) {
+                    // ----- Look for mandatory option
+                    if ($v_requested_options[$key] == 'mandatory') {
+                        // ----- Look if present
+                        if (!isset($p_file_list[$key])) {
+                            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter " . PclZipUtilOptionText($key) . "(" . $key . ")");
+
+                            return PclZip::errorCode();
+                        }
+                    }
+                }
+            }
+
+            // end foreach
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privFileDescrExpand()
+    // Description :
+    //   This method look for each item of the list to see if its a file, a folder
+    //   or a string to be added as file. For any other type of files (link, other)
+    //   just ignore the item.
+    //   Then prepare the information that will be stored for that file.
+    //   When its a folder, expand the folder with all the files that are in that
+    //   folder (recursively).
+    // Parameters :
+    // Return Values :
+    //   1 on success.
+    //   0 on failure.
+    // --------------------------------------------------------------------------------
+    public function privFileDescrExpand(&$p_filedescr_list, &$p_options)
+    {
+        $v_result = 1;
+
+        // ----- Create a result list
+        $v_result_list = array();
+
+        // ----- Look each entry
+        for ($i = 0; $i < sizeof($p_filedescr_list); $i++) {
+
+            // ----- Get filedescr
+            $v_descr = $p_filedescr_list[$i];
+
+            // ----- Reduce the filename
+            $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
+            $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
+
+            // ----- Look for real file or folder
+            if (file_exists($v_descr['filename'])) {
+                if (@is_file($v_descr['filename'])) {
+                    $v_descr['type'] = 'file';
+                } elseif (@is_dir($v_descr['filename'])) {
+                    $v_descr['type'] = 'folder';
+                } elseif (@is_link($v_descr['filename'])) {
+                    // skip
+                    continue;
+                } else {
+                    // skip
+                    continue;
+                }
+
+            // ----- Look for string added as file
+            } elseif (isset($v_descr['content'])) {
+                $v_descr['type'] = 'virtual_file';
+
+            // ----- Missing file
+            } else {
+                // ----- Error log
+                PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '" . $v_descr['filename'] . "' does not exist");
+
+                // ----- Return
+                return PclZip::errorCode();
+            }
+
+            // ----- Calculate the stored filename
+            $this->privCalculateStoredFilename($v_descr, $p_options);
+
+            // ----- Add the descriptor in result list
+            $v_result_list[sizeof($v_result_list)] = $v_descr;
+
+            // ----- Look for folder
+            if ($v_descr['type'] == 'folder') {
+                // ----- List of items in folder
+                $v_dirlist_descr = array();
+                $v_dirlist_nb    = 0;
+                if ($v_folder_handler = @opendir($v_descr['filename'])) {
+                    while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
+
+                        // ----- Skip '.' and '..'
+                        if (($v_item_handler == '.') || ($v_item_handler == '..')) {
+                            continue;
+                        }
+
+                        // ----- Compose the full filename
+                        $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'] . '/' . $v_item_handler;
+
+                        // ----- Look for different stored filename
+                        // Because the name of the folder was changed, the name of the
+                        // files/sub-folders also change
+                        if (($v_descr['stored_filename'] != $v_descr['filename']) && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
+                            if ($v_descr['stored_filename'] != '') {
+                                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'] . '/' . $v_item_handler;
+                            } else {
+                                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
+                            }
+                        }
+
+                        $v_dirlist_nb++;
+                    }
+
+                    @closedir($v_folder_handler);
+                } else {
+                    // TBC : unable to open folder in read mode
+                }
+
+                // ----- Expand each element of the list
+                if ($v_dirlist_nb != 0) {
+                    // ----- Expand
+                    if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
+                        return $v_result;
+                    }
+
+                    // ----- Concat the resulting list
+                    $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
+                } else {
+                }
+
+                // ----- Free local array
+                unset($v_dirlist_descr);
+            }
+        }
+
+        // ----- Get the result list
+        $p_filedescr_list = $v_result_list;
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privCreate()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
+    {
+        $v_result      = 1;
+        $v_list_detail = array();
+
+        // ----- Magic quotes trick
+        $this->privDisableMagicQuotes();
+
+        // ----- Open the file in write mode
+        if (($v_result = $this->privOpenFd('wb')) != 1) {
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Add the list of files
+        $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
+
+        // ----- Close
+        $this->privCloseFd();
+
+        // ----- Magic quotes trick
+        $this->privSwapBackMagicQuotes();
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privAdd()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
+    {
+        $v_result      = 1;
+        $v_list_detail = array();
+
+        // ----- Look if the archive exists or is empty
+        if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) {
+
+            // ----- Do a create
+            $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
+
+            // ----- Return
+            return $v_result;
+        }
+        // ----- Magic quotes trick
+        $this->privDisableMagicQuotes();
+
+        // ----- Open the zip file
+        if (($v_result = $this->privOpenFd('rb')) != 1) {
+            // ----- Magic quotes trick
+            $this->privSwapBackMagicQuotes();
+
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Read the central directory informations
+        $v_central_dir = array();
+        if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
+            $this->privCloseFd();
+            $this->privSwapBackMagicQuotes();
+
+            return $v_result;
+        }
+
+        // ----- Go to beginning of File
+        @rewind($this->zip_fd);
+
+        // ----- Creates a temporay file
+        $v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp';
+
+        // ----- Open the temporary file in write mode
+        if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) {
+            $this->privCloseFd();
+            $this->privSwapBackMagicQuotes();
+
+            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_zip_temp_name . '\' in binary write mode');
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Copy the files from the archive to the temporary file
+        // TBC : Here I should better append the file and go back to erase the central dir
+        $v_size = $v_central_dir['offset'];
+        while ($v_size != 0) {
+            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = fread($this->zip_fd, $v_read_size);
+            @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+            $v_size -= $v_read_size;
+        }
+
+        // ----- Swap the file descriptor
+        // Here is a trick : I swap the temporary fd with the zip fd, in order to use
+        // the following methods on the temporary fil and not the real archive
+        $v_swap        = $this->zip_fd;
+        $this->zip_fd  = $v_zip_temp_fd;
+        $v_zip_temp_fd = $v_swap;
+
+        // ----- Add the files
+        $v_header_list = array();
+        if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) {
+            fclose($v_zip_temp_fd);
+            $this->privCloseFd();
+            @unlink($v_zip_temp_name);
+            $this->privSwapBackMagicQuotes();
+
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Store the offset of the central dir
+        $v_offset = @ftell($this->zip_fd);
+
+        // ----- Copy the block of file headers from the old archive
+        $v_size = $v_central_dir['size'];
+        while ($v_size != 0) {
+            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = @fread($v_zip_temp_fd, $v_read_size);
+            @fwrite($this->zip_fd, $v_buffer, $v_read_size);
+            $v_size -= $v_read_size;
+        }
+
+        // ----- Create the Central Dir files header
+        for ($i = 0, $v_count = 0; $i < sizeof($v_header_list); $i++) {
+            // ----- Create the file header
+            if ($v_header_list[$i]['status'] == 'ok') {
+                if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
+                    fclose($v_zip_temp_fd);
+                    $this->privCloseFd();
+                    @unlink($v_zip_temp_name);
+                    $this->privSwapBackMagicQuotes();
+
+                    // ----- Return
+                    return $v_result;
+                }
+                $v_count++;
+            }
+
+            // ----- Transform the header to a 'usable' info
+            $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+        }
+
+        // ----- Zip file comment
+        $v_comment = $v_central_dir['comment'];
+        if (isset($p_options[PCLZIP_OPT_COMMENT])) {
+            $v_comment = $p_options[PCLZIP_OPT_COMMENT];
+        }
+        if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
+            $v_comment = $v_comment . $p_options[PCLZIP_OPT_ADD_COMMENT];
+        }
+        if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
+            $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT] . $v_comment;
+        }
+
+        // ----- Calculate the size of the central header
+        $v_size = @ftell($this->zip_fd) - $v_offset;
+
+        // ----- Create the central dir footer
+        if (($v_result = $this->privWriteCentralHeader($v_count + $v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) {
+            // ----- Reset the file list
+            unset($v_header_list);
+            $this->privSwapBackMagicQuotes();
+
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Swap back the file descriptor
+        $v_swap        = $this->zip_fd;
+        $this->zip_fd  = $v_zip_temp_fd;
+        $v_zip_temp_fd = $v_swap;
+
+        // ----- Close
+        $this->privCloseFd();
+
+        // ----- Close the temporary file
+        @fclose($v_zip_temp_fd);
+
+        // ----- Magic quotes trick
+        $this->privSwapBackMagicQuotes();
+
+        // ----- Delete the zip file
+        // TBC : I should test the result ...
+        @unlink($this->zipname);
+
+        // ----- Rename the temporary file
+        // TBC : I should test the result ...
+        //@rename($v_zip_temp_name, $this->zipname);
+        PclZipUtilRename($v_zip_temp_name, $this->zipname);
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privOpenFd()
+    // Description :
+    // Parameters :
+    // --------------------------------------------------------------------------------
+    public function privOpenFd($p_mode)
+    {
+        $v_result = 1;
+
+        // ----- Look if already open
+        if ($this->zip_fd != 0) {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \'' . $this->zipname . '\' already open');
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Open the zip file
+        if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in ' . $p_mode . ' mode');
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privCloseFd()
+    // Description :
+    // Parameters :
+    // --------------------------------------------------------------------------------
+    public function privCloseFd()
+    {
+        $v_result = 1;
+
+        if ($this->zip_fd != 0) {
+            @fclose($this->zip_fd);
+        }
+        $this->zip_fd = 0;
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privAddList()
+    // Description :
+    //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
+    //   different from the real path of the file. This is usefull if you want to have PclTar
+    //   running in any directory, and memorize relative path from an other directory.
+    // Parameters :
+    //   $p_list : An array containing the file or directory names to add in the tar
+    //   $p_result_list : list of added files with their properties (specially the status field)
+    //   $p_add_dir : Path to add in the filename path archived
+    //   $p_remove_dir : Path to remove in the filename path archived
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    //  function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
+    public function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
+    {
+        $v_result = 1;
+
+        // ----- Add the files
+        $v_header_list = array();
+        if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) {
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Store the offset of the central dir
+        $v_offset = @ftell($this->zip_fd);
+
+        // ----- Create the Central Dir files header
+        for ($i = 0, $v_count = 0; $i < sizeof($v_header_list); $i++) {
+            // ----- Create the file header
+            if ($v_header_list[$i]['status'] == 'ok') {
+                if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
+                    // ----- Return
+                    return $v_result;
+                }
+                $v_count++;
+            }
+
+            // ----- Transform the header to a 'usable' info
+            $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+        }
+
+        // ----- Zip file comment
+        $v_comment = '';
+        if (isset($p_options[PCLZIP_OPT_COMMENT])) {
+            $v_comment = $p_options[PCLZIP_OPT_COMMENT];
+        }
+
+        // ----- Calculate the size of the central header
+        $v_size = @ftell($this->zip_fd) - $v_offset;
+
+        // ----- Create the central dir footer
+        if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) {
+            // ----- Reset the file list
+            unset($v_header_list);
+
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privAddFileList()
+    // Description :
+    // Parameters :
+    //   $p_filedescr_list : An array containing the file description
+    //                      or directory names to add in the zip
+    //   $p_result_list : list of added files with their properties (specially the status field)
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
+    {
+        $v_result = 1;
+        $v_header = array();
+
+        // ----- Recuperate the current number of elt in list
+        $v_nb = sizeof($p_result_list);
+
+        // ----- Loop on the files
+        for ($j = 0; ($j < sizeof($p_filedescr_list)) && ($v_result == 1); $j++) {
+            // ----- Format the filename
+            $p_filedescr_list[$j]['filename'] = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
+
+            // ----- Skip empty file names
+            // TBC : Can this be possible ? not checked in DescrParseAtt ?
+            if ($p_filedescr_list[$j]['filename'] == "") {
+                continue;
+            }
+
+            // ----- Check the filename
+            if (($p_filedescr_list[$j]['type'] != 'virtual_file') && (!file_exists($p_filedescr_list[$j]['filename']))) {
+                PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '" . $p_filedescr_list[$j]['filename'] . "' does not exist");
+
+                return PclZip::errorCode();
+            }
+
+            // ----- Look if it is a file or a dir with no all path remove option
+            // or a dir with all its path removed
+            //      if (   (is_file($p_filedescr_list[$j]['filename']))
+            //          || (   is_dir($p_filedescr_list[$j]['filename'])
+            if (($p_filedescr_list[$j]['type'] == 'file') || ($p_filedescr_list[$j]['type'] == 'virtual_file') || (($p_filedescr_list[$j]['type'] == 'folder') && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
+
+                // ----- Add the file
+                $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, $p_options);
+                if ($v_result != 1) {
+                    return $v_result;
+                }
+
+                // ----- Store the file infos
+                $p_result_list[$v_nb++] = $v_header;
+            }
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privAddFile()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privAddFile($p_filedescr, &$p_header, &$p_options)
+    {
+        $v_result = 1;
+
+        // ----- Working variable
+        $p_filename = $p_filedescr['filename'];
+
+        // TBC : Already done in the fileAtt check ... ?
+        if ($p_filename == "") {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Look for a stored different filename
+        /* TBC : Removed
+        if (isset($p_filedescr['stored_filename'])) {
+        $v_stored_filename = $p_filedescr['stored_filename'];
+        } else {
+        $v_stored_filename = $p_filedescr['stored_filename'];
+        }
+        */
+
+        // ----- Set the file properties
+        clearstatcache();
+        $p_header['version']           = 20;
+        $p_header['version_extracted'] = 10;
+        $p_header['flag']              = 0;
+        $p_header['compression']       = 0;
+        $p_header['crc']               = 0;
+        $p_header['compressed_size']   = 0;
+        $p_header['filename_len']      = strlen($p_filename);
+        $p_header['extra_len']         = 0;
+        $p_header['disk']              = 0;
+        $p_header['internal']          = 0;
+        $p_header['offset']            = 0;
+        $p_header['filename']          = $p_filename;
+        // TBC : Removed    $p_header['stored_filename'] = $v_stored_filename;
+        $p_header['stored_filename']   = $p_filedescr['stored_filename'];
+        $p_header['extra']             = '';
+        $p_header['status']            = 'ok';
+        $p_header['index']             = -1;
+
+        // ----- Look for regular file
+        if ($p_filedescr['type'] == 'file') {
+            $p_header['external'] = 0x00000000;
+            $p_header['size']     = filesize($p_filename);
+
+        // ----- Look for regular folder
+        } elseif ($p_filedescr['type'] == 'folder') {
+            $p_header['external'] = 0x00000010;
+            $p_header['mtime']    = filemtime($p_filename);
+            $p_header['size']     = filesize($p_filename);
+
+        // ----- Look for virtual file
+        } elseif ($p_filedescr['type'] == 'virtual_file') {
+            $p_header['external'] = 0x00000000;
+            $p_header['size']     = strlen($p_filedescr['content']);
+        }
+
+        // ----- Look for filetime
+        if (isset($p_filedescr['mtime'])) {
+            $p_header['mtime'] = $p_filedescr['mtime'];
+        } elseif ($p_filedescr['type'] == 'virtual_file') {
+            $p_header['mtime'] = time();
+        } else {
+            $p_header['mtime'] = filemtime($p_filename);
+        }
+
+        // ------ Look for file comment
+        if (isset($p_filedescr['comment'])) {
+            $p_header['comment_len'] = strlen($p_filedescr['comment']);
+            $p_header['comment']     = $p_filedescr['comment'];
+        } else {
+            $p_header['comment_len'] = 0;
+            $p_header['comment']     = '';
+        }
+
+        // ----- Look for pre-add callback
+        if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
+
+            // ----- Generate a local information
+            $v_local_header = array();
+            $this->privConvertHeader2FileInfo($p_header, $v_local_header);
+
+            // ----- Call the callback
+            // Here I do not use call_user_func() because I need to send a reference to the
+            // header.
+            //      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
+            $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
+            if ($v_result == 0) {
+                // ----- Change the file status
+                $p_header['status'] = "skipped";
+                $v_result           = 1;
+            }
+
+            // ----- Update the informations
+            // Only some fields can be modified
+            if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
+                $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
+            }
+        }
+
+        // ----- Look for empty stored filename
+        if ($p_header['stored_filename'] == "") {
+            $p_header['status'] = "filtered";
+        }
+
+        // ----- Check the path length
+        if (strlen($p_header['stored_filename']) > 0xFF) {
+            $p_header['status'] = 'filename_too_long';
+        }
+
+        // ----- Look if no error, or file not skipped
+        if ($p_header['status'] == 'ok') {
+
+            // ----- Look for a file
+            if ($p_filedescr['type'] == 'file') {
+                // ----- Look for using temporary file to zip
+                if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])))) {
+                    $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
+                    if ($v_result < PCLZIP_ERR_NO_ERROR) {
+                        return $v_result;
+                    }
+
+                // ----- Use "in memory" zip algo
+                } else {
+
+                    // ----- Open the source file
+                    if (($v_file = @fopen($p_filename, "rb")) == 0) {
+                        PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
+
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Read the file content
+                    $v_content = @fread($v_file, $p_header['size']);
+
+                    // ----- Close the file
+                    @fclose($v_file);
+
+                    // ----- Calculate the CRC
+                    $p_header['crc'] = @crc32($v_content);
+
+                    // ----- Look for no compression
+                    if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
+                        // ----- Set header parameters
+                        $p_header['compressed_size'] = $p_header['size'];
+                        $p_header['compression']     = 0;
+
+                    // ----- Look for normal compression
+                    } else {
+                        // ----- Compress the content
+                        $v_content = @gzdeflate($v_content);
+
+                        // ----- Set header parameters
+                        $p_header['compressed_size'] = strlen($v_content);
+                        $p_header['compression']     = 8;
+                    }
+
+                    // ----- Call the header generation
+                    if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
+                        @fclose($v_file);
+
+                        return $v_result;
+                    }
+
+                    // ----- Write the compressed (or not) content
+                    @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
+
+                }
+
+            // ----- Look for a virtual file (a file from string)
+            } elseif ($p_filedescr['type'] == 'virtual_file') {
+
+                $v_content = $p_filedescr['content'];
+
+                // ----- Calculate the CRC
+                $p_header['crc'] = @crc32($v_content);
+
+                // ----- Look for no compression
+                if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
+                    // ----- Set header parameters
+                    $p_header['compressed_size'] = $p_header['size'];
+                    $p_header['compression']     = 0;
+
+                // ----- Look for normal compression
+                } else {
+                    // ----- Compress the content
+                    $v_content = @gzdeflate($v_content);
+
+                    // ----- Set header parameters
+                    $p_header['compressed_size'] = strlen($v_content);
+                    $p_header['compression']     = 8;
+                }
+
+                // ----- Call the header generation
+                if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
+                    @fclose($v_file);
+
+                    return $v_result;
+                }
+
+                // ----- Write the compressed (or not) content
+                @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
+
+            // ----- Look for a directory
+            } elseif ($p_filedescr['type'] == 'folder') {
+                // ----- Look for directory last '/'
+                if (@substr($p_header['stored_filename'], -1) != '/') {
+                    $p_header['stored_filename'] .= '/';
+                }
+
+                // ----- Set the file properties
+                $p_header['size']     = 0;
+                //$p_header['external'] = 0x41FF0010;   // Value for a folder : to be checked
+                $p_header['external'] = 0x00000010; // Value for a folder : to be checked
+
+                // ----- Call the header generation
+                if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
+                    return $v_result;
+                }
+            }
+        }
+
+        // ----- Look for post-add callback
+        if (isset($p_options[PCLZIP_CB_POST_ADD])) {
+
+            // ----- Generate a local information
+            $v_local_header = array();
+            $this->privConvertHeader2FileInfo($p_header, $v_local_header);
+
+            // ----- Call the callback
+            // Here I do not use call_user_func() because I need to send a reference to the
+            // header.
+            //      eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
+            $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
+            if ($v_result == 0) {
+                // ----- Ignored
+                $v_result = 1;
+            }
+
+            // ----- Update the informations
+            // Nothing can be modified
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privAddFileUsingTempFile()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
+    {
+        $v_result = PCLZIP_ERR_NO_ERROR;
+
+        // ----- Working variable
+        $p_filename = $p_filedescr['filename'];
+
+        // ----- Open the source file
+        if (($v_file = @fopen($p_filename, "rb")) == 0) {
+            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
+
+            return PclZip::errorCode();
+        }
+
+        // ----- Creates a compressed temporary file
+        $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.gz';
+        if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
+            fclose($v_file);
+            PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary write mode');
+
+            return PclZip::errorCode();
+        }
+
+        // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
+        $v_size = filesize($p_filename);
+        while ($v_size != 0) {
+            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = @fread($v_file, $v_read_size);
+            //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
+            @gzputs($v_file_compressed, $v_buffer, $v_read_size);
+            $v_size -= $v_read_size;
+        }
+
+        // ----- Close the file
+        @fclose($v_file);
+        @gzclose($v_file_compressed);
+
+        // ----- Check the minimum file size
+        if (filesize($v_gzip_temp_name) < 18) {
+            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \'' . $v_gzip_temp_name . '\' has invalid filesize - should be minimum 18 bytes');
+
+            return PclZip::errorCode();
+        }
+
+        // ----- Extract the compressed attributes
+        if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
+            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary read mode');
+
+            return PclZip::errorCode();
+        }
+
+        // ----- Read the gzip file header
+        $v_binary_data = @fread($v_file_compressed, 10);
+        $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
+
+        // ----- Check some parameters
+        $v_data_header['os'] = bin2hex($v_data_header['os']);
+
+        // ----- Read the gzip file footer
+        @fseek($v_file_compressed, filesize($v_gzip_temp_name) - 8);
+        $v_binary_data = @fread($v_file_compressed, 8);
+        $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
+
+        // ----- Set the attributes
+        $p_header['compression']     = ord($v_data_header['cm']);
+        //$p_header['mtime'] = $v_data_header['mtime'];
+        $p_header['crc']             = $v_data_footer['crc'];
+        $p_header['compressed_size'] = filesize($v_gzip_temp_name) - 18;
+
+        // ----- Close the file
+        @fclose($v_file_compressed);
+
+        // ----- Call the header generation
+        if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
+            return $v_result;
+        }
+
+        // ----- Add the compressed data
+        if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
+            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary read mode');
+
+            return PclZip::errorCode();
+        }
+
+        // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
+        fseek($v_file_compressed, 10);
+        $v_size = $p_header['compressed_size'];
+        while ($v_size != 0) {
+            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = @fread($v_file_compressed, $v_read_size);
+            //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
+            @fwrite($this->zip_fd, $v_buffer, $v_read_size);
+            $v_size -= $v_read_size;
+        }
+
+        // ----- Close the file
+        @fclose($v_file_compressed);
+
+        // ----- Unlink the temporary file
+        @unlink($v_gzip_temp_name);
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privCalculateStoredFilename()
+    // Description :
+    //   Based on file descriptor properties and global options, this method
+    //   calculate the filename that will be stored in the archive.
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privCalculateStoredFilename(&$p_filedescr, &$p_options)
+    {
+        $v_result = 1;
+
+        // ----- Working variables
+        $p_filename = $p_filedescr['filename'];
+        if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
+            $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
+        } else {
+            $p_add_dir = '';
+        }
+        if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
+            $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
+        } else {
+            $p_remove_dir = '';
+        }
+        if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
+            $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
+        } else {
+            $p_remove_all_dir = 0;
+        }
+
+        // ----- Look for full name change
+        if (isset($p_filedescr['new_full_name'])) {
+            // ----- Remove drive letter if any
+            $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
+
+        // ----- Look for path and/or short name change
+        } else {
+
+            // ----- Look for short name change
+            // Its when we cahnge just the filename but not the path
+            if (isset($p_filedescr['new_short_name'])) {
+                $v_path_info = pathinfo($p_filename);
+                $v_dir       = '';
+                if ($v_path_info['dirname'] != '') {
+                    $v_dir = $v_path_info['dirname'] . '/';
+                }
+                $v_stored_filename = $v_dir . $p_filedescr['new_short_name'];
+            } else {
+                // ----- Calculate the stored filename
+                $v_stored_filename = $p_filename;
+            }
+
+            // ----- Look for all path to remove
+            if ($p_remove_all_dir) {
+                $v_stored_filename = basename($p_filename);
+
+            // ----- Look for partial path remove
+            } elseif ($p_remove_dir != "") {
+                if (substr($p_remove_dir, -1) != '/') {
+                    $p_remove_dir .= "/";
+                }
+
+                if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./")) {
+
+                    if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./")) {
+                        $p_remove_dir = "./" . $p_remove_dir;
+                    }
+                    if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./")) {
+                        $p_remove_dir = substr($p_remove_dir, 2);
+                    }
+                }
+
+                $v_compare = PclZipUtilPathInclusion($p_remove_dir, $v_stored_filename);
+                if ($v_compare > 0) {
+                    if ($v_compare == 2) {
+                        $v_stored_filename = "";
+                    } else {
+                        $v_stored_filename = substr($v_stored_filename, strlen($p_remove_dir));
+                    }
+                }
+            }
+
+            // ----- Remove drive letter if any
+            $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
+
+            // ----- Look for path to add
+            if ($p_add_dir != "") {
+                if (substr($p_add_dir, -1) == "/") {
+                    $v_stored_filename = $p_add_dir . $v_stored_filename;
+                } else {
+                    $v_stored_filename = $p_add_dir . "/" . $v_stored_filename;
+                }
+            }
+        }
+
+        // ----- Filename (reduce the path of stored name)
+        $v_stored_filename              = PclZipUtilPathReduction($v_stored_filename);
+        $p_filedescr['stored_filename'] = $v_stored_filename;
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privWriteFileHeader()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privWriteFileHeader(&$p_header)
+    {
+        $v_result = 1;
+
+        // ----- Store the offset position of the file
+        $p_header['offset'] = ftell($this->zip_fd);
+
+        // ----- Transform UNIX mtime to DOS format mdate/mtime
+        $v_date  = getdate($p_header['mtime']);
+        $v_mtime = ($v_date['hours'] << 11) + ($v_date['minutes'] << 5) + $v_date['seconds'] / 2;
+        $v_mdate = (($v_date['year'] - 1980) << 9) + ($v_date['mon'] << 5) + $v_date['mday'];
+
+        // ----- Packed data
+        $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, $p_header['version_extracted'], $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], $p_header['compressed_size'], $p_header['size'], strlen($p_header['stored_filename']), $p_header['extra_len']);
+
+        // ----- Write the first 148 bytes of the header in the archive
+        fputs($this->zip_fd, $v_binary_data, 30);
+
+        // ----- Write the variable fields
+        if (strlen($p_header['stored_filename']) != 0) {
+            fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
+        }
+        if ($p_header['extra_len'] != 0) {
+            fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privWriteCentralFileHeader()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privWriteCentralFileHeader(&$p_header)
+    {
+        $v_result = 1;
+
+        // TBC
+        //for (reset($p_header); $key = key($p_header); next($p_header)) {
+        //}
+
+        // ----- Transform UNIX mtime to DOS format mdate/mtime
+        $v_date  = getdate($p_header['mtime']);
+        $v_mtime = ($v_date['hours'] << 11) + ($v_date['minutes'] << 5) + $v_date['seconds'] / 2;
+        $v_mdate = (($v_date['year'] - 1980) << 9) + ($v_date['mon'] << 5) + $v_date['mday'];
+
+        // ----- Packed data
+        $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, $p_header['version'], $p_header['version_extracted'], $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], $p_header['compressed_size'], $p_header['size'], strlen($p_header['stored_filename']), $p_header['extra_len'], $p_header['comment_len'], $p_header['disk'], $p_header['internal'], $p_header['external'], $p_header['offset']);
+
+        // ----- Write the 42 bytes of the header in the zip file
+        fputs($this->zip_fd, $v_binary_data, 46);
+
+        // ----- Write the variable fields
+        if (strlen($p_header['stored_filename']) != 0) {
+            fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
+        }
+        if ($p_header['extra_len'] != 0) {
+            fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
+        }
+        if ($p_header['comment_len'] != 0) {
+            fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privWriteCentralHeader()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
+    {
+        $v_result = 1;
+
+        // ----- Packed data
+        $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, $p_nb_entries, $p_size, $p_offset, strlen($p_comment));
+
+        // ----- Write the 22 bytes of the header in the zip file
+        fputs($this->zip_fd, $v_binary_data, 22);
+
+        // ----- Write the variable fields
+        if (strlen($p_comment) != 0) {
+            fputs($this->zip_fd, $p_comment, strlen($p_comment));
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privList()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privList(&$p_list)
+    {
+        $v_result = 1;
+
+        // ----- Magic quotes trick
+        $this->privDisableMagicQuotes();
+
+        // ----- Open the zip file
+        if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) {
+            // ----- Magic quotes trick
+            $this->privSwapBackMagicQuotes();
+
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in binary read mode');
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Read the central directory informations
+        $v_central_dir = array();
+        if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
+            $this->privSwapBackMagicQuotes();
+
+            return $v_result;
+        }
+
+        // ----- Go to beginning of Central Dir
+        @rewind($this->zip_fd);
+        if (@fseek($this->zip_fd, $v_central_dir['offset'])) {
+            $this->privSwapBackMagicQuotes();
+
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Read each entry
+        for ($i = 0; $i < $v_central_dir['entries']; $i++) {
+            // ----- Read the file header
+            if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) {
+                $this->privSwapBackMagicQuotes();
+
+                return $v_result;
+            }
+            $v_header['index'] = $i;
+
+            // ----- Get the only interesting attributes
+            $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
+            unset($v_header);
+        }
+
+        // ----- Close the zip file
+        $this->privCloseFd();
+
+        // ----- Magic quotes trick
+        $this->privSwapBackMagicQuotes();
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privConvertHeader2FileInfo()
+    // Description :
+    //   This function takes the file informations from the central directory
+    //   entries and extract the interesting parameters that will be given back.
+    //   The resulting file infos are set in the array $p_info
+    //     $p_info['filename'] : Filename with full path. Given by user (add),
+    //                           extracted in the filesystem (extract).
+    //     $p_info['stored_filename'] : Stored filename in the archive.
+    //     $p_info['size'] = Size of the file.
+    //     $p_info['compressed_size'] = Compressed size of the file.
+    //     $p_info['mtime'] = Last modification date of the file.
+    //     $p_info['comment'] = Comment associated with the file.
+    //     $p_info['folder'] = true/false : indicates if the entry is a folder or not.
+    //     $p_info['status'] = status of the action on the file.
+    //     $p_info['crc'] = CRC of the file content.
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privConvertHeader2FileInfo($p_header, &$p_info)
+    {
+        $v_result = 1;
+
+        // ----- Get the interesting attributes
+        $v_temp_path               = PclZipUtilPathReduction($p_header['filename']);
+        $p_info['filename']        = $v_temp_path;
+        $v_temp_path               = PclZipUtilPathReduction($p_header['stored_filename']);
+        $p_info['stored_filename'] = $v_temp_path;
+        $p_info['size']            = $p_header['size'];
+        $p_info['compressed_size'] = $p_header['compressed_size'];
+        $p_info['mtime']           = $p_header['mtime'];
+        $p_info['comment']         = $p_header['comment'];
+        $p_info['folder']          = (($p_header['external'] & 0x00000010) == 0x00000010);
+        $p_info['index']           = $p_header['index'];
+        $p_info['status']          = $p_header['status'];
+        $p_info['crc']             = $p_header['crc'];
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privExtractByRule()
+    // Description :
+    //   Extract a file or directory depending of rules (by index, by name, ...)
+    // Parameters :
+    //   $p_file_list : An array where will be placed the properties of each
+    //                  extracted file
+    //   $p_path : Path to add while writing the extracted files
+    //   $p_remove_path : Path to remove (from the file memorized path) while writing the
+    //                    extracted files. If the path does not match the file path,
+    //                    the file is extracted with its memorized path.
+    //                    $p_remove_path does not apply to 'list' mode.
+    //                    $p_path and $p_remove_path are commulative.
+    // Return Values :
+    //   1 on success,0 or less on error (see error code list)
+    // --------------------------------------------------------------------------------
+    public function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
+    {
+        $v_result = 1;
+
+        // ----- Magic quotes trick
+        $this->privDisableMagicQuotes();
+
+        // ----- Check the path
+        if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path, 1, 2) != ":/"))) {
+            $p_path = "./" . $p_path;
+        }
+
+        // ----- Reduce the path last (and duplicated) '/'
+        if (($p_path != "./") && ($p_path != "/")) {
+            // ----- Look for the path end '/'
+            while (substr($p_path, -1) == "/") {
+                $p_path = substr($p_path, 0, strlen($p_path) - 1);
+            }
+        }
+
+        // ----- Look for path to remove format (should end by /)
+        if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) {
+            $p_remove_path .= '/';
+        }
+        $p_remove_path_size = strlen($p_remove_path);
+
+        // ----- Open the zip file
+        if (($v_result = $this->privOpenFd('rb')) != 1) {
+            $this->privSwapBackMagicQuotes();
+
+            return $v_result;
+        }
+
+        // ----- Read the central directory informations
+        $v_central_dir = array();
+        if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
+            // ----- Close the zip file
+            $this->privCloseFd();
+            $this->privSwapBackMagicQuotes();
+
+            return $v_result;
+        }
+
+        // ----- Start at beginning of Central Dir
+        $v_pos_entry = $v_central_dir['offset'];
+
+        // ----- Read each entry
+        $j_start = 0;
+        for ($i = 0, $v_nb_extracted = 0; $i < $v_central_dir['entries']; $i++) {
+
+            // ----- Read next Central dir entry
+            @rewind($this->zip_fd);
+            if (@fseek($this->zip_fd, $v_pos_entry)) {
+                // ----- Close the zip file
+                $this->privCloseFd();
+                $this->privSwapBackMagicQuotes();
+
+                // ----- Error log
+                PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+                // ----- Return
+                return PclZip::errorCode();
+            }
+
+            // ----- Read the file header
+            $v_header = array();
+            if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) {
+                // ----- Close the zip file
+                $this->privCloseFd();
+                $this->privSwapBackMagicQuotes();
+
+                return $v_result;
+            }
+
+            // ----- Store the index
+            $v_header['index'] = $i;
+
+            // ----- Store the file position
+            $v_pos_entry = ftell($this->zip_fd);
+
+            // ----- Look for the specific extract rules
+            $v_extract = false;
+
+            // ----- Look for extract by name rule
+            if ((isset($p_options[PCLZIP_OPT_BY_NAME])) && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
+
+                // ----- Look if the filename is in the list
+                for ($j = 0; ($j < sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
+
+                    // ----- Look for a directory
+                    if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
+
+                        // ----- Look if the directory is in the filename path
+                        if ((strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+                            $v_extract = true;
+                        }
+
+                    // ----- Look for a filename
+                    } elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
+                        $v_extract = true;
+                    }
+                }
+            // ----- Look for extract by ereg rule
+            // ereg() is deprecated with PHP 5.3
+            /*
+            elseif (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
+            && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
+
+            if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
+            $v_extract = true;
+            }
+            }
+            */
+
+            // ----- Look for extract by preg rule
+            } elseif ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
+
+                if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
+                    $v_extract = true;
+                }
+
+            // ----- Look for extract by index rule
+            } elseif ((isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
+
+                // ----- Look if the index is in the list
+                for ($j = $j_start; ($j < sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
+
+                    if (($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i <= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
+                        $v_extract = true;
+                    }
+                    if ($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
+                        $j_start = $j + 1;
+                    }
+
+                    if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start'] > $i) {
+                        break;
+                    }
+                }
+
+            // ----- Look for no rule, which means extract all the archive
+            } else {
+                $v_extract = true;
+            }
+
+            // ----- Check compression method
+            if (($v_extract) && (($v_header['compression'] != 8) && ($v_header['compression'] != 0))) {
+                $v_header['status'] = 'unsupported_compression';
+
+                // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+                if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) {
+
+                    $this->privSwapBackMagicQuotes();
+
+                    PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, "Filename '" . $v_header['stored_filename'] . "' is " . "compressed by an unsupported compression " . "method (" . $v_header['compression'] . ") ");
+
+                    return PclZip::errorCode();
+                }
+            }
+
+            // ----- Check encrypted files
+            if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
+                $v_header['status'] = 'unsupported_encryption';
+
+                // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+                if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) {
+
+                    $this->privSwapBackMagicQuotes();
+
+                    PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, "Unsupported encryption for " . " filename '" . $v_header['stored_filename'] . "'");
+
+                    return PclZip::errorCode();
+                }
+            }
+
+            // ----- Look for real extraction
+            if (($v_extract) && ($v_header['status'] != 'ok')) {
+                $v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++]);
+                if ($v_result != 1) {
+                    $this->privCloseFd();
+                    $this->privSwapBackMagicQuotes();
+
+                    return $v_result;
+                }
+
+                $v_extract = false;
+            }
+
+            // ----- Look for real extraction
+            if ($v_extract) {
+
+                // ----- Go to the file position
+                @rewind($this->zip_fd);
+                if (@fseek($this->zip_fd, $v_header['offset'])) {
+                    // ----- Close the zip file
+                    $this->privCloseFd();
+
+                    $this->privSwapBackMagicQuotes();
+
+                    // ----- Error log
+                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+                    // ----- Return
+                    return PclZip::errorCode();
+                }
+
+                // ----- Look for extraction as string
+                if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
+
+                    $v_string = '';
+
+                    // ----- Extracting the file
+                    $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
+                    if ($v_result1 < 1) {
+                        $this->privCloseFd();
+                        $this->privSwapBackMagicQuotes();
+
+                        return $v_result1;
+                    }
+
+                    // ----- Get the only interesting attributes
+                    if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) {
+                        // ----- Close the zip file
+                        $this->privCloseFd();
+                        $this->privSwapBackMagicQuotes();
+
+                        return $v_result;
+                    }
+
+                    // ----- Set the file content
+                    $p_file_list[$v_nb_extracted]['content'] = $v_string;
+
+                    // ----- Next extracted file
+                    $v_nb_extracted++;
+
+                    // ----- Look for user callback abort
+                    if ($v_result1 == 2) {
+                        break;
+                    }
+
+                // ----- Look for extraction in standard output
+                } elseif ((isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
+                    // ----- Extracting the file in standard output
+                    $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
+                    if ($v_result1 < 1) {
+                        $this->privCloseFd();
+                        $this->privSwapBackMagicQuotes();
+
+                        return $v_result1;
+                    }
+
+                    // ----- Get the only interesting attributes
+                    if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
+                        $this->privCloseFd();
+                        $this->privSwapBackMagicQuotes();
+
+                        return $v_result;
+                    }
+
+                    // ----- Look for user callback abort
+                    if ($v_result1 == 2) {
+                        break;
+                    }
+
+                // ----- Look for normal extraction
+                } else {
+                    // ----- Extracting the file
+                    $v_result1 = $this->privExtractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_options);
+                    if ($v_result1 < 1) {
+                        $this->privCloseFd();
+                        $this->privSwapBackMagicQuotes();
+
+                        return $v_result1;
+                    }
+
+                    // ----- Get the only interesting attributes
+                    if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
+                        // ----- Close the zip file
+                        $this->privCloseFd();
+                        $this->privSwapBackMagicQuotes();
+
+                        return $v_result;
+                    }
+
+                    // ----- Look for user callback abort
+                    if ($v_result1 == 2) {
+                        break;
+                    }
+                }
+            }
+        }
+
+        // ----- Close the zip file
+        $this->privCloseFd();
+        $this->privSwapBackMagicQuotes();
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privExtractFile()
+    // Description :
+    // Parameters :
+    // Return Values :
+    //
+    // 1 : ... ?
+    // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
+    // --------------------------------------------------------------------------------
+    public function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
+    {
+        $v_result = 1;
+
+        // ----- Read the file header
+        if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Check that the file header is coherent with $p_entry info
+        if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
+            // TBC
+        }
+
+        // ----- Look for all path to remove
+        if ($p_remove_all_path == true) {
+            // ----- Look for folder entry that not need to be extracted
+            if (($p_entry['external'] & 0x00000010) == 0x00000010) {
+
+                $p_entry['status'] = "filtered";
+
+                return $v_result;
+            }
+
+            // ----- Get the basename of the path
+            $p_entry['filename'] = basename($p_entry['filename']);
+
+        // ----- Look for path to remove
+        } elseif ($p_remove_path != "") {
+            if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) {
+
+                // ----- Change the file status
+                $p_entry['status'] = "filtered";
+
+                // ----- Return
+                return $v_result;
+            }
+
+            $p_remove_path_size = strlen($p_remove_path);
+            if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) {
+
+                // ----- Remove the path
+                $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
+
+            }
+        }
+
+        // ----- Add the path
+        if ($p_path != '') {
+            $p_entry['filename'] = $p_path . "/" . $p_entry['filename'];
+        }
+
+        // ----- Check a base_dir_restriction
+        if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
+            $v_inclusion = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], $p_entry['filename']);
+            if ($v_inclusion == 0) {
+
+                PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, "Filename '" . $p_entry['filename'] . "' is " . "outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
+
+                return PclZip::errorCode();
+            }
+        }
+
+        // ----- Look for pre-extract callback
+        if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
+
+            // ----- Generate a local information
+            $v_local_header = array();
+            $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+            // ----- Call the callback
+            // Here I do not use call_user_func() because I need to send a reference to the
+            // header.
+            //      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
+            $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
+            if ($v_result == 0) {
+                // ----- Change the file status
+                $p_entry['status'] = "skipped";
+                $v_result          = 1;
+            }
+
+            // ----- Look for abort result
+            if ($v_result == 2) {
+                // ----- This status is internal and will be changed in 'skipped'
+                $p_entry['status'] = "aborted";
+                $v_result          = PCLZIP_ERR_USER_ABORTED;
+            }
+
+            // ----- Update the informations
+            // Only some fields can be modified
+            $p_entry['filename'] = $v_local_header['filename'];
+        }
+
+        // ----- Look if extraction should be done
+        if ($p_entry['status'] == 'ok') {
+
+            // ----- Look for specific actions while the file exist
+            if (file_exists($p_entry['filename'])) {
+
+                // ----- Look if file is a directory
+                if (is_dir($p_entry['filename'])) {
+
+                    // ----- Change the file status
+                    $p_entry['status'] = "already_a_directory";
+
+                    // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+                    // For historical reason first PclZip implementation does not stop
+                    // when this kind of error occurs.
+                    if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) {
+
+                        PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, "Filename '" . $p_entry['filename'] . "' is " . "already used by an existing directory");
+
+                        return PclZip::errorCode();
+                    }
+
+                // ----- Look if file is write protected
+                } elseif (!is_writeable($p_entry['filename'])) {
+
+                    // ----- Change the file status
+                    $p_entry['status'] = "write_protected";
+
+                    // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+                    // For historical reason first PclZip implementation does not stop
+                    // when this kind of error occurs.
+                    if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) {
+
+                        PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Filename '" . $p_entry['filename'] . "' exists " . "and is write protected");
+
+                        return PclZip::errorCode();
+                    }
+
+                // ----- Look if the extracted file is older
+                } elseif (filemtime($p_entry['filename']) > $p_entry['mtime']) {
+                    // ----- Change the file status
+                    if ((isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) && ($p_options[PCLZIP_OPT_REPLACE_NEWER] === true)) {
+                    } else {
+                        $p_entry['status'] = "newer_exist";
+
+                        // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+                        // For historical reason first PclZip implementation does not stop
+                        // when this kind of error occurs.
+                        if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)) {
+
+                            PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Newer version of '" . $p_entry['filename'] . "' exists " . "and option PCLZIP_OPT_REPLACE_NEWER is not selected");
+
+                            return PclZip::errorCode();
+                        }
+                    }
+                } else {
+                }
+
+            // ----- Check the directory availability and create it if necessary
+            } else {
+                if ((($p_entry['external'] & 0x00000010) == 0x00000010) || (substr($p_entry['filename'], -1) == '/')) {
+                    $v_dir_to_check = $p_entry['filename'];
+                } elseif (!strstr($p_entry['filename'], "/")) {
+                    $v_dir_to_check = "";
+                } else {
+                    $v_dir_to_check = dirname($p_entry['filename']);
+                }
+
+                if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external'] & 0x00000010) == 0x00000010))) != 1) {
+
+                    // ----- Change the file status
+                    $p_entry['status'] = "path_creation_fail";
+
+                    // ----- Return
+                    //return $v_result;
+                    $v_result = 1;
+                }
+            }
+        }
+
+        // ----- Look if extraction should be done
+        if ($p_entry['status'] == 'ok') {
+
+            // ----- Do the extraction (if not a folder)
+            if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) {
+                // ----- Look for not compressed file
+                if ($p_entry['compression'] == 0) {
+
+                    // ----- Opening destination file
+                    if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
+
+                        // ----- Change the file status
+                        $p_entry['status'] = "write_error";
+
+                        // ----- Return
+                        return $v_result;
+                    }
+
+                    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
+                    $v_size = $p_entry['compressed_size'];
+                    while ($v_size != 0) {
+                        $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+                        $v_buffer    = @fread($this->zip_fd, $v_read_size);
+                        /* Try to speed up the code
+                        $v_binary_data = pack('a'.$v_read_size, $v_buffer);
+                        @fwrite($v_dest_file, $v_binary_data, $v_read_size);
+                        */
+                        @fwrite($v_dest_file, $v_buffer, $v_read_size);
+                        $v_size -= $v_read_size;
+                    }
+
+                    // ----- Closing the destination file
+                    fclose($v_dest_file);
+
+                    // ----- Change the file mtime
+                    touch($p_entry['filename'], $p_entry['mtime']);
+
+                } else {
+                    // ----- TBC
+                    // Need to be finished
+                    if (($p_entry['flag'] & 1) == 1) {
+                        PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \'' . $p_entry['filename'] . '\' is encrypted. Encrypted files are not supported.');
+
+                        return PclZip::errorCode();
+                    }
+
+                    // ----- Look for using temporary file to unzip
+                    if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])))) {
+                        $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
+                        if ($v_result < PCLZIP_ERR_NO_ERROR) {
+                            return $v_result;
+                        }
+
+                    // ----- Look for extract in memory
+                    } else {
+
+                        // ----- Read the compressed file in a buffer (one shot)
+                        $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
+
+                        // ----- Decompress the file
+                        $v_file_content = @gzinflate($v_buffer);
+                        unset($v_buffer);
+                        if ($v_file_content === false) {
+
+                            // ----- Change the file status
+                            // TBC
+                            $p_entry['status'] = "error";
+
+                            return $v_result;
+                        }
+
+                        // ----- Opening destination file
+                        if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
+
+                            // ----- Change the file status
+                            $p_entry['status'] = "write_error";
+
+                            return $v_result;
+                        }
+
+                        // ----- Write the uncompressed data
+                        @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
+                        unset($v_file_content);
+
+                        // ----- Closing the destination file
+                        @fclose($v_dest_file);
+
+                    }
+
+                    // ----- Change the file mtime
+                    @touch($p_entry['filename'], $p_entry['mtime']);
+                }
+
+                // ----- Look for chmod option
+                if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
+
+                    // ----- Change the mode of the file
+                    @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
+                }
+
+            }
+        }
+
+        // ----- Change abort status
+        if ($p_entry['status'] == "aborted") {
+            $p_entry['status'] = "skipped";
+
+        // ----- Look for post-extract callback
+        } elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
+
+            // ----- Generate a local information
+            $v_local_header = array();
+            $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+            // ----- Call the callback
+            // Here I do not use call_user_func() because I need to send a reference to the
+            // header.
+            //      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
+            $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
+
+            // ----- Look for abort result
+            if ($v_result == 2) {
+                $v_result = PCLZIP_ERR_USER_ABORTED;
+            }
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privExtractFileUsingTempFile()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privExtractFileUsingTempFile(&$p_entry, &$p_options)
+    {
+        $v_result = 1;
+
+        // ----- Creates a temporary file
+        $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.gz';
+        if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
+            fclose($v_file);
+            PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary write mode');
+
+            return PclZip::errorCode();
+        }
+
+        // ----- Write gz file format header
+        $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
+        @fwrite($v_dest_file, $v_binary_data, 10);
+
+        // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
+        $v_size = $p_entry['compressed_size'];
+        while ($v_size != 0) {
+            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = @fread($this->zip_fd, $v_read_size);
+            //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
+            @fwrite($v_dest_file, $v_buffer, $v_read_size);
+            $v_size -= $v_read_size;
+        }
+
+        // ----- Write gz file format footer
+        $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
+        @fwrite($v_dest_file, $v_binary_data, 8);
+
+        // ----- Close the temporary file
+        @fclose($v_dest_file);
+
+        // ----- Opening destination file
+        if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
+            $p_entry['status'] = "write_error";
+
+            return $v_result;
+        }
+
+        // ----- Open the temporary gz file
+        if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
+            @fclose($v_dest_file);
+            $p_entry['status'] = "read_error";
+            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary read mode');
+
+            return PclZip::errorCode();
+        }
+
+        // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
+        $v_size = $p_entry['size'];
+        while ($v_size != 0) {
+            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = @gzread($v_src_file, $v_read_size);
+            //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
+            @fwrite($v_dest_file, $v_buffer, $v_read_size);
+            $v_size -= $v_read_size;
+        }
+        @fclose($v_dest_file);
+        @gzclose($v_src_file);
+
+        // ----- Delete the temporary file
+        @unlink($v_gzip_temp_name);
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privExtractFileInOutput()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privExtractFileInOutput(&$p_entry, &$p_options)
+    {
+        $v_result = 1;
+
+        // ----- Read the file header
+        if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
+            return $v_result;
+        }
+
+        // ----- Check that the file header is coherent with $p_entry info
+        if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
+            // TBC
+        }
+
+        // ----- Look for pre-extract callback
+        if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
+
+            // ----- Generate a local information
+            $v_local_header = array();
+            $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+            // ----- Call the callback
+            // Here I do not use call_user_func() because I need to send a reference to the
+            // header.
+            //      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
+            $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
+            if ($v_result == 0) {
+                // ----- Change the file status
+                $p_entry['status'] = "skipped";
+                $v_result          = 1;
+            }
+
+            // ----- Look for abort result
+            if ($v_result == 2) {
+                // ----- This status is internal and will be changed in 'skipped'
+                $p_entry['status'] = "aborted";
+                $v_result          = PCLZIP_ERR_USER_ABORTED;
+            }
+
+            // ----- Update the informations
+            // Only some fields can be modified
+            $p_entry['filename'] = $v_local_header['filename'];
+        }
+
+        // ----- Trace
+
+        // ----- Look if extraction should be done
+        if ($p_entry['status'] == 'ok') {
+
+            // ----- Do the extraction (if not a folder)
+            if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) {
+                // ----- Look for not compressed file
+                if ($p_entry['compressed_size'] == $p_entry['size']) {
+
+                    // ----- Read the file in a buffer (one shot)
+                    $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
+
+                    // ----- Send the file to the output
+                    echo $v_buffer;
+                    unset($v_buffer);
+                } else {
+
+                    // ----- Read the compressed file in a buffer (one shot)
+                    $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
+
+                    // ----- Decompress the file
+                    $v_file_content = gzinflate($v_buffer);
+                    unset($v_buffer);
+
+                    // ----- Send the file to the output
+                    echo $v_file_content;
+                    unset($v_file_content);
+                }
+            }
+        }
+
+        // ----- Change abort status
+        if ($p_entry['status'] == "aborted") {
+            $p_entry['status'] = "skipped";
+
+        // ----- Look for post-extract callback
+        } elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
+
+            // ----- Generate a local information
+            $v_local_header = array();
+            $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+            // ----- Call the callback
+            // Here I do not use call_user_func() because I need to send a reference to the
+            // header.
+            //      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
+            $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
+
+            // ----- Look for abort result
+            if ($v_result == 2) {
+                $v_result = PCLZIP_ERR_USER_ABORTED;
+            }
+        }
+
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privExtractFileAsString()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
+    {
+        $v_result = 1;
+
+        // ----- Read the file header
+        $v_header = array();
+        if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Check that the file header is coherent with $p_entry info
+        if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
+            // TBC
+        }
+
+        // ----- Look for pre-extract callback
+        if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
+
+            // ----- Generate a local information
+            $v_local_header = array();
+            $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+            // ----- Call the callback
+            // Here I do not use call_user_func() because I need to send a reference to the
+            // header.
+            //      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
+            $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
+            if ($v_result == 0) {
+                // ----- Change the file status
+                $p_entry['status'] = "skipped";
+                $v_result          = 1;
+            }
+
+            // ----- Look for abort result
+            if ($v_result == 2) {
+                // ----- This status is internal and will be changed in 'skipped'
+                $p_entry['status'] = "aborted";
+                $v_result          = PCLZIP_ERR_USER_ABORTED;
+            }
+
+            // ----- Update the informations
+            // Only some fields can be modified
+            $p_entry['filename'] = $v_local_header['filename'];
+        }
+
+        // ----- Look if extraction should be done
+        if ($p_entry['status'] == 'ok') {
+
+            // ----- Do the extraction (if not a folder)
+            if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) {
+                // ----- Look for not compressed file
+                //      if ($p_entry['compressed_size'] == $p_entry['size'])
+                if ($p_entry['compression'] == 0) {
+
+                    // ----- Reading the file
+                    $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
+                } else {
+
+                    // ----- Reading the file
+                    $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
+
+                    // ----- Decompress the file
+                    if (($p_string = @gzinflate($v_data)) === false) {
+                        // TBC
+                    }
+                }
+
+                // ----- Trace
+            } else {
+                // TBC : error : can not extract a folder in a string
+            }
+
+        }
+
+        // ----- Change abort status
+        if ($p_entry['status'] == "aborted") {
+            $p_entry['status'] = "skipped";
+
+        // ----- Look for post-extract callback
+        } elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
+
+            // ----- Generate a local information
+            $v_local_header = array();
+            $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+            // ----- Swap the content to header
+            $v_local_header['content'] = $p_string;
+            $p_string                  = '';
+
+            // ----- Call the callback
+            // Here I do not use call_user_func() because I need to send a reference to the
+            // header.
+            //      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
+            $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
+
+            // ----- Swap back the content to header
+            $p_string = $v_local_header['content'];
+            unset($v_local_header['content']);
+
+            // ----- Look for abort result
+            if ($v_result == 2) {
+                $v_result = PCLZIP_ERR_USER_ABORTED;
+            }
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privReadFileHeader()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privReadFileHeader(&$p_header)
+    {
+        $v_result = 1;
+
+        // ----- Read the 4 bytes signature
+        $v_binary_data = @fread($this->zip_fd, 4);
+        $v_data        = unpack('Vid', $v_binary_data);
+
+        // ----- Check signature
+        if ($v_data['id'] != 0x04034b50) {
+
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Read the first 42 bytes of the header
+        $v_binary_data = fread($this->zip_fd, 26);
+
+        // ----- Look for invalid block size
+        if (strlen($v_binary_data) != 26) {
+            $p_header['filename'] = "";
+            $p_header['status']   = "invalid_header";
+
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : " . strlen($v_binary_data));
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Extract the values
+        $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
+
+        // ----- Get filename
+        $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
+
+        // ----- Get extra_fields
+        if ($v_data['extra_len'] != 0) {
+            $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
+        } else {
+            $p_header['extra'] = '';
+        }
+
+        // ----- Extract properties
+        $p_header['version_extracted'] = $v_data['version'];
+        $p_header['compression']       = $v_data['compression'];
+        $p_header['size']              = $v_data['size'];
+        $p_header['compressed_size']   = $v_data['compressed_size'];
+        $p_header['crc']               = $v_data['crc'];
+        $p_header['flag']              = $v_data['flag'];
+        $p_header['filename_len']      = $v_data['filename_len'];
+
+        // ----- Recuperate date in UNIX format
+        $p_header['mdate'] = $v_data['mdate'];
+        $p_header['mtime'] = $v_data['mtime'];
+        if ($p_header['mdate'] && $p_header['mtime']) {
+            // ----- Extract time
+            $v_hour    = ($p_header['mtime'] & 0xF800) >> 11;
+            $v_minute  = ($p_header['mtime'] & 0x07E0) >> 5;
+            $v_seconde = ($p_header['mtime'] & 0x001F) * 2;
+
+            // ----- Extract date
+            $v_year  = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
+            $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
+            $v_day   = $p_header['mdate'] & 0x001F;
+
+            // ----- Get UNIX date format
+            $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
+
+        } else {
+            $p_header['mtime'] = time();
+        }
+
+        // TBC
+        //for (reset($v_data); $key = key($v_data); next($v_data)) {
+        //}
+
+        // ----- Set the stored filename
+        $p_header['stored_filename'] = $p_header['filename'];
+
+        // ----- Set the status field
+        $p_header['status'] = "ok";
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privReadCentralFileHeader()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privReadCentralFileHeader(&$p_header)
+    {
+        $v_result = 1;
+
+        // ----- Read the 4 bytes signature
+        $v_binary_data = @fread($this->zip_fd, 4);
+        $v_data        = unpack('Vid', $v_binary_data);
+
+        // ----- Check signature
+        if ($v_data['id'] != 0x02014b50) {
+
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Read the first 42 bytes of the header
+        $v_binary_data = fread($this->zip_fd, 42);
+
+        // ----- Look for invalid block size
+        if (strlen($v_binary_data) != 42) {
+            $p_header['filename'] = "";
+            $p_header['status']   = "invalid_header";
+
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : " . strlen($v_binary_data));
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Extract the values
+        $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
+
+        // ----- Get filename
+        if ($p_header['filename_len'] != 0) {
+            $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
+        } else {
+            $p_header['filename'] = '';
+        }
+
+        // ----- Get extra
+        if ($p_header['extra_len'] != 0) {
+            $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
+        } else {
+            $p_header['extra'] = '';
+        }
+
+        // ----- Get comment
+        if ($p_header['comment_len'] != 0) {
+            $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
+        } else {
+            $p_header['comment'] = '';
+        }
+
+        // ----- Extract properties
+
+        // ----- Recuperate date in UNIX format
+        //if ($p_header['mdate'] && $p_header['mtime'])
+        // TBC : bug : this was ignoring time with 0/0/0
+        if (1) {
+            // ----- Extract time
+            $v_hour    = ($p_header['mtime'] & 0xF800) >> 11;
+            $v_minute  = ($p_header['mtime'] & 0x07E0) >> 5;
+            $v_seconde = ($p_header['mtime'] & 0x001F) * 2;
+
+            // ----- Extract date
+            $v_year  = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
+            $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
+            $v_day   = $p_header['mdate'] & 0x001F;
+
+            // ----- Get UNIX date format
+            $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
+
+        } else {
+            $p_header['mtime'] = time();
+        }
+
+        // ----- Set the stored filename
+        $p_header['stored_filename'] = $p_header['filename'];
+
+        // ----- Set default status to ok
+        $p_header['status'] = 'ok';
+
+        // ----- Look if it is a directory
+        if (substr($p_header['filename'], -1) == '/') {
+            //$p_header['external'] = 0x41FF0010;
+            $p_header['external'] = 0x00000010;
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privCheckFileHeaders()
+    // Description :
+    // Parameters :
+    // Return Values :
+    //   1 on success,
+    //   0 on error;
+    // --------------------------------------------------------------------------------
+    public function privCheckFileHeaders(&$p_local_header, &$p_central_header)
+    {
+        $v_result = 1;
+
+        // ----- Check the static values
+        // TBC
+        if ($p_local_header['filename'] != $p_central_header['filename']) {
+        }
+        if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
+        }
+        if ($p_local_header['flag'] != $p_central_header['flag']) {
+        }
+        if ($p_local_header['compression'] != $p_central_header['compression']) {
+        }
+        if ($p_local_header['mtime'] != $p_central_header['mtime']) {
+        }
+        if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
+        }
+
+        // ----- Look for flag bit 3
+        if (($p_local_header['flag'] & 8) == 8) {
+            $p_local_header['size']            = $p_central_header['size'];
+            $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
+            $p_local_header['crc']             = $p_central_header['crc'];
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privReadEndCentralDir()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privReadEndCentralDir(&$p_central_dir)
+    {
+        $v_result = 1;
+
+        // ----- Go to the end of the zip file
+        $v_size = filesize($this->zipname);
+        @fseek($this->zip_fd, $v_size);
+        if (@ftell($this->zip_fd) != $v_size) {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \'' . $this->zipname . '\'');
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- First try : look if this is an archive with no commentaries (most of the time)
+        // in this case the end of central dir is at 22 bytes of the file end
+        $v_found = 0;
+        if ($v_size > 26) {
+            @fseek($this->zip_fd, $v_size - 22);
+            if (($v_pos = @ftell($this->zip_fd)) != ($v_size - 22)) {
+                // ----- Error log
+                PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \'' . $this->zipname . '\'');
+
+                // ----- Return
+                return PclZip::errorCode();
+            }
+
+            // ----- Read for bytes
+            $v_binary_data = @fread($this->zip_fd, 4);
+            $v_data        = @unpack('Vid', $v_binary_data);
+
+            // ----- Check signature
+            if ($v_data['id'] == 0x06054b50) {
+                $v_found = 1;
+            }
+
+            $v_pos = ftell($this->zip_fd);
+        }
+
+        // ----- Go back to the maximum possible size of the Central Dir End Record
+        if (!$v_found) {
+            $v_maximum_size = 65557; // 0xFFFF + 22;
+            if ($v_maximum_size > $v_size) {
+                $v_maximum_size = $v_size;
+            }
+            @fseek($this->zip_fd, $v_size - $v_maximum_size);
+            if (@ftell($this->zip_fd) != ($v_size - $v_maximum_size)) {
+                // ----- Error log
+                PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \'' . $this->zipname . '\'');
+
+                // ----- Return
+                return PclZip::errorCode();
+            }
+
+            // ----- Read byte per byte in order to find the signature
+            $v_pos   = ftell($this->zip_fd);
+            $v_bytes = 0x00000000;
+            while ($v_pos < $v_size) {
+                // ----- Read a byte
+                $v_byte = @fread($this->zip_fd, 1);
+
+                // -----  Add the byte
+                //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
+                // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
+                // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
+                $v_bytes = (($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
+
+                // ----- Compare the bytes
+                if ($v_bytes == 0x504b0506) {
+                    $v_pos++;
+                    break;
+                }
+
+                $v_pos++;
+            }
+
+            // ----- Look if not found end of central dir
+            if ($v_pos == $v_size) {
+
+                // ----- Error log
+                PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
+
+                // ----- Return
+                return PclZip::errorCode();
+            }
+        }
+
+        // ----- Read the first 18 bytes of the header
+        $v_binary_data = fread($this->zip_fd, 18);
+
+        // ----- Look for invalid block size
+        if (strlen($v_binary_data) != 18) {
+
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : " . strlen($v_binary_data));
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Extract the values
+        $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
+
+        // ----- Check the global size
+        if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
+
+            // ----- Removed in release 2.2 see readme file
+            // The check of the file size is a little too strict.
+            // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
+            // While decrypted, zip has training 0 bytes
+            if (0) {
+                // ----- Error log
+                PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'The central dir is not at the end of the archive.' . ' Some trailing bytes exists after the archive.');
+
+                // ----- Return
+                return PclZip::errorCode();
+            }
+        }
+
+        // ----- Get comment
+        if ($v_data['comment_size'] != 0) {
+            $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
+        } else {
+            $p_central_dir['comment'] = '';
+        }
+
+        $p_central_dir['entries']      = $v_data['entries'];
+        $p_central_dir['disk_entries'] = $v_data['disk_entries'];
+        $p_central_dir['offset']       = $v_data['offset'];
+        $p_central_dir['size']         = $v_data['size'];
+        $p_central_dir['disk']         = $v_data['disk'];
+        $p_central_dir['disk_start']   = $v_data['disk_start'];
+
+        // TBC
+        //for (reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
+        //}
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privDeleteByRule()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privDeleteByRule(&$p_result_list, &$p_options)
+    {
+        $v_result      = 1;
+        $v_list_detail = array();
+
+        // ----- Open the zip file
+        if (($v_result = $this->privOpenFd('rb')) != 1) {
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Read the central directory informations
+        $v_central_dir = array();
+        if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
+            $this->privCloseFd();
+
+            return $v_result;
+        }
+
+        // ----- Go to beginning of File
+        @rewind($this->zip_fd);
+
+        // ----- Scan all the files
+        // ----- Start at beginning of Central Dir
+        $v_pos_entry = $v_central_dir['offset'];
+        @rewind($this->zip_fd);
+        if (@fseek($this->zip_fd, $v_pos_entry)) {
+            // ----- Close the zip file
+            $this->privCloseFd();
+
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Read each entry
+        $v_header_list = array();
+        $j_start       = 0;
+        for ($i = 0, $v_nb_extracted = 0; $i < $v_central_dir['entries']; $i++) {
+
+            // ----- Read the file header
+            $v_header_list[$v_nb_extracted] = array();
+            if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) {
+                // ----- Close the zip file
+                $this->privCloseFd();
+
+                return $v_result;
+            }
+
+            // ----- Store the index
+            $v_header_list[$v_nb_extracted]['index'] = $i;
+
+            // ----- Look for the specific extract rules
+            $v_found = false;
+
+            // ----- Look for extract by name rule
+            if ((isset($p_options[PCLZIP_OPT_BY_NAME])) && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
+
+                // ----- Look if the filename is in the list
+                for ($j = 0; ($j < sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
+
+                    // ----- Look for a directory
+                    if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
+
+                        // ----- Look if the directory is in the filename path
+                        if ((strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+                            $v_found = true;
+                        } elseif ((($v_header_list[$v_nb_extracted]['external'] & 0x00000010) == 0x00000010) /* Indicates a folder */ && ($v_header_list[$v_nb_extracted]['stored_filename'] . '/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+                            $v_found = true;
+                        }
+
+                    // ----- Look for a filename
+                    } elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
+                        $v_found = true;
+                    }
+                }
+
+            // ----- Look for extract by ereg rule
+            // ereg() is deprecated with PHP 5.3
+            /*
+            elseif (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
+            && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
+
+            if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
+            $v_found = true;
+            }
+            }
+            */
+
+            // ----- Look for extract by preg rule
+            } elseif ((isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
+
+                if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
+                    $v_found = true;
+                }
+
+            // ----- Look for extract by index rule
+            } elseif ((isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
+
+                // ----- Look if the index is in the list
+                for ($j = $j_start; ($j < sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
+
+                    if (($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i <= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
+                        $v_found = true;
+                    }
+                    if ($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
+                        $j_start = $j + 1;
+                    }
+
+                    if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start'] > $i) {
+                        break;
+                    }
+                }
+            } else {
+                $v_found = true;
+            }
+
+            // ----- Look for deletion
+            if ($v_found) {
+                unset($v_header_list[$v_nb_extracted]);
+            } else {
+                $v_nb_extracted++;
+            }
+        }
+
+        // ----- Look if something need to be deleted
+        if ($v_nb_extracted > 0) {
+
+            // ----- Creates a temporay file
+            $v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp';
+
+            // ----- Creates a temporary zip archive
+            $v_temp_zip = new PclZip($v_zip_temp_name);
+
+            // ----- Open the temporary zip file in write mode
+            if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
+                $this->privCloseFd();
+
+                // ----- Return
+                return $v_result;
+            }
+
+            // ----- Look which file need to be kept
+            for ($i = 0; $i < sizeof($v_header_list); $i++) {
+
+                // ----- Calculate the position of the header
+                @rewind($this->zip_fd);
+                if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
+                    // ----- Close the zip file
+                    $this->privCloseFd();
+                    $v_temp_zip->privCloseFd();
+                    @unlink($v_zip_temp_name);
+
+                    // ----- Error log
+                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+                    // ----- Return
+                    return PclZip::errorCode();
+                }
+
+                // ----- Read the file header
+                $v_local_header = array();
+                if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
+                    // ----- Close the zip file
+                    $this->privCloseFd();
+                    $v_temp_zip->privCloseFd();
+                    @unlink($v_zip_temp_name);
+
+                    // ----- Return
+                    return $v_result;
+                }
+
+                // ----- Check that local file header is same as central file header
+                if ($this->privCheckFileHeaders($v_local_header, $v_header_list[$i]) != 1) {
+                    // TBC
+                }
+                unset($v_local_header);
+
+                // ----- Write the file header
+                if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
+                    // ----- Close the zip file
+                    $this->privCloseFd();
+                    $v_temp_zip->privCloseFd();
+                    @unlink($v_zip_temp_name);
+
+                    // ----- Return
+                    return $v_result;
+                }
+
+                // ----- Read/write the data block
+                if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
+                    // ----- Close the zip file
+                    $this->privCloseFd();
+                    $v_temp_zip->privCloseFd();
+                    @unlink($v_zip_temp_name);
+
+                    // ----- Return
+                    return $v_result;
+                }
+            }
+
+            // ----- Store the offset of the central dir
+            $v_offset = @ftell($v_temp_zip->zip_fd);
+
+            // ----- Re-Create the Central Dir files header
+            for ($i = 0; $i < sizeof($v_header_list); $i++) {
+                // ----- Create the file header
+                if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
+                    $v_temp_zip->privCloseFd();
+                    $this->privCloseFd();
+                    @unlink($v_zip_temp_name);
+
+                    // ----- Return
+                    return $v_result;
+                }
+
+                // ----- Transform the header to a 'usable' info
+                $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+            }
+
+            // ----- Zip file comment
+            $v_comment = '';
+            if (isset($p_options[PCLZIP_OPT_COMMENT])) {
+                $v_comment = $p_options[PCLZIP_OPT_COMMENT];
+            }
+
+            // ----- Calculate the size of the central header
+            $v_size = @ftell($v_temp_zip->zip_fd) - $v_offset;
+
+            // ----- Create the central dir footer
+            if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
+                // ----- Reset the file list
+                unset($v_header_list);
+                $v_temp_zip->privCloseFd();
+                $this->privCloseFd();
+                @unlink($v_zip_temp_name);
+
+                // ----- Return
+                return $v_result;
+            }
+
+            // ----- Close
+            $v_temp_zip->privCloseFd();
+            $this->privCloseFd();
+
+            // ----- Delete the zip file
+            // TBC : I should test the result ...
+            @unlink($this->zipname);
+
+            // ----- Rename the temporary file
+            // TBC : I should test the result ...
+            //@rename($v_zip_temp_name, $this->zipname);
+            PclZipUtilRename($v_zip_temp_name, $this->zipname);
+
+            // ----- Destroy the temporary archive
+            unset($v_temp_zip);
+
+        // ----- Remove every files : reset the file
+        } elseif ($v_central_dir['entries'] != 0) {
+            $this->privCloseFd();
+
+            if (($v_result = $this->privOpenFd('wb')) != 1) {
+                return $v_result;
+            }
+
+            if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
+                return $v_result;
+            }
+
+            $this->privCloseFd();
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privDirCheck()
+    // Description :
+    //   Check if a directory exists, if not it creates it and all the parents directory
+    //   which may be useful.
+    // Parameters :
+    //   $p_dir : Directory path to check.
+    // Return Values :
+    //    1 : OK
+    //   -1 : Unable to create directory
+    // --------------------------------------------------------------------------------
+    public function privDirCheck($p_dir, $p_is_dir = false)
+    {
+        $v_result = 1;
+
+        // ----- Remove the final '/'
+        if (($p_is_dir) && (substr($p_dir, -1) == '/')) {
+            $p_dir = substr($p_dir, 0, strlen($p_dir) - 1);
+        }
+
+        // ----- Check the directory availability
+        if ((is_dir($p_dir)) || ($p_dir == "")) {
+            return 1;
+        }
+
+        // ----- Extract parent directory
+        $p_parent_dir = dirname($p_dir);
+
+        // ----- Just a check
+        if ($p_parent_dir != $p_dir) {
+            // ----- Look for parent directory
+            if ($p_parent_dir != "") {
+                if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) {
+                    return $v_result;
+                }
+            }
+        }
+
+        // ----- Create the directory
+        if (!@mkdir($p_dir, 0777)) {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privMerge()
+    // Description :
+    //   If $p_archive_to_add does not exist, the function exit with a success result.
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privMerge(&$p_archive_to_add)
+    {
+        $v_result = 1;
+
+        // ----- Look if the archive_to_add exists
+        if (!is_file($p_archive_to_add->zipname)) {
+
+            // ----- Nothing to merge, so merge is a success
+            $v_result = 1;
+
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Look if the archive exists
+        if (!is_file($this->zipname)) {
+
+            // ----- Do a duplicate
+            $v_result = $this->privDuplicate($p_archive_to_add->zipname);
+
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Open the zip file
+        if (($v_result = $this->privOpenFd('rb')) != 1) {
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Read the central directory informations
+        $v_central_dir = array();
+        if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
+            $this->privCloseFd();
+
+            return $v_result;
+        }
+
+        // ----- Go to beginning of File
+        @rewind($this->zip_fd);
+
+        // ----- Open the archive_to_add file
+        if (($v_result = $p_archive_to_add->privOpenFd('rb')) != 1) {
+            $this->privCloseFd();
+
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Read the central directory informations
+        $v_central_dir_to_add = array();
+        if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) {
+            $this->privCloseFd();
+            $p_archive_to_add->privCloseFd();
+
+            return $v_result;
+        }
+
+        // ----- Go to beginning of File
+        @rewind($p_archive_to_add->zip_fd);
+
+        // ----- Creates a temporay file
+        $v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp';
+
+        // ----- Open the temporary file in write mode
+        if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) {
+            $this->privCloseFd();
+            $p_archive_to_add->privCloseFd();
+
+            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \'' . $v_zip_temp_name . '\' in binary write mode');
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Copy the files from the archive to the temporary file
+        // TBC : Here I should better append the file and go back to erase the central dir
+        $v_size = $v_central_dir['offset'];
+        while ($v_size != 0) {
+            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = fread($this->zip_fd, $v_read_size);
+            @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+            $v_size -= $v_read_size;
+        }
+
+        // ----- Copy the files from the archive_to_add into the temporary file
+        $v_size = $v_central_dir_to_add['offset'];
+        while ($v_size != 0) {
+            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = fread($p_archive_to_add->zip_fd, $v_read_size);
+            @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+            $v_size -= $v_read_size;
+        }
+
+        // ----- Store the offset of the central dir
+        $v_offset = @ftell($v_zip_temp_fd);
+
+        // ----- Copy the block of file headers from the old archive
+        $v_size = $v_central_dir['size'];
+        while ($v_size != 0) {
+            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = @fread($this->zip_fd, $v_read_size);
+            @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+            $v_size -= $v_read_size;
+        }
+
+        // ----- Copy the block of file headers from the archive_to_add
+        $v_size = $v_central_dir_to_add['size'];
+        while ($v_size != 0) {
+            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = @fread($p_archive_to_add->zip_fd, $v_read_size);
+            @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+            $v_size -= $v_read_size;
+        }
+
+        // ----- Merge the file comments
+        $v_comment = $v_central_dir['comment'] . ' ' . $v_central_dir_to_add['comment'];
+
+        // ----- Calculate the size of the (new) central header
+        $v_size = @ftell($v_zip_temp_fd) - $v_offset;
+
+        // ----- Swap the file descriptor
+        // Here is a trick : I swap the temporary fd with the zip fd, in order to use
+        // the following methods on the temporary fil and not the real archive fd
+        $v_swap        = $this->zip_fd;
+        $this->zip_fd  = $v_zip_temp_fd;
+        $v_zip_temp_fd = $v_swap;
+
+        // ----- Create the central dir footer
+        if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries'] + $v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) {
+            $this->privCloseFd();
+            $p_archive_to_add->privCloseFd();
+            @fclose($v_zip_temp_fd);
+            $this->zip_fd = null;
+
+            // ----- Reset the file list
+            unset($v_header_list);
+
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Swap back the file descriptor
+        $v_swap        = $this->zip_fd;
+        $this->zip_fd  = $v_zip_temp_fd;
+        $v_zip_temp_fd = $v_swap;
+
+        // ----- Close
+        $this->privCloseFd();
+        $p_archive_to_add->privCloseFd();
+
+        // ----- Close the temporary file
+        @fclose($v_zip_temp_fd);
+
+        // ----- Delete the zip file
+        // TBC : I should test the result ...
+        @unlink($this->zipname);
+
+        // ----- Rename the temporary file
+        // TBC : I should test the result ...
+        //@rename($v_zip_temp_name, $this->zipname);
+        PclZipUtilRename($v_zip_temp_name, $this->zipname);
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privDuplicate()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privDuplicate($p_archive_filename)
+    {
+        $v_result = 1;
+
+        // ----- Look if the $p_archive_filename exists
+        if (!is_file($p_archive_filename)) {
+
+            // ----- Nothing to duplicate, so duplicate is a success.
+            $v_result = 1;
+
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Open the zip file
+        if (($v_result = $this->privOpenFd('wb')) != 1) {
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Open the temporary file in write mode
+        if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) {
+            $this->privCloseFd();
+
+            PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \'' . $p_archive_filename . '\' in binary write mode');
+
+            // ----- Return
+            return PclZip::errorCode();
+        }
+
+        // ----- Copy the files from the archive to the temporary file
+        // TBC : Here I should better append the file and go back to erase the central dir
+        $v_size = filesize($p_archive_filename);
+        while ($v_size != 0) {
+            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = fread($v_zip_temp_fd, $v_read_size);
+            @fwrite($this->zip_fd, $v_buffer, $v_read_size);
+            $v_size -= $v_read_size;
+        }
+
+        // ----- Close
+        $this->privCloseFd();
+
+        // ----- Close the temporary file
+        @fclose($v_zip_temp_fd);
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privErrorLog()
+    // Description :
+    // Parameters :
+    // --------------------------------------------------------------------------------
+    public function privErrorLog($p_error_code = 0, $p_error_string = '')
+    {
+        if (PCLZIP_ERROR_EXTERNAL == 1) {
+            PclError($p_error_code, $p_error_string);
+        } else {
+            $this->error_code   = $p_error_code;
+            $this->error_string = $p_error_string;
+        }
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privErrorReset()
+    // Description :
+    // Parameters :
+    // --------------------------------------------------------------------------------
+    public function privErrorReset()
+    {
+        if (PCLZIP_ERROR_EXTERNAL == 1) {
+            PclErrorReset();
+        } else {
+            $this->error_code   = 0;
+            $this->error_string = '';
+        }
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privDisableMagicQuotes()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privDisableMagicQuotes()
+    {
+        $v_result = 1;
+
+        // ----- Look if function exists
+        if ((!function_exists("get_magic_quotes_runtime")) || (!function_exists("set_magic_quotes_runtime"))) {
+            return $v_result;
+        }
+
+        // ----- Look if already done
+        if ($this->magic_quotes_status != -1) {
+            return $v_result;
+        }
+
+        // ----- Get and memorize the magic_quote value
+        $this->magic_quotes_status = @get_magic_quotes_runtime();
+
+        // ----- Disable magic_quotes
+        if ($this->magic_quotes_status == 1) {
+            @set_magic_quotes_runtime(0);
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+
+    // --------------------------------------------------------------------------------
+    // Function : privSwapBackMagicQuotes()
+    // Description :
+    // Parameters :
+    // Return Values :
+    // --------------------------------------------------------------------------------
+    public function privSwapBackMagicQuotes()
+    {
+        $v_result = 1;
+
+        // ----- Look if function exists
+        if ((!function_exists("get_magic_quotes_runtime")) || (!function_exists("set_magic_quotes_runtime"))) {
+            return $v_result;
+        }
+
+        // ----- Look if something to do
+        if ($this->magic_quotes_status != -1) {
+            return $v_result;
+        }
+
+        // ----- Swap back magic_quotes
+        if ($this->magic_quotes_status == 1) {
+            @set_magic_quotes_runtime($this->magic_quotes_status);
+        }
+
+        // ----- Return
+        return $v_result;
+    }
+    // --------------------------------------------------------------------------------
+}
+
+// End of class
+// --------------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------------
+// Function : PclZipUtilPathReduction()
+// Description :
+// Parameters :
+// Return Values :
+// --------------------------------------------------------------------------------
+function PclZipUtilPathReduction($p_dir)
+{
+    $v_result = "";
+
+    // ----- Look for not empty path
+    if ($p_dir != "") {
+        // ----- Explode path by directory names
+        $v_list = explode("/", $p_dir);
+
+        // ----- Study directories from last to first
+        $v_skip = 0;
+        for ($i = sizeof($v_list) - 1; $i >= 0; $i--) {
+            // ----- Look for current path
+            if ($v_list[$i] == ".") {
+                // ----- Ignore this directory
+                // Should be the first $i=0, but no check is done
+            } elseif ($v_list[$i] == "..") {
+                $v_skip++;
+            } elseif ($v_list[$i] == "") {
+                // ----- First '/' i.e. root slash
+                if ($i == 0) {
+                    $v_result = "/" . $v_result;
+                    if ($v_skip > 0) {
+                        // ----- It is an invalid path, so the path is not modified
+                        // TBC
+                        $v_result = $p_dir;
+                        $v_skip   = 0;
+                    }
+
+                // ----- Last '/' i.e. indicates a directory
+                } elseif ($i == (sizeof($v_list) - 1)) {
+                    $v_result = $v_list[$i];
+
+                // ----- Double '/' inside the path
+                } else {
+                    // ----- Ignore only the double '//' in path,
+                    // but not the first and last '/'
+                }
+            } else {
+                // ----- Look for item to skip
+                if ($v_skip > 0) {
+                    $v_skip--;
+                } else {
+                    $v_result = $v_list[$i] . ($i != (sizeof($v_list) - 1) ? "/" . $v_result : "");
+                }
+            }
+        }
+
+        // ----- Look for skip
+        if ($v_skip > 0) {
+            while ($v_skip > 0) {
+                $v_result = '../' . $v_result;
+                $v_skip--;
+            }
+        }
+    }
+
+    // ----- Return
+    return $v_result;
+}
+// --------------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------------
+// Function : PclZipUtilPathInclusion()
+// Description :
+//   This function indicates if the path $p_path is under the $p_dir tree. Or,
+//   said in an other way, if the file or sub-dir $p_path is inside the dir
+//   $p_dir.
+//   The function indicates also if the path is exactly the same as the dir.
+//   This function supports path with duplicated '/' like '//', but does not
+//   support '.' or '..' statements.
+// Parameters :
+// Return Values :
+//   0 if $p_path is not inside directory $p_dir
+//   1 if $p_path is inside directory $p_dir
+//   2 if $p_path is exactly the same as $p_dir
+// --------------------------------------------------------------------------------
+function PclZipUtilPathInclusion($p_dir, $p_path)
+{
+    $v_result = 1;
+
+    // ----- Look for path beginning by ./
+    if (($p_dir == '.') || ((strlen($p_dir) >= 2) && (substr($p_dir, 0, 2) == './'))) {
+        $p_dir = PclZipUtilTranslateWinPath(getcwd(), false) . '/' . substr($p_dir, 1);
+    }
+    if (($p_path == '.') || ((strlen($p_path) >= 2) && (substr($p_path, 0, 2) == './'))) {
+        $p_path = PclZipUtilTranslateWinPath(getcwd(), false) . '/' . substr($p_path, 1);
+    }
+
+    // ----- Explode dir and path by directory separator
+    $v_list_dir       = explode("/", $p_dir);
+    $v_list_dir_size  = sizeof($v_list_dir);
+    $v_list_path      = explode("/", $p_path);
+    $v_list_path_size = sizeof($v_list_path);
+
+    // ----- Study directories paths
+    $i = 0;
+    $j = 0;
+    while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
+
+        // ----- Look for empty dir (path reduction)
+        if ($v_list_dir[$i] == '') {
+            $i++;
+            continue;
+        }
+        if ($v_list_path[$j] == '') {
+            $j++;
+            continue;
+        }
+
+        // ----- Compare the items
+        if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ($v_list_path[$j] != '')) {
+            $v_result = 0;
+        }
+
+        // ----- Next items
+        $i++;
+        $j++;
+    }
+
+    // ----- Look if everything seems to be the same
+    if ($v_result) {
+        // ----- Skip all the empty items
+        while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) {
+            $j++;
+        }
+        while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) {
+            $i++;
+        }
+
+        if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
+            // ----- There are exactly the same
+            $v_result = 2;
+        } elseif ($i < $v_list_dir_size) {
+            // ----- The path is shorter than the dir
+            $v_result = 0;
+        }
+    }
+
+    // ----- Return
+    return $v_result;
+}
+// --------------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------------
+// Function : PclZipUtilCopyBlock()
+// Description :
+// Parameters :
+//   $p_mode : read/write compression mode
+//             0 : src & dest normal
+//             1 : src gzip, dest normal
+//             2 : src normal, dest gzip
+//             3 : src & dest gzip
+// Return Values :
+// --------------------------------------------------------------------------------
+function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode = 0)
+{
+    $v_result = 1;
+
+    if ($p_mode == 0) {
+        while ($p_size != 0) {
+            $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = @fread($p_src, $v_read_size);
+            @fwrite($p_dest, $v_buffer, $v_read_size);
+            $p_size -= $v_read_size;
+        }
+    } elseif ($p_mode == 1) {
+        while ($p_size != 0) {
+            $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = @gzread($p_src, $v_read_size);
+            @fwrite($p_dest, $v_buffer, $v_read_size);
+            $p_size -= $v_read_size;
+        }
+    } elseif ($p_mode == 2) {
+        while ($p_size != 0) {
+            $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = @fread($p_src, $v_read_size);
+            @gzwrite($p_dest, $v_buffer, $v_read_size);
+            $p_size -= $v_read_size;
+        }
+    } elseif ($p_mode == 3) {
+        while ($p_size != 0) {
+            $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+            $v_buffer    = @gzread($p_src, $v_read_size);
+            @gzwrite($p_dest, $v_buffer, $v_read_size);
+            $p_size -= $v_read_size;
+        }
+    }
+
+    // ----- Return
+    return $v_result;
+}
+// --------------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------------
+// Function : PclZipUtilRename()
+// Description :
+//   This function tries to do a simple rename() function. If it fails, it
+//   tries to copy the $p_src file in a new $p_dest file and then unlink the
+//   first one.
+// Parameters :
+//   $p_src : Old filename
+//   $p_dest : New filename
+// Return Values :
+//   1 on success, 0 on failure.
+// --------------------------------------------------------------------------------
+function PclZipUtilRename($p_src, $p_dest)
+{
+    $v_result = 1;
+
+    // ----- Try to rename the files
+    if (!@rename($p_src, $p_dest)) {
+
+        // ----- Try to copy & unlink the src
+        if (!@copy($p_src, $p_dest)) {
+            $v_result = 0;
+        } elseif (!@unlink($p_src)) {
+            $v_result = 0;
+        }
+    }
+
+    // ----- Return
+    return $v_result;
+}
+// --------------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------------
+// Function : PclZipUtilOptionText()
+// Description :
+//   Translate option value in text. Mainly for debug purpose.
+// Parameters :
+//   $p_option : the option value.
+// Return Values :
+//   The option text value.
+// --------------------------------------------------------------------------------
+function PclZipUtilOptionText($p_option)
+{
+
+    $v_list = get_defined_constants();
+    for (reset($v_list); $v_key = key($v_list); next($v_list)) {
+        $v_prefix = substr($v_key, 0, 10);
+        if ((($v_prefix == 'PCLZIP_OPT') || ($v_prefix == 'PCLZIP_CB_') || ($v_prefix == 'PCLZIP_ATT')) && ($v_list[$v_key] == $p_option)) {
+            return $v_key;
+        }
+    }
+
+    $v_result = 'Unknown';
+
+    return $v_result;
+}
+// --------------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------------
+// Function : PclZipUtilTranslateWinPath()
+// Description :
+//   Translate windows path by replacing '\' by '/' and optionally removing
+//   drive letter.
+// Parameters :
+//   $p_path : path to translate.
+//   $p_remove_disk_letter : true | false
+// Return Values :
+//   The path translated.
+// --------------------------------------------------------------------------------
+function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter = true)
+{
+    if (stristr(php_uname(), 'windows')) {
+        // ----- Look for potential disk letter
+        if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
+            $p_path = substr($p_path, $v_position + 1);
+        }
+        // ----- Change potential windows directory separator
+        if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0, 1) == '\\')) {
+            $p_path = strtr($p_path, '\\', '/');
+        }
+    }
+
+    return $p_path;
+}
+// --------------------------------------------------------------------------------
diff --git a/htdocs/includes/html2pdf/zip/pclzip/readme.txt b/htdocs/includes/html2pdf/zip/pclzip/readme.txt
new file mode 100644 (file)
index 0000000..f028134
--- /dev/null
@@ -0,0 +1,425 @@
+// --------------------------------------------------------------------------------
+// PclZip 2.8.4 - readme.txt
+// --------------------------------------------------------------------------------
+// License GNU/LGPL - August 2009
+// Vincent Blavet - vincent@phpconcept.net
+// http://www.phpconcept.net
+// --------------------------------------------------------------------------------
+
+
+
+0 - Summary
+============
+    1 - Introduction
+    2 - What's new
+    3 - Corrected bugs
+    4 - Known bugs or limitations
+    5 - License
+    6 - Warning
+    7 - Documentation
+    8 - Author
+    9 - Contribute
+
+1 - Introduction
+================
+
+  PclZip is a library that allow you to manage a Zip archive.
+
+  Full documentation about PclZip can be found here : http://www.phpconcept.net/pclzip
+
+2 - What's new
+==============
+
+  Version 2.8.4 :
+    - Update composer.json to indicate that pclzip/pclzip is replaced
+
+  Version 2.8.3 :
+    - Fix compatibility with PHP v7.1
+    
+  Version 2.8.2 :
+    - PCLZIP_CB_PRE_EXTRACT and PCLZIP_CB_POST_EXTRACT are now supported with
+      extraction as a string (PCLZIP_OPT_EXTRACT_AS_STRING). The string
+      can also be modified in the post-extract call back.
+    **Bugs correction :
+    - PCLZIP_OPT_REMOVE_ALL_PATH was not working correctly
+    - Remove use of eval() and do direct call to callback functions
+    - Correct support of 64bits systems (Thanks to WordPress team)
+
+  Version 2.8.1 :
+    - Move option PCLZIP_OPT_BY_EREG to PCLZIP_OPT_BY_PREG because ereg() is
+      deprecated in PHP 5.3. When using option PCLZIP_OPT_BY_EREG, PclZip will
+      automatically replace it by PCLZIP_OPT_BY_PREG.
+
+  Version 2.8 :
+    - Improve extraction of zip archive for large files by using temporary files
+      This feature is working like the one defined in r2.7.
+      Options are renamed : PCLZIP_OPT_TEMP_FILE_ON, PCLZIP_OPT_TEMP_FILE_OFF,
+      PCLZIP_OPT_TEMP_FILE_THRESHOLD
+    - Add a ratio constant PCLZIP_TEMPORARY_FILE_RATIO to configure the auto
+      sense of temporary file use.
+    - Bug correction : Reduce filepath in returned file list to remove ennoying
+      './/' preambule in file path.
+
+  Version 2.7 :
+    - Improve creation of zip archive for large files :
+      PclZip will now autosense the configured memory and use temporary files
+      when large file is suspected.
+      This feature can also ne triggered by manual options in create() and add()
+      methods. 'PCLZIP_OPT_ADD_TEMP_FILE_ON' force the use of temporary files,
+      'PCLZIP_OPT_ADD_TEMP_FILE_OFF' disable the autosense technic,
+      'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD' allow for configuration of a size
+      threshold to use temporary files.
+      Using "temporary files" rather than "memory" might take more time, but
+      might give the ability to zip very large files :
+      Tested on my win laptop with a 88Mo file :
+        Zip "in-memory" : 18sec (max_execution_time=30, memory_limit=180Mo)
+        Zip "tmporary-files" : 23sec (max_execution_time=30, memory_limit=30Mo)
+    - Replace use of mktime() by time() to limit the E_STRICT error messages.
+    - Bug correction : When adding files with full windows path (drive letter)
+      PclZip is now working. Before, if the drive letter is not the default
+      path, PclZip was not able to add the file.
+
+  Version 2.6 :
+    - Code optimisation
+    - New attributes PCLZIP_ATT_FILE_COMMENT gives the ability to
+      add a comment for a specific file. (Don't really know if this is usefull)
+    - New attribute PCLZIP_ATT_FILE_CONTENT gives the ability to add a string
+      as a file.
+    - New attribute PCLZIP_ATT_FILE_MTIME modify the timestamp associated with
+      a file.
+    - Correct a bug. Files archived with a timestamp with 0h0m0s were extracted
+      with current time
+    - Add CRC value in the informations returned back for each file after an
+      action.
+    - Add missing closedir() statement.
+    - When adding a folder, and removing the path of this folder, files were
+      incorrectly added with a '/' at the beginning. Which means files are
+      related to root in unix systems. Corrected.
+    - Add conditional if before constant definition. This will allow users
+      to redefine constants without changing the file, and then improve
+      upgrade of pclzip code for new versions.
+
+  Version 2.5 :
+    - Introduce the ability to add file/folder with individual properties (file descriptor).
+      This gives for example the ability to change the filename of a zipped file.
+      . Able to add files individually
+      . Able to change full name
+      . Able to change short name
+      . Compatible with global options
+    - New attributes : PCLZIP_ATT_FILE_NAME, PCLZIP_ATT_FILE_NEW_SHORT_NAME, PCLZIP_ATT_FILE_NEW_FULL_NAME
+    - New error code : PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE
+    - Add a security control feature. PclZip can extract any file in any folder
+      of a system. People may use this to upload a zip file and try to override
+      a system file. The PCLZIP_OPT_EXTRACT_DIR_RESTRICTION will give the
+      ability to forgive any directory transversal behavior.
+    - New PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : check extraction path
+    - New error code : PCLZIP_ERR_DIRECTORY_RESTRICTION
+    - Modification in PclZipUtilPathInclusion() : dir and path beginning with ./ will be prepend
+      by current path (getcwd())
+
+  Version 2.4 :
+    - Code improvment : try to speed up the code by removing unusefull call to pack()
+    - Correct bug in delete() : delete() should be called with no argument. This was not
+      the case in 2.3. This is corrected in 2.4.
+    - Correct a bug in path_inclusion function. When the path has several '../../', the
+      result was bad.
+    - Add a check for magic_quotes_runtime configuration. If enabled, PclZip will
+      disable it while working and det it back to its original value.
+      This resolve a lots of bad formated archive errors.
+    - Bug correction : PclZip now correctly unzip file in some specific situation,
+      when compressed content has same size as uncompressed content.
+    - Bug correction : When selecting option 'PCLZIP_OPT_REMOVE_ALL_PATH',
+      directories are not any more created.
+    - Code improvment : correct unclosed opendir(), better handling of . and .. in
+      loops.
+
+
+  Version 2.3 :
+    - Correct a bug with PHP5 : affecting the value 0xFE49FFE0 to a variable does not
+      give the same result in PHP4 and PHP5 ....
+
+  Version 2.2 :
+    - Try development of PCLZIP_OPT_CRYPT .....
+      However this becomes to a stop. To crypt/decrypt I need to multiply 2 long integers,
+      the result (greater than a long) is not supported by PHP. Even the use of bcmath
+      functions does not help. I did not find yet a solution ...;
+    - Add missing '/' at end of directory entries
+    - Check is a file is encrypted or not. Returns status 'unsupported_encryption' and/or
+      error code PCLZIP_ERR_UNSUPPORTED_ENCRYPTION.
+    - Corrected : Bad "version need to extract" field in local file header
+    - Add private method privCheckFileHeaders() in order to check local and central
+      file headers. PclZip is now supporting purpose bit flag bit 3. Purpose bit flag bit 3 gives
+      the ability to have a local file header without size, compressed size and crc filled.
+    - Add a generic status 'error' for file status
+    - Add control of compression type. PclZip only support deflate compression method.
+      Before v2.2, PclZip does not check the compression method used in an archive while
+      extracting. With v2.2 PclZip returns a new error status for a file using an unsupported
+      compression method. New status is "unsupported_compression". New error code is
+      PCLZIP_ERR_UNSUPPORTED_COMPRESSION.
+    - Add optional attribute PCLZIP_OPT_STOP_ON_ERROR. This will stop the extract of files
+      when errors like 'a folder with same name exists' or 'a newer file exists' or
+      'a write protected file' exists, rather than set a status for the concerning file
+      and resume the extract of the zip.
+    - Add optional attribute PCLZIP_OPT_REPLACE_NEWER. This will force, during an extract' the
+      replacement of the file, even if a  newer version of the file exists.
+      Note that today if a file with the same name already exists but is older it will be
+      replaced by the extracted one.
+    - Improve PclZipUtilOption()
+    - Support of zip archive with trailing bytes. Before 2.2, PclZip checks that the central
+      directory structure is the last data in the archive. Crypt encryption/decryption of
+      zip archive put trailing 0 bytes after decryption. PclZip is now supporting this.
+
+  Version 2.1 :
+    - Add the ability to abort the extraction by using a user callback function.
+      The user can now return the value '2' in its callback which indicates to stop the
+      extraction. For a pre call-back extract is stopped before the extration of the current
+      file. For a post call back, the extraction is stopped after.
+    - Add the ability to extract a file (or several files) directly in the standard output.
+      This is done by the new parameter PCLZIP_OPT_EXTRACT_IN_OUTPUT with method extract().
+    - Add support for parameters PCLZIP_OPT_COMMENT, PCLZIP_OPT_ADD_COMMENT,
+      PCLZIP_OPT_PREPEND_COMMENT. This will create, replace, add, or prepend comments
+      in the zip archive.
+    - When merging two archives, the comments are not any more lost, but merged, with a
+      blank space separator.
+    - Corrected bug : Files are not deleted when all files are asked to be deleted.
+    - Corrected bug : Folders with name '0' made PclZip to abort the create or add feature.
+
+
+  Version 2.0 :
+    ***** Warning : Some new features may break the backward compatibility for your scripts.
+                    Please carefully read the readme file.
+    - Add the ability to delete by Index, name and regular expression. This feature is
+      performed by the method delete(), which uses the optional parameters
+      PCLZIP_OPT_BY_INDEX, PCLZIP_OPT_BY_NAME, PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG.
+    - Add the ability to extract by regular expression. To extract by regexp you must use the method
+      extract(), with the option PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG
+      (depending if you want to use ereg() or preg_match() syntax) followed by the
+      regular expression pattern.
+    - Add the ability to extract by index, directly with the extract() method. This is a
+      code improvment of the extractByIndex() method.
+    - Add the ability to extract by name. To extract by name you must use the method
+      extract(), with the option PCLZIP_OPT_BY_NAME followed by the filename to
+      extract or an array of filenames to extract. To extract all a folder, use the folder
+      name rather than the filename with a '/' at the end.
+    - Add the ability to add files without compression. This is done with a new attribute
+      which is PCLZIP_OPT_NO_COMPRESSION.
+    - Add the attribute PCLZIP_OPT_EXTRACT_AS_STRING, which allow to extract a file directly
+      in a string without using any file (or temporary file).
+    - Add constant PCLZIP_SEPARATOR for static configuration of filename separators in a single string.
+      The default separator is now a comma (,) and not any more a blank space.
+      THIS BREAK THE BACKWARD COMPATIBILITY : Please check if this may have an impact with
+      your script.
+    - Improve algorythm performance by removing the use of temporary files when adding or
+      extracting files in an archive.
+    - Add (correct) detection of empty filename zipping. This can occurs when the removed
+      path is the same
+      as a zipped dir. The dir is not zipped (['status'] = filtered), only its content.
+    - Add better support for windows paths (thanks for help from manus@manusfreedom.com).
+    - Corrected bug : When the archive file already exists with size=0, the add() method
+      fails. Corrected in 2.0.
+    - Remove the use of OS_WINDOWS constant. Use php_uname() function rather.
+    - Control the order of index ranges in extract by index feature.
+    - Change the internal management of folders (better handling of internal flag).
+
+
+  Version 1.3 :
+    - Removing the double include check. This is now done by include_once() and require_once()
+      PHP directives.
+    - Changing the error handling mecanism : Remove the use of an external error library.
+      The former PclError...() functions are replaced by internal equivalent methods.
+      By changing the environment variable PCLZIP_ERROR_EXTERNAL you can still use the former library.
+      Introducing the use of constants for error codes rather than integer values. This will help
+      in futur improvment.
+      Introduction of error handling functions like errorCode(), errorName() and errorInfo().
+    - Remove the deprecated use of calling function with arguments passed by reference.
+    - Add the calling of extract(), extractByIndex(), create() and add() functions
+      with variable options rather than fixed arguments.
+    - Add the ability to remove all the file path while extracting or adding,
+      without any need to specify the path to remove.
+      This is available for extract(), extractByIndex(), create() and add() functionS by using
+      the new variable options parameters :
+      - PCLZIP_OPT_REMOVE_ALL_PATH : by indicating this option while calling the fct.
+    - Ability to change the mode of a file after the extraction (chmod()).
+      This is available for extract() and extractByIndex() functionS by using
+      the new variable options parameters.
+      - PCLZIP_OPT_SET_CHMOD : by setting the value of this option.
+    - Ability to definition call-back options. These call-back will be called during the adding,
+      or the extracting of file (extract(), extractByIndex(), create() and add() functions) :
+      - PCLZIP_CB_PRE_EXTRACT : will be called before each extraction of a file. The user
+        can trigerred the change the filename of the extracted file. The user can triggered the
+        skip of the extraction. This is adding a 'skipped' status in the file list result value.
+      - PCLZIP_CB_POST_EXTRACT : will be called after each extraction of a file.
+        Nothing can be triggered from that point.
+      - PCLZIP_CB_PRE_ADD : will be called before each add of a file. The user
+        can trigerred the change the stored filename of the added file. The user can triggered the
+        skip of the add. This is adding a 'skipped' status in the file list result value.
+      - PCLZIP_CB_POST_ADD : will be called after each add of a file.
+        Nothing can be triggered from that point.
+    - Two status are added in the file list returned as function result : skipped & filename_too_long
+      'skipped' is used when a call-back function ask for skipping the file.
+      'filename_too_long' is used while adding a file with a too long filename to archive (the file is
+      not added)
+    - Adding the function PclZipUtilPathInclusion(), that check the inclusion of a path into
+      a directory.
+    - Add a check of the presence of the archive file before some actions (like list, ...)
+    - Add the initialisation of field "index" in header array. This means that by
+      default index will be -1 when not explicitly set by the methods.
+
+  Version 1.2 :
+    - Adding a duplicate function.
+    - Adding a merge function. The merge function is a "quick merge" function,
+      it just append the content of an archive at the end of the first one. There
+      is no check for duplicate files or more recent files.
+    - Improve the search of the central directory end.
+
+  Version 1.1.2 :
+
+    - Changing the license of PclZip. PclZip is now released under the GNU / LGPL license
+      (see License section).
+    - Adding the optional support of a static temporary directory. You will need to configure
+      the constant PCLZIP_TEMPORARY_DIR if you want to use this feature.
+    - Improving the rename() function. In some cases rename() does not work (different
+      Filesystems), so it will be replaced by a copy() + unlink() functions.
+
+  Version 1.1.1 :
+
+    - Maintenance release, no new feature.
+
+  Version 1.1 :
+
+    - New method Add() : adding files in the archive
+    - New method ExtractByIndex() : partial extract of the archive, files are identified by
+      their index in the archive
+    - New method DeleteByIndex() : delete some files/folder entries from the archive,
+      files are identified by their index in the archive.
+    - Adding a test of the zlib extension presence. If not present abort the script.
+
+  Version 1.0.1 :
+
+    - No new feature
+
+
+3 - Corrected bugs
+==================
+
+  Corrected in Version 2.0 :
+    - Corrected : During an extraction, if a call-back fucntion is used and try to skip
+                  a file, all the extraction process is stopped.
+
+  Corrected in Version 1.3 :
+    - Corrected : Support of static synopsis for method extract() is broken.
+    - Corrected : invalid size of archive content field (0xFF) should be (0xFFFF).
+    - Corrected : When an extract is done with a remove_path parameter, the entry for
+      the directory with exactly the same path is not skipped/filtered.
+    - Corrected : extractByIndex() and deleteByIndex() were not managing index in the
+      right way. For example indexes '1,3-5,11' will only extract files 1 and 11. This
+      is due to a sort of the index resulting table that puts 11 before 3-5 (sort on
+      string and not interger). The sort is temporarilly removed, this means that
+      you must provide a sorted list of index ranges.
+
+  Corrected in Version 1.2 :
+
+    - Nothing.
+
+  Corrected in Version 1.1.2 :
+
+    - Corrected : Winzip is unable to delete or add new files in a PclZip created archives.
+
+  Corrected in Version 1.1.1 :
+
+    - Corrected : When archived file is not compressed (0% compression), the
+      extract method fails.
+
+  Corrected in Version 1.1 :
+
+    - Corrected : Adding a complete tree of folder may result in a bad archive
+      creation.
+
+  Corrected in Version 1.0.1 :
+
+    - Corrected : Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024).
+
+
+4 - Known bugs or limitations
+=============================
+
+  Please publish bugs reports in SourceForge :
+    http://sourceforge.net/tracker/?group_id=40254&atid=427564
+
+  In Version 2.x :
+    - PclZip does only support file uncompressed or compressed with deflate (compression method 8)
+    - PclZip does not support password protected zip archive
+    - Some concern were seen when changing mtime of a file while archiving.
+      Seems to be linked to Daylight Saving Time (PclTest_changing_mtime).
+
+  In Version 1.2 :
+
+    - merge() methods does not check for duplicate files or last date of modifications.
+
+  In Version 1.1 :
+
+    - Limitation : Using 'extract' fields in the file header in the zip archive is not supported.
+    - WinZip is unable to delete a single file in a PclZip created archive. It is also unable to
+      add a file in a PclZip created archive. (Corrected in v.1.2)
+
+  In Version 1.0.1 :
+
+    - Adding a complete tree of folder may result in a bad archive
+      creation. (Corrected in V.1.1).
+    - Path given to methods must be in the unix format (/) and not the Windows format (\).
+      Workaround : Use only / directory separators.
+    - PclZip is using temporary files that are sometime the name of the file with a .tmp or .gz
+      added suffix. Files with these names may already exist and may be overwritten.
+      Workaround : none.
+    - PclZip does not check if the zlib extension is present. If it is absent, the zip
+      file is not created and the lib abort without warning.
+      Workaround : enable the zlib extension on the php install
+
+  In Version 1.0 :
+
+    - Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024).
+      (Corrected in v.1.0.1)
+    - Limitation : Multi-disk zip archive are not supported.
+
+
+5 - License
+===========
+
+  Since version 1.1.2, PclZip Library is released under GNU/LGPL license.
+  This library is free, so you can use it at no cost.
+
+  HOWEVER, if you release a script, an application, a library or any kind of
+  code using PclZip library (or a part of it), YOU MUST :
+  - Indicate in the documentation (or a readme file), that your work
+    uses PclZip Library, and make a reference to the author and the web site
+    http://www.phpconcept.net
+  - Gives the ability to the final user to update the PclZip libary.
+
+  I will also appreciate that you send me a mail (vincent@phpconcept.net), just to
+  be aware that someone is using PclZip.
+
+  For more information about GNU/LGPL license : http://www.gnu.org
+
+6 - Warning
+=================
+
+  This library and the associated files are non commercial, non professional work.
+  It should not have unexpected results. However if any damage is caused by this software
+  the author can not be responsible.
+  The use of this software is at the risk of the user.
+
+7 - Documentation
+=================
+  PclZip User Manuel is available in English on PhpConcept : http://www.phpconcept.net/pclzip/man/en/index.php
+  A Russian translation was done by Feskov Kuzma : http://php.russofile.ru/ru/authors/unsort/zip/
+
+8 - Author
+==========
+
+  This software was written by Vincent Blavet (vincent@phpconcept.net) on its leasure time.
+
+9 - Contribute
+==============
+  If you want to contribute to the development of PclZip, please contact vincent@phpconcept.net.
+  If you can help in financing PhpConcept hosting service, please go to
+  http://www.phpconcept.net/soutien.php
diff --git a/htdocs/mailmanspip/class/mailmanspip.class.php b/htdocs/mailmanspip/class/mailmanspip.class.php
deleted file mode 100644 (file)
index 46701a4..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-<?php
-/* Copyright (C) 2002-2003  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
- * Copyright (C) 2002-2003  Jean-Louis Bergamo      <jlb@j1b.org>
- * Copyright (C) 2004-2013  Laurent Destailleur     <eldy@users.sourceforge.net>
- * Copyright (C) 2004       Sebastien Di Cintio     <sdicintio@ressource-toi.org>
- * Copyright (C) 2004       Benoit Mortier          <benoit.mortier@opensides.be>
- * Copyright (C) 2009       Regis Houssin           <regis.houssin@inodbox.com>
- * Copyright (C) 2012       Marcos García           <marcosgdf@gmail.com>
- * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file       htdocs/mailmanspip/class/mailmanspip.class.php
- *     \ingroup    member
- *     \brief      File of class to manage mailman and spip actions
- */
-
-require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
-require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
-
-
-/**
- *     Class to manage mailman and spip
- */
-class MailmanSpip
-{
-       /**
-        * @var DoliDB Database handler.
-        */
-       public $db;
-
-       /**
-        * @var string Error code (or message)
-        */
-       public $error = '';
-
-       /**
-        * @var string[]        Array of error strings
-        */
-       public $errors = array();
-
-       public $mladded_ok;
-       public $mladded_ko;
-       public $mlremoved_ok;
-       public $mlremoved_ko;
-
-
-       /**
-        *      Constructor
-        *
-        *      @param          DoliDB          $db             Database handler
-        */
-       public function __construct($db)
-       {
-               $this->db = $db;
-       }
-
-       /**
-        * Function used to check if SPIP is enabled on the system
-        *
-        * @return boolean
-        */
-       public function isSpipEnabled()
-       {
-               if (getDolGlobalInt("ADHERENT_USE_SPIP") == 1) {
-                       return true;
-               }
-
-               return false;
-       }
-
-       /**
-        * Function used to check if the SPIP config is correct
-        *
-        * @return boolean
-        */
-       public function checkSpipConfig()
-       {
-               if (getDolGlobalString('ADHERENT_SPIP_SERVEUR') != '' && getDolGlobalString('ADHERENT_SPIP_USER') != '' && getDolGlobalString('ADHERENT_SPIP_PASS') != '' && getDolGlobalString('ADHERENT_SPIP_DB') != '') {
-                       return true;
-               }
-
-               return false;
-       }
-
-       /**
-        * Function used to connect to SPIP
-        *
-        * @return boolean|DoliDB               Boolean of DoliDB
-        */
-       public function connectSpip()
-       {
-               $resource = getDoliDBInstance('mysql', ADHERENT_SPIP_SERVEUR, ADHERENT_SPIP_USER, ADHERENT_SPIP_PASS, ADHERENT_SPIP_DB, ADHERENT_SPIP_PORT);
-
-               if ($resource->ok) {
-                       return $resource;
-               }
-
-               dol_syslog('Error when connecting to SPIP '.ADHERENT_SPIP_SERVEUR.' '.ADHERENT_SPIP_USER.' '.ADHERENT_SPIP_PASS.' '.ADHERENT_SPIP_DB, LOG_ERR);
-
-               return false;
-       }
-
-       /**
-        * Function used to connect to Mailman
-        *
-        * @param       Adherent        $object         Object with the data
-        * @param       string  $url            Mailman URL to be called with patterns
-        * @param       string  $list           Name of mailing-list
-        * @return      mixed                           Boolean or string
-        */
-       private function callMailman($object, $url, $list)
-       {
-               global $conf;
-
-               //Patterns that are going to be replaced with their original value
-               $patterns = array(
-                       '%LISTE%',
-                       '%EMAIL%',
-                       '%PASSWORD%',
-                       '%MAILMAN_ADMINPW%'
-               );
-               $replace = array(
-                       $list,
-                       $object->email,
-                       $object->pass,
-                       $conf->global->ADHERENT_MAILMAN_ADMIN_PASSWORD
-               );
-
-               $curl_url = str_replace($patterns, $replace, $url);
-               dol_syslog('Calling Mailman: '.$curl_url);
-
-               $result = getURLContent($curl_url);
-
-               return $result['content'];
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        *  Fonction qui donne les droits redacteurs dans spip
-        *
-        *      @param  Adherent        $object         Object with data (->firstname, ->lastname, ->email and ->login)
-        *  @return     int                                     =0 if KO, >0 if OK
-        */
-       public function add_to_spip($object)
-       {
-               // phpcs:enable
-               dol_syslog(get_class($this)."::add_to_spip");
-
-               if ($this->isSpipEnabled()) {
-                       if ($this->checkSpipConfig()) {
-                               $mydb = $this->connectSpip();
-
-                               if ($mydb) {
-                                       require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
-                                       $mdpass = dol_hash($object->pass);
-                                       $htpass = crypt($object->pass, makesalt());
-                                       $query = "INSERT INTO spip_auteurs (nom, email, login, pass, htpass, alea_futur, statut) VALUES(\"".dolGetFirstLastname($object->firstname, $object->lastname)."\",\"".$object->email."\",\"".$object->login."\",\"$mdpass\",\"$htpass\",FLOOR(32000*RAND()),\"1comite\")";
-
-                                       $result = $mydb->query($query);
-
-                                       $mydb->close();
-
-                                       if ($result) {
-                                               return 1;
-                                       } else {
-                                               $this->error = $mydb->lasterror();
-                                       }
-                               } else {
-                                       $this->error = 'Failed to connect to SPIP';
-                               }
-                       } else {
-                               $this->error = 'BadSPIPConfiguration';
-                       }
-               } else {
-                       $this->error = 'SPIPNotEnabled';
-               }
-
-               return 0;
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        *  Fonction qui enleve les droits redacteurs dans spip
-        *
-        *      @param  Adherent        $object         Object with data (->login)
-        *  @return     int                                     =0 if KO, >0 if OK
-        */
-       public function del_to_spip($object)
-       {
-               // phpcs:enable
-               dol_syslog(get_class($this)."::del_to_spip");
-
-               if ($this->isSpipEnabled()) {
-                       if ($this->checkSpipConfig()) {
-                               $mydb = $this->connectSpip();
-
-                               if ($mydb) {
-                                       $query = "DELETE FROM spip_auteurs WHERE login = '".$mydb->escape($object->login)."'";
-
-                                       $result = $mydb->query($query);
-
-                                       $mydb->close();
-
-                                       if ($result) {
-                                               return 1;
-                                       } else {
-                                               $this->error = $mydb->lasterror();
-                                       }
-                               } else {
-                                       $this->error = 'Failed to connect to SPIP';
-                               }
-                       } else {
-                               $this->error = 'BadSPIPConfiguration';
-                       }
-               } else {
-                       $this->error = 'SPIPNotEnabled';
-               }
-
-               return 0;
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        *  Fonction qui dit si cet utilisateur est un redacteur existant dans spip
-        *
-        *      @param  object  $object         Object with data (->login)
-        *  @return int                         1=exists, 0=does not exists, -1=error
-        */
-       public function is_in_spip($object)
-       {
-               // phpcs:enable
-               if ($this->isSpipEnabled()) {
-                       if ($this->checkSpipConfig()) {
-                               $mydb = $this->connectSpip();
-
-                               if ($mydb) {
-                                       $query = "SELECT login FROM spip_auteurs WHERE login = '".$mydb->escape($object->login)."'";
-
-                                       $result = $mydb->query($query);
-
-                                       if ($result) {
-                                               if ($mydb->num_rows($result)) {
-                                                       // nous avons au moins une reponse
-                                                       $mydb->close();
-                                                       return 1;
-                                               } else {
-                                                       // nous n'avons pas de reponse => n'existe pas
-                                                       $mydb->close();
-                                                       return 0;
-                                               }
-                                       } else {
-                                               $this->error = $mydb->lasterror();
-                                               $mydb->close();
-                                       }
-                               } else {
-                                       $this->error = 'Failed to connect to SPIP';
-                               }
-                       } else {
-                               $this->error = 'BadSPIPConfiguration';
-                       }
-               } else {
-                       $this->error = 'SPIPNotEnabled';
-               }
-
-               return -1;
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        *  Subscribe an email to all mailing-lists
-        *
-        *      @param  Adherent        $object         Object with data (->email, ->pass, ->element, ->type)
-        *  @param      array   $listes         To force mailing-list (string separated with ,)
-        *  @return     int                                     <0 if KO, >=0 if OK
-        */
-       public function add_to_mailman($object, $listes = '')
-       {
-               // phpcs:enable
-               global $conf, $langs, $user;
-
-               dol_syslog(get_class($this)."::add_to_mailman");
-
-               $this->mladded_ok = array();
-               $this->mladded_ko = array();
-
-               if (!function_exists("curl_init")) {
-                       $langs->load("errors");
-                       $this->error = $langs->trans("ErrorFunctionNotAvailableInPHP", "curl_init");
-                       return -1;
-               }
-
-               if ($conf->adherent->enabled) { // Synchro for members
-                       if (!empty($conf->global->ADHERENT_MAILMAN_URL)) {
-                               if ($listes == '' && !empty($conf->global->ADHERENT_MAILMAN_LISTS)) {
-                                       $lists = explode(',', $conf->global->ADHERENT_MAILMAN_LISTS);
-                               } else {
-                                       $lists = explode(',', $listes);
-                               }
-
-                               $categstatic = new Categorie($this->db);
-
-                               foreach ($lists as $list) {
-                                       // Filter on type something (ADHERENT_MAILMAN_LISTS = "mailinglist0,TYPE:typevalue:mailinglist1,CATEG:categvalue:mailinglist2")
-                                       $tmp = explode(':', $list);
-                                       if (!empty($tmp[2])) {
-                                               $list = $tmp[2];
-                                               if ($object->element == 'member' && $tmp[0] == 'TYPE' && $object->type != $tmp[1]) {    // Filter on member type label
-                                                       dol_syslog("We ignore list ".$list." because object member type ".$object->type." does not match ".$tmp[1], LOG_DEBUG);
-                                                       continue;
-                                               }
-                                               if ($object->element == 'member' && $tmp[0] == 'CATEG' && !in_array($tmp[1], $categstatic->containing($object->id, 'member', 'label'))) {    // Filter on member category
-                                                       dol_syslog("We ignore list ".$list." because object member is not into category ".$tmp[1], LOG_DEBUG);
-                                                       continue;
-                                               }
-                                       }
-
-                                       //We call Mailman to subscribe the user
-                                       $result = $this->callMailman($object, $conf->global->ADHERENT_MAILMAN_URL, $list);
-
-                                       if ($result === false) {
-                                               $this->mladded_ko[$list] = $object->email;
-                                               return -2;
-                                       } else {
-                                               $this->mladded_ok[$list] = $object->email;
-                                       }
-                               }
-                               return count($lists);
-                       } else {
-                               $this->error = "ADHERENT_MAILMAN_URL not defined";
-                               return -1;
-                       }
-               }
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        *  Unsubscribe an email from all mailing-lists
-        *  Used when a user is resiliated
-        *
-        *      @param  Adherent        $object         Object with data (->email, ->pass, ->element, ->type)
-        *  @param      array   $listes     To force mailing-list (string separated with ,)
-        *  @return int                         <0 if KO, >=0 if OK
-        */
-       public function del_to_mailman($object, $listes = '')
-       {
-               // phpcs:enable
-               global $conf, $langs, $user;
-
-               dol_syslog(get_class($this)."::del_to_mailman");
-
-               $this->mlremoved_ok = array();
-               $this->mlremoved_ko = array();
-
-               if (!function_exists("curl_init")) {
-                       $langs->load("errors");
-                       $this->error = $langs->trans("ErrorFunctionNotAvailableInPHP", "curl_init");
-                       return -1;
-               }
-
-               if ($conf->adherent->enabled) { // Synchro for members
-                       if (!empty($conf->global->ADHERENT_MAILMAN_UNSUB_URL)) {
-                               if ($listes == '' && !empty($conf->global->ADHERENT_MAILMAN_LISTS)) {
-                                       $lists = explode(',', $conf->global->ADHERENT_MAILMAN_LISTS);
-                               } else {
-                                       $lists = explode(',', $listes);
-                               }
-
-                               $categstatic = new Categorie($this->db);
-
-                               foreach ($lists as $list) {
-                                       // Filter on type something (ADHERENT_MAILMAN_LISTS = "mailinglist0,TYPE:typevalue:mailinglist1,CATEG:categvalue:mailinglist2")
-                                       $tmp = explode(':', $list);
-                                       if (!empty($tmp[2])) {
-                                               $list = $tmp[2];
-                                               if ($object->element == 'member' && $tmp[0] == 'TYPE' && $object->type != $tmp[1]) {    // Filter on member type label
-                                                       dol_syslog("We ignore list ".$list." because object member type ".$object->type." does not match ".$tmp[1], LOG_DEBUG);
-                                                       continue;
-                                               }
-                                               if ($object->element == 'member' && $tmp[0] == 'CATEG' && !in_array($tmp[1], $categstatic->containing($object->id, 'member', 'label'))) {    // Filter on member category
-                                                       dol_syslog("We ignore list ".$list." because object member is not into category ".$tmp[1], LOG_DEBUG);
-                                                       continue;
-                                               }
-                                       }
-
-                                       //We call Mailman to unsubscribe the user
-                                       $result = $this->callMailman($object, $conf->global->ADHERENT_MAILMAN_UNSUB_URL, $list);
-
-                                       if ($result === false) {
-                                               $this->mlremoved_ko[$list] = $object->email;
-                                               return -2;
-                                       } else {
-                                               $this->mlremoved_ok[$list] = $object->email;
-                                       }
-                               }
-                               return count($lists);
-                       } else {
-                               $this->error = "ADHERENT_MAILMAN_UNSUB_URL not defined";
-                               return -1;
-                       }
-               }
-       }
-}
diff --git a/htdocs/modulebuilder/README.md b/htdocs/modulebuilder/README.md
deleted file mode 100644 (file)
index 26b0ecf..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-Module Builder
-==============
-
-This is a module to provide embedded tools to develop your own application/features inside Dolibarr ERP CRM software.
-It provide tools for module developers to kickstart their project and give an hands-on sample of which features Dolibarr
-has to offer for module development.
-
-If you don't need to develop your own module/application, you just don't need this.
-
-After enabling this module, you should find features to generate or edit modules/application from menu *Home - Tools - Module builder*
-
-Documentation
--------------
-
-[Module tutorial](https://wiki.dolibarr.org/index.php/Module_development)
-
-[Dolibarr development](https://wiki.dolibarr.org/index.php/Developer_documentation)
diff --git a/htdocs/modulebuilder/admin/setup.php b/htdocs/modulebuilder/admin/setup.php
deleted file mode 100644 (file)
index 4c7e597..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-<?php
-/* Copyright (C) 2018 Nicolas ZABOURI   <info@inovea-conseil.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *  \file       htdocs/modulebuilder/admin/setup.php
- *  \ingroup    modulebuilder
- *  \brief      Page setup for modulebuilder module
- */
-require '../../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
-
-global $conf, $langs, $user, $db;
-$langs->loadLangs(array("admin", "other", "modulebuilder"));
-
-if (!$user->admin || !isModEnabled('modulebuilder')) {
-       accessforbidden();
-}
-
-$action = GETPOST('action', 'aZ09');
-$backtopage = GETPOST('backtopage', 'alpha');
-
-
-/*
- * Actions
- */
-
-if ($action == "update") {
-       $res1 = dolibarr_set_const($db, 'MODULEBUILDER_SPECIFIC_README', GETPOST('MODULEBUILDER_SPECIFIC_README', 'restricthtml'), 'chaine', 0, '', $conf->entity);
-       $res2 = dolibarr_set_const($db, 'MODULEBUILDER_ASCIIDOCTOR', GETPOST('MODULEBUILDER_ASCIIDOCTOR', 'alphanohtml'), 'chaine', 0, '', $conf->entity);
-       $res3 = dolibarr_set_const($db, 'MODULEBUILDER_ASCIIDOCTORPDF', GETPOST('MODULEBUILDER_ASCIIDOCTORPDF', 'alphanohtml'), 'chaine', 0, '', $conf->entity);
-       $res4 = dolibarr_set_const($db, 'MODULEBUILDER_SPECIFIC_EDITOR_NAME', GETPOST('MODULEBUILDER_SPECIFIC_EDITOR_NAME', 'alphanohtml'), 'chaine', 0, '', $conf->entity);
-       $res5 = dolibarr_set_const($db, 'MODULEBUILDER_SPECIFIC_EDITOR_URL', GETPOST('MODULEBUILDER_SPECIFIC_EDITOR_URL', 'alphanohtml'), 'chaine', 0, '', $conf->entity);
-       $res6 = dolibarr_set_const($db, 'MODULEBUILDER_SPECIFIC_FAMILY', GETPOST('MODULEBUILDER_SPECIFIC_FAMILY', 'alphanohtml'), 'chaine', 0, '', $conf->entity);
-       $res7 = dolibarr_set_const($db, 'MODULEBUILDER_SPECIFIC_AUTHOR', GETPOST('MODULEBUILDER_SPECIFIC_AUTHOR', 'html'), 'chaine', 0, '', $conf->entity);
-       $res8 = dolibarr_set_const($db, 'MODULEBUILDER_SPECIFIC_VERSION', GETPOST('MODULEBUILDER_SPECIFIC_VERSION', 'alphanohtml'), 'chaine', 0, '', $conf->entity);
-       if ($res1 < 0 || $res2 < 0 || $res3 < 0 || $res4 < 0 || $res5 < 0 || $res6 < 0 || $res7 < 0 || $res8 < 0) {
-               setEventMessages('ErrorFailedToSaveDate', null, 'errors');
-               $db->rollback();
-       } else {
-               setEventMessages('RecordModifiedSuccessfully', null, 'mesgs');
-               $db->commit();
-       }
-}
-
-$reg = array();
-if (preg_match('/set_(.*)/', $action, $reg)) {
-       $code = $reg[1];
-       $values = GETPOST($code);
-       if (is_array($values)) {
-               $values = implode(',', $values);
-       }
-
-       if (dolibarr_set_const($db, $code, $values, 'chaine', 0, '', $conf->entity) > 0) {
-               header("Location: ".$_SERVER["PHP_SELF"]);
-               exit;
-       } else {
-               dol_print_error($db);
-       }
-}
-
-if (preg_match('/del_(.*)/', $action, $reg)) {
-       $code = $reg[1];
-       if (dolibarr_del_const($db, $code, 0) > 0) {
-               Header("Location: ".$_SERVER["PHP_SELF"]);
-               exit;
-       } else {
-               dol_print_error($db);
-       }
-}
-
-
-/*
- *     View
- */
-
-$form = new Form($db);
-
-$help_url = '';
-llxHeader('', $langs->trans("ModulebuilderSetup"), $help_url);
-
-$linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php').'">'.$langs->trans("BackToModuleList").'</a>';
-
-print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-print '<input type="hidden" name="token" value="'.newToken().'">';
-print '<input type="hidden" name="action" value="update">';
-
-print load_fiche_titre($langs->trans("ModuleSetup").' '.$langs->trans('Modulebuilder'), $linkback);
-
-if (GETPOST('withtab', 'alpha')) {
-       print dol_get_fiche_head($head, 'modulebuilder', '', -1);
-}
-
-print '<span class="opacitymedium">'.$langs->trans("ModuleBuilderDesc")."</span><br>\n";
-
-print '<br>';
-
-print '<table class="noborder centpercent">';
-
-print '<tr class="liste_titre">';
-print '<td>'.$langs->trans("Parameter").'</td>';
-print '<td>'.$langs->trans("Value").'</td>';
-print "</tr>\n";
-
-
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2) {
-       // What is use case of this 2 options ?
-
-       print '<tr class="oddeven">';
-       print '<td>'.$langs->trans("UseAboutPage").'</td>';
-       print '<td>';
-       if ($conf->use_javascript_ajax) {
-               print ajax_constantonoff('MODULEBUILDER_USE_ABOUT');
-       } else {
-               if (empty($conf->global->MODULEBUILDER_USE_ABOUT)) {
-                       print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=set_MODULEBUILDER_USE_ABOUT&token='.newToken().'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
-               } else {
-                       print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=del_MODULEBUILDER_USE_ABOUT&token='.newToken().'">'.img_picto($langs->trans("Enabled"), 'on').'</a>';
-               }
-       }
-       print '</td></tr>';
-}
-
-print '<tr class="oddeven">';
-print '<td>'.$langs->trans("UseSpecificEditorName").'</td>';
-print '<td>';
-print '<input type="text" name="MODULEBUILDER_SPECIFIC_EDITOR_NAME" value="'.$conf->global->MODULEBUILDER_SPECIFIC_EDITOR_NAME.'">';
-print '</td>';
-print '</tr>';
-
-print '<tr class="oddeven">';
-print '<td>'.$langs->trans("UseSpecificEditorURL").'</td>';
-print '<td>';
-print '<input type="text" name="MODULEBUILDER_SPECIFIC_EDITOR_URL" value="'.$conf->global->MODULEBUILDER_SPECIFIC_EDITOR_URL.'">';
-print '</td>';
-print '</tr>';
-
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2) {
-       print '<tr class="oddeven">';
-       print '<td>'.$langs->trans("UseSpecificFamily").'</td>';
-       print '<td>';
-       print '<input type="text" name="MODULEBUILDER_SPECIFIC_FAMILY" value="'.$conf->global->MODULEBUILDER_SPECIFIC_FAMILY.'">';
-       print '</td>';
-       print '</tr>';
-
-       print '<tr class="oddeven">';
-       print '<td>'.$langs->trans("UseSpecificAuthor").'</td>';
-       print '<td>';
-       print '<input type="text" name="MODULEBUILDER_SPECIFIC_AUTHOR" value="'.$conf->global->MODULEBUILDER_SPECIFIC_AUTHOR.'">';
-       print '</td>';
-       print '</tr>';
-
-       print '<tr class="oddeven">';
-       print '<td>'.$langs->trans("UseSpecificVersion").'</td>';
-       print '<td>';
-       print '<input type="text" name="MODULEBUILDER_SPECIFIC_VERSION" value="'.$conf->global->MODULEBUILDER_SPECIFIC_VERSION.'">';
-       print '</td>';
-       print '</tr>';
-}
-
-print '<tr class="oddeven">';
-print '<td>'.$langs->trans("UseSpecificReadme").'</td>';
-print '<td>';
-print '<textarea class="centpercent" rows="20" name="MODULEBUILDER_SPECIFIC_README">'.$conf->global->MODULEBUILDER_SPECIFIC_README.'</textarea>';
-print '</td>';
-print '</tr>';
-
-print '<tr class="oddeven">';
-print '<td>'.$langs->trans("AsciiToHtmlConverter").'</td>';
-print '<td>';
-print '<input type="text" name="MODULEBUILDER_ASCIIDOCTOR" value="'.$conf->global->MODULEBUILDER_ASCIIDOCTOR.'">';
-print ' '.$langs->trans("Example").': asciidoc, asciidoctor';
-print '</td>';
-print '</tr>';
-
-print '<tr class="oddeven">';
-print '<td>'.$langs->trans("AsciiToPdfConverter").'</td>';
-print '<td>';
-print '<input type="text" name="MODULEBUILDER_ASCIIDOCTORPDF" value="'.$conf->global->MODULEBUILDER_ASCIIDOCTORPDF.'">';
-print ' '.$langs->trans("Example").': asciidoctor-pdf';
-print '</td>';
-print '</tr>';
-
-print '</table>';
-
-print $form->buttonsSaveCancel("Save", '');
-
-if (GETPOST('withtab', 'alpha')) {
-       print dol_get_fiche_end();
-}
-
-print '<br>';
-
-print '</form>';
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php
deleted file mode 100644 (file)
index f871d91..0000000
+++ /dev/null
@@ -1,4682 +0,0 @@
-<?php
-/* Copyright (C) 2004-2019 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2018-2019        Nicolas ZABOURI      <info@inovea-conseil.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- *
- * You can also make a direct call the page with parameter like this:
- * htdocs/modulebuilder/index.php?module=Inventory@/pathtodolibarr/htdocs/product
- */
-
-/**
- *       \file       htdocs/modulebuilder/index.php
- *       \brief      Home page for module builder module
- *
- *       You can add parameter dirins=/home/ldestailleur/git/dolibarr/htdocs/mymodule to force generation of module
- *       into the dirins directory.
- */
-
-if (!defined('NOSCANPOSTFORINJECTION')) {
-       define('NOSCANPOSTFORINJECTION', '1'); // Do not check anti SQL+XSS injection attack test
-}
-
-// Load Dolibarr environment
-require '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/modulebuilder.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php';
-
-// Load translation files required by the page
-$langs->loadLangs(array("admin", "modulebuilder", "other", "cron", "errors"));
-
-// GET Parameters
-$action  = GETPOST('action', 'aZ09');
-$confirm = GETPOST('confirm', 'alpha');
-$cancel  = GETPOST('cancel', 'alpha');
-
-$sortfield = GETPOST('sortfield', 'alpha');
-$sortorder = GETPOST('sortorder', 'alpha');
-
-$module = GETPOST('module', 'alpha');
-$tab = GETPOST('tab', 'aZ09');
-$tabobj = GETPOST('tabobj', 'alpha');
-$tabdic = GETPOST('tabdic', 'alpha');
-$propertykey = GETPOST('propertykey', 'alpha');
-if (empty($module)) {
-       $module = 'initmodule';
-}
-if (empty($tab)) {
-       $tab = 'description';
-}
-if (empty($tabobj)) {
-       $tabobj = 'newobjectifnoobj';
-}
-if (empty($tabdic)) {
-       $tabdic = 'newdicifnodic';
-}
-$file = GETPOST('file', 'alpha');
-
-$modulename = dol_sanitizeFileName(GETPOST('modulename', 'alpha'));
-$objectname = dol_sanitizeFileName(GETPOST('objectname', 'alpha'));
-$dicname = dol_sanitizeFileName(GETPOST('dicname', 'alpha'));
-$editorname= GETPOST('editorname', 'alpha');
-$editorurl= GETPOST('editorurl', 'alpha');
-$version= GETPOST('version', 'alpha');
-$family= GETPOST('family', 'alpha');
-$picto= GETPOST('idpicto', 'alpha');
-$idmodule= GETPOST('idmodule', 'alpha');
-
-// Security check
-if (!isModEnabled('modulebuilder')) {
-       accessforbidden('Module ModuleBuilder not enabled');
-}
-if (!$user->hasRight("modulebuilder", "run")) {
-       accessforbidden('ModuleBuilderNotAllowed');
-}
-
-
-// Dir for custom dirs
-$tmp = explode(',', $dolibarr_main_document_root_alt);
-$dirins = $tmp[0];
-$dirread = $dirins;
-$forceddirread = 0;
-
-$tmpdir = explode('@', $module);
-if (!empty($tmpdir[1])) {
-       $module = $tmpdir[0];
-       $dirread = $tmpdir[1];
-       $forceddirread = 1;
-}
-if (GETPOST('dirins', 'alpha')) {
-       $dirread = $dirins = GETPOST('dirins', 'alpha');
-       $forceddirread = 1;
-}
-
-$FILEFLAG = 'modulebuilder.txt';
-
-$now = dol_now();
-$newmask = 0;
-if (empty($newmask) && !empty($conf->global->MAIN_UMASK)) {
-       $newmask = $conf->global->MAIN_UMASK;
-}
-if (empty($newmask)) { // This should no happen
-       $newmask = '0664';
-}
-
-$result = restrictedArea($user, 'modulebuilder', null);
-
-$error = 0;
-
-$form = new Form($db);
-
-// Define $listofmodules
-$dirsrootforscan = array($dirread);
-
-// Add also the core modules into the list of modules to show/edit
-if ($dirread != DOL_DOCUMENT_ROOT && ($conf->global->MAIN_FEATURES_LEVEL >= 2 || !empty($conf->global->MODULEBUILDER_ADD_DOCUMENT_ROOT))) {
-       $dirsrootforscan[] = DOL_DOCUMENT_ROOT;
-}
-
-// Search modules to edit
-$textforlistofdirs = '<!-- Directory scanned -->'."\n";
-$listofmodules = array();
-$i = 0;
-foreach ($dirsrootforscan as $dirread) {
-       $moduletype = 'external';
-       if ($dirread == DOL_DOCUMENT_ROOT) {
-               $moduletype = 'internal';
-       }
-
-       $dirsincustom = dol_dir_list($dirread, 'directories');
-       if (is_array($dirsincustom) && count($dirsincustom) > 0) {
-               foreach ($dirsincustom as $dircustomcursor) {
-                       $fullname = $dircustomcursor['fullname'];
-                       if (dol_is_file($fullname.'/'.$FILEFLAG)) {
-                               // Get real name of module (MyModule instead of mymodule)
-                               $dirtoscanrel = basename($fullname).'/core/modules/';
-
-                               $descriptorfiles = dol_dir_list(dirname($fullname).'/'.$dirtoscanrel, 'files', 0, 'mod.*\.class\.php$');
-                               if (empty($descriptorfiles)) {  // If descriptor not found into module dir, we look into main module dir.
-                                       $dirtoscanrel = 'core/modules/';
-                                       $descriptorfiles = dol_dir_list($fullname.'/../'.$dirtoscanrel, 'files', 0, 'mod'.strtoupper(basename($fullname)).'\.class\.php$');
-                               }
-                               $modulenamewithcase = '';
-                               $moduledescriptorrelpath = '';
-                               $moduledescriptorfullpath = '';
-
-                               foreach ($descriptorfiles as $descriptorcursor) {
-                                       $modulenamewithcase = preg_replace('/^mod/', '', $descriptorcursor['name']);
-                                       $modulenamewithcase = preg_replace('/\.class\.php$/', '', $modulenamewithcase);
-                                       $moduledescriptorrelpath = $dirtoscanrel.$descriptorcursor['name'];
-                                       $moduledescriptorfullpath = $descriptorcursor['fullname'];
-                                       //var_dump($descriptorcursor);
-                               }
-                               if ($modulenamewithcase) {
-                                       $listofmodules[$dircustomcursor['name']] = array(
-                                               'modulenamewithcase'=>$modulenamewithcase,
-                                               'moduledescriptorrelpath'=> $moduledescriptorrelpath,
-                                               'moduledescriptorfullpath'=>$moduledescriptorfullpath,
-                                               'moduledescriptorrootpath'=>$dirread,
-                                               'moduletype'=>$moduletype
-                                       );
-                               }
-                               //var_dump($listofmodules);
-                       }
-               }
-       }
-
-       if ($forceddirread && empty($listofmodules)) {    // $forceddirread is 1 if we forced dir to read with dirins=... or with module=...@mydir
-               $listofmodules[strtolower($module)] = array(
-                       'modulenamewithcase'=>$module,
-                       'moduledescriptorrelpath'=> 'notyetimplemented',
-                       'moduledescriptorfullpath'=> 'notyetimplemented',
-                       'moduledescriptorrootpath'=> 'notyetimplemented',
-               );
-       }
-
-       // Show description of content
-       $newdircustom = $dirins;
-       if (empty($newdircustom)) {
-               $newdircustom = img_warning();
-       }
-       // If dirread was forced to somewhere else, by using URL
-       // htdocs/modulebuilder/index.php?module=Inventory@/home/ldestailleur/git/dolibarr/htdocs/product
-       if (empty($i)) {
-               $textforlistofdirs .= $langs->trans("DirScanned").' : ';
-       } else {
-               $textforlistofdirs .= ', ';
-       }
-       $textforlistofdirs .= '<strong class="wordbreakimp">'.$dirread.'</strong>';
-       if ($dirread == DOL_DOCUMENT_ROOT) {
-               if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
-                       $textforlistofdirs .= $form->textwithpicto('', $langs->trans("ConstantIsOn", "MAIN_FEATURES_LEVEL"));
-               }
-               if (getDolGlobalString('MODULEBUILDER_ADD_DOCUMENT_ROOT')) {
-                       $textforlistofdirs .= $form->textwithpicto('', $langs->trans("ConstantIsOn", "MODULEBUILDER_ADD_DOCUMENT_ROOT"));
-               }
-       }
-       $i++;
-}
-
-
-/*
- * Actions
- */
-
-if ($dirins && $action == 'initmodule' && $modulename) {
-       $modulename = ucfirst($modulename); // Force first letter in uppercase
-
-       if (preg_match('/[^a-z0-9_]/i', $modulename)) {
-               $error++;
-               setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
-       }
-
-       if (!$error) {
-               $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-               $destdir = $dirins.'/'.strtolower($modulename);
-
-               $arrayreplacement = array(
-                       'mymodule'=>strtolower($modulename),
-                       'MyModule'=>$modulename
-               );
-
-               $result = dolCopyDir($srcdir, $destdir, 0, 0, $arrayreplacement);
-               //dol_mkdir($destfile);
-               if ($result <= 0) {
-                       if ($result < 0) {
-                               $error++;
-                               $langs->load("errors");
-                               setEventMessages($langs->trans("ErrorFailToCopyDir", $srcdir, $destdir), null, 'errors');
-                       } else {
-                               // $result == 0
-                               setEventMessages($langs->trans("AllFilesDidAlreadyExist", $srcdir, $destdir), null, 'warnings');
-                       }
-               }
-
-               // Copy last html.formsetup.class.php' to backport folder
-               $tryToCopyFromSetupClass = true;
-               $backportDest = $destdir .'/backport/v16/core/class';
-               $backportFileSrc = DOL_DOCUMENT_ROOT.'/core/class/html.formsetup.class.php';
-               $backportFileDest = $backportDest.'/html.formsetup.class.php';
-               $result = dol_mkdir($backportDest);
-
-               if ($result < 0) {
-                       $error++;
-                       $langs->load("errors");
-                       setEventMessages($langs->trans("ErrorFailToCreateDir", $backportDest), null, 'errors');
-                       $tryToCopyFromSetupClass = false;
-               }
-
-               if ($tryToCopyFromSetupClass) {
-                       $result = dol_copy($backportFileSrc, $backportFileDest);
-                       if ($result <= 0) {
-                               if ($result < 0) {
-                                       $error++;
-                                       $langs->load("errors");
-                                       setEventMessages($langs->trans("ErrorFailToCopyFile", $backportFileSrc, $backportFileDest), null, 'errors');
-                               } else {
-                                       setEventMessages($langs->trans("FileDidAlreadyExist", $backportFileDest), null, 'warnings');
-                               }
-                       }
-               }
-
-               if (!empty($conf->global->MODULEBUILDER_USE_ABOUT)) {
-                       dol_delete_file($destdir.'/admin/about.php');
-               }
-
-               // Delete dir and files that can be generated in sub tabs later if we need them (we want a minimal module first)
-               dol_delete_dir_recursive($destdir.'/build/doxygen');
-               dol_delete_dir_recursive($destdir.'/core/modules/mailings');
-               dol_delete_dir_recursive($destdir.'/core/modules/'.strtolower($modulename).'');
-               dol_delete_dir_recursive($destdir.'/core/tpl');
-               dol_delete_dir_recursive($destdir.'/core/triggers');
-               dol_delete_dir_recursive($destdir.'/doc');
-               //dol_delete_dir_recursive($destdir.'/.tx');
-               dol_delete_dir_recursive($destdir.'/core/boxes');
-
-               dol_delete_file($destdir.'/admin/myobject_extrafields.php');
-
-               dol_delete_file($destdir.'/sql/data.sql');
-               dol_delete_file($destdir.'/sql/update_x.x.x-y.y.y.sql');
-
-               dol_delete_file($destdir.'/class/actions_'.strtolower($modulename).'.class.php');
-               dol_delete_file($destdir.'/class/api_'.strtolower($modulename).'.class.php');
-
-               dol_delete_file($destdir.'/css/'.strtolower($modulename).'.css.php');
-
-               dol_delete_file($destdir.'/js/'.strtolower($modulename).'.js.php');
-
-               dol_delete_file($destdir.'/scripts/'.strtolower($modulename).'.php');
-
-               dol_delete_file($destdir.'/test/phpunit/'.$modulename.'FunctionnalTest.php');
-
-               // Delete some files related to Object (because the previous dolCopyDir has copied everything)
-               dol_delete_file($destdir.'/myobject_card.php');
-               dol_delete_file($destdir.'/myobject_contact.php');
-               dol_delete_file($destdir.'/myobject_note.php');
-               dol_delete_file($destdir.'/myobject_document.php');
-               dol_delete_file($destdir.'/myobject_agenda.php');
-               dol_delete_file($destdir.'/myobject_list.php');
-               dol_delete_file($destdir.'/lib/'.strtolower($modulename).'_myobject.lib.php');
-               dol_delete_file($destdir.'/test/phpunit/MyObjectTest.php');
-               dol_delete_file($destdir.'/sql/llx_'.strtolower($modulename).'_myobject.sql');
-               dol_delete_file($destdir.'/sql/llx_'.strtolower($modulename).'_myobject_extrafields.sql');
-               dol_delete_file($destdir.'/sql/llx_'.strtolower($modulename).'_myobject.key.sql');
-               dol_delete_file($destdir.'/sql/llx_'.strtolower($modulename).'_myobject_extrafields.key.sql');
-               dol_delete_file($destdir.'/class/myobject.class.php');
-
-               dol_delete_dir($destdir.'/class', 1);
-               dol_delete_dir($destdir.'/sql', 1);
-               dol_delete_dir($destdir.'/scripts', 1);
-               dol_delete_dir($destdir.'/js', 1);
-               dol_delete_dir($destdir.'/css', 1);
-               dol_delete_dir($destdir.'/test/phpunit', 1);
-               dol_delete_dir($destdir.'/test', 1);
-       }
-
-       // Edit PHP files
-       if (!$error) {
-               $listofphpfilestoedit = dol_dir_list($destdir, 'files', 1, '\.(php|MD|js|sql|txt|xml|lang)$', '', 'fullname', SORT_ASC, 0, 1);
-               foreach ($listofphpfilestoedit as $phpfileval) {
-                       //var_dump($phpfileval['fullname']);
-                       $arrayreplacement = array(
-                               'mymodule'=>strtolower($modulename),
-                               'MyModule'=>$modulename,
-                               'MYMODULE'=>strtoupper($modulename),
-                               'My module'=>$modulename,
-                               'my module'=>$modulename,
-                               'Mon module'=>$modulename,
-                               'mon module'=>$modulename,
-                               'htdocs/modulebuilder/template'=>strtolower($modulename),
-                               '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : ''),
-                               'Editor name'=>$editorname,
-                               'https://www.example.com'=>$editorurl,
-                               '$this->version = \'1.0\''=>'$this->version = \''.$version.'\'',
-                               '$this->picto = \'generic\';'=>(empty($picto)) ? '$this->picto = \'generic\'' : '$this->picto = \''.$picto.'\';',
-                               "modulefamily" =>$family,
-                               '500000'=>$idmodule
-                       );
-
-                       if (!empty($conf->global->MODULEBUILDER_SPECIFIC_EDITOR_NAME)) {
-                               $arrayreplacement['Editor name'] = $conf->global->MODULEBUILDER_SPECIFIC_EDITOR_NAME;
-                       }
-                       if (!empty($conf->global->MODULEBUILDER_SPECIFIC_EDITOR_URL)) {
-                               $arrayreplacement['https://www.example.com'] = $conf->global->MODULEBUILDER_SPECIFIC_EDITOR_URL;
-                       }
-                       if (!empty($conf->global->MODULEBUILDER_SPECIFIC_AUTHOR)) {
-                               $arrayreplacement['---Put here your own copyright and developer email---'] = dol_print_date($now, '%Y').' '.$conf->global->MODULEBUILDER_SPECIFIC_AUTHOR;
-                       }
-                       if (!empty($conf->global->MODULEBUILDER_SPECIFIC_VERSION)) {
-                               $arrayreplacement['1.0'] = $conf->global->MODULEBUILDER_SPECIFIC_VERSION;
-                       }
-                       if (!empty($conf->global->MODULEBUILDER_SPECIFIC_FAMILY)) {
-                               $arrayreplacement['modulefamily'] = $conf->global->MODULEBUILDER_SPECIFIC_FAMILY;
-                       }
-
-                       $result = dolReplaceInFile($phpfileval['fullname'], $arrayreplacement);
-                       //var_dump($result);
-                       if ($result < 0) {
-                               setEventMessages($langs->trans("ErrorFailToMakeReplacementInto", $phpfileval['fullname']), null, 'errors');
-                       }
-               }
-
-               if (!empty($conf->global->MODULEBUILDER_SPECIFIC_README)) {
-                       setEventMessages($langs->trans("ContentOfREADMECustomized"), null, 'warnings');
-                       dol_delete_file($destdir.'/README.md');
-                       file_put_contents($destdir.'/README.md', $conf->global->MODULEBUILDER_SPECIFIC_README);
-               }
-       }
-
-       if (!$error) {
-               setEventMessages('ModuleInitialized', null);
-               $module = $modulename;
-
-               clearstatcache(true);
-               if (function_exists('opcache_invalidate')) {
-                       opcache_reset();        // remove the include cache hell !
-               }
-
-               header("Location: ".$_SERVER["PHP_SELF"].'?module='.$modulename);
-               exit;
-       }
-}
-
-
-// init API, PHPUnit
-if ($dirins && in_array($action, array('initapi', 'initphpunit', 'initpagecontact', 'initpagedocument', 'initpagenote', 'initpageagenda')) && !empty($module)) {
-       $modulename = ucfirst($module); // Force first letter in uppercase
-       $objectname = $tabobj;
-       $varnametoupdate = '';
-
-       if ($action == 'initapi') {
-               dol_mkdir($dirins.'/'.strtolower($module).'/class');
-               $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-               $srcfile = $srcdir.'/class/api_mymodule.class.php';
-               $destfile = $dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php';
-       } elseif ($action == 'initphpunit') {
-               dol_mkdir($dirins.'/'.strtolower($module).'/test/phpunit');
-               $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-               $srcfile = $srcdir.'/test/phpunit/MyObjectTest.php';
-               $destfile = $dirins.'/'.strtolower($module).'/test/phpunit/'.strtolower($objectname).'Test.php';
-       } elseif ($action == 'initpagecontact') {
-               dol_mkdir($dirins.'/'.strtolower($module));
-               $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-               $srcfile = $srcdir.'/myobject_contact.php';
-               $destfile = $dirins.'/'.strtolower($module).'/'.strtolower($objectname).'_contact.php';
-               $varnametoupdate = 'showtabofpagecontact';
-       } elseif ($action == 'initpagedocument') {
-               dol_mkdir($dirins.'/'.strtolower($module));
-               $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-               $srcfile = $srcdir.'/myobject_document.php';
-               $destfile = $dirins.'/'.strtolower($module).'/'.strtolower($objectname).'_document.php';
-               $varnametoupdate = 'showtabofpagedocument';
-       } elseif ($action == 'initpagenote') {
-               dol_mkdir($dirins.'/'.strtolower($module));
-               $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-               $srcfile = $srcdir.'/myobject_note.php';
-               $destfile = $dirins.'/'.strtolower($module).'/'.strtolower($objectname).'_note.php';
-               $varnametoupdate = 'showtabofpagenote';
-       } elseif ($action == 'initpageagenda') {
-               dol_mkdir($dirins.'/'.strtolower($module));
-               $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-               $srcfile = $srcdir.'/myobject_agenda.php';
-               $destfile = $dirins.'/'.strtolower($module).'/'.strtolower($objectname).'_agenda.php';
-               $varnametoupdate = 'showtabofpageagenda';
-       }
-
-       //var_dump($srcfile);
-       //var_dump($destfile);
-       $result = dol_copy($srcfile, $destfile, 0, 0);
-
-       if ($result > 0) {
-               //var_dump($phpfileval['fullname']);
-               $arrayreplacement = array(
-                       'mymodule'=>strtolower($modulename),
-                       'MyModule'=>$modulename,
-                       'MYMODULE'=>strtoupper($modulename),
-                       'My module'=>$modulename,
-                       'my module'=>$modulename,
-                       'Mon module'=>$modulename,
-                       'mon module'=>$modulename,
-                       'htdocs/modulebuilder/template'=>strtolower($modulename),
-                       'myobject'=>strtolower($objectname),
-                       'MyObject'=>$objectname,
-                       'MYOBJECT'=>strtoupper($objectname),
-                       '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
-               );
-
-               dolReplaceInFile($destfile, $arrayreplacement);
-
-               if ($varnametoupdate) {
-                       // Now we update the object file to set $$varnametoupdate to 1
-                       $srcfile = $dirins.'/'.strtolower($module).'/lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php';
-                       $arrayreplacement = array('/\$'.$varnametoupdate.' = 0;/' => '$'.$varnametoupdate.' = 1;');
-                       dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
-               }
-       } else {
-               $langs->load("errors");
-               setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
-       }
-}
-
-
-// init ExtraFields
-if ($dirins && $action == 'initsqlextrafields' && !empty($module)) {
-       $modulename = ucfirst($module); // Force first letter in uppercase
-       $objectname = $tabobj;
-
-       dol_mkdir($dirins.'/'.strtolower($module).'/sql');
-       $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-       $srcfile1 = $srcdir.'/sql/llx_mymodule_myobject_extrafields.sql';
-       $destfile1 = $dirins.'/'.strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.sql';
-       //var_dump($srcfile);
-       //var_dump($destfile);
-       $result1 = dol_copy($srcfile1, $destfile1, 0, 0);
-       $srcfile2 = $srcdir.'/sql/llx_mymodule_myobject_extrafields.key.sql';
-       $destfile2 = $dirins.'/'.strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.key.sql';
-       //var_dump($srcfile);
-       //var_dump($destfile);
-       $result2 = dol_copy($srcfile2, $destfile2, 0, 0);
-
-       if ($result1 > 0 && $result2 > 0) {
-               $modulename = ucfirst($module); // Force first letter in uppercase
-
-               //var_dump($phpfileval['fullname']);
-               $arrayreplacement = array(
-                       'mymodule'=>strtolower($modulename),
-                       'MyModule'=>$modulename,
-                       'MYMODULE'=>strtoupper($modulename),
-                       'My module'=>$modulename,
-                       'my module'=>$modulename,
-                       'Mon module'=>$modulename,
-                       'mon module'=>$modulename,
-                       'htdocs/modulebuilder/template'=>strtolower($modulename),
-                       'My Object'=>$objectname,
-                       'MyObject'=>$objectname,
-                       'my object'=>strtolower($objectname),
-                       'myobject'=>strtolower($objectname),
-                       '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
-               );
-
-               dolReplaceInFile($destfile1, $arrayreplacement);
-               dolReplaceInFile($destfile2, $arrayreplacement);
-       } else {
-               $langs->load("errors");
-               if ($result1 <= 0) {
-                       setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile1), null, 'errors');
-               }
-               if ($result2 <= 0) {
-                       setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile2), null, 'errors');
-               }
-       }
-
-       // Now we update the object file to set $isextrafieldmanaged to 1
-       $srcfile = $dirins.'/'.strtolower($module).'/class/'.strtolower($objectname).'.class.php';
-       $arrayreplacement = array('/\$isextrafieldmanaged = 0;/' => '$isextrafieldmanaged = 1;');
-       dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
-}
-
-
-// init Hook
-if ($dirins && $action == 'inithook' && !empty($module)) {
-       dol_mkdir($dirins.'/'.strtolower($module).'/class');
-       $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-       $srcfile = $srcdir.'/class/actions_mymodule.class.php';
-       $destfile = $dirins.'/'.strtolower($module).'/class/actions_'.strtolower($module).'.class.php';
-       //var_dump($srcfile);
-       //var_dump($destfile);
-       $result = dol_copy($srcfile, $destfile, 0, 0);
-
-       if ($result > 0) {
-               $modulename = ucfirst($module); // Force first letter in uppercase
-
-               //var_dump($phpfileval['fullname']);
-               $arrayreplacement = array(
-                       'mymodule'=>strtolower($modulename),
-                       'MyModule'=>$modulename,
-                       'MYMODULE'=>strtoupper($modulename),
-                       'My module'=>$modulename,
-                       'my module'=>$modulename,
-                       'Mon module'=>$modulename,
-                       'mon module'=>$modulename,
-                       'htdocs/modulebuilder/template'=>strtolower($modulename),
-                       '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
-               );
-
-               dolReplaceInFile($destfile, $arrayreplacement);
-       } else {
-               $langs->load("errors");
-               setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
-       }
-}
-
-
-// init Trigger
-if ($dirins && $action == 'inittrigger' && !empty($module)) {
-       dol_mkdir($dirins.'/'.strtolower($module).'/core/triggers');
-       $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-       $srcfile = $srcdir.'/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php';
-       $destfile = $dirins.'/'.strtolower($module).'/core/triggers/interface_99_mod'.$module.'_'.$module.'Triggers.class.php';
-       //var_dump($srcfile);
-       //var_dump($destfile);
-       $result = dol_copy($srcfile, $destfile, 0, 0);
-
-       if ($result > 0) {
-               $modulename = ucfirst($module); // Force first letter in uppercase
-
-               //var_dump($phpfileval['fullname']);
-               $arrayreplacement = array(
-                       'mymodule'=>strtolower($modulename),
-                       'MyModule'=>$modulename,
-                       'MYMODULE'=>strtoupper($modulename),
-                       'My module'=>$modulename,
-                       'my module'=>$modulename,
-                       'Mon module'=>$modulename,
-                       'mon module'=>$modulename,
-                       'htdocs/modulebuilder/template'=>strtolower($modulename),
-                       '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
-               );
-
-               dolReplaceInFile($destfile, $arrayreplacement);
-       } else {
-               $langs->load("errors");
-               setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
-       }
-}
-
-
-// init Widget
-if ($dirins && $action == 'initwidget' && !empty($module)) {
-       dol_mkdir($dirins.'/'.strtolower($module).'/core/boxes');
-       $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-       $srcfile = $srcdir.'/core/boxes/mymodulewidget1.php';
-       $destfile = $dirins.'/'.strtolower($module).'/core/boxes/'.strtolower($module).'widget1.php';
-       //var_dump($srcfile);
-       //var_dump($destfile);
-       $result = dol_copy($srcfile, $destfile, 0, 0);
-
-       if ($result > 0) {
-               $modulename = ucfirst($module); // Force first letter in uppercase
-
-               //var_dump($phpfileval['fullname']);
-               $arrayreplacement = array(
-                       'mymodule'=>strtolower($modulename),
-                       'MyModule'=>$modulename,
-                       'MYMODULE'=>strtoupper($modulename),
-                       'My module'=>$modulename,
-                       'my module'=>$modulename,
-                       'Mon module'=>$modulename,
-                       'mon module'=>$modulename,
-                       'htdocs/modulebuilder/template'=>strtolower($modulename),
-                       '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
-               );
-
-               dolReplaceInFile($destfile, $arrayreplacement);
-       } else {
-               $langs->load("errors");
-               setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
-       }
-}
-
-
-// init CSS
-if ($dirins && $action == 'initcss' && !empty($module)) {
-       dol_mkdir($dirins.'/'.strtolower($module).'/css');
-       $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-       $srcfile = $srcdir.'/css/mymodule.css.php';
-       $destfile = $dirins.'/'.strtolower($module).'/css/'.strtolower($module).'.css.php';
-       //var_dump($srcfile);
-       //var_dump($destfile);
-       $result = dol_copy($srcfile, $destfile, 0, 0);
-
-       if ($result > 0) {
-               $modulename = ucfirst($module); // Force first letter in uppercase
-
-               //var_dump($phpfileval['fullname']);
-               $arrayreplacement = array(
-                       'mymodule'=>strtolower($modulename),
-                       'MyModule'=>$modulename,
-                       'MYMODULE'=>strtoupper($modulename),
-                       'My module'=>$modulename,
-                       'my module'=>$modulename,
-                       'Mon module'=>$modulename,
-                       'mon module'=>$modulename,
-                       'htdocs/modulebuilder/template'=>strtolower($modulename),
-                       '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : ''),
-               );
-
-               dolReplaceInFile($destfile, $arrayreplacement);
-
-               // Update descriptor file to uncomment file
-               $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
-               $arrayreplacement = array('/\/\/\s*\''.preg_quote('/'.strtolower($module).'/css/'.strtolower($module).'.css.php', '/').'\'/' => '\'/'.strtolower($module).'/css/'.strtolower($module).'.css.php\'');
-               dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
-       } else {
-               $langs->load("errors");
-               setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
-       }
-}
-
-
-// init JS
-if ($dirins && $action == 'initjs' && !empty($module)) {
-       dol_mkdir($dirins.'/'.strtolower($module).'/js');
-       $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-       $srcfile = $srcdir.'/js/mymodule.js.php';
-       $destfile = $dirins.'/'.strtolower($module).'/js/'.strtolower($module).'.js.php';
-       //var_dump($srcfile);
-       //var_dump($destfile);
-       $result = dol_copy($srcfile, $destfile, 0, 0);
-
-       if ($result > 0) {
-               $modulename = ucfirst($module); // Force first letter in uppercase
-
-               //var_dump($phpfileval['fullname']);
-               $arrayreplacement = array(
-                       'mymodule'=>strtolower($modulename),
-                       'MyModule'=>$modulename,
-                       'MYMODULE'=>strtoupper($modulename),
-                       'My module'=>$modulename,
-                       'my module'=>$modulename,
-                       'Mon module'=>$modulename,
-                       'mon module'=>$modulename,
-                       'htdocs/modulebuilder/template'=>strtolower($modulename),
-                       '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
-               );
-
-               dolReplaceInFile($destfile, $arrayreplacement);
-
-               // Update descriptor file to uncomment file
-               $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
-               $arrayreplacement = array('/\/\/\s*\''.preg_quote('/'.strtolower($module).'/js/'.strtolower($module).'.js.php', '/').'\'/' => '\'/'.strtolower($module).'/js/'.strtolower($module).'.js.php\'');
-               dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
-       } else {
-               $langs->load("errors");
-               setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
-       }
-}
-
-
-// init CLI
-if ($dirins && $action == 'initcli' && !empty($module)) {
-       dol_mkdir($dirins.'/'.strtolower($module).'/scripts');
-       $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-       $srcfile = $srcdir.'/scripts/mymodule.php';
-       $destfile = $dirins.'/'.strtolower($module).'/scripts/'.strtolower($module).'.php';
-       //var_dump($srcfile);
-       //var_dump($destfile);
-       $result = dol_copy($srcfile, $destfile, 0, 0);
-
-       if ($result > 0) {
-               $modulename = ucfirst($module); // Force first letter in uppercase
-
-               //var_dump($phpfileval['fullname']);
-               $arrayreplacement = array(
-                       'mymodule'=>strtolower($modulename),
-                       'MyModule'=>$modulename,
-                       'MYMODULE'=>strtoupper($modulename),
-                       'My module'=>$modulename,
-                       'my module'=>$modulename,
-                       'Mon module'=>$modulename,
-                       'mon module'=>$modulename,
-                       'htdocs/modulebuilder/template'=>strtolower($modulename),
-                       '__MYCOMPANY_NAME__'=>$mysoc->name,
-                       '__KEYWORDS__'=>$modulename,
-                       '__USER_FULLNAME__'=>$user->getFullName($langs),
-                       '__USER_EMAIL__'=>$user->email,
-                       '__YYYY-MM-DD__'=>dol_print_date($now, 'dayrfc'),
-                       '---Put here your own copyright and developer email---'=>dol_print_date($now, 'dayrfc').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
-               );
-
-               dolReplaceInFile($destfile, $arrayreplacement);
-       } else {
-               $langs->load("errors");
-               setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
-       }
-}
-
-
-// init Doc
-if ($dirins && $action == 'initdoc' && !empty($module)) {
-       dol_mkdir($dirins.'/'.strtolower($module).'/doc');
-       $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-       $srcfile = $srcdir.'/doc/Documentation.asciidoc';
-       $destfile = $dirins.'/'.strtolower($module).'/doc/Documentation.asciidoc';
-       //var_dump($srcfile);
-       //var_dump($destfile);
-       $result = dol_copy($srcfile, $destfile, 0, 0);
-
-       if ($result > 0) {
-               $modulename = ucfirst($module); // Force first letter in uppercase
-               $modulelowercase = strtolower($module);
-
-               //var_dump($phpfileval['fullname']);
-               $arrayreplacement = array(
-                       'mymodule'=>strtolower($modulename),
-                       'MyModule'=>$modulename,
-                       'MYMODULE'=>strtoupper($modulename),
-                       'My module'=>$modulename,
-                       'my module'=>$modulename,
-                       'Mon module'=>$modulename,
-                       'mon module'=>$modulename,
-                       'htdocs/modulebuilder/template'=>strtolower($modulename),
-                       '__MYCOMPANY_NAME__'=>$mysoc->name,
-                       '__KEYWORDS__'=>$modulename,
-                       '__USER_FULLNAME__'=>$user->getFullName($langs),
-                       '__USER_EMAIL__'=>$user->email,
-                       '__YYYY-MM-DD__'=>dol_print_date($now, 'dayrfc'),
-                       '---Put here your own copyright and developer email---'=>dol_print_date($now, 'dayrfc').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
-               );
-
-               dolReplaceInFile($destfile, $arrayreplacement);
-
-               // Delete old documentation files
-               $FILENAMEDOC = $modulelowercase.'.html';
-               $FILENAMEDOCPDF = $modulelowercase.'.pdf';
-               $outputfiledoc = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOC;
-               $outputfiledocurl = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOC;
-               $outputfiledocpdf = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOCPDF;
-               $outputfiledocurlpdf = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOCPDF;
-
-               dol_delete_file($outputfiledoc, 0, 0, 0, null, false, 0);
-               dol_delete_file($outputfiledocpdf, 0, 0, 0, null, false, 0);
-       } else {
-               $langs->load("errors");
-               setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
-       }
-}
-
-
-// add Language
-if ($dirins && $action == 'addlanguage' && !empty($module)) {
-       $newlangcode = GETPOST('newlangcode', 'aZ09');
-
-       if ($newlangcode) {
-               $modulelowercase = strtolower($module);
-
-               // Dir for module
-               $diroflang = dol_buildpath($modulelowercase, 0);
-
-               if ($diroflang == $dolibarr_main_document_root.'/'.$modulelowercase) {
-                       // This is not a custom module, we force diroflang to htdocs root
-                       $diroflang = $dolibarr_main_document_root;
-
-                       $srcfile = $diroflang.'/langs/en_US/'.$modulelowercase.'.lang';
-                       $destfile = $diroflang.'/langs/'.$newlangcode.'/'.$modulelowercase.'.lang';
-
-                       $result = dol_copy($srcfile, $destfile, 0, 0);
-                       if ($result < 0) {
-                               setEventMessages($langs->trans("ErrorFailToCopyFile", $srcfile, $destfile), null, 'errors');
-                       }
-               } else {
-                       $srcfile = $diroflang.'/langs/en_US';
-                       $destfile = $diroflang.'/langs/'.$newlangcode;
-
-                       $result = dolCopyDir($srcfile, $destfile, 0, 0);
-               }
-       } else {
-               setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Language")), null, 'errors');
-       }
-}
-
-
-// remove/delete File
-if ($dirins && $action == 'confirm_removefile' && !empty($module)) {
-       $objectname = $tabobj;
-
-       $relativefilename = dol_sanitizePathName(GETPOST('file', 'restricthtml'));
-       if ($relativefilename) {
-               $dirnametodelete = dirname($relativefilename);
-               $filetodelete = $dirins.'/'.$relativefilename;
-               $dirtodelete  = $dirins.'/'.$dirnametodelete;
-
-               $result = dol_delete_file($filetodelete);
-               if (!$result) {
-                       setEventMessages($langs->trans("ErrorFailToDeleteFile", basename($filetodelete)), null, 'errors');
-               } else {
-                       // If we delete a .sql file, we delete also the other .sql file
-                       if (preg_match('/\.sql$/', $relativefilename)) {
-                               if (preg_match('/\.key\.sql$/', $relativefilename)) {
-                                       $relativefilename = preg_replace('/\.key\.sql$/', '.sql', $relativefilename);
-                                       $filetodelete = $dirins.'/'.$relativefilename;
-                                       $result = dol_delete_file($filetodelete);
-                               } elseif (preg_match('/\.sql$/', $relativefilename)) {
-                                       $relativefilename = preg_replace('/\.sql$/', '.key.sql', $relativefilename);
-                                       $filetodelete = $dirins.'/'.$relativefilename;
-                                       $result = dol_delete_file($filetodelete);
-                               }
-                       }
-
-                       if (dol_is_dir_empty($dirtodelete)) {
-                               dol_delete_dir($dirtodelete);
-                       }
-
-                       // Update descriptor file to comment file
-                       if (in_array($tab, array('css', 'js'))) {
-                               $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
-                               $arrayreplacement = array('/^\s*\''.preg_quote('/'.$relativefilename, '/').'\',*/m'=>'                // \'/'.$relativefilename.'\',');
-                               dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
-                       }
-
-                       if (preg_match('/_extrafields/', $relativefilename)) {
-                               // Now we update the object file to set $isextrafieldmanaged to 0
-                               $srcfile = $dirins.'/'.strtolower($module).'/class/'.strtolower($objectname).'.class.php';
-                               $arrayreplacement = array('/\$isextrafieldmanaged = 1;/' => '$isextrafieldmanaged = 0;');
-                               dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
-                       }
-
-                       // Now we update the lib file to set $showtabofpagexxx to 0
-                       $varnametoupdate = '';
-                       $reg = array();
-                       if (preg_match('/_([a-z]+)\.php$/', $relativefilename, $reg)) {
-                               $varnametoupdate = 'showtabofpage'.$reg[1];
-                       }
-                       if ($varnametoupdate) {
-                               $srcfile = $dirins.'/'.strtolower($module).'/lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php';
-                               $arrayreplacement = array('/\$'.$varnametoupdate.' = 1;/' => '$'.$varnametoupdate.' = 0;');
-                               dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
-                       }
-               }
-       }
-}
-
-// Init an object
-if ($dirins && $action == 'initobject' && $module && $objectname) {
-       $objectname = ucfirst($objectname);
-
-       $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
-       $moduletype = $listofmodules[strtolower($module)]['moduletype'];
-
-       if (preg_match('/[^a-z0-9_]/i', $objectname)) {
-               $error++;
-               setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
-               $tabobj = 'newobject';
-       }
-       if (class_exists($objectname)) {
-               // TODO Add a more efficient detection. Scan disk ?
-               $error++;
-               setEventMessages($langs->trans("AnObjectWithThisClassNameAlreadyExists"), null, 'errors');
-               $tabobj = 'newobject';
-       }
-
-       $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
-       $destdir = $dirins.'/'.strtolower($module);
-
-       // The dir was not created by init
-       dol_mkdir($destdir.'/class');
-       dol_mkdir($destdir.'/img');
-       dol_mkdir($destdir.'/lib');
-       dol_mkdir($destdir.'/scripts');
-       dol_mkdir($destdir.'/sql');
-
-       // Scan dir class to find if an object with same name already exists.
-       if (!$error) {
-               $dirlist = dol_dir_list($destdir.'/class', 'files', 0, '\.txt$');
-               $alreadyfound = false;
-               foreach ($dirlist as $key => $val) {
-                       $filefound = preg_replace('/\.txt$/', '', $val['name']);
-                       if (strtolower($objectname) == strtolower($filefound) && $objectname != $filefound) {
-                               $alreadyfound = true;
-                               $error++;
-                               setEventMessages($langs->trans("AnObjectAlreadyExistWithThisNameAndDiffCase"), null, 'errors');
-                               break;
-                       }
-               }
-       }
-
-       // If we must reuse a table for properties, define $stringforproperties
-       $stringforproperties = '';
-       $tablename = GETPOST('initfromtablename', 'alpha');
-       if ($tablename) {
-               $_results = $db->DDLDescTable($tablename);
-               if (empty($_results)) {
-                       $error++;
-                       $langs->load("errors");
-                       setEventMessages($langs->trans("ErrorTableNotFound", $tablename), null, 'errors');
-               } else {
-                       /**
-                        *  'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:Sortfield]]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password')
-                        *         Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)"
-                        *  'label' the translation key.
-                        *  'picto' is code of a picto to show before value in forms
-                        *  'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM' or 'isModEnabled("multicurrency")' ...)
-                        *  'position' is the sort order of field.
-                        *  'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
-                        *  'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing)
-                        *  'noteditable' says if field is not editable (1 or 0)
-                        *  'alwayseditable' says if field can be modified also when status is not draft ('1' or '0')
-                        *  'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created.
-                        *  'index' if we want an index in database.
-                        *  'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...).
-                        *  'searchall' is 1 if we want to search in this field when making a search from the quick search button.
-                        *  'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for percentage)
-                        *  'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200'
-                        *  'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click.
-                        *  'showoncombobox' if value of the field must be visible into the label of the combobox that list record
-                        *  'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code.
-                        *  'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar'
-                        *  'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1.
-                        *  'comment' is not used. You can store here any text of your choice. It is not used by application.
-                        *      'validate' is 1 if need to validate with $this->validateField()
-                        *  'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value)
-                        */
-
-                       /*public $fields=array(
-                        'rowid'          =>array('type'=>'integer',        'label'=>'TechnicalID',      'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'index'=>1, 'position'=>1, 'comment'=>'Id'),
-                        'ref'            =>array('type'=>'varchar(128)',   'label'=>'Ref',              'enabled'=>1, 'visible'=>1,  'notnull'=>1,  'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
-                        'entity'         =>array('type'=>'integer',        'label'=>'Entity',           'enabled'=>1, 'visible'=>0,  'default'=>1, 'notnull'=>1,  'index'=>1, 'position'=>20),
-                        'label'          =>array('type'=>'varchar(255)',   'label'=>'Label',            'enabled'=>1, 'visible'=>1,  'position'=>30,  'searchall'=>1, 'css'=>'minwidth200', 'help'=>'Help text', 'alwayseditable'=>'1'),
-                        'amount'         =>array('type'=>'double(24,8)',   'label'=>'Amount',           'enabled'=>1, 'visible'=>1,  'default'=>'null', 'position'=>40,  'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text'),
-                        'fk_soc'         =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'visible'=>1, 'enabled'=>1, 'position'=>50, 'notnull'=>-1, 'index'=>1, 'searchall'=>1, 'help'=>'LinkToThirdparty'),
-                        'description'    =>array('type'=>'text',                       'label'=>'Descrption',           'enabled'=>1, 'visible'=>0,  'position'=>60),
-                        'note_public'    =>array('type'=>'html',                       'label'=>'NotePublic',           'enabled'=>1, 'visible'=>0,  'position'=>61),
-                        'note_private'   =>array('type'=>'html',                       'label'=>'NotePrivate',          'enabled'=>1, 'visible'=>0,  'position'=>62),
-                        'date_creation'  =>array('type'=>'datetime',       'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>500),
-                        'tms'            =>array('type'=>'timestamp',      'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>501),
-                        //'date_valid'     =>array('type'=>'datetime',       'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'position'=>502),
-                        'fk_user_creat'  =>array('type'=>'integer',        'label'=>'UserAuthor',       'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>510),
-                        'fk_user_modif'  =>array('type'=>'integer',        'label'=>'UserModif',        'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>511),
-                        //'fk_user_valid'  =>array('type'=>'integer',        'label'=>'UserValidation',   'enabled'=>1, 'visible'=>-1, 'position'=>512),
-                        'import_key'     =>array('type'=>'varchar(14)',    'label'=>'ImportId',         'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'index'=>0,  'position'=>1000),
-                        'status'         =>array('type'=>'integer',        'label'=>'Status',           'enabled'=>1, 'visible'=>1,  'notnull'=>1,  'default'=>0, 'index'=>1,  'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Active', -1=>'Cancel')),
-                        );*/
-
-                       $stringforproperties = '// BEGIN MODULEBUILDER PROPERTIES'."\n";
-                       $stringforproperties .= 'public $fields=array('."\n";
-                       $i = 10;
-                       while ($obj = $db->fetch_object($_results)) {
-                               // fieldname
-                               $fieldname = $obj->Field;
-                               // type
-                               $type = $obj->Type;
-                               if ($type == 'int(11)') {
-                                       $type = 'integer';
-                               }
-                               if ($type == 'float') {
-                                       $type = 'real';
-                               }
-                               if (strstr($type, 'tinyint')) {
-                                       $type = 'integer';
-                               }
-                               if ($obj->Field == 'fk_soc') {
-                                       $type = 'integer:Societe:societe/class/societe.class.php';
-                               }
-                               if (preg_match('/^fk_proj/', $obj->Field)) {
-                                       $type = 'integer:Project:projet/class/project.class.php:1:fk_statut=1';
-                               }
-                               if (preg_match('/^fk_prod/', $obj->Field)) {
-                                       $type = 'integer:Product:product/class/product.class.php:1';
-                               }
-                               if ($obj->Field == 'fk_warehouse') {
-                                       $type = 'integer:Entrepot:product/stock/class/entrepot.class.php';
-                               }
-                               if (preg_match('/^(fk_user|fk_commercial)/', $obj->Field)) {
-                                       $type = 'integer:User:user/class/user.class.php';
-                               }
-
-                               // notnull
-                               $notnull = ($obj->Null == 'YES' ? 0 : 1);
-                               if ($fieldname == 'fk_user_modif') {
-                                       $notnull = -1;
-                               }
-                               // label
-                               $label = preg_replace('/_/', '', ucfirst($fieldname));
-                               if ($fieldname == 'rowid') {
-                                       $label = 'TechnicalID';
-                               }
-                               if ($fieldname == 'import_key') {
-                                       $label = 'ImportId';
-                               }
-                               if ($fieldname == 'fk_soc') {
-                                       $label = 'ThirdParty';
-                               }
-                               if ($fieldname == 'tms') {
-                                       $label = 'DateModification';
-                               }
-                               if ($fieldname == 'datec') {
-                                       $label = 'DateCreation';
-                               }
-                               if ($fieldname == 'date_valid') {
-                                       $label = 'DateValidation';
-                               }
-                               if ($fieldname == 'datev') {
-                                       $label = 'DateValidation';
-                               }
-                               if ($fieldname == 'note_private') {
-                                       $label = 'NotePublic';
-                               }
-                               if ($fieldname == 'note_public') {
-                                       $label = 'NotePrivate';
-                               }
-                               if ($fieldname == 'fk_user_creat') {
-                                       $label = 'UserAuthor';
-                               }
-                               if ($fieldname == 'fk_user_modif') {
-                                       $label = 'UserModif';
-                               }
-                               if ($fieldname == 'fk_user_valid') {
-                                       $label = 'UserValidation';
-                               }
-                               // visible
-                               $visible = -1;
-                               if ($fieldname == 'entity') {
-                                       $visible = -2;
-                               }
-                               if ($fieldname == 'import_key') {
-                                       $visible = -2;
-                               }
-                               if ($fieldname == 'fk_user_creat') {
-                                       $visible = -2;
-                               }
-                               if ($fieldname == 'fk_user_modif') {
-                                       $visible = -2;
-                               }
-                               if (in_array($fieldname, array('ref_ext', 'model_pdf', 'note_public', 'note_private'))) {
-                                       $visible = 0;
-                               }
-                               // enabled
-                               $enabled = 1;
-                               // default
-                               $default = '';
-                               if ($fieldname == 'entity') {
-                                       $default = 1;
-                               }
-                               // position
-                               $position = $i;
-                               if (in_array($fieldname, array('status', 'statut', 'fk_status', 'fk_statut'))) {
-                                       $position = 500;
-                               }
-                               if ($fieldname == 'import_key') {
-                                       $position = 900;
-                               }
-                               // $alwayseditable
-                               if ($fieldname == 'label') {
-                                       $alwayseditable = 1;
-                               }
-                               // index
-                               $index = 0;
-                               if ($fieldname == 'entity') {
-                                       $index = 1;
-                               }
-                               // css, cssview, csslist
-                               $css = '';
-                               $cssview = '';
-                               $csslist = '';
-                               if (preg_match('/^fk_/', $fieldname)) {
-                                       $css = 'maxwidth500 widthcentpercentminusxx';
-                               }
-                               if ($fieldname == 'label') {
-                                       $css = 'minwidth300';
-                                       $cssview = 'wordbreak';
-                               }
-                               if (in_array($fieldname, array('note_public', 'note_private'))) {
-                                       $cssview = 'wordbreak';
-                               }
-                               if (in_array($fieldname, array('ref', 'label')) || preg_match('/integer:/', $type)) {
-                                       $csslist = 'tdoverflowmax150';
-                               }
-
-                               // type
-                               $picto = $obj->Picto;
-                               if ($obj->Field == 'fk_soc') {
-                                       $picto = 'company';
-                               }
-                               if (preg_match('/^fk_proj/', $obj->Field)) {
-                                       $picto = 'project';
-                               }
-
-                               // Build the property string
-                               $stringforproperties .= "'".$obj->Field."'=>array('type'=>'".$type."', 'label'=>'".$label."',";
-                               if ($default != '') {
-                                       $stringforproperties .= " 'default'=>".$default.",";
-                               }
-                               $stringforproperties .= " 'enabled'=>".$enabled.",";
-                               $stringforproperties .= " 'visible'=>".$visible;
-                               if ($notnull) {
-                                       $stringforproperties .= ", 'notnull'=>".$notnull;
-                               }
-                               if ($alwayseditable) {
-                                       $stringforproperties .= ", 'alwayseditable'=>1";
-                               }
-                               if ($fieldname == 'ref' || $fieldname == 'code') {
-                                       $stringforproperties .= ", 'showoncombobox'=>1";
-                               }
-                               $stringforproperties .= ", 'position'=>".$position;
-                               if ($index) {
-                                       $stringforproperties .= ", 'index'=>".$index;
-                               }
-                               if ($picto) {
-                                       $stringforproperties .= ", 'picto'=>'".$picto."'";
-                               }
-                               if ($css) {
-                                       $stringforproperties .= ", 'css'=>'".$css."'";
-                               }
-                               if ($cssview) {
-                                       $stringforproperties .= ", 'cssview'=>'".$cssview."'";
-                               }
-                               if ($csslist) {
-                                       $stringforproperties .= ", 'csslist'=>'".$csslist."'";
-                               }
-                               $stringforproperties .= "),\n";
-                               $i += 5;
-                       }
-                       $stringforproperties .= ');'."\n";
-                       $stringforproperties .= '// END MODULEBUILDER PROPERTIES'."\n";
-               }
-       }
-
-       if (!$error) {
-               // Copy some files
-               $filetogenerate = array(
-                       'myobject_card.php'=>strtolower($objectname).'_card.php',
-                       'myobject_note.php'=>strtolower($objectname).'_note.php',
-                       'myobject_contact.php'=>strtolower($objectname).'_contact.php',
-                       'myobject_document.php'=>strtolower($objectname).'_document.php',
-                       'myobject_agenda.php'=>strtolower($objectname).'_agenda.php',
-                       'myobject_list.php'=>strtolower($objectname).'_list.php',
-                       'admin/myobject_extrafields.php'=>'admin/'.strtolower($objectname).'_extrafields.php',
-                       'lib/mymodule_myobject.lib.php'=>'lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php',
-                       //'test/phpunit/MyObjectTest.php'=>'test/phpunit/'.strtolower($objectname).'Test.php',
-                       'sql/llx_mymodule_myobject.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql',
-                       'sql/llx_mymodule_myobject.key.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql',
-                       'sql/llx_mymodule_myobject_extrafields.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.sql',
-                       'sql/llx_mymodule_myobject_extrafields.key.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.key.sql',
-                       //'scripts/mymodule.php'=>'scripts/'.strtolower($objectname).'.php',
-                       'class/myobject.class.php'=>'class/'.strtolower($objectname).'.class.php',
-                       //'class/api_mymodule.class.php'=>'class/api_'.strtolower($module).'.class.php',
-               );
-
-               if (GETPOST('includerefgeneration', 'aZ09')) {
-                       dol_mkdir($destdir.'/core/modules/'.strtolower($module));
-
-                       $filetogenerate += array(
-                               'core/modules/mymodule/mod_myobject_advanced.php'=>'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_advanced.php',
-                               'core/modules/mymodule/mod_myobject_standard.php'=>'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_standard.php',
-                               'core/modules/mymodule/modules_myobject.php'=>'core/modules/'.strtolower($module).'/modules_'.strtolower($objectname).'.php',
-                       );
-               }
-               if (GETPOST('includedocgeneration', 'aZ09')) {
-                       dol_mkdir($destdir.'/core/modules/'.strtolower($module));
-                       dol_mkdir($destdir.'/core/modules/'.strtolower($module).'/doc');
-
-                       $filetogenerate += array(
-                               'core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php'=>'core/modules/'.strtolower($module).'/doc/doc_generic_'.strtolower($objectname).'_odt.modules.php',
-                               'core/modules/mymodule/doc/pdf_standard_myobject.modules.php'=>'core/modules/'.strtolower($module).'/doc/pdf_standard_'.strtolower($objectname).'.modules.php'
-                       );
-               }
-
-
-               if (!$error) {
-                       foreach ($filetogenerate as $srcfile => $destfile) {
-                               $result = dol_copy($srcdir.'/'.$srcfile, $destdir.'/'.$destfile, $newmask, 0);
-                               if ($result <= 0) {
-                                       if ($result < 0) {
-                                               $error++;
-                                               $langs->load("errors");
-                                               setEventMessages($langs->trans("ErrorFailToCopyFile", $srcdir.'/'.$srcfile, $destdir.'/'.$destfile), null, 'errors');
-                                       } else {
-                                               // $result == 0
-                                               setEventMessages($langs->trans("FileAlreadyExists", $destfile), null, 'warnings');
-                                       }
-                               }
-                       }
-               }
-
-               // Replace property section with $stringforproperties
-               if (!$error && $stringforproperties) {
-                       //var_dump($stringforproperties);exit;
-                       $arrayreplacement = array(
-                               '/\/\/ BEGIN MODULEBUILDER PROPERTIES.*\/\/ END MODULEBUILDER PROPERTIES/ims' => $stringforproperties
-                       );
-
-                       dolReplaceInFile($destdir.'/class/'.strtolower($objectname).'.class.php', $arrayreplacement, '', 0, 0, 1);
-               }
-
-               // Edit the class 'class/'.strtolower($objectname).'.class.php'
-               if (GETPOST('includerefgeneration', 'aZ09')) {
-                       // Replace 'visible'=>1,  'noteditable'=>0, 'default'=>''
-                       $arrayreplacement = array(
-                               '/\'visible\'=>1,\s*\'noteditable\'=>0,\s*\'default\'=>\'\'/' => "'visible'=>4, 'noteditable'=>1, 'default'=>'(PROV)'"
-                       );
-                       //var_dump($arrayreplacement);exit;
-                       //var_dump($destdir.'/class/'.strtolower($objectname).'.class.php');exit;
-                       dolReplaceInFile($destdir.'/class/'.strtolower($objectname).'.class.php', $arrayreplacement, '', 0, 0, 1);
-
-                       $arrayreplacement = array(
-                               '/\'models\' => 0,/' => '\'models\' => 1,'
-                       );
-                       dolReplaceInFile($destdir.'/core/modules/mod'.$module.'.class.php', $arrayreplacement, '', 0, 0, 1);
-               }
-
-               // Edit the setup file and the card page
-               if (GETPOST('includedocgeneration', 'aZ09')) {
-                       // Replace some var init into some files
-                       $arrayreplacement = array(
-                               '/\$includedocgeneration = 0;/' => '$includedocgeneration = 1;'
-                       );
-                       dolReplaceInFile($destdir.'/class/'.strtolower($objectname).'.class.php', $arrayreplacement, '', 0, 0, 1);
-                       dolReplaceInFile($destdir.'/'.strtolower($objectname).'_card.php', $arrayreplacement, '', 0, 0, 1);
-
-                       $arrayreplacement = array(
-                               '/\'models\' => 0,/' => '\'models\' => 1,'
-                       );
-
-                       dolReplaceInFile($destdir.'/core/modules/mod'.$module.'.class.php', $arrayreplacement, '', 0, 0, 1);
-               }
-
-               // TODO Update entries '$myTmpObjects['MyObject']=array('includerefgeneration'=>0, 'includedocgeneration'=>0);'
-
-
-               // Scan for object class files
-               $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$');
-
-               $firstobjectname = '';
-               foreach ($listofobject as $fileobj) {
-                       if (preg_match('/^api_/', $fileobj['name'])) {
-                               continue;
-                       }
-                       if (preg_match('/^actions_/', $fileobj['name'])) {
-                               continue;
-                       }
-
-                       $tmpcontent = file_get_contents($fileobj['fullname']);
-                       $reg = array();
-                       if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
-                               $objectnameloop = $reg[1];
-                               if (empty($firstobjectname)) {
-                                       $firstobjectname = $objectnameloop;
-                               }
-                       }
-
-                       // Regenerate left menu entry in descriptor for $objectname
-                       $stringtoadd = "
-        \$this->menu[\$r++]=array(
-            // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
-            'fk_menu'=>'fk_mainmenu=mymodule',
-            // This is a Left menu entry
-            'type'=>'left',
-            'titre'=>'List MyObject',
-            'mainmenu'=>'mymodule',
-            'leftmenu'=>'mymodule_myobject',
-            'url'=>'/mymodule/myobject_list.php',
-            // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
-            'langs'=>'mymodule@mymodule',
-            'position'=>1100+\$r,
-            // Define condition to show or hide menu entry. Use '\$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '\$leftmenu==\'system\'' to show if leftmenu system is selected.
-            'enabled'=>'\$conf->mymodule->enabled',
-            // Use 'perms'=>'\$user->rights->mymodule->level1->level2' if you want your menu with a permission rules
-            'perms'=>'1',
-            'target'=>'',
-            // 0=Menu for internal users, 1=external users, 2=both
-            'user'=>2,
-        );
-        \$this->menu[\$r++]=array(
-            // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
-            'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=mymodule_myobject',
-            // This is a Left menu entry
-            'type'=>'left',
-            'titre'=>'New MyObject',
-            'mainmenu'=>'mymodule',
-            'leftmenu'=>'mymodule_myobject',
-            'url'=>'/mymodule/myobject_card.php?action=create',
-            // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
-            'langs'=>'mymodule@mymodule',
-            'position'=>1100+\$r,
-            // Define condition to show or hide menu entry. Use '\$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '\$leftmenu==\'system\'' to show if leftmenu system is selected.
-            'enabled'=>'\$conf->mymodule->enabled',
-            // Use 'perms'=>'\$user->rights->mymodule->level1->level2' if you want your menu with a permission rules
-            'perms'=>'1',
-            'target'=>'',
-            // 0=Menu for internal users, 1=external users, 2=both
-            'user'=>2
-        );\n";
-                       $stringtoadd = preg_replace('/MyObject/', $objectnameloop, $stringtoadd);
-                       $stringtoadd = preg_replace('/mymodule/', strtolower($module), $stringtoadd);
-                       $stringtoadd = preg_replace('/myobject/', strtolower($objectnameloop), $stringtoadd);
-
-                       $moduledescriptorfile = $destdir.'/core/modules/mod'.$module.'.class.php';
-
-                       // TODO Allow a replace with regex using dolReplaceInFile with param arryreplacementisregex to 1
-                       // TODO Avoid duplicate addition
-
-                       dolReplaceInFile($moduledescriptorfile, array('END MODULEBUILDER LEFTMENU MYOBJECT */' => '*/'."\n".$stringtoadd."\n\t\t/* END MODULEBUILDER LEFTMENU MYOBJECT */"));
-
-                       // Add module descriptor to list of files to replace "MyObject' string with real name of object.
-                       $filetogenerate[] = 'core/modules/mod'.$module.'.class.php';
-               }
-       }
-
-       if (!$error) {
-               // Edit PHP files to make replacement
-               foreach ($filetogenerate as $destfile) {
-                       $phpfileval['fullname'] = $destdir.'/'.$destfile;
-
-                       //var_dump($phpfileval['fullname']);
-                       $arrayreplacement = array(
-                               'mymodule'=>strtolower($module),
-                               'MyModule'=>$module,
-                               'MYMODULE'=>strtoupper($module),
-                               'My module'=>$module,
-                               'my module'=>$module,
-                               'mon module'=>$module,
-                               'Mon module'=>$module,
-                               'htdocs/modulebuilder/template/'=>strtolower($modulename),
-                               'myobject'=>strtolower($objectname),
-                               'MyObject'=>$objectname,
-                               'MYOBJECT'=>strtoupper($objectname),
-                               '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
-                       );
-
-                       if (!empty($conf->global->MODULEBUILDER_SPECIFIC_EDITOR_NAME)) {
-                               $arrayreplacement['Editor name'] = $conf->global->MODULEBUILDER_SPECIFIC_EDITOR_NAME;
-                       }
-                       if (!empty($conf->global->MODULEBUILDER_SPECIFIC_EDITOR_URL)) {
-                               $arrayreplacement['https://www.example.com'] = $conf->global->MODULEBUILDER_SPECIFIC_EDITOR_URL;
-                       }
-                       if (!empty($conf->global->MODULEBUILDER_SPECIFIC_AUTHOR)) {
-                               $arrayreplacement['---Put here your own copyright and developer email---'] = dol_print_date($now, '%Y').' '.$conf->global->MODULEBUILDER_SPECIFIC_AUTHOR;
-                       }
-                       if (!empty($conf->global->MODULEBUILDER_SPECIFIC_VERSION)) {
-                               $arrayreplacement['1.0'] = $conf->global->MODULEBUILDER_SPECIFIC_VERSION;
-                       }
-                       if (!empty($conf->global->MODULEBUILDER_SPECIFIC_FAMILY)) {
-                               $arrayreplacement['other'] = $conf->global->MODULEBUILDER_SPECIFIC_FAMILY;
-                       }
-
-                       $result = dolReplaceInFile($phpfileval['fullname'], $arrayreplacement);
-                       //var_dump($result);
-                       if ($result < 0) {
-                               setEventMessages($langs->trans("ErrorFailToMakeReplacementInto", $phpfileval['fullname']), null, 'errors');
-                       }
-               }
-       }
-
-       if (!$error) {
-               // Edit the class file to write properties
-               $object = rebuildObjectClass($destdir, $module, $objectname, $newmask);
-
-               if (is_numeric($object) && $object <= 0) {
-                       $pathoffiletoeditsrc = $destdir.'/class/'.strtolower($objectname).'.class.php';
-                       setEventMessages($langs->trans('ErrorFailToCreateFile', $pathoffiletoeditsrc), null, 'errors');
-                       $error++;
-               }
-       }
-       if (!$error) {
-               // Edit sql with new properties
-               $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, '', $object);
-
-               if ($result <= 0) {
-                       setEventMessages($langs->trans('ErrorFailToCreateFile', '.sql'), null);
-                       $error++;
-               }
-       }
-
-       if (!$error) {
-               setEventMessages($langs->trans('FilesForObjectInitialized', $objectname), null);
-               $tabobj = $objectname;
-       } else {
-               $tabobj = 'newobject';
-       }
-}
-
-// Add a dictionary
-if ($dirins && $action == 'initdic' && $module && $dicname) {
-       if (!$error) {
-               $newdicname = $dicname;
-               if (!preg_match('/^c_/', $newdicname)) {
-                       $newdicname = 'c_'.$dicname;
-               }
-
-               // TODO
-
-               setEventMessages($langs->trans("FeatureNotYetAvailable"), null, 'errors');
-       }
-}
-
-// Delete a SQL table
-if ($dirins && ($action == 'droptable' || $action == 'droptableextrafields') && !empty($module) && !empty($tabobj)) {
-       $objectname = $tabobj;
-
-       $arrayoftables = array();
-       if ($action == 'droptable') {
-               $arrayoftables[] = MAIN_DB_PREFIX.strtolower($module).'_'.strtolower($tabobj);
-       }
-       if ($action == 'droptableextrafields') {
-               $arrayoftables[] = MAIN_DB_PREFIX.strtolower($module).'_'.strtolower($tabobj).'_extrafields';
-       }
-
-       foreach ($arrayoftables as $tabletodrop) {
-               $nb = -1;
-               $sql = "SELECT COUNT(*) as nb FROM ".$tabletodrop;
-               $resql = $db->query($sql);
-               if ($resql) {
-                       $obj = $db->fetch_object($resql);
-                       if ($obj) {
-                               $nb = $obj->nb;
-                       }
-               } else {
-                       if ($db->lasterrno() == 'DB_ERROR_NOSUCHTABLE') {
-                               setEventMessages($langs->trans("TableDoesNotExists", $tabletodrop), null, 'warnings');
-                       } else {
-                               dol_print_error($db);
-                       }
-               }
-               if ($nb == 0) {
-                       $resql = $db->DDLDropTable($tabletodrop);
-                       //var_dump($resql);
-                       setEventMessages($langs->trans("TableDropped", $tabletodrop), null, 'mesgs');
-               } elseif ($nb > 0) {
-                       setEventMessages($langs->trans("TableNotEmptyDropCanceled", $tabletodrop), null, 'warnings');
-               }
-       }
-}
-
-if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && !empty($tabobj)) {
-       $error = 0;
-
-       $objectname = $tabobj;
-
-       $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
-       $moduletype = $listofmodules[strtolower($module)]['moduletype'];
-
-       $srcdir = $dirread.'/'.strtolower($module);
-       $destdir = $dirins.'/'.strtolower($module);
-       dol_mkdir($destdir);
-
-       // We click on add property
-       if (!GETPOST('regenerateclasssql') && !GETPOST('regeneratemissing')) {
-               if (!GETPOST('propname', 'aZ09')) {
-                       $error++;
-                       setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Name")), null, 'errors');
-               }
-               if (!GETPOST('proplabel', 'alpha')) {
-                       $error++;
-                       setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
-               }
-               if (!GETPOST('proptype', 'alpha')) {
-                       $error++;
-                       setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Type")), null, 'errors');
-               }
-
-               if (!$error && !GETPOST('regenerateclasssql')&& !GETPOST('regeneratemissing')) {
-                       $addfieldentry = array(
-                               'name'=>GETPOST('propname', 'aZ09'),
-                               'label'=>GETPOST('proplabel', 'alpha'),
-                               'type'=>GETPOST('proptype', 'alpha'),
-                               'arrayofkeyval'=>GETPOST('proparrayofkeyval', 'restricthtml'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}'
-                               'visible'=>GETPOST('propvisible', 'int'),
-                               'enabled'=>GETPOST('propenabled', 'int'),
-                               'position'=>GETPOST('propposition', 'int'),
-                               'notnull'=>GETPOST('propnotnull', 'int'),
-                               'index'=>GETPOST('propindex', 'int'),
-                               'searchall'=>GETPOST('propsearchall', 'int'),
-                               'isameasure'=>GETPOST('propisameasure', 'int'),
-                               'comment'=>GETPOST('propcomment', 'alpha'),
-                               'help'=>GETPOST('prophelp', 'alpha'),
-                               'css'=>GETPOST('propcss', 'alpha'),        // Can be 'maxwidth500 widthcentpercentminusxx' for example
-                               'cssview'=>GETPOST('propcssview', 'alpha'),
-                               'csslist'=>GETPOST('propcsslist', 'alpha'),
-                               'default'=>GETPOST('propdefault', 'restricthtml'),
-                               'noteditable'=>intval(GETPOST('propnoteditable', 'int')),
-                               'alwayseditable'=>intval(GETPOST('propalwayseditable', 'int')),
-                               'validate' => GETPOST('propvalidate', 'int')
-                       );
-
-
-                       if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval'])) {
-                               $addfieldentry['arrayofkeyval'] = json_decode($addfieldentry['arrayofkeyval'], true);
-                       }
-               }
-       } else {
-               $addfieldentry = array();
-       }
-
-       /*if (GETPOST('regeneratemissing'))
-       {
-               setEventMessages($langs->trans("FeatureNotYetAvailable"), null, 'warnings');
-               $error++;
-       }*/
-
-       $moduletype = $listofmodules[strtolower($module)]['moduletype'];
-
-       // Edit the class file to write properties
-       if (!$error) {
-               $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry, $moduletype);
-
-               if (is_numeric($object) && $object <= 0) {
-                       $pathoffiletoeditsrc = $destdir.'/class/'.strtolower($objectname).'.class.php';
-                       setEventMessages($langs->trans('ErrorFailToCreateFile', $pathoffiletoeditsrc), null, 'errors');
-                       $error++;
-               }
-       }
-
-       // Edit sql with new properties
-       if (!$error) {
-               $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object, $moduletype);
-
-               if ($result <= 0) {
-                       setEventMessages($langs->trans('ErrorFailToCreateFile', '.sql'), null, 'errors');
-                       $error++;
-               }
-       }
-
-       if (!$error) {
-               clearstatcache(true);
-
-               setEventMessages($langs->trans('FilesForObjectUpdated', $objectname), null);
-
-               setEventMessages($langs->trans('WarningDatabaseIsNotUpdated'), null);
-
-               // Make a redirect to reload all data
-               header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj='.$objectname.'&nocache='.time());
-
-               exit;
-       }
-}
-
-if ($dirins && $action == 'confirm_deleteproperty' && $propertykey) {
-       $objectname = $tabobj;
-
-       $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
-       $moduletype = $listofmodules[strtolower($module)]['moduletype'];
-
-       $srcdir = $dirread.'/'.strtolower($module);
-       $destdir = $dirins.'/'.strtolower($module);
-       dol_mkdir($destdir);
-
-       // Edit the class file to write properties
-       if (!$error) {
-               $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, array(), $propertykey);
-
-               if (is_numeric($object) && $object <= 0) {
-                       $pathoffiletoeditsrc = $destdir.'/class/'.strtolower($objectname).'.class.php';
-                       setEventMessages($langs->trans('ErrorFailToCreateFile', $pathoffiletoeditsrc), null, 'errors');
-                       $error++;
-               }
-       }
-
-       // Edit sql with new properties
-       if (!$error) {
-               $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object);
-
-               if ($result <= 0) {
-                       setEventMessages($langs->trans('ErrorFailToCreateFile', '.sql'), null, 'errors');
-                       $error++;
-               }
-       }
-
-       if (!$error) {
-               setEventMessages($langs->trans('FilesForObjectUpdated', $objectname), null);
-
-               clearstatcache(true);
-
-               // Make a redirect to reload all data
-               header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj='.$objectname);
-
-               exit;
-       }
-}
-
-if ($dirins && $action == 'confirm_deletemodule') {
-       if (preg_match('/[^a-z0-9_]/i', $module)) {
-               $error++;
-               setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
-       }
-
-       if (!$error) {
-               $modulelowercase = strtolower($module);
-
-               // Dir for module
-               $dir = $dirins.'/'.$modulelowercase;
-
-               $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-
-               // Dir for module
-               $dir = dol_buildpath($modulelowercase, 0);
-
-               // Zip file to build
-               $FILENAMEZIP = '';
-
-               // Load module
-               dol_include_once($pathtofile);
-               $class = 'mod'.$module;
-
-               if (class_exists($class)) {
-                       try {
-                               $moduleobj = new $class($db);
-                       } catch (Exception $e) {
-                               $error++;
-                               dol_print_error($db, $e->getMessage());
-                       }
-               } else {
-                       $error++;
-                       $langs->load("errors");
-                       dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
-                       exit;
-               }
-
-               $moduleobj->remove();
-
-               $result = dol_delete_dir_recursive($dir);
-
-               if ($result > 0) {
-                       setEventMessages($langs->trans("DirWasRemoved", $modulelowercase), null);
-
-                       clearstatcache(true);
-                       if (function_exists('opcache_invalidate')) {
-                               opcache_reset();        // remove the include cache hell !
-                       }
-
-                       header("Location: ".$_SERVER["PHP_SELF"].'?module=deletemodule');
-                       exit;
-               } else {
-                       setEventMessages($langs->trans("PurgeNothingToDelete"), null, 'warnings');
-               }
-       }
-
-       $action = '';
-       $module = 'deletemodule';
-}
-
-if ($dirins && $action == 'confirm_deleteobject' && $objectname) {
-       if (preg_match('/[^a-z0-9_]/i', $objectname)) {
-               $error++;
-               setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
-       }
-
-       if (!$error) {
-               $modulelowercase = strtolower($module);
-               $objectlowercase = strtolower($objectname);
-
-               // Dir for module
-               $dir = $dirins.'/'.$modulelowercase;
-
-               // Delete some files
-               $filetodelete = array(
-                       'myobject_card.php'=>strtolower($objectname).'_card.php',
-                       'myobject_note.php'=>strtolower($objectname).'_note.php',
-                       'myobject_contact.php'=>strtolower($objectname).'_contact.php',
-                       'myobject_document.php'=>strtolower($objectname).'_document.php',
-                       'myobject_agenda.php'=>strtolower($objectname).'_agenda.php',
-                       'myobject_list.php'=>strtolower($objectname).'_list.php',
-                       'admin/myobject_extrafields.php'=>'admin/'.strtolower($objectname).'_extrafields.php',
-                       'lib/mymodule_myobject.lib.php'=>'lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php',
-                       'test/phpunit/MyObjectTest.php'=>'test/phpunit/'.strtolower($objectname).'Test.php',
-                       'sql/llx_mymodule_myobject.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql',
-                       'sql/llx_mymodule_myobject_extrafields.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.sql',
-                       'sql/llx_mymodule_myobject.key.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql',
-                       'sql/llx_mymodule_myobject_extrafields.key.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.key.sql',
-                       'scripts/myobject.php'=>'scripts/'.strtolower($objectname).'.php',
-                       'class/myobject.class.php'=>'class/'.strtolower($objectname).'.class.php',
-                       'class/api_myobject.class.php'=>'class/api_'.strtolower($module).'.class.php',
-                       'core/modules/mymodule/mod_myobject_advanced.php'=>'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_advanced.php',
-                       'core/modules/mymodule/mod_myobject_standard.php'=>'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_standard.php',
-                       'core/modules/mymodule/modules_myobject.php'=>'core/modules/'.strtolower($module).'/modules_'.strtolower($objectname).'.php',
-                       'core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php'=>'core/modules/'.strtolower($module).'/doc/doc_generic_'.strtolower($objectname).'_odt.modules.php',
-                       'core/modules/mymodule/doc/pdf_standard_myobject.modules.php'=>'core/modules/'.strtolower($module).'/doc/pdf_standard_'.strtolower($objectname).'.modules.php'
-               );
-
-               $resultko = 0;
-               foreach ($filetodelete as $tmpfiletodelete) {
-                       $resulttmp = dol_delete_file($dir.'/'.$tmpfiletodelete, 0, 0, 1);
-                       $resulttmp = dol_delete_file($dir.'/'.$tmpfiletodelete.'.back', 0, 0, 1);
-                       if (!$resulttmp) {
-                               $resultko++;
-                       }
-               }
-
-               if ($resultko == 0) {
-                       setEventMessages($langs->trans("FilesDeleted"), null);
-               } else {
-                       setEventMessages($langs->trans("ErrorSomeFilesCouldNotBeDeleted"), null, 'warnings');
-               }
-       }
-
-       $action = '';
-       $tabobj = 'deleteobject';
-}
-
-if ($dirins && $action == 'generatedoc') {
-       $modulelowercase = strtolower($module);
-
-       // Dir for module
-       $dirofmodule = dol_buildpath($modulelowercase, 0).'/doc';
-
-       $FILENAMEDOC = strtolower($module).'.html';
-
-       $util = new Utils($db);
-       $result = $util->generateDoc($module);
-
-       if ($result > 0) {
-               setEventMessages($langs->trans("DocFileGeneratedInto", $dirofmodule), null);
-       } else {
-               setEventMessages($util->error, $util->errors, 'errors');
-       }
-}
-
-if ($dirins && $action == 'generatepackage') {
-       $modulelowercase = strtolower($module);
-
-       $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-
-       // Dir for module
-       $dir = dol_buildpath($modulelowercase, 0);
-
-       // Zip file to build
-       $FILENAMEZIP = '';
-
-       // Load module
-       dol_include_once($pathtofile);
-       $class = 'mod'.$module;
-
-       if (class_exists($class)) {
-               try {
-                       $moduleobj = new $class($db);
-               } catch (Exception $e) {
-                       $error++;
-                       dol_print_error($db, $e->getMessage());
-               }
-       } else {
-               $error++;
-               $langs->load("errors");
-               dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
-               exit;
-       }
-
-       $arrayversion = explode('.', $moduleobj->version, 3);
-       if (count($arrayversion)) {
-               $FILENAMEZIP = "module_".$modulelowercase.'-'.$arrayversion[0].(empty($arrayversion[1]) ? '.0' : '.'.$arrayversion[1]).(empty($arrayversion[2]) ? '' : '.'.$arrayversion[2]).'.zip';
-
-               $dirofmodule = dol_buildpath($modulelowercase, 0).'/bin';
-               $outputfilezip = $dirofmodule.'/'.$FILENAMEZIP;
-               if ($dirofmodule) {
-                       if (!dol_is_dir($dirofmodule)) {
-                               dol_mkdir($dirofmodule);
-                       }
-                       // Note: We exclude /bin/ to not include the already generated zip
-                       $result = dol_compress_dir($dir, $outputfilezip, 'zip', '/\/bin\/|\.git|\.old|\.back|\.ssh/', $modulelowercase);
-               } else {
-                       $result = -1;
-               }
-
-               if ($result > 0) {
-                       setEventMessages($langs->trans("ZipFileGeneratedInto", $outputfilezip), null);
-               } else {
-                       $error++;
-                       $langs->load("errors");
-                       setEventMessages($langs->trans("ErrorFailToGenerateFile", $outputfilezip), null, 'errors');
-               }
-       } else {
-               $error++;
-               $langs->load("errors");
-               setEventMessages($langs->trans("ErrorCheckVersionIsDefined"), null, 'errors');
-       }
-}
-
-
-// Save file
-if ($action == 'savefile' && empty($cancel)) {
-       $relofcustom = basename($dirins);
-
-       if ($relofcustom) {
-               // Check that relative path ($file) start with name 'custom'
-               if (!preg_match('/^'.$relofcustom.'/', $file)) {
-                       $file = $relofcustom.'/'.$file;
-               }
-
-               $pathoffile = dol_buildpath($file, 0);
-               $pathoffilebackup = dol_buildpath($file.'.back', 0);
-
-               // Save old version
-               if (dol_is_file($pathoffile)) {
-                       dol_copy($pathoffile, $pathoffilebackup, 0, 1);
-               }
-
-               $check = 'restricthtml';
-               $srclang = dol_mimetype($pathoffile, '', 3);
-               if ($srclang == 'md') {
-                       $check = 'restricthtml';
-               }
-               if ($srclang == 'lang') {
-                       $check = 'restricthtml';
-               }
-               if ($srclang == 'php') {
-                       $check = 'none';
-               }
-
-               $content = GETPOST('editfilecontent', $check);
-
-               // Save file on disk
-               if ($content) {
-                       dol_delete_file($pathoffile);
-                       $result = file_put_contents($pathoffile, $content);
-                       if ($result) {
-                               @chmod($pathoffile, octdec($newmask));
-
-                               setEventMessages($langs->trans("FileSaved"), null);
-                       } else {
-                               setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors');
-                       }
-               } else {
-                       setEventMessages($langs->trans("ContentCantBeEmpty"), null, 'errors');
-                       //$action='editfile';
-                       $error++;
-               }
-       }
-}
-
-// Enable module
-if ($action == 'set' && $user->admin) {
-       $param = '';
-       if ($module) {
-               $param .= '&module='.urlencode($module);
-       }
-       if ($tab) {
-               $param .= '&tab='.urlencode($tab);
-       }
-       if ($tabobj) {
-               $param .= '&tabobj='.urlencode($tabobj);
-       }
-
-       $value = GETPOST('value', 'alpha');
-       $resarray = activateModule($value);
-       if (!empty($resarray['errors'])) {
-               setEventMessages('', $resarray['errors'], 'errors');
-       } else {
-               //var_dump($resarray);exit;
-               if ($resarray['nbperms'] > 0) {
-                       $tmpsql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."user WHERE admin <> 1";
-                       $resqltmp = $db->query($tmpsql);
-                       if ($resqltmp) {
-                               $obj = $db->fetch_object($resqltmp);
-                               //var_dump($obj->nb);exit;
-                               if ($obj && $obj->nb > 1) {
-                                       $msg = $langs->trans('ModuleEnabledAdminMustCheckRights');
-                                       setEventMessages($msg, null, 'warnings');
-                               }
-                       } else {
-                               dol_print_error($db);
-                       }
-               }
-       }
-       header("Location: ".$_SERVER["PHP_SELF"]."?".$param);
-       exit;
-}
-
-// Disable module
-if ($action == 'reset' && $user->admin) {
-       $param = '';
-       if ($module) {
-               $param .= '&module='.urlencode($module);
-       }
-       if ($tab) {
-               $param .= '&tab='.urlencode($tab);
-       }
-       if ($tabobj) {
-               $param .= '&tabobj='.urlencode($tabobj);
-       }
-
-       $value = GETPOST('value', 'alpha');
-       $result = unActivateModule($value);
-       if ($result) {
-               setEventMessages($result, null, 'errors');
-       }
-       header("Location: ".$_SERVER["PHP_SELF"]."?".$param);
-       exit;
-}
-
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-$formadmin = new FormAdmin($db);
-
-// Set dir where external modules are installed
-if (!dol_is_dir($dirins)) {
-       dol_mkdir($dirins);
-}
-$dirins_ok = (dol_is_dir($dirins));
-
-$help_url = '';
-$morejs = array(
-       '/includes/ace/src/ace.js',
-       '/includes/ace/src/ext-statusbar.js',
-       '/includes/ace/src/ext-language_tools.js',
-       //'/includes/ace/src/ext-chromevox.js'
-);
-$morecss = array();
-
-llxHeader('', $langs->trans("ModuleBuilder"), $help_url, '', 0, 0, $morejs, $morecss, '', 'classforhorizontalscrolloftabs');
-
-
-$text = $langs->trans("ModuleBuilder");
-
-print load_fiche_titre($text, '', 'title_setup');
-
-print '<span class="opacitymedium hideonsmartphone">'.$langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').'</span>';
-print '<br class="hideonsmartphone">';
-
-//print $textforlistofdirs;
-//print '<br>';
-//var_dump($listofmodules);
-
-
-$message = '';
-if (!$dirins) {
-       $message = info_admin($langs->trans("ConfFileMustContainCustom", DOL_DOCUMENT_ROOT.'/custom', DOL_DOCUMENT_ROOT));
-       $allowfromweb = -1;
-} else {
-       if ($dirins_ok) {
-               if (!is_writable(dol_osencode($dirins))) {
-                       $langs->load("errors");
-                       $message = info_admin($langs->trans("ErrorFailedToWriteInDir", $dirins));
-                       $allowfromweb = 0;
-               }
-       } else {
-               $message = info_admin($langs->trans("NotExistsDirect", $dirins).$langs->trans("InfDirAlt").$langs->trans("InfDirExample"));
-               $allowfromweb = 0;
-       }
-}
-if ($message) {
-       print $message;
-}
-
-//print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).'<br>';
-$infomodulesfound = '<div style="padding: 12px 9px 12px">'.$form->textwithpicto('', $langs->trans("ModuleBuilderDesc3", count($listofmodules)).'<br><br>'.$langs->trans("ModuleBuilderDesc4", $FILEFLAG).'<br>'.$textforlistofdirs).'</div>';
-
-
-
-$dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
-$allowonlineinstall = true;
-if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
-       $allowonlineinstall = false;
-}
-if (empty($allowonlineinstall)) {
-       if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
-               // Show clean message
-               $message = info_admin($langs->trans('InstallModuleFromWebHasBeenDisabledContactUs'));
-       } else {
-               // Show technical message
-               $message = info_admin($langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock'), 0, 0, 1, 'warning');
-       }
-
-       print $message;
-
-       llxFooter();
-       exit(0);
-}
-
-
-// Load module descriptor
-$error = 0;
-$moduleobj = null;
-
-
-if (!empty($module) && $module != 'initmodule' && $module != 'deletemodule') {
-       $modulelowercase = strtolower($module);
-       $loadclasserrormessage = '';
-
-       // Load module
-       try {
-               $fullpathdirtodescriptor = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-
-               //throw(new Exception());
-               dol_include_once($fullpathdirtodescriptor);
-
-               $class = 'mod'.$module;
-       } catch (Throwable $e) {                // This is called in PHP 7 only. Never called with PHP 5.6
-               $loadclasserrormessage = $e->getMessage()."<br>\n";
-               $loadclasserrormessage .= 'File: '.$e->getFile()."<br>\n";
-               $loadclasserrormessage .= 'Line: '.$e->getLine()."<br>\n";
-       } catch (Exception $e) {
-               $loadclasserrormessage = $e->getMessage()."<br>\n";
-               $loadclasserrormessage .= 'File: '.$e->getFile()."<br>\n";
-               $loadclasserrormessage .= 'Line: '.$e->getLine()."<br>\n";
-       }
-
-       if (class_exists($class)) {
-               try {
-                       $moduleobj = new $class($db);
-               } catch (Exception $e) {
-                       $error++;
-                       print $e->getMessage();
-               }
-       } else {
-               if (empty($forceddirread)) {
-                       $error++;
-               }
-               $langs->load("errors");
-               print '<!-- ErrorFailedToLoadModuleDescriptorForXXX -->';
-               print img_warning('').' '.$langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module).'<br>';
-               print $loadclasserrormessage;
-       }
-}
-
-print '<br>';
-
-
-// Tabs for all modules
-$head = array();
-$h = 0;
-
-$head[$h][0] = $_SERVER["PHP_SELF"].'?module=initmodule';
-$head[$h][1] = '<span class="valignmiddle text-plus-circle">'.$langs->trans("NewModule").'</span><span class="fa fa-plus-circle valignmiddle paddingleft"></span>';
-$head[$h][2] = 'initmodule';
-$h++;
-
-$linktoenabledisable = '';
-
-if (is_array($listofmodules) && count($listofmodules) > 0) {
-       // Define $linktoenabledisable
-       $modulelowercase = strtolower($module);
-       $const_name = 'MAIN_MODULE_'.strtoupper($module);
-
-       $param = '';
-       if ($tab) {
-               $param .= '&tab='.urlencode($tab);
-       }
-       if ($module) {
-               $param .= '&module='.urlencode($module);
-       }
-       if ($tabobj) {
-               $param .= '&tabobj='.urlencode($tabobj);
-       }
-
-       $urltomodulesetup = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?search_keyword='.urlencode($module).'">'.$langs->trans('Home').'-'.$langs->trans("Setup").'-'.$langs->trans("Modules").'</a>';
-
-       // Define $linktoenabledisable to show after module title
-       if (isModEnabled($modulelowercase)) {   // If module is already activated
-               $linktoenabledisable .= '<a class="reposition asetresetmodule valignmiddle" href="'.$_SERVER["PHP_SELF"].'?id='.$moduleobj->numero.'&action=reset&token='.newToken().'&value=mod'.$module.$param.'">';
-               $linktoenabledisable .= img_picto($langs->trans("Activated"), 'switch_on', '', false, 0, 0, '', '', 1);
-               $linktoenabledisable .= '</a>';
-
-               $linktoenabledisable .= $form->textwithpicto('', $langs->trans("Warning").' : '.$langs->trans("ModuleIsLive"), -1, 'warning');
-
-               $objMod = $moduleobj;
-               $backtourlparam = '';
-               $backtourlparam .= ($backtourlparam ? '&' : '?').'module='.$module; // No urlencode here, done later
-               if ($tab) {
-                       $backtourlparam .= ($backtourlparam ? '&' : '?').'tab='.$tab; // No urlencode here, done later
-               }
-               $backtourl = $_SERVER["PHP_SELF"].$backtourlparam;
-
-               $regs = array();
-               if (is_array($objMod->config_page_url)) {
-                       $i = 0;
-                       foreach ($objMod->config_page_url as $page) {
-                               $urlpage = $page;
-                               if ($i++) {
-                                       $linktoenabledisable .= ' <a href="'.$urlpage.'" title="'.$langs->trans($page).'">'.img_picto(ucfirst($page), "setup").'</a>';
-                                       //    print '<a href="'.$page.'">'.ucfirst($page).'</a>&nbsp;';
-                               } else {
-                                       if (preg_match('/^([^@]+)@([^@]+)$/i', $urlpage, $regs)) {
-                                               $urltouse = dol_buildpath('/'.$regs[2].'/admin/'.$regs[1], 1);
-                                               $linktoenabledisable .= ' <a href="'.$urltouse.(preg_match('/\?/', $urltouse) ? '&' : '?').'save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 8px"').'</a>';
-                                       } else {
-                                               // Case standard admin page (not a page provided by the
-                                               // module but a page provided by dolibarr)
-                                               $urltouse = DOL_URL_ROOT.'/admin/'.$urlpage;
-                                               $linktoenabledisable .= ' <a href="'.$urltouse.(preg_match('/\?/', $urltouse) ? '&' : '?').'save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 8px"').'</a>';
-                                       }
-                               }
-                       }
-               } elseif (preg_match('/^([^@]+)@([^@]+)$/i', $objMod->config_page_url, $regs)) {
-                       $linktoenabledisable .= ' &nbsp; <a href="'.dol_buildpath('/'.$regs[2].'/admin/'.$regs[1], 1).'?save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 8px"').'</a>';
-               }
-       } else {
-               if (!empty($moduleobj)) {
-                       $linktoenabledisable .= '<a class="reposition asetresetmodule valignmiddle" href="'.$_SERVER["PHP_SELF"].'?id='.$moduleobj->numero.'&action=set&token='.newToken().'&value=mod'.$module.$param.'">';
-                       $linktoenabledisable .= img_picto($langs->trans("ModuleIsNotActive", $urltomodulesetup), 'switch_off', 'style="padding-right: 8px"', false, 0, 0, '', 'classfortooltip', 1);
-                       $linktoenabledisable .= "</a>\n";
-               }
-       }
-
-       // Loop to show tab of each module
-       foreach ($listofmodules as $tmpmodule => $tmpmodulearray) {
-               $head[$h][0] = $_SERVER["PHP_SELF"].'?module='.$tmpmodulearray['modulenamewithcase'].($forceddirread ? '@'.$dirread : '');
-               $head[$h][1] = $tmpmodulearray['modulenamewithcase'];
-               $head[$h][2] = $tmpmodulearray['modulenamewithcase'];
-
-               if ($tmpmodulearray['modulenamewithcase'] == $module) {
-                       $head[$h][4] = '<span class="inline-block">'.$linktoenabledisable.'</span>';
-               }
-
-               $h++;
-       }
-}
-
-$head[$h][0] = $_SERVER["PHP_SELF"].'?module=deletemodule';
-$head[$h][1] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("DangerZone");
-$head[$h][2] = 'deletemodule';
-$h++;
-
-
-print dol_get_fiche_head($head, $module, '', -1, '', 0, $infomodulesfound, '', 8); // Modules
-
-if ($module == 'initmodule') {
-       // New module
-       print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-       print '<input type="hidden" name="token" value="'.newToken().'">';
-       print '<input type="hidden" name="action" value="initmodule">';
-       print '<input type="hidden" name="module" value="initmodule">';
-
-       //print '<span class="opacitymedium">'.$langs->trans("ModuleBuilderDesc2", 'conf/conf.php', $newdircustom).'</span><br>';
-       print '<br>';
-
-       print '<div class="tagtable">';
-
-       print '<div class="tagtr"><div class="tagtd">';
-       print '<span class="opacitymedium">'.$langs->trans("IdModule").'</span>';
-       print '</div><div class="tagtd">';
-       print '<input type="text" name="idmodule" class="width75" value="500000" placeholder="'.dol_escape_htmltag($langs->trans("IdModule")).'">';
-       print '<span class="opacitymedium">';
-       print ' &nbsp; (';
-       print dolButtonToOpenUrlInDialogPopup('popup_modules_id', $langs->transnoentitiesnoconv("SeeIDsInUse"), $langs->transnoentitiesnoconv("SeeIDsInUse"), '/admin/system/modules.php?mainmenu=home&leftmenu=admintools_info', '', '');
-       print ' - ';
-       print '<a href="https://wiki.dolibarr.org/index.php/List_of_modules_id" target="_blank" rel="noopener noreferrer external">'.$langs->trans("SeeReservedIDsRangeHere").'</a>';
-       print ')';
-       print '</span>';
-       print '</div></div>';
-
-       print '<div class="tagtr"><div class="tagtd">';
-       print '<span class="opacitymedium">'.$langs->trans("ModuleName").'</span>';
-       print '</div><div class="tagtd">';
-       print '<input type="text" name="modulename" value="'.dol_escape_htmltag($modulename).'" autofocus>';
-       print ' '.$form->textwithpicto('', $langs->trans("EnterNameOfModuleDesc"));
-       print '</div></div>';
-
-       print '<div class="tagtr"><div class="tagtd">';
-       print '<span class="opacitymedium">'.$langs->trans("Description").'</span>';
-       print '</div><div class="tagtd">';
-       print '<input type="text" name="description" value="" class="minwidth500"><br>';
-       print '</div></div>';
-
-       print '<div class="tagtr"><div class="tagtd">';
-       print '<span class="opacitymedium">'.$langs->trans("Version").'</span>';
-       print '</div><div class="tagtd">';
-       print '<input type="text" name="version" class="width75" value="'.(GETPOSTISSET('version') ? GETPOST('version') : getDolGlobalString('MODULEBUILDER_SPECIFIC_VERSION', '1.0')).'" placeholder="'.dol_escape_htmltag($langs->trans("Version")).'">';
-       print '</div></div>';
-
-       print '<div class="tagtr"><div class="tagtd">';
-       print '<span class="opacitymedium">'.$langs->trans("Family").'</span>';
-       print '</div><div class="tagtd">';
-       print '<select name="family" id="family" class="minwidth400">';
-       $arrayoffamilies = array(
-               'hr' => "ModuleFamilyHr",
-               'crm' => "ModuleFamilyCrm",
-               'srm' => "ModuleFamilySrm",
-               'financial' => 'ModuleFamilyFinancial',
-               'products' => 'ModuleFamilyProducts',
-               'projects' => 'ModuleFamilyProjects',
-               'ecm' => 'ModuleFamilyECM',
-               'technic' => 'ModuleFamilyTechnic',
-               'portal' => 'ModuleFamilyPortal',
-               'interface' => 'ModuleFamilyInterface',
-               'base' => 'ModuleFamilyBase',
-               'other' => 'ModuleFamilyOther'
-       );
-       foreach ($arrayoffamilies as $key => $value) {
-               print '<option value="hr"'.($key == getDolGlobalString('MODULEBUILDER_SPECIFIC_FAMILY', 'other') ? ' selected="selected"' : '').' data-html="'.dol_escape_htmltag($langs->trans($value).' <span class="opacitymedium">- '.$key.'</span>').'">'.$langs->trans($value).'</option>';
-       }
-       print '</select>';
-       print ajax_combobox("family");
-       print '</div></div>';
-
-       print '<div class="tagtr"><div class="tagtd">';
-       print '<span class="opacitymedium">'.$langs->trans("Picto").'</span>';
-       print '</div><div class="tagtd">';
-       print '<input type="text" name="idpicto" value="'.(GETPOSTISSET('idpicto') ? GETPOST('idpicto') : getDolGlobalString('MODULEBUILDER_DEFAULTPICTO', 'fa-generic')).'" placeholder="'.dol_escape_htmltag($langs->trans("Picto")).'">';
-       print $form->textwithpicto('', $langs->trans("Example").': fa-generic, fa-globe, ... any font awesome code.<br>Advanced syntax is fa-fakey[_faprefix[_facolor[_fasize]]]');
-       print '</div></div>';
-
-       print '<div class="tagtr"><div class="tagtd">';
-       print '<span class="opacitymedium">'.$langs->trans("EditorName").'</span>';
-       print '</div><div class="tagtd">';
-       print '<input type="text" name="editorname" value="'.(GETPOSTISSET('editorname') ? GETPOST('editorname') : getDolGlobalString('MODULEBUILDER_SPECIFIC_EDITOR_NAME', $mysoc->name)).'" placeholder="'.dol_escape_htmltag($langs->trans("EditorName")).'"><br>';
-       print '</div></div>';
-
-       print '<div class="tagtr"><div class="tagtd">';
-       print '<span class="opacitymedium">'.$langs->trans("EditorUrl").'</span>';
-       print '</div><div class="tagtd">';
-       print '<input type="text" name="editorurl" value="'.(GETPOSTISSET('editorurl') ? GETPOST('editorurl') : getDolGlobalString('MODULEBUILDER_SPECIFIC_EDITOR_URL', $mysoc->url)).'" placeholder="'.dol_escape_htmltag($langs->trans("EditorUrl")).'"><br>';
-       print '</div></div>';
-
-       print '<br><input type="submit" class="button" name="create" value="'.dol_escape_htmltag($langs->trans("Create")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
-       print '</form>';
-} elseif ($module == 'deletemodule') {
-       print '<!-- Form to init a module -->'."\n";
-       print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="delete">';
-       print '<input type="hidden" name="token" value="'.newToken().'">';
-       print '<input type="hidden" name="action" value="confirm_deletemodule">';
-       print '<input type="hidden" name="module" value="deletemodule">';
-
-       print $langs->trans("EnterNameOfModuleToDeleteDesc").'<br><br>';
-
-       print '<input type="text" name="module" placeholder="'.dol_escape_htmltag($langs->trans("ModuleKey")).'" value="">';
-       print '<input type="submit" class="button smallpaddingimp" value="'.$langs->trans("Delete").'"'.($dirins ? '' : ' disabled="disabled"').'>';
-       print '</form>';
-} elseif (!empty($module)) {
-       // Tabs for module
-       if (!$error) {
-               $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
-
-               $head2 = array();
-               $h = 0;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=description&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("Description");
-               $head2[$h][2] = 'description';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("Objects");
-               $head2[$h][2] = 'objects';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=languages&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("Languages");
-               $head2[$h][2] = 'languages';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("Dictionaries");
-               $head2[$h][2] = 'dictionaries';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=permissions&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("Permissions");
-               $head2[$h][2] = 'permissions';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=tabs&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("Tabs");
-               $head2[$h][2] = 'tabs';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=menus&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("Menus");
-               $head2[$h][2] = 'menus';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=hooks&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("Hooks");
-               $head2[$h][2] = 'hooks';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=triggers&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("Triggers");
-               $head2[$h][2] = 'triggers';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=widgets&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("Widgets");
-               $head2[$h][2] = 'widgets';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=exportimport&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("Export").'-'.$langs->trans("Import");
-               $head2[$h][2] = 'exportimport';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=css&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("CSS");
-               $head2[$h][2] = 'css';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=js&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("JS");
-               $head2[$h][2] = 'js';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=cli&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("CLI");
-               $head2[$h][2] = 'cli';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=cron&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("CronList");
-               $head2[$h][2] = 'cron';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=specifications&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("Documentation");
-               $head2[$h][2] = 'specifications';
-               $h++;
-
-               $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=buildpackage&module='.$module.($forceddirread ? '@'.$dirread : '');
-               $head2[$h][1] = $langs->trans("BuildPackage");
-               $head2[$h][2] = 'buildpackage';
-               $h++;
-
-               $MAXTABFOROBJECT = 15;
-
-               print '<!-- Section for a given module -->';
-
-               // Note module is inside $dirread
-
-               if ($tab == 'description') {
-                       print '<!-- tab=description -->'."\n";
-                       $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-                       $pathtofilereadme = $modulelowercase.'/README.md';
-                       $pathtochangelog = $modulelowercase.'/ChangeLog.md';
-
-                       if ($action != 'editfile' || empty($file)) {
-                               print dol_get_fiche_head($head2, $tab, '', -1, '', 0, '', '', $MAXTABFOROBJECT, 'formodulesuffix'); // Description - level 2
-
-                               print '<span class="opacitymedium">'.$langs->trans("ModuleBuilderDesc".$tab).'</span>';
-                               $infoonmodulepath = '';
-                               if (realpath($dirread.'/'.$modulelowercase) != $dirread.'/'.$modulelowercase) {
-                                       $infoonmodulepath = '<span class="opacitymedium">'.$langs->trans("RealPathOfModule").' :</span> <strong class="wordbreak">'.realpath($dirread.'/'.$modulelowercase).'</strong><br>';
-                                       print ' '.$infoonmodulepath;
-                               }
-                               print '<br>';
-
-                               print '<table>';
-
-                               print '<tr><td>';
-                               print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                               print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                               print '</td></tr>';
-
-                               print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("ReadmeFile").' : <strong class="wordbreak">'.$pathtofilereadme.'</strong>';
-                               print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=markdown&file='.urlencode($pathtofilereadme).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                               print '</td></tr>';
-
-                               print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("ChangeLog").' : <strong class="wordbreak">'.$pathtochangelog.'</strong>';
-                               print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=markdown&file='.urlencode($pathtochangelog).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                               print '</td></tr>';
-
-                               print '</table>';
-                               print '<br>';
-
-                               print load_fiche_titre($form->textwithpicto($langs->trans("DescriptorFile"), $langs->transnoentitiesnoconv("File").' '.$pathtofile), '', '');
-
-                               if (!empty($moduleobj)) {
-                                       print '<div class="underbanner clearboth"></div>';
-                                       print '<div class="fichecenter">';
-
-                                       print '<table class="border centpercent">';
-                                       print '<tr class="liste_titre"><td class="titlefield">';
-                                       print $langs->trans("Parameter");
-                                       print '</td><td>';
-                                       print $langs->trans("Value");
-                                       print '</td></tr>';
-
-                                       print '<tr><td>';
-                                       print $langs->trans("IdModule");
-                                       print '</td><td>';
-                                       print $moduleobj->numero;
-                                       print '<span class="opacitymedium">';
-                                       print ' &nbsp; (<a href="'.DOL_URL_ROOT.'/admin/system/modules.php?mainmenu=home&leftmenu=admintools_info" target="_blank" rel="noopener noreferrer">'.$langs->trans("SeeIDsInUse").'</a>';
-                                       print ' - <a href="https://wiki.dolibarr.org/index.php/List_of_modules_id" target="_blank" rel="noopener noreferrer external">'.$langs->trans("SeeReservedIDsRangeHere").'</a>)';
-                                       print '</span>';
-                                       print '</td></tr>';
-
-                                       print '<tr><td>';
-                                       print $langs->trans("ModuleName");
-                                       print '</td><td>';
-                                       print $moduleobj->getName();
-                                       print '</td></tr>';
-
-                                       print '<tr><td>';
-                                       print $langs->trans("Description");
-                                       print '</td><td>';
-                                       print $moduleobj->getDesc();
-                                       print '</td></tr>';
-
-                                       print '<tr><td>';
-                                       print $langs->trans("Version");
-                                       print '</td><td>';
-                                       print $moduleobj->getVersion();
-                                       print '</td></tr>';
-
-                                       print '<tr><td>';
-                                       print $langs->trans("Family");
-                                       //print "<br>'crm','financial','hr','projects','products','ecm','technic','interface','other'";
-                                       print '</td><td>';
-                                       print $moduleobj->family;
-                                       print '</td></tr>';
-
-                                       print '<tr><td>';
-                                       print $langs->trans("Picto");
-                                       print '</td><td>';
-                                       print $moduleobj->picto;
-                                       print ' &nbsp; '.img_picto('', $moduleobj->picto, 'class="valignmiddle pictomodule paddingrightonly"');
-                                       print '</td></tr>';
-
-                                       print '<tr><td>';
-                                       print $langs->trans("EditorName");
-                                       print '</td><td>';
-                                       print $moduleobj->editor_name;
-                                       print '</td></tr>';
-
-                                       print '<tr><td>';
-                                       print $langs->trans("EditorUrl");
-                                       print '</td><td>';
-                                       if (!empty($moduleobj->editor_url)) {
-                                               print '<a href="'.$moduleobj->editor_url.'" target="_blank" rel="noopener">'.$moduleobj->editor_url.' '.img_picto('', 'globe').'</a>';
-                                       }
-                                       print '</td></tr>';
-
-                                       print '</table>';
-                               } else {
-                                       print $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module).'<br>';
-                               }
-
-                               if (!empty($moduleobj)) {
-                                       print '<br><br>';
-
-                                       // Readme file
-                                       print load_fiche_titre($form->textwithpicto($langs->trans("ReadmeFile"), $langs->transnoentitiesnoconv("File").' '.$pathtofilereadme), '', '');
-
-                                       print '<!-- readme file -->';
-                                       if (dol_is_file($dirread.'/'.$pathtofilereadme)) {
-                                               print '<div class="underbanner clearboth"></div><div class="fichecenter">'.$moduleobj->getDescLong().'</div>';
-                                       } else {
-                                               print '<span class="opacitymedium">'.$langs->trans("ErrorFileNotFound", $pathtofilereadme).'</span>';
-                                       }
-
-                                       print '<br><br>';
-
-                                       // ChangeLog
-                                       print load_fiche_titre($form->textwithpicto($langs->trans("ChangeLog"), $langs->transnoentitiesnoconv("File").' '.$pathtochangelog), '', '');
-
-                                       print '<!-- changelog file -->';
-                                       if (dol_is_file($dirread.'/'.$pathtochangelog)) {
-                                               print '<div class="underbanner clearboth"></div><div class="fichecenter">'.$moduleobj->getChangeLog().'</div>';
-                                       } else {
-                                               print '<span class="opacitymedium">'.$langs->trans("ErrorFileNotFound", $pathtochangelog).'</span>';
-                                       }
-                               }
-
-                               print dol_get_fiche_end();
-                       } else {        // Edit text file
-                               $fullpathoffile = dol_buildpath($file, 0, 1); // Description - level 2
-
-                               if ($fullpathoffile) {
-                                       $content = file_get_contents($fullpathoffile);
-                               }
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               print dol_get_fiche_head($head2, $tab, '', -1, '', 0, '', '', 0, 'formodulesuffix');
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%', '');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-
-                               print dol_get_fiche_end();
-
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               } else {
-                       print dol_get_fiche_head($head2, $tab, '', -1, '', 0, '', '', $MAXTABFOROBJECT, 'formodulesuffix'); // Level 2
-               }
-
-               if ($tab == 'languages') {
-                       print '<!-- tab=languages -->'."\n";
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">'.$langs->trans("LanguageDefDesc").'</span><br>';
-                               print '<br>';
-
-
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="addlanguage">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-                               print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'newlangcode', 0, 0, 1, 0, 0, 'minwidth300', 1);
-                               print '<input type="submit" name="addlanguage" class="button smallpaddingimp" value="'.dol_escape_htmltag($langs->trans("AddLanguageFile")).'"><br>';
-                               print '</form>';
-
-                               print '<br>';
-                               print '<br>';
-
-                               $modulelowercase = strtolower($module);
-
-                               // Dir for module
-                               $diroflang = dol_buildpath($modulelowercase, 0);
-                               $diroflang .= '/langs';
-                               $langfiles = dol_dir_list($diroflang, 'files', 1, '\.lang$');
-
-                               if (!preg_match('/custom/', $dirread)) {
-                                       // If this is not a module into custom
-                                       $diroflang = $dirread;
-                                       $diroflang .= '/langs';
-                                       $langfiles = dol_dir_list($diroflang, 'files', 1, $modulelowercase.'\.lang$');
-                               }
-
-                               print '<table class="none">';
-                               foreach ($langfiles as $langfile) {
-                                       $pathtofile = $modulelowercase.'/langs/'.$langfile['relativename'];
-                                       if (!preg_match('/custom/', $dirread)) {        // If this is not a module into custom
-                                               $pathtofile = 'langs/'.$langfile['relativename'];
-                                       }
-                                       print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("LanguageFile").' '.basename(dirname($pathtofile)).' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                                       print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=ini&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                       print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
-                                       print '</td>';
-                               }
-                               print '</table>';
-                       } else {
-                               // Edit text language file
-
-                               //print $langs->trans("UseAsciiDocFormat").'<br>';
-
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'text'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab == 'objects') {
-                       print '<!-- tab=objects -->'."\n";
-                       $head3 = array();
-                       $h = 0;
-
-                       // Dir for module
-                       $dir = $dirread.'/'.$modulelowercase.'/class';
-
-                       $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj=newobject';
-                       $head3[$h][1] = '<span class="valignmiddle text-plus-circle">'.$langs->trans("NewObjectInModulebuilder").'</span><span class="fa fa-plus-circle valignmiddle paddingleft"></span>';
-                       $head3[$h][2] = 'newobject';
-                       $h++;
-
-                       // Scan for object class files
-                       $listofobject = dol_dir_list($dir, 'files', 0, '\.class\.php$');
-
-                       $firstobjectname = '';
-                       foreach ($listofobject as $fileobj) {
-                               if (preg_match('/^api_/', $fileobj['name'])) {
-                                       continue;
-                               }
-                               if (preg_match('/^actions_/', $fileobj['name'])) {
-                                       continue;
-                               }
-
-                               $tmpcontent = file_get_contents($fileobj['fullname']);
-                               if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
-                                       //$objectname = preg_replace('/\.txt$/', '', $fileobj['name']);
-                                       $objectname = $reg[1];
-                                       if (empty($firstobjectname)) {
-                                               $firstobjectname = $objectname;
-                                       }
-
-                                       $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj='.$objectname;
-                                       $head3[$h][1] = $objectname;
-                                       $head3[$h][2] = $objectname;
-                                       $h++;
-                               }
-                       }
-
-                       if ($h > 1) {
-                               $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj=deleteobject';
-                               $head3[$h][1] =img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("DangerZone");
-                               $head3[$h][2] = 'deleteobject';
-                               $h++;
-                       }
-
-                       // If tabobj was not defined, then we check if there is one obj. If yes, we force on it, if no, we will show tab to create new objects.
-                       if ($tabobj == 'newobjectifnoobj') {
-                               if ($firstobjectname) {
-                                       $tabobj = $firstobjectname;
-                               } else {
-                                       $tabobj = 'newobject';
-                               }
-                       }
-
-                       print dol_get_fiche_head($head3, $tabobj, '', -1, ''); // Level 3
-
-                       if ($tabobj == 'newobject') {
-                               // New object tab
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="initobject">';
-                               print '<input type="hidden" name="tab" value="objects">';
-                               print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
-
-                               print '<span class="opacitymedium">'.$langs->trans("EnterNameOfObjectDesc").'</span><br><br>';
-
-                               print '<div class="tagtable">';
-
-                               print '<div class="tagtr"><div class="tagtd">';
-                               print '<span class="opacitymedium">'.$langs->trans("ObjectKey").'</span> &nbsp; ';
-                               print '</div><div class="tagtd">';
-                               print '<input type="text" name="objectname" maxlength="64" value="'.dol_escape_htmltag(GETPOST('objectname', 'alpha') ? GETPOST('objectname', 'alpha') : $modulename).'" autofocus><br>';
-                               print '</div></div>';
-
-                               print '<div class="tagtr"><div class="tagtd">';
-                               print '<span class="opacitymedium">'.$langs->trans("Picto").'</span> &nbsp; ';
-                               print '</div><div class="tagtd">';
-                               print '<input type="text" name="idpicto" value="fa-generic" placeholder="'.dol_escape_htmltag($langs->trans("Picto")).'">';
-                               print $form->textwithpicto('', $langs->trans("Example").': fa-generic, fa-globe, ... any font awesome code.<br>Advanced syntax is fa-fakey[_faprefix[_facolor[_fasize]]]');
-                               print '</div></div>';
-
-                               print '<div class="tagtr"><div class="tagtd">';
-                               print '<span class="opacitymedium">'.$langs->trans("DefinePropertiesFromExistingTable").'</span> &nbsp; ';
-                               print '</div><div class="tagtd">';
-                               print '<input type="text" name="initfromtablename" value="'.GETPOST('initfromtablename').'" placeholder="'.$langs->trans("TableName").'">';
-                               print $form->textwithpicto('', $langs->trans("DefinePropertiesFromExistingTableDesc").'<br>'.$langs->trans("DefinePropertiesFromExistingTableDesc2"));
-                               print '</div></div>';
-
-                               print '</div>';
-
-                               print '<br>';
-                               print '<input type="checkbox" name="includerefgeneration" id="includerefgeneration" value="includerefgeneration"> <label class="margintoponly" for="includerefgeneration">'.$form->textwithpicto($langs->trans("IncludeRefGeneration"), $langs->trans("IncludeRefGenerationHelp")).'</label><br>';
-                               print '<input type="checkbox" name="includedocgeneration" id="includedocgeneration" value="includedocgeneration"> <label for="includedocgeneration">'.$form->textwithpicto($langs->trans("IncludeDocGeneration"), $langs->trans("IncludeDocGenerationHelp")).'</label><br>';
-                               print '<br>';
-                               print '<input type="submit" class="button small" name="create" value="'.dol_escape_htmltag($langs->trans("GenerateCode")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
-                               print '<br>';
-                               print '<br>';
-                               /*
-                               print '<br>';
-                               print '<span class="opacitymedium">'.$langs->trans("or").'</span>';
-                               print '<br>';
-                               print '<br>';
-                               //print '<input type="checkbox" name="initfromtablecheck"> ';
-                               print $langs->trans("InitStructureFromExistingTable");
-                               print '<input type="text" name="initfromtablename" value="" placeholder="'.$langs->trans("TableName").'">';
-                               print '<input type="submit" class="button smallpaddingimp" name="createtablearray" value="'.dol_escape_htmltag($langs->trans("GenerateCode")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
-                               print '<br>';
-                               */
-
-                               print '</form>';
-                       } elseif ($tabobj == 'deleteobject') {
-                               // Delete object tab
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="confirm_deleteobject">';
-                               print '<input type="hidden" name="tab" value="objects">';
-                               print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
-
-                               print $langs->trans("EnterNameOfObjectToDeleteDesc").'<br><br>';
-
-                               print '<input type="text" name="objectname" value="'.dol_escape_htmltag($modulename).'" placeholder="'.dol_escape_htmltag($langs->trans("ObjectKey")).'">';
-                               print '<input type="submit" class="button smallpaddingimp" name="delete" value="'.dol_escape_htmltag($langs->trans("Delete")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
-                               print '</form>';
-                       } else {
-                               // tabobj = module
-                               if ($action == 'deleteproperty') {
-                                       $formconfirm = $form->formconfirm(
-                                               $_SERVER["PHP_SELF"].'?propertykey='.urlencode(GETPOST('propertykey', 'alpha')).'&objectname='.urlencode($objectname).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj),
-                                               $langs->trans('Delete'),
-                                               $langs->trans('ConfirmDeleteProperty', GETPOST('propertykey', 'alpha')),
-                                               'confirm_deleteproperty',
-                                               '',
-                                               0,
-                                               1
-                                       );
-
-                                       // Print form confirm
-                                       print $formconfirm;
-                               }
-
-                               if ($action != 'editfile' || empty($file)) {
-                                       try {
-                                               //$pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-
-                                               $pathtoclass    = strtolower($module).'/class/'.strtolower($tabobj).'.class.php';
-                                               $pathtoapi      = strtolower($module).'/class/api_'.strtolower($module).'.class.php';
-                                               $pathtoagenda   = strtolower($module).'/'.strtolower($tabobj).'_agenda.php';
-                                               $pathtocard     = strtolower($module).'/'.strtolower($tabobj).'_card.php';
-                                               $pathtodocument = strtolower($module).'/'.strtolower($tabobj).'_document.php';
-                                               $pathtolist     = strtolower($module).'/'.strtolower($tabobj).'_list.php';
-                                               $pathtonote     = strtolower($module).'/'.strtolower($tabobj).'_note.php';
-                                               $pathtocontact  = strtolower($module).'/'.strtolower($tabobj).'_contact.php';
-                                               $pathtophpunit  = strtolower($module).'/test/phpunit/'.strtolower($tabobj).'Test.php';
-
-                                               // Try to load object class file
-                                               clearstatcache(true);
-                                               if (function_exists('opcache_invalidate')) {
-                                                       opcache_invalidate($dirread.'/'.$pathtoclass, true); // remove the include cache hell !
-                                               }
-
-                                               if (empty($forceddirread) && empty($dirread)) {
-                                                       $result = dol_include_once($pathtoclass);
-                                                       $stringofinclude = "dol_include_once(".$pathtoclass.")";
-                                               } else {
-                                                       $result = @include_once $dirread.'/'.$pathtoclass;
-                                                       $stringofinclude = "@include_once ".$dirread.'/'.$pathtoclass;
-                                               }
-                                               if (class_exists($tabobj)) {
-                                                       try {
-                                                               $tmpobject = @new $tabobj($db);
-                                                       } catch (Exception $e) {
-                                                               dol_syslog('Failed to load Constructor of class: '.$e->getMessage(), LOG_WARNING);
-                                                       }
-                                               } else {
-                                                       print '<span class="warning">'.$langs->trans('Failed to find the class '.$tabobj.' despite the '.$stringofinclude).'</span><br><br>';
-                                               }
-
-                                               // Define path for sql file
-                                               $pathtosql = strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($tabobj).'-'.strtolower($module).'.sql';
-                                               $result = dol_buildpath($pathtosql);
-                                               if (! dol_is_file($result)) {
-                                                       $pathtosql = strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($tabobj).'.sql';
-                                                       $result = dol_buildpath($pathtosql);
-                                                       if (! dol_is_file($result)) {
-                                                               $pathtosql = 'install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($tabobj).'-'.strtolower($module).'.sql';
-                                                               $result = dol_buildpath($pathtosql);
-                                                               if (! dol_is_file($result)) {
-                                                                       $pathtosql = 'install/mysql/tables/llx_'.strtolower($module).'-'.strtolower($module).'.sql';
-                                                                       $result = dol_buildpath($pathtosql);
-                                                                       if (! dol_is_file($result)) {
-                                                                               $pathtosql = 'install/mysql/tables/llx_'.strtolower($module).'.sql';
-                                                                               $pathtosqlextra = 'install/mysql/tables/llx_'.strtolower($module).'_extrafields.sql';
-                                                                               $result = dol_buildpath($pathtosql);
-                                                                       } else {
-                                                                               $pathtosqlextra = 'install/mysql/tables/llx_'.strtolower($module).'_extrafields-'.strtolower($module).'.sql';
-                                                                       }
-                                                               } else {
-                                                                       $pathtosqlextra = 'install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($tabobj).'_extrafields-'.strtolower($module).'.sql';
-                                                               }
-                                                       } else {
-                                                               $pathtosqlextra = strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($tabobj).'_extrafields.sql';
-                                                       }
-                                               } else {
-                                                       $pathtosqlextra = strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($tabobj).'_extrafields-'.strtolower($module).'.sql';
-                                               }
-                                               $pathtosqlroot = preg_replace('/\/llx_.*$/', '', $pathtosql);
-
-                                               $pathtosqlkey   = preg_replace('/\.sql$/', '.key.sql', $pathtosql);
-                                               $pathtosqlextrakey   = preg_replace('/\.sql$/', '.key.sql', $pathtosqlextra);
-
-                                               $pathtolib      = strtolower($module).'/lib/'.strtolower($module).'.lib.php';
-                                               $pathtoobjlib   = strtolower($module).'/lib/'.strtolower($module).'_'.strtolower($tabobj).'.lib.php';
-                                               $pathtopicto    = strtolower($module).'/img/object_'.strtolower($tabobj).'.png';
-
-                                               //var_dump($pathtoclass);
-                                               //var_dump($dirread);
-                                               $realpathtoclass    = $dirread.'/'.$pathtoclass;
-                                               $realpathtoapi      = $dirread.'/'.$pathtoapi;
-                                               $realpathtoagenda   = $dirread.'/'.$pathtoagenda;
-                                               $realpathtocard     = $dirread.'/'.$pathtocard;
-                                               $realpathtodocument = $dirread.'/'.$pathtodocument;
-                                               $realpathtolist     = $dirread.'/'.$pathtolist;
-                                               $realpathtonote     = $dirread.'/'.$pathtonote;
-                                               $realpathtocontact  = $dirread.'/'.$pathtocontact;
-                                               $realpathtophpunit  = $dirread.'/'.$pathtophpunit;
-                                               $realpathtosql      = $dirread.'/'.$pathtosql;
-                                               $realpathtosqlextra = $dirread.'/'.$pathtosqlextra;
-                                               $realpathtosqlkey   = $dirread.'/'.$pathtosqlkey;
-                                               $realpathtosqlextrakey = $dirread.'/'.$pathtosqlextrakey;
-                                               $realpathtolib      = $dirread.'/'.$pathtolib;
-                                               $realpathtoobjlib   = $dirread.'/'.$pathtoobjlib;
-                                               $realpathtopicto    = $dirread.'/'.$pathtopicto;
-
-                                               if (empty($realpathtoapi)) {    // For compatibility with some old modules
-                                                       $pathtoapi = strtolower($module).'/class/api_'.strtolower($module).'s.class.php';
-                                                       $realpathtoapi = $dirread.'/'.$pathtoapi;
-                                               }
-
-                                               $urloflist = dol_buildpath('/'.$pathtolist, 1);
-                                               $urlofcard = dol_buildpath('/'.$pathtocard, 1);
-
-
-                                               print '<!-- section for object -->';
-                                               print '<div class="fichehalfleft smallxxx">';
-                                               // Main DAO class file
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("ClassFile").' : <strong>'.(dol_is_file($realpathtoclass) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtoclass).(dol_is_file($realpathtoclass) ? '' : '</strike>').'</strong>';
-                                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtoclass).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                               print '<br>';
-                                               // Image
-                                               if (dol_is_file($realpathtopicto)) {
-                                                       print '<span class="fa fa-file-image-o"></span> '.$langs->trans("Image").' : <strong>'.(dol_is_file($realpathtopicto) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtopicto).(dol_is_file($realpathtopicto) ? '' : '</strike>').'</strong>';
-                                                       //print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtopicto).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                                       print '<br>';
-                                               } elseif (!empty($tmpobject)) {
-                                                       print '<span class="fa fa-file-image-o"></span> '.$langs->trans("Image").' : '.img_picto('', $tmpobject->picto, 'class="pictofixedwidth"');
-                                                       print '<br>';
-                                               }
-
-                                               // API file
-                                               print '<br>';
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("ApiClassFile").' : <strong class="wordbreak">'.(dol_is_file($realpathtoapi) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtoapi).(dol_is_file($realpathtoapi)?'':'</span></strike>').'</strong>';
-                                               if (dol_is_file($realpathtoapi)) {
-                                                       print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtoapi).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                                       print ' ';
-                                                       print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtoapi).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
-                                                       print ' &nbsp; ';
-                                                       if (empty($conf->global->$const_name)) {        // If module is not activated
-                                                               print '<a href="#" class="classfortooltip" target="apiexplorer" title="'.$langs->trans("ModuleMustBeEnabled", $module).'"><strike>'.$langs->trans("ApiExplorer").'</strike></a>';
-                                                       } else {
-                                                               print '<a href="'.DOL_URL_ROOT.'/api/index.php/explorer/" target="apiexplorer">'.$langs->trans("ApiExplorer").'</a>';
-                                                       }
-                                               } else {
-                                                       print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initapi&token='.newToken().'&format=php&file='.urlencode($pathtoapi).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
-                                               }
-                                               // PHPUnit
-                                               print '<br>';
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("TestClassFile").' : <strong class="wordbreak">'.(dol_is_file($realpathtophpunit) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtophpunit).(dol_is_file($realpathtophpunit)?'':'</span></strike>').'</strong>';
-                                               if (dol_is_file($realpathtophpunit)) {
-                                                       print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtophpunit).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                                       print ' ';
-                                                       print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtophpunit).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
-                                               } else {
-                                                       print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initphpunit&token='.newToken().'&format=php&file='.urlencode($pathtophpunit).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
-                                               }
-                                               print '<br>';
-
-                                               print '<br>';
-
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("PageForLib").' : <strong class="wordbreak">'.(dol_is_file($realpathtolib) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtolib).(dol_is_file($realpathtolib) ? '' : '</strike>').'</strong>';
-                                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtolib).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                               print '<br>';
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("PageForObjLib").' : <strong class="wordbreak">'.(dol_is_file($realpathtoobjlib) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtoobjlib).(dol_is_file($realpathtoobjlib) ? '' : '</strike>').'</strong>';
-                                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtoobjlib).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                               print '<br>';
-
-                                               print '<br>';
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("SqlFile").' : <strong class="wordbreak">'.(dol_is_file($realpathtosql) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtosql).(dol_is_file($realpathtosql) ? '' : '</strike>').'</strong>';
-                                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=sql&file='.urlencode($pathtosql).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                               print ' &nbsp; <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=droptable&token='.newToken().'">'.$langs->trans("DropTableIfEmpty").'</a>';
-                                               //print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("RunSql").'</a>';
-                                               print '<br>';
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("SqlFileKey").' : <strong class="wordbreak">'.(dol_is_file($realpathtosqlkey) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlkey).(dol_is_file($realpathtosqlkey) ? '' : '</strike>').'</strong>';
-                                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=sql&file='.urlencode($pathtosqlkey).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                               //print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("RunSql").'</a>';
-                                               print '<br>';
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("SqlFileExtraFields").' : <strong class="wordbreak">'.(dol_is_file($realpathtosqlextra) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlextra).(dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey) ? '' : '</span></strike>').'</strong>';
-                                               if (dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey)) {
-                                                       print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&file='.urlencode($pathtosqlextra).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                                       print ' ';
-                                                       print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtosqlextra).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
-                                                       print ' &nbsp; ';
-                                                       print '<a class="reposition editfielda" href="'.$_SERVER["PHP_SELF"].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=droptableextrafields&token='.newToken().'">'.$langs->trans("DropTableIfEmpty").'</a>';
-                                               } else {
-                                                       print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initsqlextrafields&token='.newToken().'&format=sql&file='.urlencode($pathtosqlextra).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
-                                               }
-                                               //print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("RunSql").'</a>';
-                                               print '<br>';
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("SqlFileKeyExtraFields").' : <strong class="wordbreak">'.(dol_is_file($realpathtosqlextrakey) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlextrakey).(dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey) ? '' : '</span></strike>').'</strong>';
-                                               if (dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey)) {
-                                                       print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=sql&file='.urlencode($pathtosqlextrakey).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                                       print ' ';
-                                                       print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtosqlextrakey).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
-                                               } else {
-                                                       print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initsqlextrafields&token='.newToken().'&format=sql&file='.urlencode($pathtosqlextra).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
-                                               }
-                                               print '<br>';
-                                               print '</div>';
-
-                                               print '<div class="fichehalfleft smallxxxx">';
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("PageForList").' : <strong class="wordbreak"><a href="'.$urloflist.'" target="_test">'.(dol_is_file($realpathtolist) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtolist).(dol_is_file($realpathtolist) ? '' : '</span></strike>').'</a></strong>';
-                                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtolist).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                               print '<br>';
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("PageForCreateEditView").' : <strong class="wordbreak"><a href="'.$urlofcard.'?action=create" target="_test">'.(dol_is_file($realpathtocard) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtocard).(dol_is_file($realpathtocard) ? '' : '</strike>').'?action=create</a></strong>';
-                                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtocard).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                               print '<br>';
-                                               // Page contact
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("PageForContactTab").' : <strong class="wordbreak">'.(dol_is_file($realpathtocontact) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtocontact).(dol_is_file($realpathtocontact) ? '' : '</span></strike>').'</strong>';
-                                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtocontact).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                               if (dol_is_file($realpathtocontact)) {
-                                                       print ' ';
-                                                       print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtocontact).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
-                                               } else {
-                                                       print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initpagecontact&token='.newToken().'&format=php&file='.urlencode($pathtocontact).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
-                                               }
-                                               print '<br>';
-                                               // Page document
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("PageForDocumentTab").' : <strong class="wordbreak">'.(dol_is_file($realpathtodocument) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtodocument).(dol_is_file($realpathtodocument) ? '' : '</span></strike>').'</strong>';
-                                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtodocument).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                               if (dol_is_file($realpathtodocument)) {
-                                                       print ' ';
-                                                       print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtodocument).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
-                                               } else {
-                                                       print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initpagedocument&token='.newToken().'&format=php&file='.urlencode($pathtocontact).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
-                                               }
-                                               print '<br>';
-                                               // Page notes
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("PageForNoteTab").' : <strong class="wordbreak">'.(dol_is_file($realpathtonote) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtonote).(dol_is_file($realpathtonote) ? '' : '</span></strike>').'</strong>';
-                                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtonote).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                               if (dol_is_file($realpathtonote)) {
-                                                       print ' ';
-                                                       print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtonote).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
-                                               } else {
-                                                       print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initpagenote&token='.newToken().'&format=php&file='.urlencode($pathtocontact).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
-                                               }
-                                               print '<br>';
-                                               // Page agenda
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("PageForAgendaTab").' : <strong class="wordbreak">'.(dol_is_file($realpathtoagenda) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtoagenda).(dol_is_file($realpathtoagenda) ? '' : '</span></strike>').'</strong>';
-                                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&format=php&token='.newToken().'&file='.urlencode($pathtoagenda).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                               if (dol_is_file($realpathtoagenda)) {
-                                                       print ' ';
-                                                       print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtoagenda).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
-                                               } else {
-                                                       print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initpageagenda&token='.newToken().'&format=php&file='.urlencode($pathtocontact).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
-                                               }
-                                               print '<br>';
-                                               print '<br>';
-
-                                               print '</div>';
-
-                                               print '<br><br><br>';
-
-                                               if (!empty($tmpobject)) {
-                                                       $reflector = new ReflectionClass($tabobj);
-                                                       $reflectorproperties = $reflector->getProperties(); // Can also use get_object_vars
-                                                       $reflectorpropdefault = $reflector->getDefaultProperties(); // Can also use get_object_vars
-                                                       //$propstat = $reflector->getStaticProperties();
-                                                       //var_dump($reflectorpropdefault);
-
-                                                       print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                                                       print '<input type="hidden" name="token" value="'.newToken().'">';
-                                                       print '<input type="hidden" name="action" value="addproperty">';
-                                                       print '<input type="hidden" name="tab" value="objects">';
-                                                       print '<input type="hidden" name="page_y" value="">';
-                                                       print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module.($forceddirread ? '@'.$dirread : '')).'">';
-                                                       print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
-
-                                                       print '<input class="button smallpaddingimp" type="submit" name="regenerateclasssql" value="'.$langs->trans("RegenerateClassAndSql").'">';
-                                                       print '<br><br>';
-
-                                                       print load_fiche_titre($langs->trans("ObjectProperties"), '', '');
-
-                                                       print '<!-- Table with properties of object -->'."\n";
-                                                       print '<div class="div-table-responsive">';
-                                                       print '<table class="noborder small">';
-                                                       print '<tr class="liste_titre">';
-                                                       print '<th class="none">';
-
-                                                       $htmltext = $langs->trans("PropertyDesc").'<br><br><a class="" href="https://wiki.dolibarr.org/index.php/Language_and_development_rules#Table_and_fields_structures" target="_blank" rel="noopener noreferrer external">'.$langs->trans("SeeExamples").'</a>';
-                                                       print $form->textwithpicto($langs->trans("Code"), $htmltext, 1, 'help', 'extracss', 0, 3, 'propertyhelp');
-
-                                                       print '</th>';
-                                                       print '<th>';
-                                                       print $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey"));
-                                                       print '</th>';
-                                                       print '<th>'.$form->textwithpicto($langs->trans("Type"), $langs->trans("TypeOfFieldsHelpIntro").'<br><br>'.$langs->trans("TypeOfFieldsHelp"), 1, 'help', 'extracss', 0, 3, 'typehelp').'</th>';
-                                                       print '<th>'.$form->textwithpicto($langs->trans("ArrayOfKeyValues"), $langs->trans("ArrayOfKeyValuesDesc")).'</th>';
-                                                       print '<th class="center">'.$form->textwithpicto($langs->trans("NotNull"), $langs->trans("NotNullDesc")).'</th>';
-                                                       print '<th class="center">'.$langs->trans("DefaultValue").'</th>';
-                                                       print '<th class="center">'.$langs->trans("DatabaseIndex").'</th>';
-                                                       print '<th class="center">'.$form->textwithpicto($langs->trans("ForeignKey"), $langs->trans("ForeignKeyDesc"), 1, 'help', 'extracss', 0, 3, 'foreignkeyhelp').'</th>';
-                                                       print '<th class="right">'.$langs->trans("Position").'</th>';
-                                                       print '<th class="center">'.$form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc"), 1, 'help', 'extracss', 0, 3, 'enabledhelp').'</th>';
-                                                       print '<th class="center">'.$form->textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc").'<br><br>'.$langs->trans("ItCanBeAnExpression"), 1, 'help', 'extracss', 0, 3, 'visiblehelp').'</th>';
-                                                       print '<th class="center">'.$langs->trans("NotEditable").'</th>';
-                                                       print '<th class="center">'.$langs->trans("AlwaysEditable").'</th>';
-                                                       print '<th class="center">'.$form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")).'</th>';
-                                                       print '<th class="center">'.$form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")).'</th>';
-                                                       print '<th class="center">'.$langs->trans("CSSClass").'</th>';
-                                                       print '<th class="center">'.$langs->trans("CSSViewClass").'</th>';
-                                                       print '<th class="center">'.$langs->trans("CSSListClass").'</th>';
-                                                       print '<th>'.$langs->trans("KeyForTooltip").'</th>';
-                                                       print '<th class="center">'.$langs->trans("ShowOnCombobox").'</th>';
-                                                       //print '<th class="center">'.$langs->trans("Disabled").'</th>';
-                                                       print '<th>'.$form->textwithpicto($langs->trans("Validate"), $langs->trans("ValidateModBuilderDesc")).'</th>';
-                                                       print '<th>'.$langs->trans("Comment").'</th>';
-                                                       print '<th class="none"></th>';
-                                                       print '</tr>';
-
-                                                       // We must use $reflectorpropdefault['fields'] to get list of fields because $tmpobject->fields may have been
-                                                       // modified during the constructor and we want value into head of class before constructor is called.
-                                                       //$properties = dol_sort_array($tmpobject->fields, 'position');
-                                                       $properties = dol_sort_array($reflectorpropdefault['fields'], 'position');
-
-                                                       if (!empty($properties)) {
-                                                               // Line to add a property
-                                                               print '<tr>';
-                                                               print '<td class="none"><input type="text" class="maxwidth75" name="propname" value="'.dol_escape_htmltag(GETPOST('propname', 'alpha')).'"></td>';
-                                                               print '<td><input type="text" class="maxwidth75" name="proplabel" value="'.dol_escape_htmltag(GETPOST('proplabel', 'alpha')).'"></td>';
-                                                               print '<td><input type="text" class="maxwidth75" name="proptype" value="'.dol_escape_htmltag(GETPOST('proptype', 'alpha')).'"></td>';
-                                                               print '<td><input type="text" class="maxwidth75" name="proparrayofkeyval" value="'.dol_escape_htmltag(GETPOST('proparrayofkeyval', 'restricthtml')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="center maxwidth50" name="propnotnull" value="'.dol_escape_htmltag(GETPOST('propnotnull', 'alpha')).'"></td>';
-                                                               print '<td><input type="text" class="center maxwidth50" name="propdefault" value="'.dol_escape_htmltag(GETPOST('propdefault', 'alpha')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="center maxwidth50" name="propindex" value="'.dol_escape_htmltag(GETPOST('propindex', 'alpha')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="maxwidth100" name="propforeignkey" value="'.dol_escape_htmltag(GETPOST('propforeignkey', 'alpha')).'"></td>';
-                                                               print '<td class="right"><input type="text" class="right" size="2" name="propposition" value="'.dol_escape_htmltag(GETPOST('propposition', 'alpha')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="center maxwidth50" name="propenabled" value="'.dol_escape_htmltag(GETPOST('propenabled', 'alpha')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="center maxwidth50" name="propvisible" value="'.dol_escape_htmltag(GETPOST('propvisible', 'alpha')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="center maxwidth50" name="propnoteditable" value="'.dol_escape_htmltag(GETPOST('propnoteditable', 'alpha')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="center maxwidth50" name="propalwayseditable" value="'.dol_escape_htmltag(GETPOST('propalwayseditable', 'alpha')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="center maxwidth50" name="propsearchall" value="'.dol_escape_htmltag(GETPOST('propsearchall', 'alpha')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="center maxwidth50" name="propisameasure" value="'.dol_escape_htmltag(GETPOST('propisameasure', 'alpha')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="maxwidth50" name="propcss" value="'.dol_escape_htmltag(GETPOST('propcss', 'alpha')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="maxwidth50" name="propcssview" value="'.dol_escape_htmltag(GETPOST('propcssview', 'alpha')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="maxwidth50" name="propcsslist" value="'.dol_escape_htmltag(GETPOST('propcsslist', 'alpha')).'"></td>';
-                                                               print '<td><input type="text" size="2" name="prophelp" value="'.dol_escape_htmltag(GETPOST('prophelp', 'alpha')).'"></td>';
-                                                               print '<td class="center"><input type="text" class="center maxwidth50" name="propshowoncombobox" value="'.dol_escape_htmltag(GETPOST('propshowoncombobox', 'alpha')).'"></td>';
-                                                               //print '<td class="center"><input type="text" size="2" name="propdisabled" value="'.dol_escape_htmltag(GETPOST('propdisabled', 'alpha')).'"></td>';
-                                                               print '<td><input type="number" step="1" min="0" max="1" class="text maxwidth100" name="propvalidate" value="'.dol_escape_htmltag(GETPOST('propvalidate', 'alpha')).'"></td>';
-                                                               print '<td><input class="text maxwidth100" name="propcomment" value="'.dol_escape_htmltag(GETPOST('propcomment', 'alpha')).'"></td>';
-                                                               print '<td class="center tdstickyright tdstickyghostwhite">';
-                                                               print '<input type="submit" class="button" name="add" value="'.$langs->trans("Add").'">';
-                                                               print '</td></tr>';
-
-                                                               // List of existing properties
-                                                               foreach ($properties as $propkey => $propval) {
-                                                                       /* If from Reflection
-                                                                        if ($propval->class == $tabobj)
-                                                                        {
-                                                                        $propname=$propval->getName();
-                                                                        $comment=$propval->getDocComment();
-                                                                        $type=gettype($tmpobject->$propname);
-                                                                        $default=$propdefault[$propname];
-                                                                        // Discard generic properties
-                                                                        if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'ismultientitymanaged'))) continue;
-
-                                                                        // Keep or not lines
-                                                                        if (in_array($propname, array('fk_element', 'lines'))) continue;
-                                                                        }*/
-
-                                                                       $propname = $propkey;
-                                                                       $proplabel = $propval['label'];
-                                                                       $proptype = $propval['type'];
-                                                                       $proparrayofkeyval = !empty($propval['arrayofkeyval'])?$propval['arrayofkeyval']:'';
-                                                                       $propnotnull = !empty($propval['notnull']) ? $propval['notnull'] : '0';
-                                                                       $propdefault = !empty($propval['default'])?$propval['default']:'';
-                                                                       $propindex = !empty($propval['index'])?$propval['index']:'';
-                                                                       $propforeignkey = !empty($propval['foreignkey'])?$propval['foreignkey']:'';
-                                                                       $propposition = $propval['position'];
-                                                                       $propenabled = $propval['enabled'];
-                                                                       $propvisible = $propval['visible'];
-                                                                       $propnoteditable = !empty($propval['noteditable'])?$propval['noteditable']:0;
-                                                                       $propalwayseditable = !empty($propval['alwayseditable'])?$propval['alwayseditable']:0;
-                                                                       $propsearchall = !empty($propval['searchall'])?$propval['searchall']:0;
-                                                                       $propisameasure = !empty($propval['isameasure'])?$propval['isameasure']:0;
-                                                                       $propcss = !empty($propval['css'])?$propval['css']:'';
-                                                                       $propcssview = !empty($propval['cssview'])?$propval['cssview']:'';
-                                                                       $propcsslist = !empty($propval['csslist'])?$propval['csslist']:'';
-                                                                       $prophelp = !empty($propval['help'])?$propval['help']:'';
-                                                                       $propshowoncombobox = !empty($propval['showoncombobox'])?$propval['showoncombobox']:0;
-                                                                       //$propdisabled=$propval['disabled'];
-                                                                       $propvalidate = !empty($propval['validate'])?$propval['validate']:0;
-                                                                       $propcomment = !empty($propval['comment'])?$propval['comment']:'';
-
-                                                                       print '<tr class="oddeven">';
-
-                                                                       print '<td class="tdsticky tdstickygray">';
-                                                                       print dol_escape_htmltag($propname);
-                                                                       print '</td>';
-                                                                       print '<td>';
-                                                                       print dol_escape_htmltag($proplabel);
-                                                                       print '</td>';
-                                                                       if ($action == 'editproperty' && $propname == $propertykey) {
-                                                                               print '<td class="tdoverflowmax200">';
-                                                                               print '<input type="hidden" name="propname" value="'.dol_escape_htmltag($propname).'">';
-                                                                               print '<input type="hidden" name="proplabel" value="'.dol_escape_htmltag($proplabel).'">';
-                                                                               print '<input name="proptype" value="'.dol_escape_htmltag($proptype).'"></input>';
-                                                                               print '</td>';
-                                                                               print '<td class="tdoverflowmax200">';
-                                                                               print '<input name="proparrayofkeyval" value="';
-                                                                               if (isset($proparrayofkeyval)) {
-                                                                                       if (is_array($proparrayofkeyval) || $proparrayofkeyval != '') {
-                                                                                               print dol_escape_htmltag(json_encode($proparrayofkeyval, JSON_UNESCAPED_UNICODE));
-                                                                                       }
-                                                                               }
-                                                                               print '">';
-                                                                               print '</input>';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="center width50" name="propnotnull" value="'.dol_escape_htmltag($propnotnull).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="maxwidth50" name="propdefault" value="'.dol_escape_htmltag($propdefault).'">';
-                                                                               print '</td>';
-                                                                               print '<td class="center">';
-                                                                               print '<input class="center maxwidth50" name="propindex" value="'.dol_escape_htmltag($propindex).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="center maxwidth100" name="propforeignkey" value="'.dol_escape_htmltag($propforeignkey).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="right width50" name="propposition" value="'.dol_escape_htmltag($propposition).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="center" name="propenabled" size="2" value="'.dol_escape_htmltag($propenabled).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="center" name="propvisible" size="2" value="'.dol_escape_htmltag($propvisible).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="center" name="propnoteditable" size="2" value="'.dol_escape_htmltag($propnoteditable).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="center" name="propalwayseditable" size="2" value="'.dol_escape_htmltag($propalwayseditable).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="center" name="propsearchall" size="2" value="'.dol_escape_htmltag($propsearchall).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="center" name="propisameasure" size="2" value="'.dol_escape_htmltag($propisameasure).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="center maxwidth50" name="propcss" value="'.dol_escape_htmltag($propcss).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="center maxwidth50" name="propcssview" value="'.dol_escape_htmltag($propcssview).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="center maxwidth50" name="propcsslist" value="'.dol_escape_htmltag($propcsslist).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="maxwidth100" name="prophelp" value="'.dol_escape_htmltag($prophelp).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="center maxwidth50" name="propshowoncombobox" value="'.dol_escape_htmltag($propshowoncombobox).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input type="number" step="1" min="0" max="1" class="text maxwidth100" name="propvalidate" value="'.dol_escape_htmltag($propvalidate).'">';
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print '<input class="maxwidth100" name="propcomment" value="'.dol_escape_htmltag($propcomment).'">';
-                                                                               print '</td>';
-                                                                               print '<td class="center tdstickyright tdstickyghostwhite">';
-                                                                               print '<input class="reposition button smallpaddingimp" type="submit" name="edit" value="'.$langs->trans("Save").'">';
-                                                                               print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
-                                                                               print '</td>';
-                                                                       } else {
-                                                                               print '<td class="tdoverflowmax200">';
-                                                                               print '<span title="'.dol_escape_htmltag($proptype).'">'.dol_escape_htmltag($proptype).'</span>';
-                                                                               print '</td>';
-                                                                               print '<td class="tdoverflowmax200">';
-                                                                               if ($proparrayofkeyval) {
-                                                                                       print '<span title="'.dol_escape_htmltag(json_encode($proparrayofkeyval, JSON_UNESCAPED_UNICODE)).'">';
-                                                                                       print dol_escape_htmltag(json_encode($proparrayofkeyval, JSON_UNESCAPED_UNICODE));
-                                                                                       print '</span>';
-                                                                               }
-                                                                               print '</td>';
-                                                                               print '<td class="center">';
-                                                                               print dol_escape_htmltag($propnotnull);
-                                                                               print '</td>';
-                                                                               print '<td>';
-                                                                               print dol_escape_htmltag($propdefault);
-                                                                               print '</td>';
-                                                                               print '<td class="center">';
-                                                                               print $propindex ? '1' : '';
-                                                                               print '</td>';
-                                                                               print '<td class="center">';
-                                                                               print $propforeignkey ? dol_escape_htmltag($propforeignkey) : '';
-                                                                               print '</td>';
-                                                                               print '<td class="right">';
-                                                                               print dol_escape_htmltag($propposition);
-                                                                               print '</td>';
-                                                                               print '<td class="center tdoverflowmax100" title="'.($propnoteditable ? dol_escape_htmltag($propnoteditable) : '').'">';
-                                                                               print $propenabled ? dol_escape_htmltag($propenabled) : '';
-                                                                               print '</td>';
-                                                                               // Visibility
-                                                                               print '<td class="center tdoverflowmax100" title="'.($propvisible ? dol_escape_htmltag($propvisible) : '0').'">';
-                                                                               print $propvisible ? dol_escape_htmltag($propvisible) : '0';
-                                                                               print '</td>';
-                                                                               // Readonly
-                                                                               print '<td class="center tdoverflowmax100" title="'.($propnoteditable ? dol_escape_htmltag($propnoteditable) : '').'">';
-                                                                               print $propnoteditable ? dol_escape_htmltag($propnoteditable) : '';
-                                                                               print '</td>';
-                                                                               print '<td class="center">';
-                                                                               print $propalwayseditable ? dol_escape_htmltag($propalwayseditable) : '';
-                                                                               print '</td>';
-                                                                               print '<td class="center">';
-                                                                               print $propsearchall ? '1' : '';
-                                                                               print '</td>';
-                                                                               print '<td class="center">';
-                                                                               print $propisameasure ? dol_escape_htmltag($propisameasure) : '';
-                                                                               print '</td>';
-                                                                               print '<td class="center tdoverflowmax100" title="'.($propcss ? dol_escape_htmltag($propcss) : '').'">';
-                                                                               print $propcss ? dol_escape_htmltag($propcss) : '';
-                                                                               print '</td>';
-                                                                               print '<td class="center tdoverflowmax100" title="'.($propcssview ? dol_escape_htmltag($propcssview) : '').'">';
-                                                                               print $propcssview ? dol_escape_htmltag($propcssview) : '';
-                                                                               print '</td>';
-                                                                               print '<td class="center tdoverflowmax100" title="'.($propcsslist ? dol_escape_htmltag($propcsslist) : '').'">';
-                                                                               print $propcsslist ? dol_escape_htmltag($propcsslist) : '';
-                                                                               print '</td>';
-                                                                               // Key for tooltop
-                                                                               print '<td class="tdoverflowmax150" title="'.($prophelp ? dol_escape_htmltag($prophelp) : '').'">';
-                                                                               print $prophelp ? dol_escape_htmltag($prophelp) : '';
-                                                                               print '</td>';
-                                                                               print '<td class="center">';
-                                                                               print $propshowoncombobox ? dol_escape_htmltag($propshowoncombobox) : '';
-                                                                               print '</td>';
-                                                                               /*print '<td class="center">';
-                                                                               print $propdisabled?$propdisabled:'';
-                                                                               print '</td>';*/
-                                                                               print '<td class="center">';
-                                                                               print $propvalidate ? dol_escape_htmltag($propvalidate) : '';
-                                                                               print '</td>';
-                                                                               print '<td class="tdoverflowmax200">';
-                                                                               print '<span title="'.dol_escape_htmltag($propcomment).'">';
-                                                                               print dol_escape_htmltag($propcomment);
-                                                                               print '</span>';
-                                                                               print '</td>';
-                                                                               print '<td class="center tdstickyright tdstickyghostwhite">';
-                                                                               if ($propname != 'rowid') {
-                                                                                       print '<a class="editfielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=editproperty&token='.newToken().'&propertykey='.urlencode($propname).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj).'">'.img_edit().'</a>';
-                                                                                       print '<a class="marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=deleteproperty&token='.newToken().'&propertykey='.urlencode($propname).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj).'">'.img_delete().'</a>';
-                                                                               }
-                                                                               print '</td>';
-                                                                       }
-                                                                       print '</tr>';
-                                                               }
-                                                       } else {
-                                                               if ($tab == 'specifications') {
-                                                                       if ($action != 'editfile' || empty($file)) {
-                                                                               print '<span class="opacitymedium">'.$langs->trans("SpecDefDesc").'</span><br>';
-                                                                               print '<br>';
-
-                                                                               $specs = dol_dir_list(dol_buildpath($modulelowercase.'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$', array('\/temp\/'));
-
-                                                                               foreach ($specs as $spec) {
-                                                                                       $pathtofile = $modulelowercase.'/doc/'.$spec['relativename'];
-                                                                                       $format = 'asciidoc';
-                                                                                       if (preg_match('/\.md$/i', $spec['name'])) {
-                                                                                               $format = 'markdown';
-                                                                                       }
-                                                                                       print '<span class="fa fa-file-o"></span> '.$langs->trans("SpecificationFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                                                                                       print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format='.$format.'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                                                                       print '<br>';
-                                                                               }
-                                                                       } else {
-                                                                               // Use MD or asciidoc
-
-                                                                               //print $langs->trans("UseAsciiDocFormat").'<br>';
-
-                                                                               $fullpathoffile = dol_buildpath($file, 0);
-
-                                                                               $content = file_get_contents($fullpathoffile);
-
-                                                                               // New module
-                                                                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                                                                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                                                                               print '<input type="hidden" name="action" value="savefile">';
-                                                                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                                                                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                                                                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                                                                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                                                                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                                                                               print '<br>';
-                                                                               print '<center>';
-                                                                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                                                                               print ' &nbsp; ';
-                                                                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                                                                               print '</center>';
-
-                                                                               print '</form>';
-                                                                       }
-                                                               }
-                                                               print '<tr><td><span class="warning">'.$langs->trans('Property $field not found into the class. The class was probably not generated by modulebuilder.').'</warning></td></tr>';
-                                                       }
-                                                       print '</table>';
-                                                       print '</div>';
-
-                                                       print '</form>';
-                                               } else {
-                                                       print '<span class="warning">'.$langs->trans('Failed to init the object with the new '.$tabobj.'($db)').'</warning>';
-                                               }
-                                       } catch (Exception $e) {
-                                               print $e->getMessage();
-                                       }
-                               } else {
-                                       if (empty($forceddirread)) {
-                                               $fullpathoffile = dol_buildpath($file, 0);
-                                       } else {
-                                               $fullpathoffile = $dirread.'/'.$file;
-                                       }
-
-                                       $content = file_get_contents($fullpathoffile);
-
-                                       // New module
-                                       print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                                       print '<input type="hidden" name="token" value="'.newToken().'">';
-                                       print '<input type="hidden" name="action" value="savefile">';
-                                       print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                                       print '<input type="hidden" name="tab" value="'.$tab.'">';
-                                       print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
-                                       print '<input type="hidden" name="module" value="'.$module.($forceddirread ? '@'.$dirread : '').'">';
-
-                                       $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                                       print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                                       print '<br>';
-                                       print '<center>';
-                                       print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                                       print ' &nbsp; ';
-                                       print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                                       print '</center>';
-
-                                       print '</form>';
-                               }
-                       }
-
-                       print dol_get_fiche_end(); // Level 3
-               }
-
-               if ($tab == 'dictionaries') {
-                       print '<!-- tab=dictionaries -->'."\n";
-                       $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-
-                       $dicts = $moduleobj->dictionaries;
-
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">';
-                               $htmlhelp = $langs->trans("DictionariesDefDescTooltip", '{s1}');
-                               $htmlhelp = str_replace('{s1}', '<a target="adminbis" class="nofocusvisible" href="'.DOL_URL_ROOT.'/admin/dict.php">'.$langs->trans('Setup').' - '.$langs->trans('Dictionaries').'</a>', $htmlhelp);
-                               print $form->textwithpicto($langs->trans("DictionariesDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'<br>';
-                               print '</span>';
-                               print '<br>';
-
-                               print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                               print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                               print '<br>';
-                               if (is_array($dicts) && !empty($dicts)) {
-                                       print '<span class="fa fa-file-o"></span> '.$langs->trans("LanguageFile").' :</span> ';
-                                       print '<strong class="wordbreak">'.$dicts['langs'].'</strong>';
-                                       print '<br>';
-                               }
-
-                               print '<!-- tab=objects -->'."\n";
-                               $head3 = array();
-                               $h = 0;
-
-                               // Dir for module
-                               //$dir = $dirread.'/'.$modulelowercase.'/class';
-
-                               $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabdic=newdictionary';
-                               $head3[$h][1] = '<span class="valignmiddle text-plus-circle">'.$langs->trans("NewDictionary").'</span><span class="fa fa-plus-circle valignmiddle paddingleft"></span>';
-                               $head3[$h][2] = 'newdictionary';
-                               $h++;
-
-                               // Scan for object class files
-                               //$listofobject = dol_dir_list($dir, 'files', 0, '\.class\.php$');
-
-                               $firstdicname = '';
-                               if (!empty($dicts['tabname'])) {
-                                       foreach ($dicts['tabname'] as $key => $dic) {
-                                               $dicname = $dic;
-                                               $diclabel = $dicts['tablib'][$key];
-
-                                               if (empty($firstdicname)) {
-                                                       $firstdicname = $dicname;
-                                               }
-
-                                               $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabdic='.$dicname;
-                                               $head3[$h][1] = $diclabel;
-                                               $head3[$h][2] = $dicname;
-                                               $h++;
-                                       }
-                               }
-
-                               if ($h > 1) {
-                                       $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabdic=deletedictionary';
-                                       $head3[$h][1] = $langs->trans("DangerZone");
-                                       $head3[$h][2] = 'deletedictionary';
-                                       $h++;
-                               }
-
-                               // If tabobj was not defined, then we check if there is one obj. If yes, we force on it, if no, we will show tab to create new objects.
-                               if ($tabdic == 'newdicifnodic') {
-                                       if ($firstdicname) {
-                                               $tabdic = $firstdicname;
-                                       } else {
-                                               $tabdic = 'newdictionary';
-                                       }
-                               }
-
-                               print load_fiche_titre($langs->trans("ListOfDictionariesEntries"), '', '');
-
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="addproperty">';
-                               print '<input type="hidden" name="tab" value="dictionaries">';
-                               print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
-                               print '<input type="hidden" name="tabdic" value="'.dol_escape_htmltag($tabdic).'">';
-
-                               print '<div class="div-table-responsive">';
-                               print '<table class="noborder">';
-
-                               print '<tr class="liste_titre">';
-                               print_liste_field_titre("#", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'thsticky thstickygrey ');
-                               print_liste_field_titre("Table", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("Label", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("SQL", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("SQLSort", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("FieldsView", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("FieldsEdit", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("FieldsInsert", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("Rowid", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("Condition", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print "</tr>\n";
-
-                               if (!empty($dicts) && is_array($dicts) && !empty($dicts['tabname']) && is_array($dicts['tabname'])) {
-                                       $i = 0;
-                                       $maxi = count($dicts['tabname']);
-                                       while ($i < $maxi) {
-                                               print '<tr class="oddeven">';
-
-                                               print '<td class="tdsticky tdstickygray">';
-                                               print ($i + 1);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print $dicts['tabname'][$i];
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print $dicts['tablib'][$i];
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print $dicts['tabsql'][$i];
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print $dicts['tabsqlsort'][$i];
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print $dicts['tabfield'][$i];
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print $dicts['tabfieldvalue'][$i];
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print $dicts['tabfieldinsert'][$i];
-                                               print '</td>';
-
-                                               print '<td class="right">';
-                                               print $dicts['tabrowid'][$i];
-                                               print '</td>';
-
-                                               print '<td class="right">';
-                                               print $dicts['tabcond'][$i];
-                                               print '</td>';
-
-                                               print '</tr>';
-                                               $i++;
-                                       }
-                               } else {
-                                       print '<tr><td colspan="10"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
-                               }
-
-                               print '</table>';
-                               print '</div>';
-
-                               print '</form>';
-
-                               print dol_get_fiche_head($head3, $tabdic, '', -1, ''); // Level 3
-
-                               if ($tabdic == 'newdictionary') {
-                                       // New dic tab
-                                       print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                                       print '<input type="hidden" name="token" value="'.newToken().'">';
-                                       print '<input type="hidden" name="action" value="initdic">';
-                                       print '<input type="hidden" name="tab" value="dictionaries">';
-                                       print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
-
-                                       print '<span class="opacitymedium">'.$langs->trans("EnterNameOfDictionaryDesc").'</span><br><br>';
-
-                                       print '<input type="text" name="dicname" maxlength="64" value="'.dol_escape_htmltag(GETPOST('dicname', 'alpha') ? GETPOST('dicname', 'alpha') : $modulename).'" placeholder="'.dol_escape_htmltag($langs->trans("DicKey")).'" autofocus><br>';
-                                       //print '<input type="checkbox" name="includerefgeneration" id="includerefgeneration" value="includerefgeneration"> <label for="includerefgeneration">'.$form->textwithpicto($langs->trans("IncludeRefGeneration"), $langs->trans("IncludeRefGenerationHelp")).'</label><br>';
-                                       //print '<input type="checkbox" name="includedocgeneration" id="includedocgeneration" value="includedocgeneration"> <label for="includedocgeneration">'.$form->textwithpicto($langs->trans("IncludeDocGeneration"), $langs->trans("IncludeDocGenerationHelp")).'</label><br>';
-                                       print '<input type="submit" class="button smallpaddingimp" name="create" value="'.dol_escape_htmltag($langs->trans("GenerateCode")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
-                                       /*print '<br>';
-                                       print '<br>';
-                                       print '<br>';
-                                       print '<span class="opacitymedium">'.$langs->trans("or").'</span>';
-                                       print '<br>';
-                                       print '<br>';
-                                       //print '<input type="checkbox" name="initfromtablecheck"> ';
-                                       print $langs->trans("InitStructureFromExistingTable");
-                                       print '<input type="text" name="initfromtablename" value="" placeholder="'.$langs->trans("TableName").'">';
-                                       print '<input type="submit" class="button smallpaddingimp" name="createtablearray" value="'.dol_escape_htmltag($langs->trans("GenerateCode")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
-                                       print '<br>';
-                                       */
-                                       print '</form>';
-                               } elseif ($tabdic == 'deletedictionary') {
-                                       // Delete dic tab
-                                       print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                                       print '<input type="hidden" name="token" value="'.newToken().'">';
-                                       print '<input type="hidden" name="action" value="confirm_deleteobject">';
-                                       print '<input type="hidden" name="tab" value="dictionaries">';
-                                       print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
-
-                                       print $langs->trans("EnterNameOfObjectToDeleteDesc").'<br><br>';
-
-                                       print '<input type="text" name="objectname" value="'.dol_escape_htmltag($modulename).'" placeholder="'.dol_escape_htmltag($langs->trans("ObjectKey")).'">';
-                                       print '<input type="submit" class="button smallpaddingimp" name="delete" value="'.dol_escape_htmltag($langs->trans("Delete")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
-                                       print '</form>';
-                               } else {
-                                       print $langs->trans("FeatureNotYetAvailable");
-                               }
-
-                               print dol_get_fiche_end();
-                       } else {
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab == 'menus') {
-                       print '<!-- tab=menus -->'."\n";
-                       $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-
-                       $menus = $moduleobj->menu;
-
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">';
-                               $htmlhelp = $langs->trans("MenusDefDescTooltip", '{s1}');
-                               $htmlhelp = str_replace('{s1}', '<a target="adminbis" class="nofocusvisible" href="'.DOL_URL_ROOT.'/admin/menus/index.php">'.$langs->trans('Setup').' - '.$langs->trans('Menus').'</a>', $htmlhelp);
-                               print $form->textwithpicto($langs->trans("MenusDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'<br>';
-                               print '</span>';
-                               print '<br>';
-
-                               print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                               print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                               print '<br>';
-
-                               print '<br>';
-                               print load_fiche_titre($langs->trans("ListOfMenusEntries"), '', '');
-
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="addproperty">';
-                               print '<input type="hidden" name="tab" value="objects">';
-                               print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
-                               print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
-
-                               print '<div class="div-table-responsive">';
-                               print '<table class="noborder small">';
-
-                               print '<tr class="liste_titre">';
-                               print_liste_field_titre("#", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'thsticky ');
-                               print_liste_field_titre("Position", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("LinkToParentMenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("Title", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("mainmenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("leftmenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("URL", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->transnoentitiesnoconv('DetailUrl'));
-                               print_liste_field_titre("LanguageFile", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("Position", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'right ');
-                               print_liste_field_titre("Enabled", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center ', $langs->trans('DetailEnabled'));
-                               print_liste_field_titre("Rights", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->trans('DetailRight'));
-                               print_liste_field_titre("Target", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->trans('DetailTarget'));
-                               print_liste_field_titre("MenuForUsers", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'right ', $langs->trans('DetailUser'));
-                               print "</tr>\n";
-
-                               if (count($menus)) {
-                                       $i = 0;
-                                       foreach ($menus as $menu) {
-                                               $i++;
-
-                                               print '<tr class="oddeven">';
-
-                                               print '<td class="tdsticky tdstickygray">';
-                                               print $i;
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print dol_escape_htmltag($menu['type']);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print dol_escape_htmltag($menu['fk_menu']);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print dol_escape_htmltag($menu['titre']);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print dol_escape_htmltag($menu['mainmenu']);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print dol_escape_htmltag($menu['leftmenu']);
-                                               print '</td>';
-
-                                               print '<td class="tdoverflowmax300" title="'.dol_escape_htmltag($menu['url']).'">';
-                                               print dol_escape_htmltag($menu['url']);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print dol_escape_htmltag($menu['langs']);
-                                               print '</td>';
-
-                                               print '<td class="right">';
-                                               print dol_escape_htmltag($menu['position']);
-                                               print '</td>';
-
-                                               print '<td class="center tdoverflowmax200" title="'.dol_escape_htmltag($menu['enabled']).'">';
-                                               print dol_escape_htmltag($menu['enabled']);
-                                               print '</td>';
-
-                                               print '<td class="center tdoverflowmax200" title="'.dol_escape_htmltag($menu['perms']).'">';
-                                               print dol_escape_htmltag($menu['perms']);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print dol_escape_htmltag($menu['target']);
-                                               print '</td>';
-
-                                               print '<td class="right">';
-                                               if ($menu['user'] == 2) {
-                                                       print $langs->trans("AllMenus");
-                                               } elseif ($menu['user'] == 0) {
-                                                       print $langs->trans('Internal');
-                                               } elseif ($menu['user'] == 1) {
-                                                       print $langs->trans('External');
-                                               } else {
-                                                       print $menu['user']; // should not happen
-                                               }
-                                               print '</td>';
-
-                                               print '</tr>';
-                                       }
-                               } else {
-                                       print '<tr><td colspan="5"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
-                               }
-
-                               print '</table>';
-                               print '</div>';
-
-                               print '</form>';
-                       } else {
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab == 'permissions') {
-                       print '<!-- tab=permissions -->'."\n";
-                       $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-
-                       $perms = $moduleobj->rights;
-
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">';
-                               $htmlhelp = $langs->trans("PermissionsDefDescTooltip", '{s1}');
-                               $htmlhelp = str_replace('{s1}', '<a target="adminbis" class="nofocusvisible" href="'.DOL_URL_ROOT.'/admin/perms.php">'.$langs->trans('DefaultRights').'</a>', $htmlhelp);
-                               print $form->textwithpicto($langs->trans("PermissionsDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'<br>';
-                               print '</span>';
-                               print '<br>';
-
-                               print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                               print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                               print '<br>';
-
-                               print '<br>';
-                               print load_fiche_titre($langs->trans("ListOfPermissionsDefined"), '', '');
-
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="addproperty">';
-                               print '<input type="hidden" name="tab" value="objects">';
-                               print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
-                               print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
-
-                               print '<div class="div-table-responsive">';
-                               print '<table class="noborder">';
-
-                               print '<tr class="liste_titre">';
-                               print_liste_field_titre("ID", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("Label", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("Permission", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print "</tr>\n";
-
-                               if (count($perms)) {
-                                       foreach ($perms as $perm) {
-                                               print '<tr class="oddeven">';
-
-                                               print '<td>';
-                                               print $perm[0];
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print $langs->trans($perm[1]);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print $perm[4];
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print $perm[5];
-                                               print '</td>';
-
-                                               print '</tr>';
-                                       }
-                               } else {
-                                       print '<tr><td colspan="4"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
-                               }
-
-                               print '</table>';
-                               print '</div>';
-
-                               print '</form>';
-                       } else {
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab == 'hooks') {
-                       print '<!-- tab=hooks -->'."\n";
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">'.$langs->trans("HooksDefDesc").'</span><br>';
-                               print '<br>';
-
-                               print '<table>';
-
-                               $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-                               print '<tr><td>';
-                               print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                               print '</td><td>';
-                               print '<a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                               print '</td></tr>';
-
-                               print '<tr><td>';
-                               $pathtohook = strtolower($module).'/class/actions_'.strtolower($module).'.class.php';
-                               print '<span class="fa fa-file-o"></span> '.$langs->trans("HooksFile").' : ';
-                               if (dol_is_file($dirins.'/'.$pathtohook)) {
-                                       print '<strong class="wordbreak">'.$pathtohook.'</strong>';
-                                       print '</td>';
-                                       print '<td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Edit"), 'edit').'</a> ';
-                                       print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
-                               } else {
-                                       print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
-                                       print '<a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=inithook&format=php&file='.urlencode($pathtohook).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</td>';
-                                       print '<td></td>';
-                               }
-                               print '</tr>';
-                       } else {
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab == 'triggers') {
-                       print '<!-- tab=triggers -->'."\n";
-                       require_once DOL_DOCUMENT_ROOT.'/core/class/interfaces.class.php';
-
-                       $interfaces = new Interfaces($db);
-                       $triggers = $interfaces->getTriggersList(array('/'.strtolower($module).'/core/triggers'));
-
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">'.$langs->trans("TriggerDefDesc").'</span><br>';
-                               print '<br>';
-
-                               print '<table>';
-
-                               $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-                               print '<tr><td>';
-                               print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                               print '</td><td>';
-                               print '<a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                               print '</td></tr>';
-
-                               if (!empty($triggers)) {
-                                       foreach ($triggers as $trigger) {
-                                               $pathtofile = $trigger['relpath'];
-
-                                               print '<tr><td>';
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("TriggersFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                                               print '</td><td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a></td>';
-                                               print '<td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
-                                               print '</tr>';
-                                       }
-                               } else {
-                                       print '<tr><td>';
-                                       print '<span class="fa fa-file-o"></span> '.$langs->trans("TriggersFile");
-                                       print ' : <span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
-                                       print '<a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=inittrigger&format=php">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a></td>';
-                                       print '<td></td>';
-                                       print '</tr>';
-                               }
-
-                               print '</table>';
-                       } else {
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab == 'css') {
-                       print '<!-- tab=css -->'."\n";
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">'.$langs->trans("CSSDesc").'</span><br>';
-                               print '<br>';
-
-                               print '<table>';
-
-                               print '<tr><td>';
-                               $pathtohook = strtolower($module).'/css/'.strtolower($module).'.css.php';
-                               print '<span class="fa fa-file-o"></span> '.$langs->trans("CSSFile").' : ';
-                               if (dol_is_file($dirins.'/'.$pathtohook)) {
-                                       print '<strong class="wordbreak">'.$pathtohook.'</strong>';
-                                       print '</td><td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Edit"), 'edit').'</a></td>';
-                                       print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&format='.$format.'&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
-                               } else {
-                                       print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
-                                       print '</td><td><a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initcss&format=php&file='.urlencode($pathtohook).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a></td>';
-                               }
-                               print '</tr>';
-                       } else {
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab == 'js') {
-                       print '<!-- tab=js -->'."\n";
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">'.$langs->trans("JSDesc").'</span><br>';
-                               print '<br>';
-
-                               print '<table>';
-
-                               print '<tr><td>';
-                               $pathtohook = strtolower($module).'/js/'.strtolower($module).'.js.php';
-                               print '<span class="fa fa-file-o"></span> '.$langs->trans("JSFile").' : ';
-                               if (dol_is_file($dirins.'/'.$pathtohook)) {
-                                       print '<strong class="wordbreak">'.$pathtohook.'</strong>';
-                                       print '</td><td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Edit"), 'edit').'</a></td>';
-                                       print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
-                               } else {
-                                       print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
-                                       print '</td><td><a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initjs&token='.newToken().'&format=php&file='.urlencode($pathtohook).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a></td>';
-                               }
-                               print '</tr>';
-                       } else {
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab == 'widgets') {
-                       print '<!-- tab=widgets -->'."\n";
-                       require_once DOL_DOCUMENT_ROOT.'/core/boxes/modules_boxes.php';
-
-                       $widgets = ModeleBoxes::getWidgetsList(array('/'.strtolower($module).'/core/boxes'));
-
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">'.$langs->trans("WidgetDesc").'</span><br>';
-                               print '<br>';
-
-                               print '<table>';
-                               if (!empty($widgets)) {
-                                       foreach ($widgets as $widget) {
-                                               $pathtofile = $widget['relpath'];
-
-                                               print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("WidgetFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                                               print '</td><td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                                               print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
-                                               print '</tr>';
-                                       }
-                               } else {
-                                       print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("WidgetFile").' : <span class="opacitymedium">'.$langs->trans("NoWidget").'</span>';
-                                       print '</td><td><a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initwidget&token='.newToken().'&format=php">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
-                                       print '</td></tr>';
-                               }
-                               print '</table>';
-                       } else {
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab == 'exportimport') {
-                       print '<!-- tab=exportimport -->'."\n";
-                       $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-
-                       $exportlist = $moduleobj->export_label;
-                       $importlist = $moduleobj->import_label;
-
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">'.$langs->transnoentities('ImportExportProfiles').'</span><br>';
-                               print '<br>';
-
-                               print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                               print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                               print '<br>';
-                       } else {
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab == 'cli') {
-                       print '<!-- tab=cli -->'."\n";
-                       $clifiles = array();
-                       $i = 0;
-
-                       $dircli = array('/'.strtolower($module).'/scripts');
-
-                       foreach ($dircli as $reldir) {
-                               $dir = dol_buildpath($reldir, 0);
-                               $newdir = dol_osencode($dir);
-
-                               // Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php at each call)
-                               if (!is_dir($newdir)) {
-                                       continue;
-                               }
-
-                               $handle = opendir($newdir);
-                               if (is_resource($handle)) {
-                                       while (($tmpfile = readdir($handle)) !== false) {
-                                               if (is_readable($newdir.'/'.$file) && preg_match('/^(.+)\.php/', $tmpfile, $reg)) {
-                                                       if (preg_match('/\.back$/', $tmpfile)) {
-                                                               continue;
-                                                       }
-
-                                                       $clifiles[$i]['relpath'] = preg_replace('/^\//', '', $reldir).'/'.$tmpfile;
-
-                                                       $i++;
-                                               }
-                                       }
-                                       closedir($handle);
-                               }
-                       }
-
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">'.$langs->trans("CLIDesc").'</span><br>';
-                               print '<br>';
-
-                               print '<table>';
-                               if (!empty($clifiles)) {
-                                       foreach ($clifiles as $clifile) {
-                                               $pathtofile = $clifile['relpath'];
-
-                                               print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("CLIFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                                               print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a></td>';
-                                               print '<td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
-                                               print '</tr>';
-                                       }
-                               } else {
-                                       print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("CLIFile").' : <span class="opacitymedium">'.$langs->trans("FileNotYetGenerated"); '</span>';
-                                       print '</td><td><a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initcli&token='.newToken().'&format=php">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
-                                       print '</td></tr>';
-                               }
-                               print '</table>';
-                       } else {
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab == 'cron') {
-                       print '<!-- tab=cron -->'."\n";
-                       $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-
-                       $cronjobs = $moduleobj->cronjobs;
-
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">'.str_replace('{s1}', '<a target="adminbis" class="nofocusvisible" href="'.DOL_URL_ROOT.'/cron/list.php">'.$langs->transnoentities('CronList').'</a>', $langs->trans("CronJobDefDesc", '{s1}')).'</span><br>';
-                               print '<br>';
-
-                               print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                               print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                               print '<br>';
-
-                               print '<br>';
-                               print load_fiche_titre($langs->trans("CronJobProfiles"), '', '');
-
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="addproperty">';
-                               print '<input type="hidden" name="tab" value="objects">';
-                               print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
-                               print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
-
-                               print '<div class="div-table-responsive">';
-                               print '<table class="noborder">';
-
-                               print '<tr class="liste_titre">';
-                               print_liste_field_titre("CronLabel", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("CronTask", '', '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("CronFrequency", '', "", "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("StatusAtInstall", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("Comment", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder);
-                               print "</tr>\n";
-
-                               if (count($cronjobs)) {
-                                       foreach ($cronjobs as $cron) {
-                                               print '<tr class="oddeven">';
-
-                                               print '<td>';
-                                               print $cron['label'];
-                                               print '</td>';
-
-                                               print '<td>';
-                                               if ($cron['jobtype'] == 'method') {
-                                                       $text = $langs->trans("CronClass");
-                                                       $texttoshow = $langs->trans('CronModule').': '.$module.'<br>';
-                                                       $texttoshow .= $langs->trans('CronClass').': '.$cron['class'].'<br>';
-                                                       $texttoshow .= $langs->trans('CronObject').': '.$cron['objectname'].'<br>';
-                                                       $texttoshow .= $langs->trans('CronMethod').': '.$cron['method'];
-                                                       $texttoshow .= '<br>'.$langs->trans('CronArgs').': '.$cron['parameters'];
-                                                       $texttoshow .= '<br>'.$langs->trans('Comment').': '.$langs->trans($cron['comment']);
-                                               } elseif ($cron['jobtype'] == 'command') {
-                                                       $text = $langs->trans('CronCommand');
-                                                       $texttoshow = $langs->trans('CronCommand').': '.dol_trunc($cron['command']);
-                                                       $texttoshow .= '<br>'.$langs->trans('CronArgs').': '.$cron['parameters'];
-                                                       $texttoshow .= '<br>'.$langs->trans('Comment').': '.$langs->trans($cron['comment']);
-                                               }
-                                               print $form->textwithpicto($text, $texttoshow, 1);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               if ($cron['unitfrequency'] == "60") {
-                                                       print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Minutes');
-                                               }
-                                               if ($cron['unitfrequency'] == "3600") {
-                                                       print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Hours');
-                                               }
-                                               if ($cron['unitfrequency'] == "86400") {
-                                                       print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Days');
-                                               }
-                                               if ($cron['unitfrequency'] == "604800") {
-                                                       print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Weeks');
-                                               }
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print $cron['status'];
-                                               print '</td>';
-
-                                               print '<td>';
-                                               if (!empty($cron['comment'])) {
-                                                       print $cron['comment'];
-                                               }
-                                               print '</td>';
-
-                                               print '</tr>';
-                                       }
-                               } else {
-                                       print '<tr><td colspan="5"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
-                               }
-
-                               print '</table>';
-                               print '</div>';
-
-                               print '</form>';
-                       } else {
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab == 'specifications') {
-                       print '<!-- tab=specifications -->'."\n";
-                       $specs = dol_dir_list(dol_buildpath($modulelowercase.'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$', array('\/temp\/'));
-
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">'.$langs->trans("SpecDefDesc").'</span><br>';
-                               print '<br>';
-
-                               print '<table>';
-                               if (is_array($specs) && !empty($specs)) {
-                                       foreach ($specs as $spec) {
-                                               $pathtofile = $modulelowercase.'/doc/'.$spec['relativename'];
-                                               $format = 'asciidoc';
-                                               if (preg_match('/\.md$/i', $spec['name'])) {
-                                                       $format = 'markdown';
-                                               }
-                                               print '<tr><td>';
-                                               print '<span class="fa fa-file-o"></span> '.$langs->trans("SpecificationFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
-                                               print '</td><td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format='.$format.'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a></td>';
-                                               print '<td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&format='.$format.'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
-                                               print '</tr>';
-                                       }
-                               } else {
-                                       print '<tr><td>';
-                                       print '<span class="fa fa-file-o"></span> '.$langs->trans("SpecificationFile").' : <span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
-                                       print '</td><td><a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initdoc&token='.newToken().'&format=php">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a></td>';
-                                       print '</tr>';
-                               }
-                               print '</table>';
-                       } else {
-                               // Use MD or asciidoc
-
-                               //print $langs->trans("UseAsciiDocFormat").'<br>';
-
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-
-                       print '<br><br><br>';
-
-                       $FILENAMEDOC = $modulelowercase.'.html';
-                       $FILENAMEDOCPDF = $modulelowercase.'.pdf';
-                       $outputfiledoc = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOC;
-                       $outputfiledocurl = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOC;
-                       $outputfiledocrel = $modulelowercase.'/doc/'.$FILENAMEDOC;
-                       $outputfiledocpdf = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOCPDF;
-                       $outputfiledocurlpdf = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOCPDF;
-                       $outputfiledocrelpdf = $modulelowercase.'/doc/'.$FILENAMEDOCPDF;
-
-                       // HTML
-                       print '<span class="fa fa-file-o"></span> '.$langs->trans("PathToModuleDocumentation", "HTML").' : ';
-                       if (!dol_is_file($outputfiledoc)) {
-                               print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
-                       } else {
-                               print '<strong>';
-                               print '<a href="'.$outputfiledocurl.'" target="_blank" rel="noopener noreferrer">';
-                               print $outputfiledoc;
-                               print '</a>';
-                               print '</strong>';
-                               print ' <span class="opacitymedium">('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledoc), 'dayhour').')</span>';
-                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&format='.$format.'&file='.urlencode($outputfiledocrel).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
-                       }
-                       print '</strong><br>';
-
-                       // PDF
-                       print '<span class="fa fa-file-o"></span> '.$langs->trans("PathToModuleDocumentation", "PDF").' : ';
-                       if (!dol_is_file($outputfiledocpdf)) {
-                               print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
-                       } else {
-                               print '<strong>';
-                               print '<a href="'.$outputfiledocurlpdf.'" target="_blank" rel="noopener noreferrer">';
-                               print $outputfiledocpdf;
-                               print '</a>';
-                               print '</strong>';
-                               print ' <span class="opacitymedium">('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledocpdf), 'dayhour').')</span>';
-                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&format='.$format.'&file='.urlencode($outputfiledocrelpdf).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
-                       }
-                       print '</strong><br>';
-
-                       print '<br>';
-
-                       print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="generatedoc">';
-                       print '<input type="hidden" name="token" value="'.newToken().'">';
-                       print '<input type="hidden" name="action" value="generatedoc">';
-                       print '<input type="hidden" name="tab" value="'.dol_escape_htmltag($tab).'">';
-                       print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
-                       print '<input type="submit" class="button" name="generatedoc" value="'.$langs->trans("BuildDocumentation").'"';
-                       if (!is_array($specs) || empty($specs)) {
-                               print ' disabled="disabled"';
-                       }
-                       print '>';
-                       print '</form>';
-               }
-
-               if ($tab == 'buildpackage') {
-                       print '<!-- tab=buildpackage -->'."\n";
-                       print '<span class="opacitymedium">'.$langs->trans("BuildPackageDesc").'</span>';
-                       print '<br>';
-
-                       if (!class_exists('ZipArchive') && !defined('ODTPHP_PATHTOPCLZIP')) {
-                               print img_warning().' '.$langs->trans("ErrNoZipEngine");
-                               print '<br>';
-                       }
-
-                       $modulelowercase = strtolower($module);
-
-                       // Zip file to build
-                       $FILENAMEZIP = '';
-
-                       // Load module
-                       $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-                       dol_include_once($pathtofile);
-                       $class = 'mod'.$module;
-
-                       if (class_exists($class)) {
-                               try {
-                                       $moduleobj = new $class($db);
-                               } catch (Exception $e) {
-                                       $error++;
-                                       dol_print_error($db, $e->getMessage());
-                               }
-                       } else {
-                               $error++;
-                               $langs->load("errors");
-                               dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
-                               exit;
-                       }
-
-                       $arrayversion = explode('.', $moduleobj->version, 3);
-                       if (count($arrayversion)) {
-                               $FILENAMEZIP = "module_".$modulelowercase.'-'.$arrayversion[0].(empty($arrayversion[1]) ? '.0' : '.'.$arrayversion[1]).(empty($arrayversion[2]) ? '' : ".".$arrayversion[2]).".zip";
-                               $outputfilezip = dol_buildpath($modulelowercase, 0).'/bin/'.$FILENAMEZIP;
-                       }
-
-                       print '<br>';
-
-                       print '<span class="fa fa-file-o"></span> '.$langs->trans("PathToModulePackage").' : ';
-                       if (!dol_is_file($outputfilezip)) {
-                               print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
-                       } else {
-                               $relativepath = $modulelowercase.'/bin/'.$FILENAMEZIP;
-                               print '<strong><a href="'.DOL_URL_ROOT.'/document.php?modulepart=packages&file='.urlencode($relativepath).'">'.$outputfilezip.'</a></strong>';
-                               print ' <span class="opacitymedium">('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfilezip), 'dayhour').')</span>';
-                               print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($relativepath).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
-                       }
-                       print '</strong>';
-
-                       print '<br>';
-
-                       print '<br>';
-
-                       print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="generatepackage">';
-                       print '<input type="hidden" name="token" value="'.newToken().'">';
-                       print '<input type="hidden" name="action" value="generatepackage">';
-                       print '<input type="hidden" name="tab" value="'.dol_escape_htmltag($tab).'">';
-                       print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
-                       print '<input type="submit" class="button" name="generatepackage" value="'.$langs->trans("BuildPackage").'">';
-                       print '</form>';
-               }
-
-               if ($tab == 'tabs') {
-                       $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
-
-                       $tabs = $moduleobj->tabs;
-
-                       if ($action != 'editfile' || empty($file)) {
-                               print '<span class="opacitymedium">';
-                               $htmlhelp = $langs->trans("TabsDefDescTooltip", '{s1}');
-                               $htmlhelp = str_replace('{s1}', '<a target="adminbis" class="nofocusvisible" href="'.DOL_URL_ROOT.'/admin/menus/index.php">'.$langs->trans('Setup').' - '.$langs->trans('Tabs').'</a>', $htmlhelp);
-                               print $form->textwithpicto($langs->trans("TabsDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'<br>';
-                               print '</span>';
-                               print '<br>';
-
-                               print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong>'.$pathtofile.'</strong>';
-                               print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
-                               print '<br>';
-
-                               print '<br>';
-                               print load_fiche_titre($langs->trans("ListOfTabsEntries"), '', '');
-
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="addproperty">';
-                               print '<input type="hidden" name="tab" value="objects">';
-                               print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
-                               print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
-
-                               print '<div class="div-table-responsive">';
-                               print '<table class="noborder small">';
-
-                               print '<tr class="liste_titre">';
-                               print_liste_field_titre("ObjectType", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("Tab", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("Title", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("LangFile", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("Condition", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print_liste_field_titre("Path", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
-                               print "</tr>\n";
-
-                               if (count($tabs)) {
-                                       foreach ($tabs as $tab) {
-                                               $parts = explode(':', $tab['data']);
-
-                                               $objectType = $parts[0];
-                                               $tabName = $parts[1];
-                                               $tabTitle = isset($parts[2]) ? $parts[2] : '';
-                                               $langFile = isset($parts[3]) ? $parts[3] : '';
-                                               $condition = isset($parts[4]) ? $parts[4] : '';
-                                               $path = isset($parts[5]) ? $parts[5] : '';
-
-                                               // If we want to remove the tab, then the format is 'objecttype:tabname:optionalcondition'
-                                               // See: https://wiki.dolibarr.org/index.php?title=Tabs_system#To_remove_an_existing_tab
-                                               if ($tabName[0] === '-') {
-                                                       $tabTitle = '';
-                                                       $condition = isset($parts[2]) ? $parts[2] : '';
-                                               }
-
-                                               print '<tr class="oddeven">';
-
-                                               print '<td>';
-                                               print dol_escape_htmltag($parts[0]);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               if ($tabName[0] === "+") {
-                                                       print '<span class="badge badge-status4 badge-status">' . dol_escape_htmltag($tabName) . '</span>';
-                                               } else {
-                                                       print '<span class="badge badge-status8 badge-status">' . dol_escape_htmltag($tabName) . '</span>';
-                                               }
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print dol_escape_htmltag($tabTitle);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print dol_escape_htmltag($langFile);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print dol_escape_htmltag($condition);
-                                               print '</td>';
-
-                                               print '<td>';
-                                               print dol_escape_htmltag($path);
-                                               print '</td>';
-
-                                               print '</tr>';
-                                       }
-                               } else {
-                                       print '<tr><td class="opacitymedium" colspan="5">'.$langs->trans("None").'</td></tr>';
-                               }
-
-                               print '</table>';
-                               print '</div>';
-
-                               print '</form>';
-                       } else {
-                               $fullpathoffile = dol_buildpath($file, 0);
-
-                               $content = file_get_contents($fullpathoffile);
-
-                               // New module
-                               print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-                               print '<input type="hidden" name="token" value="'.newToken().'">';
-                               print '<input type="hidden" name="action" value="savefile">';
-                               print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
-                               print '<input type="hidden" name="tab" value="'.$tab.'">';
-                               print '<input type="hidden" name="module" value="'.$module.'">';
-
-                               $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
-                               print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ?GETPOST('format', 'aZ09') : 'html'));
-                               print '<br>';
-                               print '<center>';
-                               print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print ' &nbsp; ';
-                               print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-                               print '</center>';
-
-                               print '</form>';
-                       }
-               }
-
-               if ($tab != 'description') {
-                       print dol_get_fiche_end();
-               }
-       }
-}
-
-print dol_get_fiche_end(); // End modules
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/modulebuilder/template/ChangeLog.md b/htdocs/modulebuilder/template/ChangeLog.md
deleted file mode 100644 (file)
index effcde1..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# CHANGELOG MYMODULE FOR [DOLIBARR ERP CRM](https://www.dolibarr.org)
-
-## 1.0
-
-Initial version
diff --git a/htdocs/modulebuilder/template/README.md b/htdocs/modulebuilder/template/README.md
deleted file mode 100644 (file)
index 03cf25d..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-# MYMODULE FOR [DOLIBARR ERP CRM](https://www.dolibarr.org)
-
-## Features
-
-Description of the module...
-
-<!--
-![Screenshot mymodule](img/screenshot_mymodule.png?raw=true "MyModule"){imgmd}
--->
-
-Other external modules are available on [Dolistore.com](https://www.dolistore.com).
-
-## Translations
-
-Translations can be completed manually by editing files into directories *langs*.
-
-<!--
-This module contains also a sample configuration for Transifex, under the hidden directory [.tx](.tx), so it is possible to manage translation using this service.
-
-For more informations, see the [translator's documentation](https://wiki.dolibarr.org/index.php/Translator_documentation).
-
-There is a [Transifex project](https://transifex.com/projects/p/dolibarr-module-template) for this module.
--->
-
-<!--
-
-## Installation
-
-### From the ZIP file and GUI interface
-
-If the module is a ready to deploy zip file, so with a name module_xxx-version.zip (like when downloading it from a market place like [Dolistore](https://www.dolistore.com)),
-go into menu ```Home - Setup - Modules - Deploy external module``` and upload the zip file.
-
-Note: If this screen tell you that there is no "custom" directory, check that your setup is correct:
-
-- In your Dolibarr installation directory, edit the ```htdocs/conf/conf.php``` file and check that following lines are not commented:
-
-    ```php
-    //$dolibarr_main_url_root_alt ...
-    //$dolibarr_main_document_root_alt ...
-    ```
-
-- Uncomment them if necessary (delete the leading ```//```) and assign a sensible value according to your Dolibarr installation
-
-    For example :
-
-    - UNIX:
-        ```php
-        $dolibarr_main_url_root_alt = '/custom';
-        $dolibarr_main_document_root_alt = '/var/www/Dolibarr/htdocs/custom';
-        ```
-
-    - Windows:
-        ```php
-        $dolibarr_main_url_root_alt = '/custom';
-        $dolibarr_main_document_root_alt = 'C:/My Web Sites/Dolibarr/htdocs/custom';
-        ```
-
-### From a GIT repository
-
-Clone the repository in ```$dolibarr_main_document_root_alt/mymodule```
-
-```sh
-cd ....../custom
-git clone git@github.com:gitlogin/mymodule.git mymodule
-```
-
-### <a name="final_steps"></a>Final steps
-
-From your browser:
-
-  - Log into Dolibarr as a super-administrator
-  - Go to "Setup" -> "Modules"
-  - You should now be able to find and enable the module
-
--->
-
-## Licenses
-
-### Main code
-
-GPLv3 or (at your option) any later version. See file COPYING for more information.
-
-### Documentation
-
-All texts and readmes are licensed under GFDL.
diff --git a/htdocs/modulebuilder/template/admin/about.php b/htdocs/modulebuilder/template/admin/about.php
deleted file mode 100644 (file)
index 6e169ca..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-<?php
-/* Copyright (C) 2004-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    htdocs/modulebuilder/template/admin/about.php
- * \ingroup mymodule
- * \brief   About page of module MyModule.
- */
-
-// Load Dolibarr environment
-$res = 0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
-       $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-}
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--; $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
-}
-if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
-       $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
-}
-// Try main.inc.php using relative path
-if (!$res && file_exists("../../main.inc.php")) {
-       $res = @include "../../main.inc.php";
-}
-if (!$res && file_exists("../../../main.inc.php")) {
-       $res = @include "../../../main.inc.php";
-}
-if (!$res) {
-       die("Include of main fails");
-}
-
-// Libraries
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-require_once '../lib/mymodule.lib.php';
-
-// Translations
-$langs->loadLangs(array("errors", "admin", "mymodule@mymodule"));
-
-// Access control
-if (!$user->admin) {
-       accessforbidden();
-}
-
-// Parameters
-$action = GETPOST('action', 'aZ09');
-$backtopage = GETPOST('backtopage', 'alpha');
-
-
-/*
- * Actions
- */
-
-// None
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-$help_url = '';
-$page_name = "MyModuleAbout";
-
-llxHeader('', $langs->trans($page_name), $help_url);
-
-// Subheader
-$linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1').'">'.$langs->trans("BackToModuleList").'</a>';
-
-print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup');
-
-// Configuration header
-$head = mymoduleAdminPrepareHead();
-print dol_get_fiche_head($head, 'about', $langs->trans($page_name), 0, 'mymodule@mymodule');
-
-dol_include_once('/mymodule/core/modules/modMyModule.class.php');
-$tmpmodule = new modMyModule($db);
-print $tmpmodule->getDescLong();
-
-// Page end
-print dol_get_fiche_end();
-llxFooter();
-$db->close();
diff --git a/htdocs/modulebuilder/template/admin/myobject_extrafields.php b/htdocs/modulebuilder/template/admin/myobject_extrafields.php
deleted file mode 100644 (file)
index 0765375..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-<?php
-/* Copyright (C) 2001-2002     Rodolphe Quiedeville    <rodolphe@quiedeville.org>
- * Copyright (C) 2003          Jean-Louis Bergamo              <jlb@j1b.org>
- * Copyright (C) 2004-2011     Laurent Destailleur             <eldy@users.sourceforge.net>
- * Copyright (C) 2012          Regis Houssin                   <regis.houssin@inodbox.com>
- * Copyright (C) 2014          Florian Henry                   <florian.henry@open-concept.pro>
- * Copyright (C) 2015          Jean-François Ferry            <jfefe@aternatik.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *      \file       htdocs/modulebuilder/template/admin/myobject_extrafields.php
- *             \ingroup    mymodule
- *             \brief      Page to setup extra fields of myobject
- */
-
-// Load Dolibarr environment
-$res = 0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
-       $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-}
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--; $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
-}
-if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
-       $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
-}
-// Try main.inc.php using relative path
-if (!$res && file_exists("../../main.inc.php")) {
-       $res = @include "../../main.inc.php";
-}
-if (!$res && file_exists("../../../main.inc.php")) {
-       $res = @include "../../../main.inc.php";
-}
-if (!$res) {
-       die("Include of main fails");
-}
-
-require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
-require_once '../lib/mymodule.lib.php';
-
-// Load translation files required by the page
-$langs->loadLangs(array('mymodule@mymodule', 'admin'));
-
-$extrafields = new ExtraFields($db);
-$form = new Form($db);
-
-// List of supported format
-$tmptype2label = ExtraFields::$type2label;
-$type2label = array('');
-foreach ($tmptype2label as $key => $val) {
-       $type2label[$key] = $langs->transnoentitiesnoconv($val);
-}
-
-$action = GETPOST('action', 'aZ09');
-$attrname = GETPOST('attrname', 'alpha');
-$elementtype = 'mymodule_myobject'; //Must be the $table_element of the class that manage extrafield
-
-if (!$user->admin) {
-       accessforbidden();
-}
-
-
-/*
- * Actions
- */
-
-require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php';
-
-
-
-/*
- * View
- */
-
-$textobject = $langs->transnoentitiesnoconv("MyObject");
-
-$help_url = '';
-$page_name = "MyModuleSetup";
-
-llxHeader('', $langs->trans("MyModuleSetup"), $help_url);
-
-
-$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
-print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup');
-
-
-$head = mymoduleAdminPrepareHead();
-
-print dol_get_fiche_head($head, 'myobject_extrafields', $langs->trans($page_name), -1, 'mymodule@mymodule');
-
-require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php';
-
-print dol_get_fiche_end();
-
-
-// Buttons
-if ((float) DOL_VERSION < 17) {        // On v17+, the "New Attribute" button is included into tpl.
-       if ($action != 'create' && $action != 'edit') {
-               print '<div class="tabsAction">';
-               print '<a class="butAction reposition" href="'.$_SERVER["PHP_SELF"].'?action=create">'.$langs->trans("NewAttribute").'</a>';
-               print "</div>";
-       }
-}
-
-
-/*
- * Creation of an optional field
- */
-if ($action == 'create') {
-       print '<br><div id="newattrib"></div>';
-       print load_fiche_titre($langs->trans('NewAttribute'));
-
-       require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
-}
-
-/*
- * Edition of an optional field
- */
-if ($action == 'edit' && !empty($attrname)) {
-       print "<br>";
-       print load_fiche_titre($langs->trans("FieldEdition", $attrname));
-
-       require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php
deleted file mode 100644 (file)
index dea2a1a..0000000
+++ /dev/null
@@ -1,588 +0,0 @@
-<?php
-/* Copyright (C) 2004-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    htdocs/modulebuilder/template/admin/setup.php
- * \ingroup mymodule
- * \brief   MyModule setup page.
- */
-
-// Load Dolibarr environment
-$res = 0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
-       $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-}
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--; $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
-}
-if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
-       $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
-}
-// Try main.inc.php using relative path
-if (!$res && file_exists("../../main.inc.php")) {
-       $res = @include "../../main.inc.php";
-}
-if (!$res && file_exists("../../../main.inc.php")) {
-       $res = @include "../../../main.inc.php";
-}
-if (!$res) {
-       die("Include of main fails");
-}
-
-global $langs, $user;
-
-// Libraries
-require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
-require_once '../lib/mymodule.lib.php';
-//require_once "../class/myclass.class.php";
-
-// Translations
-$langs->loadLangs(array("admin", "mymodule@mymodule"));
-
-// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
-$hookmanager->initHooks(array('mymodulesetup', 'globalsetup'));
-
-// Access control
-if (!$user->admin) {
-       accessforbidden();
-}
-
-// Parameters
-$action = GETPOST('action', 'aZ09');
-$backtopage = GETPOST('backtopage', 'alpha');
-$modulepart = GETPOST('modulepart', 'aZ09');   // Used by actions_setmoduleoptions.inc.php
-
-$value = GETPOST('value', 'alpha');
-$label = GETPOST('label', 'alpha');
-$scandir = GETPOST('scan_dir', 'alpha');
-$type = 'myobject';
-
-
-$error = 0;
-$setupnotempty = 0;
-
-// Set this to 1 to use the factory to manage constants. Warning, the generated module will be compatible with version v15+ only
-$useFormSetup = 1;
-
-if (!class_exists('FormSetup')) {
-       // For retrocompatibility Dolibarr < 16.0
-       if (floatval(DOL_VERSION) < 16.0 && !class_exists('FormSetup')) {
-               require_once __DIR__.'/../backport/v16/core/class/html.formsetup.class.php';
-       } else {
-               require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsetup.class.php';
-       }
-}
-
-$formSetup = new FormSetup($db);
-
-
-// HTTP HOST
-$item = $formSetup->newItem('NO_PARAM_JUST_TEXT');
-$item->fieldOverride = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'];
-$item->cssClass = 'minwidth500';
-
-// Setup conf MYMODULE_MYPARAM1 as a simple string input
-$item = $formSetup->newItem('MYMODULE_MYPARAM1');
-$item->defaultFieldValue = 'default value';
-
-// Setup conf MYMODULE_MYPARAM2 as a simple textarea input but we replace the text of field title
-$item = $formSetup->newItem('MYMODULE_MYPARAM2');
-$item->nameText = $item->getNameText().' more html text ';
-
-// Setup conf MYMODULE_MYPARAM3
-$item = $formSetup->newItem('MYMODULE_MYPARAM3');
-$item->setAsThirdpartyType();
-
-// Setup conf MYMODULE_MYPARAM4 : exemple of quick define write style
-$formSetup->newItem('MYMODULE_MYPARAM4')->setAsYesNo();
-
-// Setup conf MYMODULE_MYPARAM5
-$formSetup->newItem('MYMODULE_MYPARAM5')->setAsEmailTemplate('thirdparty');
-
-// Setup conf MYMODULE_MYPARAM6
-$formSetup->newItem('MYMODULE_MYPARAM6')->setAsSecureKey()->enabled = 0; // disabled
-
-// Setup conf MYMODULE_MYPARAM7
-$formSetup->newItem('MYMODULE_MYPARAM7')->setAsProduct();
-
-$formSetup->newItem('Title')->setAsTitle();
-
-// Setup conf MYMODULE_MYPARAM8
-$item = $formSetup->newItem('MYMODULE_MYPARAM8');
-$TField = array(
-       'test01' => $langs->trans('test01'),
-       'test02' => $langs->trans('test02'),
-       'test03' => $langs->trans('test03'),
-       'test04' => $langs->trans('test04'),
-       'test05' => $langs->trans('test05'),
-       'test06' => $langs->trans('test06'),
-);
-$item->setAsMultiSelect($TField);
-$item->helpText = $langs->transnoentities('MYMODULE_MYPARAM8');
-
-
-// Setup conf MYMODULE_MYPARAM9
-$formSetup->newItem('MYMODULE_MYPARAM9')->setAsSelect($TField);
-
-
-// Setup conf MYMODULE_MYPARAM10
-$item = $formSetup->newItem('MYMODULE_MYPARAM10');
-$item->setAsColor();
-$item->defaultFieldValue = '#FF0000';
-$item->nameText = $item->getNameText().' more html text ';
-$item->fieldInputOverride = '';
-$item->helpText = $langs->transnoentities('AnHelpMessage');
-//$item->fieldValue = '';
-//$item->fieldAttr = array() ; // fields attribute only for compatible fields like input text
-//$item->fieldOverride = false; // set this var to override field output will override $fieldInputOverride and $fieldOutputOverride too
-//$item->fieldInputOverride = false; // set this var to override field input
-//$item->fieldOutputOverride = false; // set this var to override field output
-
-
-$setupnotempty =+ count($formSetup->items);
-
-
-$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
-
-
-/*
- * Actions
- */
-
-// For retrocompatibility Dolibarr < 15.0
-if ( versioncompare(explode('.', DOL_VERSION), array(15)) < 0 && $action == 'update' && !empty($user->admin)) {
-       $formSetup->saveConfFromPost();
-}
-
-include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
-
-if ($action == 'updateMask') {
-       $maskconst = GETPOST('maskconst', 'aZ09');
-       $maskvalue = GETPOST('maskvalue', 'alpha');
-
-       if ($maskconst && preg_match('/_MASK$/', $maskconst)) {
-               $res = dolibarr_set_const($db, $maskconst, $maskvalue, 'chaine', 0, '', $conf->entity);
-               if (!($res > 0)) {
-                       $error++;
-               }
-       }
-
-       if (!$error) {
-               setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
-       } else {
-               setEventMessages($langs->trans("Error"), null, 'errors');
-       }
-} elseif ($action == 'specimen') {
-       $modele = GETPOST('module', 'alpha');
-       $tmpobjectkey = GETPOST('object');
-
-       $tmpobject = new $tmpobjectkey($db);
-       $tmpobject->initAsSpecimen();
-
-       // Search template files
-       $file = ''; $classname = ''; $filefound = 0;
-       $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
-       foreach ($dirmodels as $reldir) {
-               $file = dol_buildpath($reldir."core/modules/mymodule/doc/pdf_".$modele."_".strtolower($tmpobjectkey).".modules.php", 0);
-               if (file_exists($file)) {
-                       $filefound = 1;
-                       $classname = "pdf_".$modele."_".strtolower($tmpobjectkey);
-                       break;
-               }
-       }
-
-       if ($filefound) {
-               require_once $file;
-
-               $module = new $classname($db);
-
-               if ($module->write_file($tmpobject, $langs) > 0) {
-                       header("Location: ".DOL_URL_ROOT."/document.php?modulepart=mymodule-".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf");
-                       return;
-               } else {
-                       setEventMessages($module->error, null, 'errors');
-                       dol_syslog($module->error, LOG_ERR);
-               }
-       } else {
-               setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
-               dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
-       }
-} elseif ($action == 'setmod') {
-       // TODO Check if numbering module chosen can be activated by calling method canBeActivated
-       $tmpobjectkey = GETPOST('object');
-       if (!empty($tmpobjectkey)) {
-               $constforval = 'MYMODULE_'.strtoupper($tmpobjectkey)."_ADDON";
-               dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity);
-       }
-} elseif ($action == 'set') {
-       // Activate a model
-       $ret = addDocumentModel($value, $type, $label, $scandir);
-} elseif ($action == 'del') {
-       $ret = delDocumentModel($value, $type);
-       if ($ret > 0) {
-               $tmpobjectkey = GETPOST('object');
-               if (!empty($tmpobjectkey)) {
-                       $constforval = 'MYMODULE_'.strtoupper($tmpobjectkey).'_ADDON_PDF';
-                       if ($conf->global->$constforval == "$value") {
-                               dolibarr_del_const($db, $constforval, $conf->entity);
-                       }
-               }
-       }
-} elseif ($action == 'setdoc') {
-       // Set or unset default model
-       $tmpobjectkey = GETPOST('object');
-       if (!empty($tmpobjectkey)) {
-               $constforval = 'MYMODULE_'.strtoupper($tmpobjectkey).'_ADDON_PDF';
-               if (dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity)) {
-                       // The constant that was read before the new set
-                       // We therefore requires a variable to have a coherent view
-                       $conf->global->$constforval = $value;
-               }
-
-               // We disable/enable the document template (into llx_document_model table)
-               $ret = delDocumentModel($value, $type);
-               if ($ret > 0) {
-                       $ret = addDocumentModel($value, $type, $label, $scandir);
-               }
-       }
-} elseif ($action == 'unsetdoc') {
-       $tmpobjectkey = GETPOST('object');
-       if (!empty($tmpobjectkey)) {
-               $constforval = 'MYMODULE_'.strtoupper($tmpobjectkey).'_ADDON_PDF';
-               dolibarr_del_const($db, $constforval, $conf->entity);
-       }
-}
-
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-$help_url = '';
-$page_name = "MyModuleSetup";
-
-llxHeader('', $langs->trans($page_name), $help_url);
-
-// Subheader
-$linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1').'">'.$langs->trans("BackToModuleList").'</a>';
-
-print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup');
-
-// Configuration header
-$head = mymoduleAdminPrepareHead();
-print dol_get_fiche_head($head, 'settings', $langs->trans($page_name), -1, "mymodule@mymodule");
-
-// Setup page goes here
-echo '<span class="opacitymedium">'.$langs->trans("MyModuleSetupPage").'</span><br><br>';
-
-
-if ($action == 'edit') {
-       print $formSetup->generateOutput(true);
-       print '<br>';
-} elseif (!empty($formSetup->items)) {
-       print $formSetup->generateOutput();
-       print '<div class="tabsAction">';
-       print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'">'.$langs->trans("Modify").'</a>';
-       print '</div>';
-} else {
-       print '<br>'.$langs->trans("NothingToSetup");
-}
-
-
-$moduledir = 'mymodule';
-$myTmpObjects = array();
-// TODO Scan list of objects
-$myTmpObjects['myobject'] = array('label'=>'MyObject', 'includerefgeneration'=>0, 'includedocgeneration'=>0);
-
-
-foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
-       if ($myTmpObjectKey != $type) {
-               continue;
-       }
-       if ($myTmpObjectArray['includerefgeneration']) {
-               /*
-                * Orders Numbering model
-                */
-               $setupnotempty++;
-
-               print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectArray['label']), '', '');
-
-               print '<table class="noborder centpercent">';
-               print '<tr class="liste_titre">';
-               print '<td>'.$langs->trans("Name").'</td>';
-               print '<td>'.$langs->trans("Description").'</td>';
-               print '<td class="nowrap">'.$langs->trans("Example").'</td>';
-               print '<td class="center" width="60">'.$langs->trans("Status").'</td>';
-               print '<td class="center" width="16">'.$langs->trans("ShortInfo").'</td>';
-               print '</tr>'."\n";
-
-               clearstatcache();
-
-               foreach ($dirmodels as $reldir) {
-                       $dir = dol_buildpath($reldir."core/modules/".$moduledir);
-
-                       if (is_dir($dir)) {
-                               $handle = opendir($dir);
-                               if (is_resource($handle)) {
-                                       while (($file = readdir($handle)) !== false) {
-                                               if (strpos($file, 'mod_'.strtolower($myTmpObjectKey).'_') === 0 && substr($file, dol_strlen($file) - 3, 3) == 'php') {
-                                                       $file = substr($file, 0, dol_strlen($file) - 4);
-
-                                                       require_once $dir.'/'.$file.'.php';
-
-                                                       $module = new $file($db);
-
-                                                       // Show modules according to features level
-                                                       if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) {
-                                                               continue;
-                                                       }
-                                                       if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) {
-                                                               continue;
-                                                       }
-
-                                                       if ($module->isEnabled()) {
-                                                               dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php');
-
-                                                               print '<tr class="oddeven"><td>'.$module->name."</td><td>\n";
-                                                               print $module->info();
-                                                               print '</td>';
-
-                                                               // Show example of numbering model
-                                                               print '<td class="nowrap">';
-                                                               $tmp = $module->getExample();
-                                                               if (preg_match('/^Error/', $tmp)) {
-                                                                       $langs->load("errors");
-                                                                       print '<div class="error">'.$langs->trans($tmp).'</div>';
-                                                               } elseif ($tmp == 'NotConfigured') {
-                                                                       print $langs->trans($tmp);
-                                                               } else {
-                                                                       print $tmp;
-                                                               }
-                                                               print '</td>'."\n";
-
-                                                               print '<td class="center">';
-                                                               $constforvar = 'MYMODULE_'.strtoupper($myTmpObjectKey).'_ADDON';
-                                                               if (getDolGlobalString($constforvar) == $file) {
-                                                                       print img_picto($langs->trans("Activated"), 'switch_on');
-                                                               } else {
-                                                                       print '<a href="'.$_SERVER["PHP_SELF"].'?action=setmod&token='.newToken().'&object='.strtolower($myTmpObjectKey).'&value='.urlencode($file).'">';
-                                                                       print img_picto($langs->trans("Disabled"), 'switch_off');
-                                                                       print '</a>';
-                                                               }
-                                                               print '</td>';
-
-                                                               $mytmpinstance = new $myTmpObjectKey($db);
-                                                               $mytmpinstance->initAsSpecimen();
-
-                                                               // Info
-                                                               $htmltooltip = '';
-                                                               $htmltooltip .= ''.$langs->trans("Version").': <b>'.$module->getVersion().'</b><br>';
-
-                                                               $nextval = $module->getNextValue($mytmpinstance);
-                                                               if ("$nextval" != $langs->trans("NotAvailable")) {  // Keep " on nextval
-                                                                       $htmltooltip .= ''.$langs->trans("NextValue").': ';
-                                                                       if ($nextval) {
-                                                                               if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') {
-                                                                                       $nextval = $langs->trans($nextval);
-                                                                               }
-                                                                               $htmltooltip .= $nextval.'<br>';
-                                                                       } else {
-                                                                               $htmltooltip .= $langs->trans($module->error).'<br>';
-                                                                       }
-                                                               }
-
-                                                               print '<td class="center">';
-                                                               print $form->textwithpicto('', $htmltooltip, 1, 0);
-                                                               print '</td>';
-
-                                                               print "</tr>\n";
-                                                       }
-                                               }
-                                       }
-                                       closedir($handle);
-                               }
-                       }
-               }
-               print "</table><br>\n";
-       }
-
-       if ($myTmpObjectArray['includedocgeneration']) {
-               /*
-                * Document templates generators
-                */
-               $setupnotempty++;
-               $type = strtolower($myTmpObjectKey);
-
-               print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', '');
-
-               // Load array def with activated templates
-               $def = array();
-               $sql = "SELECT nom";
-               $sql .= " FROM ".MAIN_DB_PREFIX."document_model";
-               $sql .= " WHERE type = '".$db->escape($type)."'";
-               $sql .= " AND entity = ".$conf->entity;
-               $resql = $db->query($sql);
-               if ($resql) {
-                       $i = 0;
-                       $num_rows = $db->num_rows($resql);
-                       while ($i < $num_rows) {
-                               $array = $db->fetch_array($resql);
-                               array_push($def, $array[0]);
-                               $i++;
-                       }
-               } else {
-                       dol_print_error($db);
-               }
-
-               print "<table class=\"noborder\" width=\"100%\">\n";
-               print "<tr class=\"liste_titre\">\n";
-               print '<td>'.$langs->trans("Name").'</td>';
-               print '<td>'.$langs->trans("Description").'</td>';
-               print '<td class="center" width="60">'.$langs->trans("Status")."</td>\n";
-               print '<td class="center" width="60">'.$langs->trans("Default")."</td>\n";
-               print '<td class="center" width="38">'.$langs->trans("ShortInfo").'</td>';
-               print '<td class="center" width="38">'.$langs->trans("Preview").'</td>';
-               print "</tr>\n";
-
-               clearstatcache();
-
-               foreach ($dirmodels as $reldir) {
-                       foreach (array('', '/doc') as $valdir) {
-                               $realpath = $reldir."core/modules/".$moduledir.$valdir;
-                               $dir = dol_buildpath($realpath);
-
-                               if (is_dir($dir)) {
-                                       $handle = opendir($dir);
-                                       if (is_resource($handle)) {
-                                               while (($file = readdir($handle)) !== false) {
-                                                       $filelist[] = $file;
-                                               }
-                                               closedir($handle);
-                                               arsort($filelist);
-
-                                               foreach ($filelist as $file) {
-                                                       if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
-                                                               if (file_exists($dir.'/'.$file)) {
-                                                                       $name = substr($file, 4, dol_strlen($file) - 16);
-                                                                       $classname = substr($file, 0, dol_strlen($file) - 12);
-
-                                                                       require_once $dir.'/'.$file;
-                                                                       $module = new $classname($db);
-
-                                                                       $modulequalified = 1;
-                                                                       if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) {
-                                                                               $modulequalified = 0;
-                                                                       }
-                                                                       if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) {
-                                                                               $modulequalified = 0;
-                                                                       }
-
-                                                                       if ($modulequalified) {
-                                                                               print '<tr class="oddeven"><td width="100">';
-                                                                               print (empty($module->name) ? $name : $module->name);
-                                                                               print "</td><td>\n";
-                                                                               if (method_exists($module, 'info')) {
-                                                                                       print $module->info($langs);
-                                                                               } else {
-                                                                                       print $module->description;
-                                                                               }
-                                                                               print '</td>';
-
-                                                                               // Active
-                                                                               if (in_array($name, $def)) {
-                                                                                       print '<td class="center">'."\n";
-                                                                                       print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&token='.newToken().'&value='.urlencode($name).'">';
-                                                                                       print img_picto($langs->trans("Enabled"), 'switch_on');
-                                                                                       print '</a>';
-                                                                                       print '</td>';
-                                                                               } else {
-                                                                                       print '<td class="center">'."\n";
-                                                                                       print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
-                                                                                       print "</td>";
-                                                                               }
-
-                                                                               // Default
-                                                                               print '<td class="center">';
-                                                                               $constforvar = 'MYMODULE_'.strtoupper($myTmpObjectKey).'_ADDON_PDF';
-                                                                               if (getDolGlobalString($constforvar) == $name) {
-                                                                                       //print img_picto($langs->trans("Default"), 'on');
-                                                                                       // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset
-                                                                                       print '<a href="'.$_SERVER["PHP_SELF"].'?action=unsetdoc&token='.newToken().'&object='.urlencode(strtolower($myTmpObjectKey)).'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'&amp;type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').'</a>';
-                                                                               } else {
-                                                                                       print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&token='.newToken().'&object='.urlencode(strtolower($myTmpObjectKey)).'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
-                                                                               }
-                                                                               print '</td>';
-
-                                                                               // Info
-                                                                               $htmltooltip = ''.$langs->trans("Name").': '.$module->name;
-                                                                               $htmltooltip .= '<br>'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown"));
-                                                                               if ($module->type == 'pdf') {
-                                                                                       $htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
-                                                                               }
-                                                                               $htmltooltip .= '<br>'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file;
-
-                                                                               $htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
-                                                                               $htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
-                                                                               $htmltooltip .= '<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1);
-
-                                                                               print '<td class="center">';
-                                                                               print $form->textwithpicto('', $htmltooltip, 1, 0);
-                                                                               print '</td>';
-
-                                                                               // Preview
-                                                                               print '<td class="center">';
-                                                                               if ($module->type == 'pdf') {
-                                                                                       $newname = preg_replace('/_'.preg_quote(strtolower($myTmpObjectKey), '/').'/', '', $name);
-                                                                                       print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.urlencode($newname).'&object='.urlencode($myTmpObjectKey).'">'.img_object($langs->trans("Preview"), 'pdf').'</a>';
-                                                                               } else {
-                                                                                       print img_object($langs->trans("PreviewNotAvailable"), 'generic');
-                                                                               }
-                                                                               print '</td>';
-
-                                                                               print "</tr>\n";
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               print '</table>';
-       }
-}
-
-if (empty($setupnotempty)) {
-       print '<br>'.$langs->trans("NothingToSetup");
-}
-
-// Page end
-print dol_get_fiche_end();
-
-llxFooter();
-$db->close();
diff --git a/htdocs/modulebuilder/template/ajax/myobject.php b/htdocs/modulebuilder/template/ajax/myobject.php
deleted file mode 100644 (file)
index 3e22eb2..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-/* Copyright (C) 2022 Laurent Destailleur  <eldy@users.sourceforge.net>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *       \file       htdocs/mymodule/ajax/myobject.php
- *       \brief      File to return Ajax response on product list request
- */
-
-if (!defined('NOTOKENRENEWAL')) {
-       define('NOTOKENRENEWAL', 1); // Disables token renewal
-}
-if (!defined('NOREQUIREMENU')) {
-       define('NOREQUIREMENU', '1');
-}
-if (!defined('NOREQUIREHTML')) {
-       define('NOREQUIREHTML', '1');
-}
-if (!defined('NOREQUIREAJAX')) {
-       define('NOREQUIREAJAX', '1');
-}
-if (!defined('NOREQUIRESOC')) {
-       define('NOREQUIRESOC', '1');
-}
-if (!defined('NOCSRFCHECK')) {
-       define('NOCSRFCHECK', '1');
-}
-if (!defined('NOREQUIREHTML')) {
-       define('NOREQUIREHTML', '1');
-}
-
-// Load Dolibarr environment
-require '../../main.inc.php';
-
-$mode = GETPOST('mode', 'aZ09');
-
-// Security check
-restrictedArea($user, 'mymodule', 0, 'myobject');
-
-
-/*
- * View
- */
-
-dol_syslog("Call ajax mymodule/ajax/myobject.php");
-
-top_httphead('application/json');
-
-$arrayresult = array();
-
-// ....
-
-$db->close();
-
-print json_encode($arrayresult);
diff --git a/htdocs/modulebuilder/template/build/doxygen/mymodule.doxyfile b/htdocs/modulebuilder/template/build/doxygen/mymodule.doxyfile
deleted file mode 100644 (file)
index 837a869..0000000
+++ /dev/null
@@ -1,2419 +0,0 @@
-# Doxyfile 1.8.12
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project.
-#
-# All text after a double hash (##) is considered a comment and is placed in
-# front of the TAG it is preceding.
-#
-# All text after a single hash (#) is considered a comment and will be ignored.
-# The format is:
-# TAG = value [value, ...]
-# For lists, items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (\" \").
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all text
-# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
-# built into libc) for the transcoding. See https://www.gnu.org/software/libiconv
-# for the list of possible encodings.
-# The default value is: UTF-8.
-
-DOXYFILE_ENCODING      = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
-# double-quotes, unless you are using Doxywizard) that should identify the
-# project for which the documentation is generated. This name is used in the
-# title of most generated pages and in a few other places.
-# The default value is: My Project.
-
-PROJECT_NAME           = mymodule
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
-# could be handy for archiving the generated documentation or if some version
-# control system is used.
-
-PROJECT_NUMBER         = development
-
-# Using the PROJECT_BRIEF tag one can provide an optional one line description
-# for a project that appears at the top of each page and should give viewer a
-# quick idea about the purpose of the project. Keep the description short.
-
-PROJECT_BRIEF          = My module brief.
-
-# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
-# in the documentation. The maximum height of the logo should not exceed 55
-# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
-# the logo to the output directory.
-
-PROJECT_LOGO           = ../../img/mymodule.png
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
-# into which the generated documentation will be written. If a relative path is
-# entered, it will be relative to the location where doxygen was started. If
-# left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = ../../doc/code/doxygen
-
-# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
-# directories (in 2 levels) under the output directory of each output format and
-# will distribute the generated files over these directories. Enabling this
-# option can be useful when feeding doxygen a huge amount of source files, where
-# putting all generated files in the same directory would otherwise causes
-# performance problems for the file system.
-# The default value is: NO.
-
-CREATE_SUBDIRS         = YES
-
-# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
-# characters to appear in the names of generated files. If set to NO, non-ASCII
-# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
-# U+3044.
-# The default value is: NO.
-
-ALLOW_UNICODE_NAMES    = YES
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
-# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
-# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
-# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
-# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
-# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
-# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
-# Ukrainian and Vietnamese.
-# The default value is: English.
-
-OUTPUT_LANGUAGE        = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
-# descriptions after the members that are listed in the file and class
-# documentation (similar to Javadoc). Set to NO to disable this.
-# The default value is: YES.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
-# description of a member or function before the detailed description
-#
-# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-# The default value is: YES.
-
-REPEAT_BRIEF           = NO
-
-# This tag implements a quasi-intelligent brief description abbreviator that is
-# used to form the text in various listings. Each string in this list, if found
-# as the leading text of the brief description, will be stripped from the text
-# and the result, after processing the whole list, is used as the annotated
-# text. Otherwise, the brief description is used as-is. If left blank, the
-# following values are used ($name is automatically replaced with the name of
-# the entity):The $name class, The $name widget, The $name file, is, provides,
-# specifies, contains, represents, a, an and the.
-
-ABBREVIATE_BRIEF       =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# doxygen will generate a detailed section even if there is only a brief
-# description.
-# The default value is: NO.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-# The default value is: NO.
-
-INLINE_INHERITED_MEMB  = NO
-
-# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
-# before files name in the file list and in the header files. If set to NO the
-# shortest path that makes the file name unique will be used
-# The default value is: YES.
-
-FULL_PATH_NAMES        = YES
-
-# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
-# Stripping is only done if one of the specified strings matches the left-hand
-# part of the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the path to
-# strip.
-#
-# Note that you can specify absolute paths here, but also relative paths, which
-# will be relative from the directory where doxygen is started.
-# This tag requires that the tag FULL_PATH_NAMES is set to YES.
-
-STRIP_FROM_PATH        = "../.."
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
-# path mentioned in the documentation of a class, which tells the reader which
-# header file to include in order to use a class. If left blank only the name of
-# the header file containing the class definition is used. Otherwise one should
-# specify the list of include paths that are normally passed to the compiler
-# using the -I flag.
-
-STRIP_FROM_INC_PATH    =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
-# less readable) file names. This can be useful is your file systems doesn't
-# support long names like on DOS, Mac, or CD-ROM.
-# The default value is: NO.
-
-SHORT_NAMES            = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
-# first line (until the first dot) of a Javadoc-style comment as the brief
-# description. If set to NO, the Javadoc-style will behave just like regular Qt-
-# style comments (thus requiring an explicit @brief command for a brief
-# description.)
-# The default value is: NO.
-
-JAVADOC_AUTOBRIEF      = YES
-
-# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
-# line (until the first dot) of a Qt-style comment as the brief description. If
-# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
-# requiring an explicit \brief command for a brief description.)
-# The default value is: NO.
-
-QT_AUTOBRIEF           = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
-# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
-# a brief description. This used to be the default behavior. The new default is
-# to treat a multi-line C++ comment block as a detailed description. Set this
-# tag to YES if you prefer the old behavior instead.
-#
-# Note that setting this tag to YES also means that rational rose comments are
-# not recognized any more.
-# The default value is: NO.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
-# documentation from any documented member that it re-implements.
-# The default value is: YES.
-
-INHERIT_DOCS           = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
-# page for each member. If set to NO, the documentation of a member will be part
-# of the file/class/namespace that contains it.
-# The default value is: NO.
-
-SEPARATE_MEMBER_PAGES  = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
-# uses this value to replace tabs by spaces in code fragments.
-# Minimum value: 1, maximum value: 16, default value: 4.
-
-TAB_SIZE               = 4
-
-# This tag can be used to specify a number of aliases that act as commands in
-# the documentation. An alias has the form:
-# name=value
-# For example adding
-# "sideeffect=@par Side Effects:\n"
-# will allow you to put the command \sideeffect (or @sideeffect) in the
-# documentation, which will result in a user-defined paragraph with heading
-# "Side Effects:". You can put \n's in the value part of an alias to insert
-# newlines.
-
-ALIASES                =
-
-# This tag can be used to specify a number of word-keyword mappings (TCL only).
-# A mapping has the form "name=value". For example adding "class=itcl::class"
-# will allow you to use the command class in the itcl::class meaning.
-
-TCL_SUBST              =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
-# only. Doxygen will then generate output that is more tailored for C. For
-# instance, some of the names that are used will be different. The list of all
-# members will be omitted, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_FOR_C  = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
-# Python sources only. Doxygen will then generate output that is more tailored
-# for that language. For instance, namespaces will be presented as packages,
-# qualified scopes will look different, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_JAVA   = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources. Doxygen will then generate output that is tailored for Fortran.
-# The default value is: NO.
-
-OPTIMIZE_FOR_FORTRAN   = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for VHDL.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_VHDL   = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given
-# extension. Doxygen has a built-in mapping, but you can override or extend it
-# using this tag. The format is ext=language, where ext is a file extension, and
-# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
-# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
-# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
-# Fortran. In the later case the parser tries to guess whether the code is fixed
-# or free formatted code, this is the default for Fortran type files), VHDL. For
-# instance to make doxygen treat .inc files as Fortran files (default is PHP),
-# and .f files as C (default is Fortran), use: inc=Fortran f=C.
-#
-# Note: For files without extension you can use no_extension as a placeholder.
-#
-# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
-# the files are not read by doxygen.
-
-EXTENSION_MAPPING      =
-
-# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
-# according to the Markdown format, which allows for more readable
-# documentation. See http://daringfireball.net/projects/markdown/ for details.
-# The output of markdown processing is further processed by doxygen, so you can
-# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
-# case of backward compatibilities issues.
-# The default value is: YES.
-
-MARKDOWN_SUPPORT       = YES
-
-# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
-# to that level are automatically included in the table of contents, even if
-# they do not have an id attribute.
-# Note: This feature currently applies only to Markdown headings.
-# Minimum value: 0, maximum value: 99, default value: 0.
-# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
-
-TOC_INCLUDE_HEADINGS   = 0
-
-# When enabled doxygen tries to link words that correspond to documented
-# classes, or namespaces to their corresponding documentation. Such a link can
-# be prevented in individual cases by putting a % sign in front of the word or
-# globally by setting AUTOLINK_SUPPORT to NO.
-# The default value is: YES.
-
-AUTOLINK_SUPPORT       = YES
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should set this
-# tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string);
-# versus func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-# The default value is: NO.
-
-BUILTIN_STL_SUPPORT    = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-# The default value is: NO.
-
-CPP_CLI_SUPPORT        = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
-# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
-# will parse them like normal C++ but will assume all classes use public instead
-# of private inheritance when no explicit protection keyword is present.
-# The default value is: NO.
-
-SIP_SUPPORT            = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate
-# getter and setter methods for a property. Setting this option to YES will make
-# doxygen to replace the get and set methods by a property in the documentation.
-# This will only work if the methods are indeed getting or setting a simple
-# type. If this is not the case, or you want to show the methods anyway, you
-# should set this option to NO.
-# The default value is: YES.
-
-IDL_PROPERTY_SUPPORT   = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-# The default value is: NO.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# If one adds a struct or class to a group and this option is enabled, then also
-# any nested class or struct is added to the same group. By default this option
-# is disabled and one has to add nested compounds explicitly via \ingroup.
-# The default value is: NO.
-
-GROUP_NESTED_COMPOUNDS = NO
-
-# Set the SUBGROUPING tag to YES to allow class member groups of the same type
-# (for instance a group of public functions) to be put as a subgroup of that
-# type (e.g. under the Public Functions section). Set it to NO to prevent
-# subgrouping. Alternatively, this can be done per class using the
-# \nosubgrouping command.
-# The default value is: YES.
-
-SUBGROUPING            = YES
-
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
-# are shown inside the group in which they are included (e.g. using \ingroup)
-# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
-# and RTF).
-#
-# Note that this feature does not work in combination with
-# SEPARATE_MEMBER_PAGES.
-# The default value is: NO.
-
-INLINE_GROUPED_CLASSES = NO
-
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
-# with only public data fields or simple typedef fields will be shown inline in
-# the documentation of the scope in which they are defined (i.e. file,
-# namespace, or group documentation), provided this scope is documented. If set
-# to NO, structs, classes, and unions are shown on a separate page (for HTML and
-# Man pages) or section (for LaTeX and RTF).
-# The default value is: NO.
-
-INLINE_SIMPLE_STRUCTS  = NO
-
-# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
-# enum is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically be
-# useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-# The default value is: NO.
-
-TYPEDEF_HIDES_STRUCT   = NO
-
-# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
-# cache is used to resolve symbols given their name and scope. Since this can be
-# an expensive process and often the same symbol appears multiple times in the
-# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
-# doxygen will become slower. If the cache is too large, memory is wasted. The
-# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
-# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
-# symbols. At the end of a run doxygen will report the cache usage and suggest
-# the optimal cache size from a speed point of view.
-# Minimum value: 0, maximum value: 9, default value: 0.
-
-LOOKUP_CACHE_SIZE      = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
-# documentation are documented, even if no documentation was available. Private
-# class members and static file members will be hidden unless the
-# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
-# Note: This will also disable the warnings about undocumented members that are
-# normally produced when WARNINGS is set to YES.
-# The default value is: NO.
-
-EXTRACT_ALL            = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
-# be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PRIVATE        = YES
-
-# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
-# scope will be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PACKAGE        = NO
-
-# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
-# included in the documentation.
-# The default value is: NO.
-
-EXTRACT_STATIC         = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
-# locally in source files will be included in the documentation. If set to NO,
-# only classes defined in header files are included. Does not have any effect
-# for Java sources.
-# The default value is: YES.
-
-EXTRACT_LOCAL_CLASSES  = YES
-
-# This flag is only useful for Objective-C code. If set to YES, local methods,
-# which are defined in the implementation section but not in the interface are
-# included in the documentation. If set to NO, only methods in the interface are
-# included.
-# The default value is: NO.
-
-EXTRACT_LOCAL_METHODS  = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base name of
-# the file that contains the anonymous namespace. By default anonymous namespace
-# are hidden.
-# The default value is: NO.
-
-EXTRACT_ANON_NSPACES   = YES
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
-# undocumented members inside documented classes or files. If set to NO these
-# members will be included in the various overviews, but no documentation
-# section is generated. This option has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_MEMBERS     = YES
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy. If set
-# to NO, these classes will be included in the various overviews. This option
-# has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_CLASSES     = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
-# (class|struct|union) declarations. If set to NO, these declarations will be
-# included in the documentation.
-# The default value is: NO.
-
-HIDE_FRIEND_COMPOUNDS  = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
-# documentation blocks found inside the body of a function. If set to NO, these
-# blocks will be appended to the function's detailed documentation block.
-# The default value is: NO.
-
-HIDE_IN_BODY_DOCS      = NO
-
-# The INTERNAL_DOCS tag determines if documentation that is typed after a
-# \internal command is included. If the tag is set to NO then the documentation
-# will be excluded. Set it to YES to include the internal documentation.
-# The default value is: NO.
-
-INTERNAL_DOCS          = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
-# names in lower-case letters. If set to YES, upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-# The default value is: system dependent.
-
-CASE_SENSE_NAMES       = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
-# their full class and namespace scopes in the documentation. If set to YES, the
-# scope will be hidden.
-# The default value is: NO.
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
-# append additional text to a page's title, such as Class Reference. If set to
-# YES the compound reference will be hidden.
-# The default value is: NO.
-
-HIDE_COMPOUND_REFERENCE= NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
-# the files that are included by a file in the documentation of that file.
-# The default value is: YES.
-
-SHOW_INCLUDE_FILES     = YES
-
-# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
-# grouped member an include statement to the documentation, telling the reader
-# which file to include in order to use the member.
-# The default value is: NO.
-
-SHOW_GROUPED_MEMB_INC  = NO
-
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
-# files with double quotes in the documentation rather than with sharp brackets.
-# The default value is: NO.
-
-FORCE_LOCAL_INCLUDES   = NO
-
-# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
-# documentation for inline members.
-# The default value is: YES.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
-# (detailed) documentation of file and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order.
-# The default value is: YES.
-
-SORT_MEMBER_DOCS       = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
-# descriptions of file, namespace and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order. Note that
-# this will also influence the order of the classes in the class list.
-# The default value is: NO.
-
-SORT_BRIEF_DOCS        = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
-# (brief and detailed) documentation of class members so that constructors and
-# destructors are listed first. If set to NO the constructors will appear in the
-# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
-# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
-# member documentation.
-# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
-# detailed member documentation.
-# The default value is: NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
-# of group names into alphabetical order. If set to NO the group names will
-# appear in their defined order.
-# The default value is: NO.
-
-SORT_GROUP_NAMES       = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
-# fully-qualified names, including namespaces. If set to NO, the class list will
-# be sorted only by class name, not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the alphabetical
-# list.
-# The default value is: NO.
-
-SORT_BY_SCOPE_NAME     = NO
-
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
-# type resolution of all parameters of a function it will reject a match between
-# the prototype and the implementation of a member function even if there is
-# only one candidate or it is obvious which candidate to choose by doing a
-# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
-# accept a match between prototype and implementation in such cases.
-# The default value is: NO.
-
-STRICT_PROTO_MATCHING  = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
-# list. This list is created by putting \todo commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
-# list. This list is created by putting \test commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TESTLIST      = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
-# list. This list is created by putting \bug commands in the documentation.
-# The default value is: YES.
-
-GENERATE_BUGLIST       = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
-# the deprecated list. This list is created by putting \deprecated commands in
-# the documentation.
-# The default value is: YES.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional documentation
-# sections, marked by \if <section_label> ... \endif and \cond <section_label>
-# ... \endcond blocks.
-
-ENABLED_SECTIONS       =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
-# initial value of a variable or macro / define can have for it to appear in the
-# documentation. If the initializer consists of more lines than specified here
-# it will be hidden. Use a value of 0 to hide initializers completely. The
-# appearance of the value of individual variables and macros / defines can be
-# controlled using \showinitializer or \hideinitializer command in the
-# documentation regardless of this setting.
-# Minimum value: 0, maximum value: 10000, default value: 30.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
-# the bottom of the documentation of classes and structs. If set to YES, the
-# list will mention the files that were used to generate the documentation.
-# The default value is: YES.
-
-SHOW_USED_FILES        = YES
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
-# will remove the Files entry from the Quick Index and from the Folder Tree View
-# (if specified).
-# The default value is: YES.
-
-SHOW_FILES             = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
-# page. This will remove the Namespaces entry from the Quick Index and from the
-# Folder Tree View (if specified).
-# The default value is: YES.
-
-SHOW_NAMESPACES        = NO
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command command input-file, where command is the value of the
-# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
-# by doxygen. Whatever the program writes to standard output is used as the file
-# version. For an example see the documentation.
-
-FILE_VERSION_FILTER    =
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. To create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option. You can
-# optionally specify a file name after the option, if omitted DoxygenLayout.xml
-# will be used as the name of the layout file.
-#
-# Note that if you run doxygen from a directory containing a file called
-# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
-# tag is left empty.
-
-LAYOUT_FILE            =
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
-# the reference definitions. This must be a list of .bib files. The .bib
-# extension is automatically appended if omitted. This requires the bibtex tool
-# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
-# For LaTeX the style of the bibliography can be controlled using
-# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
-# search path. See also \cite for info how to create references.
-
-CITE_BIB_FILES         =
-
-#---------------------------------------------------------------------------
-# Configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated to
-# standard output by doxygen. If QUIET is set to YES this implies that the
-# messages are off.
-# The default value is: NO.
-
-QUIET                  = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
-# this implies that the warnings are on.
-#
-# Tip: Turn warnings on while writing the documentation.
-# The default value is: YES.
-
-WARNINGS               = YES
-
-# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
-# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
-# will automatically be disabled.
-# The default value is: YES.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some parameters
-# in a documented function, or documenting parameters that don't exist or using
-# markup commands wrongly.
-# The default value is: YES.
-
-WARN_IF_DOC_ERROR      = YES
-
-# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
-# are documented, but have no documentation for their parameters or return
-# value. If set to NO, doxygen will only warn about wrong or incomplete
-# parameter documentation, but not about the absence of documentation.
-# The default value is: NO.
-
-WARN_NO_PARAMDOC       = YES
-
-# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
-# a warning is encountered.
-# The default value is: NO.
-
-WARN_AS_ERROR          = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that doxygen
-# can produce. The string should contain the $file, $line, and $text tags, which
-# will be replaced by the file and line number from which the warning originated
-# and the warning text. Optionally the format may contain $version, which will
-# be replaced by the version of the file (if it could be obtained via
-# FILE_VERSION_FILTER)
-# The default value is: $file:$line: $text.
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning and error
-# messages should be written. If left blank the output is written to standard
-# error (stderr).
-
-WARN_LOGFILE           = doxygen_warnings.log
-
-#---------------------------------------------------------------------------
-# Configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag is used to specify the files and/or directories that contain
-# documented source files. You may enter file names like myfile.cpp or
-# directories like /usr/src/myproject. Separate the files or directories with
-# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
-# Note: If this tag is empty the current directory is searched.
-
-INPUT                  = ../..
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: https://www.gnu.org/software/libiconv) for the list of
-# possible encodings.
-# The default value is: UTF-8.
-
-INPUT_ENCODING         = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
-# *.h) to filter out the source-files in the directories.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# read by doxygen.
-#
-# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
-# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
-# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
-# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
-# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
-
-FILE_PATTERNS          = *.php \
-                         *.pl
-
-# The RECURSIVE tag can be used to specify whether or not subdirectories should
-# be searched for input files as well.
-# The default value is: NO.
-
-RECURSIVE              = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should be
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-#
-# Note that relative paths are relative to the directory from which doxygen is
-# run.
-
-EXCLUDE                = ../../build \
-                         ../../dev \
-                         ../../doc \
-                         ../../vendor
-
-# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
-# from the input.
-# The default value is: NO.
-
-EXCLUDE_SYMLINKS       = YES
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories for example use the pattern */test/*
-
-EXCLUDE_PATTERNS       =
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories use the pattern */test/*
-
-EXCLUDE_SYMBOLS        =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or directories
-# that contain example code fragments that are included (see the \include
-# command).
-
-EXAMPLE_PATH           =
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
-# *.h) to filter out the source-files in the directories. If left blank all
-# files are included.
-
-EXAMPLE_PATTERNS       = *.php
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude commands
-# irrespective of the value of the RECURSIVE tag.
-# The default value is: NO.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or directories
-# that contain images that are to be included in the documentation (see the
-# \image command).
-
-IMAGE_PATH             = ../../doc/images
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command:
-#
-# <filter> <input-file>
-#
-# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
-# name of an input file. Doxygen will then use the output that the filter
-# program writes to standard output. If FILTER_PATTERNS is specified, this tag
-# will be ignored.
-#
-# Note that the filter must not add or remove lines; it is applied before the
-# code is scanned, but not when the output code is generated. If lines are added
-# or removed, the anchors will not be placed correctly.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-INPUT_FILTER           =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form: pattern=filter
-# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
-# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
-# patterns match the file name, INPUT_FILTER is applied.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-FILTER_PATTERNS        =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will also be used to filter the input files that are used for
-# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
-# The default value is: NO.
-
-FILTER_SOURCE_FILES    = NO
-
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
-# it is also possible to disable source filtering for a specific pattern using
-# *.ext= (so without naming a filter).
-# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
-
-FILTER_SOURCE_PATTERNS =
-
-# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
-# is part of the input, its contents will be placed on the main page
-# (index.html). This can be useful if you have a project on for instance GitHub
-# and want to reuse the introduction page also for the doxygen output.
-
-USE_MDFILE_AS_MAINPAGE =
-
-#---------------------------------------------------------------------------
-# Configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
-# generated. Documented entities will be cross-referenced with these sources.
-#
-# Note: To get rid of all source code in the generated output, make sure that
-# also VERBATIM_HEADERS is set to NO.
-# The default value is: NO.
-
-SOURCE_BROWSER         = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body of functions,
-# classes and enums directly into the documentation.
-# The default value is: NO.
-
-INLINE_SOURCES         = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
-# special comment blocks from generated source code fragments. Normal C, C++ and
-# Fortran comments will always remain visible.
-# The default value is: YES.
-
-STRIP_CODE_COMMENTS    = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
-# function all documented functions referencing it will be listed.
-# The default value is: NO.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES then for each documented function
-# all documented entities called/used by that function will be listed.
-# The default value is: NO.
-
-REFERENCES_RELATION    = YES
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
-# to YES then the hyperlinks from functions in REFERENCES_RELATION and
-# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
-# link to the documentation.
-# The default value is: YES.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
-# source code will show a tooltip with additional information such as prototype,
-# brief description and links to the definition and documentation. Since this
-# will make the HTML file larger and loading of large files a bit slower, you
-# can opt to disable this feature.
-# The default value is: YES.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-SOURCE_TOOLTIPS        = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code will
-# point to the HTML generated by the htags(1) tool instead of doxygen built-in
-# source browser. The htags tool is part of GNU's global source tagging system
-# (see https://www.gnu.org/software/global/global.html). You will need version
-# 4.8.6 or higher.
-#
-# To use it do the following:
-# - Install the latest version of global
-# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
-# - Make sure the INPUT points to the root of the source tree
-# - Run doxygen as normal
-#
-# Doxygen will invoke htags (and that will in turn invoke gtags), so these
-# tools must be available from the command line (i.e. in the search path).
-#
-# The result: instead of the source browser generated by doxygen, the links to
-# source code will now point to the output of htags.
-# The default value is: NO.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-USE_HTAGS              = NO
-
-# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
-# verbatim copy of the header file for each class for which an include is
-# specified. Set to NO to disable this.
-# See also: Section \class.
-# The default value is: YES.
-
-VERBATIM_HEADERS       = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
-# compounds will be generated. Enable this if the project contains a lot of
-# classes, structs, unions or interfaces.
-# The default value is: YES.
-
-ALPHABETICAL_INDEX     = YES
-
-# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
-# which the alphabetical index list will be split.
-# Minimum value: 1, maximum value: 20, default value: 5.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all classes will
-# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
-# can be used to specify a prefix (or a list of prefixes) that should be ignored
-# while generating the index headers.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-IGNORE_PREFIX          =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
-# The default value is: YES.
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_OUTPUT            = ./
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
-# generated HTML page (for example: .htm, .php, .asp).
-# The default value is: .html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FILE_EXTENSION    = .html
-
-# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
-# each generated HTML page. If the tag is left blank doxygen will generate a
-# standard header.
-#
-# To get valid HTML the header file that includes any scripts and style sheets
-# that doxygen needs, which is dependent on the configuration options used (e.g.
-# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
-# default header using
-# doxygen -w html new_header.html new_footer.html new_stylesheet.css
-# YourConfigFile
-# and then modify the file new_header.html. See also section "Doxygen usage"
-# for information on how to generate the default header that doxygen normally
-# uses.
-# Note: The header is subject to change so you typically have to regenerate the
-# default header when upgrading to a newer version of doxygen. For a description
-# of the possible markers and block names see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_HEADER            =
-
-# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
-# generated HTML page. If the tag is left blank doxygen will generate a standard
-# footer. See HTML_HEADER for more information on how to generate a default
-# footer and what special commands can be used inside the footer. See also
-# section "Doxygen usage" for information on how to generate the default footer
-# that doxygen normally uses.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FOOTER            =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
-# sheet that is used by each HTML page. It can be used to fine-tune the look of
-# the HTML output. If left blank doxygen will generate a default style sheet.
-# See also section "Doxygen usage" for information on how to generate the style
-# sheet that doxygen normally uses.
-# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
-# it is more robust and this tag (HTML_STYLESHEET) will in the future become
-# obsolete.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_STYLESHEET        =
-
-# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# cascading style sheets that are included after the standard style sheets
-# created by doxygen. Using this option one can overrule certain style aspects.
-# This is preferred over using HTML_STYLESHEET since it does not replace the
-# standard style sheet and is therefore more robust against future updates.
-# Doxygen will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list). For an example see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_STYLESHEET  =
-
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the HTML output directory. Note
-# that these files will be copied to the base HTML output directory. Use the
-# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
-# files will be copied as-is; there are no commands or markers available.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_FILES       =
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
-# will adjust the colors in the style sheet and background images according to
-# this color. Hue is specified as an angle on a colorwheel, see
-# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
-# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
-# purple, and 360 is red again.
-# Minimum value: 0, maximum value: 359, default value: 220.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_HUE    = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
-# in the HTML output. For a value of 0 the output will use grayscales only. A
-# value of 255 will produce the most vivid colors.
-# Minimum value: 0, maximum value: 255, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_SAT    = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
-# luminance component of the colors in the HTML output. Values below 100
-# gradually make the output lighter, whereas values above 100 make the output
-# darker. The value divided by 100 is the actual gamma applied, so 80 represents
-# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
-# change the gamma.
-# Minimum value: 40, maximum value: 240, default value: 80.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_GAMMA  = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting this
-# to YES can help to show when doxygen was last run and thus if the
-# documentation is up to date.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_TIMESTAMP         = YES
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_DYNAMIC_SECTIONS  = YES
-
-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
-# shown in the various tree structured indices initially; the user can expand
-# and collapse entries dynamically later on. Doxygen will expand the tree to
-# such a level that at most the specified number of entries are visible (unless
-# a fully collapsed tree already exceeds this amount). So setting the number of
-# entries 1 will produce a full collapsed tree by default. 0 is a special value
-# representing an infinite number of entries and will result in a full expanded
-# tree by default.
-# Minimum value: 0, maximum value: 9999, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_INDEX_NUM_ENTRIES = 100
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files will be
-# generated that can be used as input for Apple's Xcode 3 integrated development
-# environment (see: http://developer.apple.com/tools/xcode/), introduced with
-# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
-# Makefile in the HTML output directory. Running make will produce the docset in
-# that directory and running make install will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
-# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_DOCSET        = NO
-
-# This tag determines the name of the docset feed. A documentation feed provides
-# an umbrella under which multiple documentation sets from a single provider
-# (such as a company or product suite) can be grouped.
-# The default value is: Doxygen generated docs.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_FEEDNAME        = "Doxygen generated docs"
-
-# This tag specifies a string that should uniquely identify the documentation
-# set bundle. This should be a reverse domain-name style string, e.g.
-# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_BUNDLE_ID       = org.doxygen.Project
-
-# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-# The default value is: org.doxygen.Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_ID    = org.dolibarr.doc
-
-# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
-# The default value is: Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_NAME  = Dolibarrteam
-
-# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
-# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
-# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
-# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
-# Windows.
-#
-# The HTML Help Workshop contains a compiler that can convert all HTML output
-# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
-# files are now used as the Windows 98 help format, and will replace the old
-# Windows help format (.hlp) on all Windows platforms in the future. Compressed
-# HTML files also contain an index, a table of contents, and you can search for
-# words in the documentation. The HTML workshop also contains a viewer for
-# compressed HTML files.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_HTMLHELP      = NO
-
-# The CHM_FILE tag can be used to specify the file name of the resulting .chm
-# file. You can add a path in front of the file if the result should not be
-# written to the html output directory.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_FILE               =
-
-# The HHC_LOCATION tag can be used to specify the location (absolute path
-# including file name) of the HTML help compiler (hhc.exe). If non-empty,
-# doxygen will try to run the HTML help compiler on the generated index.hhp.
-# The file has to be specified with full path.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-HHC_LOCATION           =
-
-# The GENERATE_CHI flag controls if a separate .chi index file is generated
-# (YES) or that it should be included in the master .chm file (NO).
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-GENERATE_CHI           = NO
-
-# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
-# and project file content.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_INDEX_ENCODING     =
-
-# The BINARY_TOC flag controls whether a binary table of contents is generated
-# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
-# enables the Previous and Next buttons.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members to
-# the table of contents of the HTML help documentation and to the tree view.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-TOC_EXPAND             = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
-# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
-# (.qch) of the generated HTML documentation.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_QHP           = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
-# the file name of the resulting .qch file. The path specified is relative to
-# the HTML output folder.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QCH_FILE               =
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
-# Project output. For more information please see Qt Help Project / Namespace
-# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_NAMESPACE          = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
-# Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
-# folders).
-# The default value is: doc.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_VIRTUAL_FOLDER     = doc
-
-# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
-# filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_NAME   =
-
-# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_ATTRS  =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_SECT_FILTER_ATTRS  =
-
-# The QHG_LOCATION tag can be used to specify the location of Qt's
-# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
-# generated .qhp file.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHG_LOCATION           =
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
-# generated, together with the HTML files, they form an Eclipse help plugin. To
-# install this plugin and make it available under the help contents menu in
-# Eclipse, the contents of the directory containing the HTML and XML files needs
-# to be copied into the plugins directory of eclipse. The name of the directory
-# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
-# After copying Eclipse needs to be restarted before the help appears.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_ECLIPSEHELP   = YES
-
-# A unique identifier for the Eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have this
-# name. Each documentation set should have its own identifier.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
-
-ECLIPSE_DOC_ID         = org.doxygen.Project
-
-# If you want full control over the layout of the generated HTML pages it might
-# be necessary to disable the index and replace it with your own. The
-# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
-# of each HTML page. A value of NO enables the index and the value YES disables
-# it. Since the tabs in the index contain the same information as the navigation
-# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-DISABLE_INDEX          = NO
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information. If the tag
-# value is set to YES, a side panel will be generated containing a tree-like
-# index structure (just like the one that is generated for HTML Help). For this
-# to work a browser that supports JavaScript, DHTML, CSS and frames is required
-# (i.e. any modern browser). Windows users are probably better off using the
-# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
-# further fine-tune the look of the index. As an example, the default style
-# sheet generated by doxygen has an example that shows how to put an image at
-# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
-# the same information as the tab index, you could consider setting
-# DISABLE_INDEX to YES when enabling this option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_TREEVIEW      = NO
-
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
-# doxygen will group on one line in the generated HTML documentation.
-#
-# Note that a value of 0 will completely suppress the enum values from appearing
-# in the overview section.
-# Minimum value: 0, maximum value: 20, default value: 4.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-ENUM_VALUES_PER_LINE   = 4
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
-# to set the initial width (in pixels) of the frame in which the tree is shown.
-# Minimum value: 0, maximum value: 1500, default value: 250.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-TREEVIEW_WIDTH         = 250
-
-# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
-# external symbols imported via tag files in a separate window.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-EXT_LINKS_IN_WINDOW    = NO
-
-# Use this tag to change the font size of LaTeX formulas included as images in
-# the HTML documentation. When you change the font size after a successful
-# doxygen run you need to manually remove any form_*.png images from the HTML
-# output directory to force them to be regenerated.
-# Minimum value: 8, maximum value: 50, default value: 10.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_FONTSIZE       = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are not
-# supported properly for IE 6.0, but are supported on all modern browsers.
-#
-# Note that when changing this option you need to delete any form_*.png files in
-# the HTML output directory before the changes have effect.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_TRANSPARENT    = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# http://www.mathjax.org) which uses client side Javascript for the rendering
-# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
-# installed or if you want to formulas look prettier in the HTML output. When
-# enabled you may also need to install MathJax separately and configure the path
-# to it using the MATHJAX_RELPATH option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-USE_MATHJAX            = NO
-
-# When MathJax is enabled you can set the default output format to be used for
-# the MathJax output. See the MathJax site (see:
-# http://docs.mathjax.org/en/latest/output.html) for more details.
-# Possible values are: HTML-CSS (which is slower, but has the best
-# compatibility), NativeMML (i.e. MathML) and SVG.
-# The default value is: HTML-CSS.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_FORMAT         = HTML-CSS
-
-# When MathJax is enabled you need to specify the location relative to the HTML
-# output directory using the MATHJAX_RELPATH option. The destination directory
-# should contain the MathJax.js script. For instance, if the mathjax directory
-# is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
-# Content Delivery Network so you can quickly see the result without installing
-# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from http://www.mathjax.org before deployment.
-# The default value is: http://cdn.mathjax.org/mathjax/latest.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
-# extension names that should be enabled during MathJax rendering. For example
-# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_EXTENSIONS     =
-
-# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
-# of code that will be used on startup of the MathJax code. See the MathJax site
-# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
-# example see the documentation.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_CODEFILE       =
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
-# the HTML output. The underlying search engine uses javascript and DHTML and
-# should work on any modern browser. Note that when using HTML help
-# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
-# there is already a search function so this one should typically be disabled.
-# For large projects the javascript based search engine can be slow, then
-# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
-# search using the keyboard; to jump to the search box use <access key> + S
-# (what the <access key> is depends on the OS and browser, but it is typically
-# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
-# key> to jump into the search results window, the results can be navigated
-# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
-# the search. The filter options can be selected when the cursor is inside the
-# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
-# to select a filter and <Enter> or <escape> to activate or cancel the filter
-# option.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-SEARCHENGINE           = NO
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a web server instead of a web client using Javascript. There
-# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
-# setting. When disabled, doxygen will generate a PHP script for searching and
-# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
-# and searching needs to be provided by external tools. See the section
-# "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SERVER_BASED_SEARCH    = NO
-
-# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
-# script for searching. Instead the search results are written to an XML file
-# which needs to be processed by an external indexer. Doxygen will invoke an
-# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
-# search results.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/).
-#
-# See the section "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH        = NO
-
-# The SEARCHENGINE_URL should point to a search engine hostedc by a web server
-# which will return the search results when EXTERNAL_SEARCH is enabled.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/). See the section "External Indexing and
-# Searching" for details.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHENGINE_URL       =
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
-# search data is written to a file for indexing by an external tool. With the
-# SEARCHDATA_FILE tag the name of this file can be specified.
-# The default file is: searchdata.xml.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHDATA_FILE        = searchdata.xml
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
-# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
-# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
-# projects and redirect the results back to the right project.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH_ID     =
-
-# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
-# projects other than the one defined by this configuration file, but that are
-# all added to the same external search index. Each project needs to have a
-# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
-# to a relative location where the documentation can be found. The format is:
-# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTRA_SEARCH_MAPPINGS  =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
-# The default value is: YES.
-
-GENERATE_LATEX         = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_OUTPUT           = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked.
-#
-# Note that when enabling USE_PDFLATEX this option is only used for generating
-# bitmaps for formulas in the HTML output, but not in the Makefile that is
-# written to the output directory.
-# The default file is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_CMD_NAME         = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
-# index for LaTeX.
-# The default file is: makeindex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-MAKEINDEX_CMD_NAME     = makeindex
-
-# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used by the
-# printer.
-# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
-# 14 inches) and executive (7.25 x 10.5 inches).
-# The default value is: a4.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PAPER_TYPE             = a4
-
-# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
-# that should be included in the LaTeX output. The package can be specified just
-# by its name or with the correct syntax as to be used with the LaTeX
-# \usepackage command. To get the times font for instance you can specify :
-# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
-# To use the option intlimits with the amsmath package you can specify:
-# EXTRA_PACKAGES=[intlimits]{amsmath}
-# If left blank no extra packages will be included.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-EXTRA_PACKAGES         =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
-# generated LaTeX document. The header should contain everything until the first
-# chapter. If it is left blank doxygen will generate a standard header. See
-# section "Doxygen usage" for information on how to let doxygen write the
-# default header to a separate file.
-#
-# Note: Only use a user-defined header if you know what you are doing! The
-# following commands have a special meaning inside the header: $title,
-# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
-# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
-# string, for the replacement values of the other commands the user is referred
-# to HTML_HEADER.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HEADER           =
-
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
-# generated LaTeX document. The footer should contain everything after the last
-# chapter. If it is left blank doxygen will generate a standard footer. See
-# LATEX_HEADER for more information on how to generate a default footer and what
-# special commands can be used inside the footer.
-#
-# Note: Only use a user-defined footer if you know what you are doing!
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_FOOTER           =
-
-# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# LaTeX style sheets that are included after the standard style sheets created
-# by doxygen. Using this option one can overrule certain style aspects. Doxygen
-# will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list).
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_STYLESHEET =
-
-# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the LATEX_OUTPUT output
-# directory. Note that the files will be copied as-is; there are no commands or
-# markers available.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_FILES      =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
-# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
-# contain links (just like the HTML output) instead of page references. This
-# makes the output suitable for online browsing using a PDF viewer.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PDF_HYPERLINKS         = YES
-
-# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
-# the PDF file directly from the LaTeX files. Set this option to YES, to get a
-# higher quality PDF documentation.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-USE_PDFLATEX           = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
-# command to the generated LaTeX files. This will instruct LaTeX to keep running
-# if errors occur, instead of asking the user for help. This option is also used
-# when generating formulas in HTML.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BATCHMODE        = NO
-
-# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
-# index chapters (such as File Index, Compound Index, etc.) in the output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HIDE_INDICES     = NO
-
-# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
-# code with syntax highlighting in the LaTeX output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_SOURCE_CODE      = NO
-
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
-# bibliography, e.g. plainnat, or ieeetr. See
-# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
-# The default value is: plain.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BIB_STYLE        = plain
-
-# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
-# page will contain the date and time when the page was generated. Setting this
-# to NO can help when comparing the output of multiple runs.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_TIMESTAMP        = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
-# RTF output is optimized for Word 97 and may not look too pretty with other RTF
-# readers/editors.
-# The default value is: NO.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: rtf.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
-# contain hyperlink fields. The RTF file will contain links (just like the HTML
-# output) instead of page references. This makes the output suitable for online
-# browsing using Word or some other Word compatible readers that support those
-# fields.
-#
-# Note: WordPad (write) and others do not support links.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's config
-# file, i.e. a series of assignments. You only have to provide replacements,
-# missing definitions are set to their default value.
-#
-# See also section "Doxygen usage" for information on how to generate the
-# default style sheet that doxygen normally uses.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_STYLESHEET_FILE    =
-
-# Set optional variables used in the generation of an RTF document. Syntax is
-# similar to doxygen's config file. A template extensions file can be generated
-# using doxygen -e rtf extensionFile.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_EXTENSIONS_FILE    =
-
-# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
-# with syntax highlighting in the RTF output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_SOURCE_CODE        = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
-# classes and files.
-# The default value is: NO.
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it. A directory man3 will be created inside the directory specified by
-# MAN_OUTPUT.
-# The default directory is: man.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to the generated
-# man pages. In case the manual section does not start with a number, the number
-# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
-# optional.
-# The default value is: .3.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_EXTENSION          = .3
-
-# The MAN_SUBDIR tag determines the name of the directory created within
-# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
-# MAN_EXTENSION with the initial . removed.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_SUBDIR             =
-
-# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
-# will generate one additional man file for each entity documented in the real
-# man page(s). These additional files only source the real man page, but without
-# them the man command would be unable to find the correct page.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
-# captures the structure of the code including all documentation.
-# The default value is: NO.
-
-GENERATE_XML           = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: xml.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_OUTPUT             = xml
-
-# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
-# listings (including syntax highlighting and cross-referencing information) to
-# the XML output. Note that enabling this will significantly increase the size
-# of the XML output.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_PROGRAMLISTING     = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to the DOCBOOK output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
-# that can be used to generate PDF.
-# The default value is: NO.
-
-GENERATE_DOCBOOK       = NO
-
-# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
-# front of it.
-# The default directory is: docbook.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_OUTPUT         = docbook
-
-# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
-# program listings (including syntax highlighting and cross-referencing
-# information) to the DOCBOOK output. Note that enabling this will significantly
-# increase the size of the DOCBOOK output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_PROGRAMLISTING = NO
-
-#---------------------------------------------------------------------------
-# Configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
-# AutoGen Definitions (see http://autogen.sf.net) file that captures the
-# structure of the code including all documentation. Note that this feature is
-# still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
-# file that captures the structure of the code including all documentation.
-#
-# Note that this feature is still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_PERLMOD       = NO
-
-# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
-# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
-# output from the Perl module output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_LATEX          = NO
-
-# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
-# formatted so it can be parsed by a human reader. This is useful if you want to
-# understand what is going on. On the other hand, if this tag is set to NO, the
-# size of the Perl module output will be much smaller and Perl will parse it
-# just the same.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_PRETTY         = YES
-
-# The names of the make variables in the generated doxyrules.make file are
-# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
-# so different doxyrules.make files included by the same Makefile don't
-# overwrite each other's variables.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
-# C-preprocessor directives found in the sources and include files.
-# The default value is: YES.
-
-ENABLE_PREPROCESSING   = NO
-
-# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
-# in the source code. If set to NO, only conditional compilation will be
-# performed. Macro expansion can be done in a controlled way by setting
-# EXPAND_ONLY_PREDEF to YES.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-MACRO_EXPANSION        = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
-# the macro expansion is limited to the macros specified with the PREDEFINED and
-# EXPAND_AS_DEFINED tags.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_ONLY_PREDEF     = YES
-
-# If the SEARCH_INCLUDES tag is set to YES, the include files in the
-# INCLUDE_PATH will be searched if a #include is found.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by the
-# preprocessor.
-# This tag requires that the tag SEARCH_INCLUDES is set to YES.
-
-INCLUDE_PATH           =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will be
-# used.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-INCLUDE_FILE_PATTERNS  =
-
-# The PREDEFINED tag can be used to specify one or more macro names that are
-# defined before the preprocessor is started (similar to the -D option of e.g.
-# gcc). The argument of the tag is a list of macros of the form: name or
-# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
-# is assumed. To prevent a macro definition from being undefined via #undef or
-# recursively expanded use the := operator instead of the = operator.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-PREDEFINED             =
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
-# tag can be used to specify a list of macro names that should be expanded. The
-# macro definition that is found in the sources will be used. Use the PREDEFINED
-# tag if you want to use a different macro definition that overrules the
-# definition found in the source code.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_AS_DEFINED      =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
-# remove all references to function-like macros that are alone on a line, have
-# an all uppercase name, and do not end with a semicolon. Such function macros
-# are typically used for boiler-plate code, and will confuse the parser if not
-# removed.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tag files. For each tag
-# file the location of the external documentation should be added. The format of
-# a tag file without this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where loc1 and loc2 can be relative or absolute paths or URLs. See the
-# section "Linking to external documentation" for more information about the use
-# of tag files.
-# Note: Each tag file must have a unique name (where the name does NOT include
-# the path). If a tag file is not located in the directory in which doxygen is
-# run, you must also specify the path to the tagfile here.
-
-TAGFILES               =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
-# tag file that is based on the input files it reads. See section "Linking to
-# external documentation" for more information about the usage of tag files.
-
-GENERATE_TAGFILE       =
-
-# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
-# the class index. If set to NO, only the inherited external classes will be
-# listed.
-# The default value is: NO.
-
-ALLEXTERNALS           = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will be
-# listed.
-# The default value is: YES.
-
-EXTERNAL_GROUPS        = YES
-
-# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
-# the related pages index. If set to NO, only the current project's pages will
-# be listed.
-# The default value is: YES.
-
-EXTERNAL_PAGES         = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of 'which perl').
-# The default file (with absolute path) is: /usr/bin/perl.
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
-# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
-# NO turns the diagrams off. Note that this option also works with HAVE_DOT
-# disabled, but it is recommended to install and use dot, since it yields more
-# powerful graphs.
-# The default value is: YES.
-
-CLASS_DIAGRAMS         = NO
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see:
-# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH            =
-
-# You can include diagrams made with dia in doxygen documentation. Doxygen will
-# then run dia to produce the diagram and insert it in the documentation. The
-# DIA_PATH tag allows you to specify the directory where the dia binary resides.
-# If left empty dia is assumed to be found in the default search path.
-
-DIA_PATH               =
-
-# If set to YES the inheritance and collaboration graphs will hide inheritance
-# and usage relations if the target is undocumented or is not a class.
-# The default value is: YES.
-
-HIDE_UNDOC_RELATIONS   = NO
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz (see:
-# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
-# Bell Labs. The other options in this section have no effect if this option is
-# set to NO
-# The default value is: NO.
-
-HAVE_DOT               = YES
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
-# to run in parallel. When set to 0 doxygen will base this on the number of
-# processors available in the system. You can set it explicitly to a value
-# larger than 0 to get control over the balance between CPU load and processing
-# speed.
-# Minimum value: 0, maximum value: 32, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_NUM_THREADS        = 0
-
-# When you want a differently looking font in the dot files that doxygen
-# generates you can specify the font name using DOT_FONTNAME. You need to make
-# sure dot is able to find the font, which can be done by putting it in a
-# standard location or by setting the DOTFONTPATH environment variable or by
-# setting DOT_FONTPATH to the directory containing the font.
-# The default value is: Helvetica.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTNAME           = FreeSans.ttf
-
-# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
-# dot graphs.
-# Minimum value: 4, maximum value: 24, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTSIZE           = 10
-
-# By default doxygen will tell dot to use the default font as specified with
-# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
-# the path where dot can find it using this tag.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTPATH           =
-
-# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
-# each documented class showing the direct and indirect inheritance relations.
-# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
-# graph for each documented class showing the direct and indirect implementation
-# dependencies (inheritance, containment, and class references variables) of the
-# class with other documented classes.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-COLLABORATION_GRAPH    = YES
-
-# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
-# groups, showing the direct groups dependencies.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GROUP_GRAPHS           = NO
-
-# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LOOK               = NO
-
-# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
-# class node. If there are many fields or methods and many nodes the graph may
-# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
-# number of items for each type to make the size more manageable. Set this to 0
-# for no limit. Note that the threshold may be exceeded by 50% before the limit
-# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
-# but if the number exceeds 15, the total amount of fields shown is limited to
-# 10.
-# Minimum value: 0, maximum value: 100, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LIMIT_NUM_FIELDS   = 10
-
-# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
-# collaboration graphs will show the relations between templates and their
-# instances.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-TEMPLATE_RELATIONS     = NO
-
-# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
-# YES then doxygen will generate a graph for each documented file showing the
-# direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDE_GRAPH          = YES
-
-# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
-# set to YES then doxygen will generate a graph for each documented file showing
-# the direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command. Disabling a call graph can be
-# accomplished by means of the command \hidecallgraph.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALL_GRAPH             = NO
-
-# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command. Disabling a caller graph can be
-# accomplished by means of the command \hidecallergraph.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALLER_GRAPH           = NO
-
-# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
-# hierarchy of all classes instead of a textual one.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GRAPHICAL_HIERARCHY    = YES
-
-# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
-# dependencies a directory has on other directories in a graphical way. The
-# dependency relations are determined by the #include relations between the
-# files in the directories.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DIRECTORY_GRAPH        = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. For an explanation of the image formats see the section
-# output formats in the documentation of the dot tool (Graphviz (see:
-# http://www.graphviz.org/)).
-# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
-# to make the SVG files visible in IE 9+ (other browsers do not have this
-# requirement).
-# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
-# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
-# png:gdiplus:gdiplus.
-# The default value is: png.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_IMAGE_FORMAT       = svg
-
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
-# enable generation of interactive SVG images that allow zooming and panning.
-#
-# Note that this requires a modern browser other than Internet Explorer. Tested
-# and working are Firefox, Chrome, Safari, and Opera.
-# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
-# the SVG files visible. Older versions of IE do not have SVG support.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INTERACTIVE_SVG        = YES
-
-# The DOT_PATH tag can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_PATH               =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the \dotfile
-# command).
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOTFILE_DIRS           =
-
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the \mscfile
-# command).
-
-MSCFILE_DIRS           =
-
-# The DIAFILE_DIRS tag can be used to specify one or more directories that
-# contain dia files that are included in the documentation (see the \diafile
-# command).
-
-DIAFILE_DIRS           =
-
-# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
-# path where java can find the plantuml.jar file. If left blank, it is assumed
-# PlantUML is not used or called during a preprocessing step. Doxygen will
-# generate a warning when it encounters a \startuml command in this case and
-# will not generate output for the diagram.
-
-PLANTUML_JAR_PATH      =
-
-# When using plantuml, the specified paths are searched for files specified by
-# the !include statement in a plantuml block.
-
-PLANTUML_INCLUDE_PATH  =
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
-# that will be shown in the graph. If the number of nodes in a graph becomes
-# larger than this value, doxygen will truncate the graph, which is visualized
-# by representing a node as a red box. Note that doxygen if the number of direct
-# children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
-# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-# Minimum value: 0, maximum value: 10000, default value: 50.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_GRAPH_MAX_NODES    = 1024
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
-# generated by dot. A depth value of 3 means that only nodes reachable from the
-# root by following a path via at most 3 edges will be shown. Nodes that lay
-# further from the root node will be omitted. Note that setting this option to 1
-# or 2 may greatly reduce the computation time needed for large code bases. Also
-# note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-# Minimum value: 0, maximum value: 1000, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-MAX_DOT_GRAPH_DEPTH    = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not seem
-# to support this out of the box.
-#
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_TRANSPARENT        = YES
-
-# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10) support
-# this, this feature is disabled by default.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_MULTI_TARGETS      = NO
-
-# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
-# explaining the meaning of the various boxes and arrows in the dot generated
-# graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
-# files that are used to generate the various graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_CLEANUP            = YES
diff --git a/htdocs/modulebuilder/template/build/makepack-mymodule.conf b/htdocs/modulebuilder/template/build/makepack-mymodule.conf
deleted file mode 100644 (file)
index 16dc1e7..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# Your module name here
-#
-# Goal:    Goal of module
-# Version: <version>
-# Author:  Copyright <year> - <name of author>
-# License: GPLv3
-# Install: Just unpack content of module package in Dolibarr directory.
-# Setup:   Go on Dolibarr setup - modules to enable module.
-#
-# Files in module
-mymodule/
\ No newline at end of file
diff --git a/htdocs/modulebuilder/template/class/actions_mymodule.class.php b/htdocs/modulebuilder/template/class/actions_mymodule.class.php
deleted file mode 100644 (file)
index 25e440d..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-<?php
-/* Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    htdocs/modulebuilder/template/class/actions_mymodule.class.php
- * \ingroup mymodule
- * \brief   Example hook overload.
- *
- * Put detailed description here.
- */
-
-/**
- * Class ActionsMyModule
- */
-class ActionsMyModule
-{
-       /**
-        * @var DoliDB Database handler.
-        */
-       public $db;
-
-       /**
-        * @var string Error code (or message)
-        */
-       public $error = '';
-
-       /**
-        * @var array Errors
-        */
-       public $errors = array();
-
-
-       /**
-        * @var array Hook results. Propagated to $hookmanager->resArray for later reuse
-        */
-       public $results = array();
-
-       /**
-        * @var string String displayed by executeHook() immediately after return
-        */
-       public $resprints;
-
-       /**
-        * @var int             Priority of hook (50 is used if value is not defined)
-        */
-       public $priority;
-
-
-       /**
-        * Constructor
-        *
-        *  @param              DoliDB          $db      Database handler
-        */
-       public function __construct($db)
-       {
-               $this->db = $db;
-       }
-
-
-       /**
-        * Execute action
-        *
-        * @param       array                   $parameters             Array of parameters
-        * @param       CommonObject    $object         The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
-        * @param       string                  $action         'add', 'update', 'view'
-        * @return      int                                             <0 if KO,
-        *                                                      =0 if OK but we want to process standard actions too,
-        *                                                      >0 if OK and we want to replace standard actions.
-        */
-       public function getNomUrl($parameters, &$object, &$action)
-       {
-               global $db, $langs, $conf, $user;
-               $this->resprints = '';
-               return 0;
-       }
-
-       /**
-        * Overloading the doActions function : replacing the parent's function with the one below
-        *
-        * @param   array           $parameters     Hook metadatas (context, etc...)
-        * @param   CommonObject    $object         The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
-        * @param   string          $action         Current action (if set). Generally create or edit or null
-        * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
-        * @return  int                             < 0 on error, 0 on success, 1 to replace standard code
-        */
-       public function doActions($parameters, &$object, &$action, $hookmanager)
-       {
-               global $conf, $user, $langs;
-
-               $error = 0; // Error counter
-
-               /* 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.
-               }
-
-               if (!$error) {
-                       $this->results = array('myreturn' => 999);
-                       $this->resprints = 'A text to show';
-                       return 0; // or return 1 to replace standard code
-               } else {
-                       $this->errors[] = 'Error message';
-                       return -1;
-               }
-       }
-
-
-       /**
-        * Overloading the doMassActions function : replacing the parent's function with the one below
-        *
-        * @param   array           $parameters     Hook metadatas (context, etc...)
-        * @param   CommonObject    $object         The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
-        * @param   string          $action         Current action (if set). Generally create or edit or null
-        * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
-        * @return  int                             < 0 on error, 0 on success, 1 to replace standard code
-        */
-       public function doMassActions($parameters, &$object, &$action, $hookmanager)
-       {
-               global $conf, $user, $langs;
-
-               $error = 0; // Error counter
-
-               /* 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'
-                       foreach ($parameters['toselect'] as $objectid) {
-                               // Do action on each object id
-                       }
-               }
-
-               if (!$error) {
-                       $this->results = array('myreturn' => 999);
-                       $this->resprints = 'A text to show';
-                       return 0; // or return 1 to replace standard code
-               } else {
-                       $this->errors[] = 'Error message';
-                       return -1;
-               }
-       }
-
-
-       /**
-        * Overloading the addMoreMassActions function : replacing the parent's function with the one below
-        *
-        * @param   array           $parameters     Hook metadatas (context, etc...)
-        * @param   CommonObject    $object         The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
-        * @param   string          $action         Current action (if set). Generally create or edit or null
-        * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
-        * @return  int                             < 0 on error, 0 on success, 1 to replace standard code
-        */
-       public function addMoreMassActions($parameters, &$object, &$action, $hookmanager)
-       {
-               global $conf, $user, $langs;
-
-               $error = 0; // Error counter
-               $disabled = 1;
-
-               /* 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'
-                       $this->resprints = '<option value="0"'.($disabled ? ' disabled="disabled"' : '').'>'.$langs->trans("MyModuleMassAction").'</option>';
-               }
-
-               if (!$error) {
-                       return 0; // or return 1 to replace standard code
-               } else {
-                       $this->errors[] = 'Error message';
-                       return -1;
-               }
-       }
-
-
-
-       /**
-        * Execute action
-        *
-        * @param       array   $parameters     Array of parameters
-        * @param   Object      $object                 Object output on PDF
-        * @param   string      $action         'add', 'update', 'view'
-        * @return  int                                 <0 if KO,
-        *                                      =0 if OK but we want to process standard actions too,
-        *                                  >0 if OK and we want to replace standard actions.
-        */
-       public function beforePDFCreation($parameters, &$object, &$action)
-       {
-               global $conf, $user, $langs;
-               global $hookmanager;
-
-               $outputlangs = $langs;
-
-               $ret = 0; $deltemp = array();
-               dol_syslog(get_class($this).'::executeHooks action='.$action);
-
-               /* 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'
-               }
-
-               return $ret;
-       }
-
-       /**
-        * Execute action
-        *
-        * @param       array   $parameters     Array of parameters
-        * @param   Object      $pdfhandler     PDF builder handler
-        * @param   string      $action         'add', 'update', 'view'
-        * @return  int                             <0 if KO,
-        *                                  =0 if OK but we want to process standard actions too,
-        *                                  >0 if OK and we want to replace standard actions.
-        */
-       public function afterPDFCreation($parameters, &$pdfhandler, &$action)
-       {
-               global $conf, $user, $langs;
-               global $hookmanager;
-
-               $outputlangs = $langs;
-
-               $ret = 0; $deltemp = array();
-               dol_syslog(get_class($this).'::executeHooks action='.$action);
-
-               /* 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'
-               }
-
-               return $ret;
-       }
-
-
-
-       /**
-        * Overloading the loadDataForCustomReports function : returns data to complete the customreport tool
-        *
-        * @param   array           $parameters     Hook metadatas (context, etc...)
-        * @param   string          $action         Current action (if set). Generally create or edit or null
-        * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
-        * @return  int                             < 0 on error, 0 on success, 1 to replace standard code
-        */
-       public function loadDataForCustomReports($parameters, &$action, $hookmanager)
-       {
-               global $conf, $user, $langs;
-
-               $langs->load("mymodule@mymodule");
-
-               $this->results = array();
-
-               $head = array();
-               $h = 0;
-
-               if ($parameters['tabfamily'] == 'mymodule') {
-                       $head[$h][0] = dol_buildpath('/module/index.php', 1);
-                       $head[$h][1] = $langs->trans("Home");
-                       $head[$h][2] = 'home';
-                       $h++;
-
-                       $this->results['title'] = $langs->trans("MyModule");
-                       $this->results['picto'] = 'mymodule@mymodule';
-               }
-
-               $head[$h][0] = 'customreports.php?objecttype='.$parameters['objecttype'].(empty($parameters['tabfamily']) ? '' : '&tabfamily='.$parameters['tabfamily']);
-               $head[$h][1] = $langs->trans("CustomReports");
-               $head[$h][2] = 'customreports';
-
-               $this->results['head'] = $head;
-
-               return 1;
-       }
-
-
-
-       /**
-        * Overloading the restrictedArea function : check permission on an object
-        *
-        * @param   array           $parameters     Hook metadatas (context, etc...)
-        * @param   string          $action         Current action (if set). Generally create or edit or null
-        * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
-        * @return  int                                                 <0 if KO,
-        *                                                      =0 if OK but we want to process standard actions too,
-        *                                              >0 if OK and we want to replace standard actions.
-        */
-       public function restrictedArea($parameters, &$action, $hookmanager)
-       {
-               global $user;
-
-               if ($parameters['features'] == 'myobject') {
-                       if ($user->rights->mymodule->myobject->read) {
-                               $this->results['result'] = 1;
-                               return 1;
-                       } else {
-                               $this->results['result'] = 0;
-                               return 1;
-                       }
-               }
-
-               return 0;
-       }
-
-       /**
-        * Execute action completeTabsHead
-        *
-        * @param   array           $parameters     Array of parameters
-        * @param   CommonObject    $object         The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
-        * @param   string          $action         'add', 'update', 'view'
-        * @param   Hookmanager     $hookmanager    hookmanager
-        * @return  int                             <0 if KO,
-        *                                          =0 if OK but we want to process standard actions too,
-        *                                          >0 if OK and we want to replace standard actions.
-        */
-       public function completeTabsHead(&$parameters, &$object, &$action, $hookmanager)
-       {
-               global $langs, $conf, $user;
-
-               if (!isset($parameters['object']->element)) {
-                       return 0;
-               }
-               if ($parameters['mode'] == 'remove') {
-                       // utilisé si on veut faire disparaitre des onglets.
-                       return 0;
-               } elseif ($parameters['mode'] == 'add') {
-                       $langs->load('mymodule@mymodule');
-                       // utilisé si on veut ajouter des onglets.
-                       $counter = count($parameters['head']);
-                       $element = $parameters['object']->element;
-                       $id = $parameters['object']->id;
-                       // verifier le type d'onglet comme member_stats où Ã§a ne doit pas apparaitre
-                       // if (in_array($element, ['societe', 'member', 'contrat', 'fichinter', 'project', 'propal', 'commande', 'facture', 'order_supplier', 'invoice_supplier'])) {
-                       if (in_array($element, ['context1', 'context2'])) {
-                               $datacount = 0;
-
-                               $parameters['head'][$counter][0] = dol_buildpath('/mymodule/mymodule_tab.php', 1) . '?id=' . $id . '&amp;module='.$element;
-                               $parameters['head'][$counter][1] = $langs->trans('MyModuleTab');
-                               if ($datacount > 0) {
-                                       $parameters['head'][$counter][1] .= '<span class="badge marginleftonlyshort">' . $datacount . '</span>';
-                               }
-                               $parameters['head'][$counter][2] = 'mymoduleemails';
-                               $counter++;
-                       }
-                       if ($counter > 0 && (int) DOL_VERSION < 14) {
-                               $this->results = $parameters['head'];
-                               // return 1 to replace standard code
-                               return 1;
-                       } else {
-                               // en V14 et + $parameters['head'] est modifiable par référence
-                               return 0;
-                       }
-               }
-       }
-
-       /* Add here any other hooked methods... */
-}
diff --git a/htdocs/modulebuilder/template/class/api_mymodule.class.php b/htdocs/modulebuilder/template/class/api_mymodule.class.php
deleted file mode 100644 (file)
index fdb56ff..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-<?php
-/* Copyright (C) 2015   Jean-François Ferry     <jfefe@aternatik.fr>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-use Luracast\Restler\RestException;
-
-dol_include_once('/mymodule/class/myobject.class.php');
-
-
-
-/**
- * \file    htdocs/modulebuilder/template/class/api_mymodule.class.php
- * \ingroup mymodule
- * \brief   File for API management of myobject.
- */
-
-/**
- * API class for mymodule myobject
- *
- * @access protected
- * @class  DolibarrApiAccess {@requires user,external}
- */
-class MyModuleApi extends DolibarrApi
-{
-       /**
-        * @var MyObject $myobject {@type MyObject}
-        */
-       public $myobject;
-
-       /**
-        * Constructor
-        *
-        * @url     GET /
-        *
-        */
-       public function __construct()
-       {
-               global $db;
-               $this->db = $db;
-               $this->myobject = new MyObject($this->db);
-       }
-
-       /**
-        * Get properties of a myobject object
-        *
-        * Return an array with myobject informations
-        *
-        * @param       int     $id ID of myobject
-        * @return      array|mixed data without useless information
-        *
-        * @url GET myobjects/{id}
-        *
-        * @throws RestException 401 Not allowed
-        * @throws RestException 404 Not found
-        */
-       public function get($id)
-       {
-               if (!DolibarrApiAccess::$user->rights->mymodule->myobject->read) {
-                       throw new RestException(401);
-               }
-
-               $result = $this->myobject->fetch($id);
-               if (!$result) {
-                       throw new RestException(404, 'MyObject not found');
-               }
-
-               if (!DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id, 'mymodule_myobject')) {
-                       throw new RestException(401, 'Access to instance id='.$this->myobject->id.' of object not allowed for login '.DolibarrApiAccess::$user->login);
-               }
-
-               return $this->_cleanObjectDatas($this->myobject);
-       }
-
-
-       /**
-        * List myobjects
-        *
-        * Get a list of myobjects
-        *
-        * @param string               $sortfield               Sort field
-        * @param string               $sortorder               Sort order
-        * @param int                  $limit                   Limit for list
-        * @param int                  $page                    Page number
-        * @param string           $sqlfilters          Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
-        * @return  array                               Array of order objects
-        *
-        * @throws RestException
-        *
-        * @url GET /myobjects/
-        */
-       public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
-       {
-               global $db, $conf;
-
-               $obj_ret = array();
-               $tmpobject = new MyObject($this->db);
-
-               if (!DolibarrApiAccess::$user->rights->mymodule->myobject->read) {
-                       throw new RestException(401);
-               }
-
-               $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : '';
-
-               $restrictonsocid = 0; // Set to 1 if there is a field socid in table of object
-
-               // If the internal user must only see his customers, force searching by him
-               $search_sale = 0;
-               if ($restrictonsocid && !DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) {
-                       $search_sale = DolibarrApiAccess::$user->id;
-               }
-
-               $sql = "SELECT t.rowid";
-               if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
-                       $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
-               }
-               $sql .= " FROM ".MAIN_DB_PREFIX.$tmpobject->table_element." as t";
-
-               if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
-                       $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
-               }
-               $sql .= " WHERE 1 = 1";
-
-               // Example of use $mode
-               //if ($mode == 1) $sql.= " AND s.client IN (1, 3)";
-               //if ($mode == 2) $sql.= " AND s.client IN (2, 3)";
-
-               if ($tmpobject->ismultientitymanaged) {
-                       $sql .= ' AND t.entity IN ('.getEntity($tmpobject->element).')';
-               }
-               if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
-                       $sql .= " AND t.fk_soc = sc.fk_soc";
-               }
-               if ($restrictonsocid && $socid) {
-                       $sql .= " AND t.fk_soc = ".((int) $socid);
-               }
-               if ($restrictonsocid && $search_sale > 0) {
-                       $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
-               }
-               // Insert sale filter
-               if ($restrictonsocid && $search_sale > 0) {
-                       $sql .= " AND sc.fk_user = ".((int) $search_sale);
-               }
-               if ($sqlfilters) {
-                       $errormessage = '';
-                       $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
-                       if ($errormessage) {
-                               throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
-                       }
-               }
-
-               $sql .= $this->db->order($sortfield, $sortorder);
-               if ($limit) {
-                       if ($page < 0) {
-                               $page = 0;
-                       }
-                       $offset = $limit * $page;
-
-                       $sql .= $this->db->plimit($limit + 1, $offset);
-               }
-
-               $result = $this->db->query($sql);
-               $i = 0;
-               if ($result) {
-                       $num = $this->db->num_rows($result);
-                       while ($i < $num) {
-                               $obj = $this->db->fetch_object($result);
-                               $tmp_object = new MyObject($this->db);
-                               if ($tmp_object->fetch($obj->rowid)) {
-                                       $obj_ret[] = $this->_cleanObjectDatas($tmp_object);
-                               }
-                               $i++;
-                       }
-               } else {
-                       throw new RestException(503, 'Error when retrieving myobject list: '.$this->db->lasterror());
-               }
-               if (!count($obj_ret)) {
-                       throw new RestException(404, 'No myobject found');
-               }
-               return $obj_ret;
-       }
-
-       /**
-        * Create myobject object
-        *
-        * @param array $request_data   Request datas
-        * @return int  ID of myobject
-        *
-        * @throws RestException
-        *
-        * @url POST myobjects/
-        */
-       public function post($request_data = null)
-       {
-               if (!DolibarrApiAccess::$user->rights->mymodule->myobject->write) {
-                       throw new RestException(401);
-               }
-
-               // Check mandatory fields
-               $result = $this->_validate($request_data);
-
-               foreach ($request_data as $field => $value) {
-                       $this->myobject->$field = $this->_checkValForAPI($field, $value, $this->myobject);
-               }
-
-               // Clean data
-               // $this->myobject->abc = sanitizeVal($this->myobject->abc, 'alphanohtml');
-
-               if ($this->myobject->create(DolibarrApiAccess::$user)<0) {
-                       throw new RestException(500, "Error creating MyObject", array_merge(array($this->myobject->error), $this->myobject->errors));
-               }
-               return $this->myobject->id;
-       }
-
-       /**
-        * Update myobject
-        *
-        * @param int   $id             Id of myobject to update
-        * @param array $request_data   Datas
-        * @return int
-        *
-        * @throws RestException
-        *
-        * @url PUT myobjects/{id}
-        */
-       public function put($id, $request_data = null)
-       {
-               if (!DolibarrApiAccess::$user->rights->mymodule->myobject->write) {
-                       throw new RestException(401);
-               }
-
-               $result = $this->myobject->fetch($id);
-               if (!$result) {
-                       throw new RestException(404, 'MyObject not found');
-               }
-
-               if (!DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id, 'mymodule_myobject')) {
-                       throw new RestException(401, 'Access to instance id='.$this->myobject->id.' of object not allowed for login '.DolibarrApiAccess::$user->login);
-               }
-
-               foreach ($request_data as $field => $value) {
-                       if ($field == 'id') {
-                               continue;
-                       }
-                       $this->myobject->$field = $this->_checkValForAPI($field, $value, $this->myobject);
-               }
-
-               // Clean data
-               // $this->myobject->abc = sanitizeVal($this->myobject->abc, 'alphanohtml');
-
-               if ($this->myobject->update(DolibarrApiAccess::$user, false) > 0) {
-                       return $this->get($id);
-               } else {
-                       throw new RestException(500, $this->myobject->error);
-               }
-       }
-
-       /**
-        * Delete myobject
-        *
-        * @param   int     $id   MyObject ID
-        * @return  array
-        *
-        * @throws RestException
-        *
-        * @url DELETE myobjects/{id}
-        */
-       public function delete($id)
-       {
-               if (!DolibarrApiAccess::$user->rights->mymodule->myobject->delete) {
-                       throw new RestException(401);
-               }
-               $result = $this->myobject->fetch($id);
-               if (!$result) {
-                       throw new RestException(404, 'MyObject not found');
-               }
-
-               if (!DolibarrApi::_checkAccessToResource('myobject', $this->myobject->id, 'mymodule_myobject')) {
-                       throw new RestException(401, 'Access to instance id='.$this->myobject->id.' of object not allowed for login '.DolibarrApiAccess::$user->login);
-               }
-
-               if ($this->myobject->delete(DolibarrApiAccess::$user) == 0) {
-                       throw new RestException(409, 'Error when deleting MyObject : '.$this->myobject->error);
-               } elseif ($this->myobject->delete(DolibarrApiAccess::$user) < 0) {
-                       throw new RestException(500, 'Error when deleting MyObject : '.$this->myobject->error);
-               }
-
-               return array(
-                       'success' => array(
-                               'code' => 200,
-                               'message' => 'MyObject deleted'
-                       )
-               );
-       }
-
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
-       /**
-        * Clean sensible object datas
-        *
-        * @param   Object  $object     Object to clean
-        * @return  Object              Object with cleaned properties
-        */
-       protected function _cleanObjectDatas($object)
-       {
-               // phpcs:enable
-               $object = parent::_cleanObjectDatas($object);
-
-               unset($object->rowid);
-               unset($object->canvas);
-
-               /*unset($object->name);
-               unset($object->lastname);
-               unset($object->firstname);
-               unset($object->civility_id);
-               unset($object->statut);
-               unset($object->state);
-               unset($object->state_id);
-               unset($object->state_code);
-               unset($object->region);
-               unset($object->region_code);
-               unset($object->country);
-               unset($object->country_id);
-               unset($object->country_code);
-               unset($object->barcode_type);
-               unset($object->barcode_type_code);
-               unset($object->barcode_type_label);
-               unset($object->barcode_type_coder);
-               unset($object->total_ht);
-               unset($object->total_tva);
-               unset($object->total_localtax1);
-               unset($object->total_localtax2);
-               unset($object->total_ttc);
-               unset($object->fk_account);
-               unset($object->comments);
-               unset($object->note);
-               unset($object->mode_reglement_id);
-               unset($object->cond_reglement_id);
-               unset($object->cond_reglement);
-               unset($object->shipping_method_id);
-               unset($object->fk_incoterms);
-               unset($object->label_incoterms);
-               unset($object->location_incoterms);
-               */
-
-               // If object has lines, remove $db property
-               if (isset($object->lines) && is_array($object->lines) && count($object->lines) > 0) {
-                       $nboflines = count($object->lines);
-                       for ($i = 0; $i < $nboflines; $i++) {
-                               $this->_cleanObjectDatas($object->lines[$i]);
-
-                               unset($object->lines[$i]->lines);
-                               unset($object->lines[$i]->note);
-                       }
-               }
-
-               return $object;
-       }
-
-       /**
-        * Validate fields before create or update object
-        *
-        * @param       array           $data   Array of data to validate
-        * @return      array
-        *
-        * @throws      RestException
-        */
-       private function _validate($data)
-       {
-               $myobject = array();
-               foreach ($this->myobject->fields as $field => $propfield) {
-                       if (in_array($field, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat')) || $propfield['notnull'] != 1) {
-                               continue; // Not a mandatory field
-                       }
-                       if (!isset($data[$field])) {
-                               throw new RestException(400, "$field field missing");
-                       }
-                       $myobject[$field] = $data[$field];
-               }
-               return $myobject;
-       }
-}
diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php
deleted file mode 100644 (file)
index f309ef3..0000000
+++ /dev/null
@@ -1,1177 +0,0 @@
-<?php
-/* Copyright (C) 2017  Laurent Destailleur <eldy@users.sourceforge.net>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file        htdocs/modulebuilder/template/class/myobject.class.php
- * \ingroup     mymodule
- * \brief       This file is a CRUD class file for MyObject (Create/Read/Update/Delete)
- */
-
-// Put here all includes required by your class file
-require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
-//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
-//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
-
-/**
- * Class for MyObject
- */
-class MyObject extends CommonObject
-{
-       /**
-        * @var string ID of module.
-        */
-       public $module = 'mymodule';
-
-       /**
-        * @var string ID to identify managed object.
-        */
-       public $element = 'myobject';
-
-       /**
-        * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management.
-        */
-       public $table_element = 'mymodule_myobject';
-
-       /**
-        * @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
-        */
-       public $ismultientitymanaged = 0;
-
-       /**
-        * @var int  Does object support extrafields ? 0=No, 1=Yes
-        */
-       public $isextrafieldmanaged = 1;
-
-       /**
-        * @var string String with name of icon for myobject. Must be a 'fa-xxx' fontawesome code (or 'fa-xxx_fa_color_size') or 'myobject@mymodule' if picto is file 'img/object_myobject.png'.
-        */
-       public $picto = 'fa-file';
-
-
-       const STATUS_DRAFT = 0;
-       const STATUS_VALIDATED = 1;
-       const STATUS_CANCELED = 9;
-
-
-       /**
-        *  'type' field format:
-        *      'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',
-        *      'select' (list of values are in 'options'),
-        *      'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:Sortfield]]]]',
-        *      'chkbxlst:...',
-        *      'varchar(x)',
-        *      'text', 'text:none', 'html',
-        *      'double(24,8)', 'real', 'price',
-        *      'date', 'datetime', 'timestamp', 'duration',
-        *      'boolean', 'checkbox', 'radio', 'array',
-        *      'mail', 'phone', 'url', 'password', 'ip'
-        *              Note: Filter must be a Dolibarr filter syntax string. Example: "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.status:!=:0) or (t.nature:is:NULL)"
-        *  'label' the translation key.
-        *  'picto' is code of a picto to show before value in forms
-        *  'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM' or 'isModEnabled("multicurrency")' ...)
-        *  'position' is the sort order of field.
-        *  'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
-        *  'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing)
-        *  'noteditable' says if field is not editable (1 or 0)
-        *  'alwayseditable' says if field can be modified also when status is not draft ('1' or '0')
-        *  'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created.
-        *  'index' if we want an index in database.
-        *  'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...).
-        *  'searchall' is 1 if we want to search in this field when making a search from the quick search button.
-        *  'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for percentage)
-        *  'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200'
-        *  'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click.
-        *  'showoncombobox' if value of the field must be visible into the label of the combobox that list record
-        *  'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code.
-        *  'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar'
-        *  'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1.
-        *  'comment' is not used. You can store here any text of your choice. It is not used by application.
-        *      'validate' is 1 if need to validate with $this->validateField()
-        *  'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value)
-        *
-        *  Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor.
-        */
-
-       // BEGIN MODULEBUILDER PROPERTIES
-       /**
-        * @var array  Array with all fields into database and their property. Do not use it as a static var. It may be modified by constructor.
-        */
-       public $fields = array(
-               'rowid'         => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'noteditable'=>1, 'notnull'=> 1, 'index'=>1, 'position'=>1, 'comment'=>'Id', 'css'=>'left'),
-               'entity'        => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>10),
-               'ref'           => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'noteditable'=>0, 'default'=>'', 'notnull'=> 1, 'showoncombobox'=>1, 'index'=>1, 'position'=>20, 'searchall'=>1, 'comment'=>'Reference of object', 'validate'=>1),
-               'label'         => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>'Help text', 'showoncombobox'=>2, 'validate'=>1, 'alwayseditable'=>1),
-               'amount'        => array('type'=>'price', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'default'=>'null', 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for amount', 'validate'=>1),
-               'qty'           => array('type'=>'real', 'label'=>'Qty', 'enabled'=>1, 'visible'=>1, 'default'=>'0', 'position'=>45, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for quantity', 'css'=>'maxwidth75imp', 'validate'=>1),
-               'fk_soc'                => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'picto'=>'company', 'label'=>'ThirdParty', 'visible'=> 1, 'enabled'=>'$conf->societe->enabled', 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'OrganizationEventLinkToThirdParty', 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'),
-               'fk_project'    => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'position'=>52, 'notnull'=>-1, 'index'=>1, 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'),
-               'description'   => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>3, 'position'=>60, 'validate'=>1),
-               'note_public'   => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61, 'validate'=>1, 'cssview'=>'wordbreak'),
-               'note_private'  => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62, 'validate'=>1, 'cssview'=>'wordbreak'),
-               'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 1, 'position'=>500),
-               'tms'           => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 0, 'position'=>501),
-               //'date_validation '    =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'position'=>502),
-               'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 1, 'position'=>510, 'foreignkey'=>'user.rowid', 'csslist'=>'tdoverflowmax150'),
-               'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'picto'=>'user', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>511, 'csslist'=>'tdoverflowmax150'),
-               //'fk_user_valid' => array('type'=>'integer:User:user/class/user.class.php',      'label'=>'UserValidation',        'enabled'=>1, 'visible'=>-1, 'position'=>512),
-               'last_main_doc' => array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>0, 'notnull'=>0, 'position'=>600),
-               'import_key'    => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'index'=>0, 'position'=>1000),
-               'model_pdf'     => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'notnull'=>-1, 'position'=>1010),
-               'status'        => array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=> 1, 'default'=>0, 'index'=>1, 'position'=>2000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 9=>'Canceled'), 'validate'=>1),
-       );
-
-       /**
-        * @var int ID
-        */
-       public $rowid;
-
-       /**
-        * @var string Ref
-        */
-       public $ref;
-
-       /**
-        * @var int Entity
-        */
-       public $entity;
-
-       /**
-        * @var string label
-        */
-       public $label;
-
-       /**
-        * @var string amount
-        */
-       public $amount;
-
-       /**
-        * @var int Thirdparty ID
-        */
-       public $socid;          // both socid and fk_soc are used
-       public $fk_soc;         // both socid and fk_soc are used
-
-       /**
-        * @var int Status
-        */
-       public $status;
-
-       /**
-        * @var integer|string date_creation
-        */
-       public $date_creation;
-
-       /**
-        * @var integer tms
-        */
-       public $tms;
-
-       /**
-        * @var int ID
-        */
-       public $fk_user_creat;
-
-       /**
-        * @var int ID
-        */
-       public $fk_user_modif;
-
-       /**
-        * @var string public $last_main_doc
-        */
-       public $last_main_doc;
-
-       /**
-        * @var string import_key
-        */
-       public $import_key;
-       // END MODULEBUILDER PROPERTIES
-
-
-       // If this object has a subtable with lines
-
-       // /**
-       //  * @var string    Name of subtable line
-       //  */
-       // public $table_element_line = 'mymodule_myobjectline';
-
-       // /**
-       //  * @var string    Field with ID of parent key if this object has a parent
-       //  */
-       // public $fk_element = 'fk_myobject';
-
-       // /**
-       //  * @var string    Name of subtable class that manage subtable lines
-       //  */
-       // public $class_element_line = 'MyObjectline';
-
-       // /**
-       //  * @var array        List of child tables. To test if we can delete object.
-       //  */
-       // protected $childtables = array();
-
-       // /**
-       //  * @var array    List of child tables. To know object to delete on cascade.
-       //  *               If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
-       //  *               call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
-       //  */
-       // protected $childtablesoncascade = array('mymodule_myobjectdet');
-
-       // /**
-       //  * @var MyObjectLine[]     Array of subtable lines
-       //  */
-       // public $lines = array();
-
-
-
-       /**
-        * Constructor
-        *
-        * @param DoliDb $db Database handler
-        */
-       public function __construct(DoliDB $db)
-       {
-               global $conf, $langs;
-
-               $this->db = $db;
-
-               if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid']) && !empty($this->fields['ref'])) {
-                       $this->fields['rowid']['visible'] = 0;
-               }
-               if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
-                       $this->fields['entity']['enabled'] = 0;
-               }
-
-               // Example to show how to set values of fields definition dynamically
-               /*if ($user->rights->mymodule->myobject->read) {
-                       $this->fields['myfield']['visible'] = 1;
-                       $this->fields['myfield']['noteditable'] = 0;
-               }*/
-
-               // Unset fields that are disabled
-               foreach ($this->fields as $key => $val) {
-                       if (isset($val['enabled']) && empty($val['enabled'])) {
-                               unset($this->fields[$key]);
-                       }
-               }
-
-               // Translate some data of arrayofkeyval
-               if (is_object($langs)) {
-                       foreach ($this->fields as $key => $val) {
-                               if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
-                                       foreach ($val['arrayofkeyval'] as $key2 => $val2) {
-                                               $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Create object into database
-        *
-        * @param  User $user      User that creates
-        * @param  bool $notrigger false=launch triggers after, true=disable triggers
-        * @return int             <0 if KO, Id of created object if OK
-        */
-       public function create(User $user, $notrigger = false)
-       {
-               $resultcreate = $this->createCommon($user, $notrigger);
-
-               //$resultvalidate = $this->validate($user, $notrigger);
-
-               return $resultcreate;
-       }
-
-       /**
-        * Clone an object into another one
-        *
-        * @param       User    $user           User that creates
-        * @param       int     $fromid     Id of object to clone
-        * @return      mixed                           New object created, <0 if KO
-        */
-       public function createFromClone(User $user, $fromid)
-       {
-               global $langs, $extrafields;
-               $error = 0;
-
-               dol_syslog(__METHOD__, LOG_DEBUG);
-
-               $object = new self($this->db);
-
-               $this->db->begin();
-
-               // Load source object
-               $result = $object->fetchCommon($fromid);
-               if ($result > 0 && !empty($object->table_element_line)) {
-                       $object->fetchLines();
-               }
-
-               // get lines so they will be clone
-               //foreach($this->lines as $line)
-               //      $line->fetch_optionals();
-
-               // Reset some properties
-               unset($object->id);
-               unset($object->fk_user_creat);
-               unset($object->import_key);
-
-               // Clear fields
-               if (property_exists($object, 'ref')) {
-                       $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
-               }
-               if (property_exists($object, 'label')) {
-                       $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
-               }
-               if (property_exists($object, 'status')) {
-                       $object->status = self::STATUS_DRAFT;
-               }
-               if (property_exists($object, 'date_creation')) {
-                       $object->date_creation = dol_now();
-               }
-               if (property_exists($object, 'date_modification')) {
-                       $object->date_modification = null;
-               }
-               // ...
-               // Clear extrafields that are unique
-               if (is_array($object->array_options) && count($object->array_options) > 0) {
-                       $extrafields->fetch_name_optionals_label($this->table_element);
-                       foreach ($object->array_options as $key => $option) {
-                               $shortkey = preg_replace('/options_/', '', $key);
-                               if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
-                                       //var_dump($key);
-                                       //var_dump($clonedObj->array_options[$key]); exit;
-                                       unset($object->array_options[$key]);
-                               }
-                       }
-               }
-
-               // Create clone
-               $object->context['createfromclone'] = 'createfromclone';
-               $result = $object->createCommon($user);
-               if ($result < 0) {
-                       $error++;
-                       $this->error = $object->error;
-                       $this->errors = $object->errors;
-               }
-
-               if (!$error) {
-                       // copy internal contacts
-                       if ($this->copy_linked_contact($object, 'internal') < 0) {
-                               $error++;
-                       }
-               }
-
-               if (!$error) {
-                       // copy external contacts if same company
-                       if (!empty($object->socid) && property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
-                               if ($this->copy_linked_contact($object, 'external') < 0) {
-                                       $error++;
-                               }
-                       }
-               }
-
-               unset($object->context['createfromclone']);
-
-               // End
-               if (!$error) {
-                       $this->db->commit();
-                       return $object;
-               } else {
-                       $this->db->rollback();
-                       return -1;
-               }
-       }
-
-       /**
-        * Load object in memory from the database
-        *
-        * @param int    $id   Id object
-        * @param string $ref  Ref
-        * @return int         <0 if KO, 0 if not found, >0 if OK
-        */
-       public function fetch($id, $ref = null)
-       {
-               $result = $this->fetchCommon($id, $ref);
-               if ($result > 0 && !empty($this->table_element_line)) {
-                       $this->fetchLines();
-               }
-               return $result;
-       }
-
-       /**
-        * Load object lines in memory from the database
-        *
-        * @return int         <0 if KO, 0 if not found, >0 if OK
-        */
-       public function fetchLines()
-       {
-               $this->lines = array();
-
-               $result = $this->fetchLinesCommon();
-               return $result;
-       }
-
-
-       /**
-        * Load list of objects in memory from the database.
-        *
-        * @param  string      $sortorder    Sort Order
-        * @param  string      $sortfield    Sort field
-        * @param  int         $limit        limit
-        * @param  int         $offset       Offset
-        * @param  array       $filter       Filter array. Example array('field'=>'valueforlike', 'customurl'=>...)
-        * @param  string      $filtermode   Filter mode (AND or OR)
-        * @return array|int                 int <0 if KO, array of pages if OK
-        */
-       public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
-       {
-               global $conf;
-
-               dol_syslog(__METHOD__, LOG_DEBUG);
-
-               $records = array();
-
-               $sql = "SELECT ";
-               $sql .= $this->getFieldList('t');
-               $sql .= " FROM ".$this->db->prefix().$this->table_element." as t";
-               if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
-                       $sql .= " WHERE t.entity IN (".getEntity($this->element).")";
-               } else {
-                       $sql .= " WHERE 1 = 1";
-               }
-               // Manage filter
-               $sqlwhere = array();
-               if (count($filter) > 0) {
-                       foreach ($filter as $key => $value) {
-                               if ($key == 't.rowid') {
-                                       $sqlwhere[] = $key." = ".((int) $value);
-                               } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) {
-                                       $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
-                               } elseif ($key == 'customsql') {
-                                       $sqlwhere[] = $value;
-                               } elseif (strpos($value, '%') === false) {
-                                       $sqlwhere[] = $key." IN (".$this->db->sanitize($this->db->escape($value)).")";
-                               } else {
-                                       $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
-                               }
-                       }
-               }
-               if (count($sqlwhere) > 0) {
-                       $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
-               }
-
-               if (!empty($sortfield)) {
-                       $sql .= $this->db->order($sortfield, $sortorder);
-               }
-               if (!empty($limit)) {
-                       $sql .= $this->db->plimit($limit, $offset);
-               }
-
-               $resql = $this->db->query($sql);
-               if ($resql) {
-                       $num = $this->db->num_rows($resql);
-                       $i = 0;
-                       while ($i < ($limit ? min($limit, $num) : $num)) {
-                               $obj = $this->db->fetch_object($resql);
-
-                               $record = new self($this->db);
-                               $record->setVarsFromFetchObj($obj);
-
-                               $records[$record->id] = $record;
-
-                               $i++;
-                       }
-                       $this->db->free($resql);
-
-                       return $records;
-               } else {
-                       $this->errors[] = 'Error '.$this->db->lasterror();
-                       dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
-
-                       return -1;
-               }
-       }
-
-       /**
-        * Update object into database
-        *
-        * @param  User $user      User that modifies
-        * @param  bool $notrigger false=launch triggers after, true=disable triggers
-        * @return int             <0 if KO, >0 if OK
-        */
-       public function update(User $user, $notrigger = false)
-       {
-               return $this->updateCommon($user, $notrigger);
-       }
-
-       /**
-        * Delete object in database
-        *
-        * @param User $user       User that deletes
-        * @param bool $notrigger  false=launch triggers, true=disable triggers
-        * @return int             <0 if KO, >0 if OK
-        */
-       public function delete(User $user, $notrigger = false)
-       {
-               return $this->deleteCommon($user, $notrigger);
-               //return $this->deleteCommon($user, $notrigger, 1);
-       }
-
-       /**
-        *  Delete a line of object in database
-        *
-        *      @param  User    $user       User that delete
-        *  @param      int             $idline         Id of line to delete
-        *  @param      bool    $notrigger  false=launch triggers after, true=disable triggers
-        *  @return int                         >0 if OK, <0 if KO
-        */
-       public function deleteLine(User $user, $idline, $notrigger = false)
-       {
-               if ($this->status < 0) {
-                       $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
-                       return -2;
-               }
-
-               return $this->deleteLineCommon($user, $idline, $notrigger);
-       }
-
-
-       /**
-        *      Validate object
-        *
-        *      @param          User    $user                   User making status change
-        *  @param              int             $notrigger              1=Does not execute triggers, 0= execute triggers
-        *      @return         int                                             <=0 if OK, 0=Nothing done, >0 if KO
-        */
-       public function validate($user, $notrigger = 0)
-       {
-               global $conf, $langs;
-
-               require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-
-               $error = 0;
-
-               // Protection
-               if ($this->status == self::STATUS_VALIDATED) {
-                       dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
-                       return 0;
-               }
-
-               /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->myobject->write))
-                || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->myobject->myobject_advance->validate))))
-                {
-                $this->error='NotEnoughPermissions';
-                dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
-                return -1;
-                }*/
-
-               $now = dol_now();
-
-               $this->db->begin();
-
-               // Define new ref
-               if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
-                       $num = $this->getNextNumRef();
-               } else {
-                       $num = $this->ref;
-               }
-               $this->newref = $num;
-
-               if (!empty($num)) {
-                       // Validate
-                       $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
-                       $sql .= " SET ref = '".$this->db->escape($num)."',";
-                       $sql .= " status = ".self::STATUS_VALIDATED;
-                       if (!empty($this->fields['date_validation'])) {
-                               $sql .= ", date_validation = '".$this->db->idate($now)."'";
-                       }
-                       if (!empty($this->fields['fk_user_valid'])) {
-                               $sql .= ", fk_user_valid = ".((int) $user->id);
-                       }
-                       $sql .= " WHERE rowid = ".((int) $this->id);
-
-                       dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
-                       $resql = $this->db->query($sql);
-                       if (!$resql) {
-                               dol_print_error($this->db);
-                               $this->error = $this->db->lasterror();
-                               $error++;
-                       }
-
-                       if (!$error && !$notrigger) {
-                               // Call trigger
-                               $result = $this->call_trigger('MYOBJECT_VALIDATE', $user);
-                               if ($result < 0) {
-                                       $error++;
-                               }
-                               // End call triggers
-                       }
-               }
-
-               if (!$error) {
-                       $this->oldref = $this->ref;
-
-                       // Rename directory if dir was a temporary ref
-                       if (preg_match('/^[\(]?PROV/i', $this->ref)) {
-                               // Now we rename also files into index
-                               $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'myobject/".$this->db->escape($this->newref)."'";
-                               $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'myobject/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
-                               $resql = $this->db->query($sql);
-                               if (!$resql) {
-                                       $error++; $this->error = $this->db->lasterror();
-                               }
-
-                               // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
-                               $oldref = dol_sanitizeFileName($this->ref);
-                               $newref = dol_sanitizeFileName($num);
-                               $dirsource = $conf->mymodule->dir_output.'/myobject/'.$oldref;
-                               $dirdest = $conf->mymodule->dir_output.'/myobject/'.$newref;
-                               if (!$error && file_exists($dirsource)) {
-                                       dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
-
-                                       if (@rename($dirsource, $dirdest)) {
-                                               dol_syslog("Rename ok");
-                                               // Rename docs starting with $oldref with $newref
-                                               $listoffiles = dol_dir_list($conf->mymodule->dir_output.'/myobject/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
-                                               foreach ($listoffiles as $fileentry) {
-                                                       $dirsource = $fileentry['name'];
-                                                       $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
-                                                       $dirsource = $fileentry['path'].'/'.$dirsource;
-                                                       $dirdest = $fileentry['path'].'/'.$dirdest;
-                                                       @rename($dirsource, $dirdest);
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               // Set new ref and current status
-               if (!$error) {
-                       $this->ref = $num;
-                       $this->status = self::STATUS_VALIDATED;
-               }
-
-               if (!$error) {
-                       $this->db->commit();
-                       return 1;
-               } else {
-                       $this->db->rollback();
-                       return -1;
-               }
-       }
-
-
-       /**
-        *      Set draft status
-        *
-        *      @param  User    $user                   Object user that modify
-        *  @param      int             $notrigger              1=Does not execute triggers, 0=Execute triggers
-        *      @return int                                             <0 if KO, >0 if OK
-        */
-       public function setDraft($user, $notrigger = 0)
-       {
-               // Protection
-               if ($this->status <= self::STATUS_DRAFT) {
-                       return 0;
-               }
-
-               /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->write))
-                || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->mymodule_advance->validate))))
-                {
-                $this->error='Permission denied';
-                return -1;
-                }*/
-
-               return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'MYOBJECT_UNVALIDATE');
-       }
-
-       /**
-        *      Set cancel status
-        *
-        *      @param  User    $user                   Object user that modify
-        *  @param      int             $notrigger              1=Does not execute triggers, 0=Execute triggers
-        *      @return int                                             <0 if KO, 0=Nothing done, >0 if OK
-        */
-       public function cancel($user, $notrigger = 0)
-       {
-               // Protection
-               if ($this->status != self::STATUS_VALIDATED) {
-                       return 0;
-               }
-
-               /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->write))
-                || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->mymodule_advance->validate))))
-                {
-                $this->error='Permission denied';
-                return -1;
-                }*/
-
-               return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'MYOBJECT_CANCEL');
-       }
-
-       /**
-        *      Set back to validated status
-        *
-        *      @param  User    $user                   Object user that modify
-        *  @param      int             $notrigger              1=Does not execute triggers, 0=Execute triggers
-        *      @return int                                             <0 if KO, 0=Nothing done, >0 if OK
-        */
-       public function reopen($user, $notrigger = 0)
-       {
-               // Protection
-               if ($this->status == self::STATUS_VALIDATED) {
-                       return 0;
-               }
-
-               /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->write))
-                || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->mymodule->mymodule_advance->validate))))
-                {
-                $this->error='Permission denied';
-                return -1;
-                }*/
-
-               return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'MYOBJECT_REOPEN');
-       }
-
-       /**
-        *  Return a link to the object card (with optionaly the picto)
-        *
-        *  @param  int     $withpicto                  Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
-        *  @param  string  $option                     On what the link point to ('nolink', ...)
-        *  @param  int     $notooltip                  1=Disable tooltip
-        *  @param  string  $morecss                    Add more css on link
-        *  @param  int     $save_lastsearch_value      -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
-        *  @return     string                              String with URL
-        */
-       public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
-       {
-               global $conf, $langs, $hookmanager;
-
-               if (!empty($conf->dol_no_mouse_hover)) {
-                       $notooltip = 1; // Force disable tooltips
-               }
-
-               $result = '';
-
-               $label = img_picto('', $this->picto).' <u>'.$langs->trans("MyObject").'</u>';
-               if (isset($this->status)) {
-                       $label .= ' '.$this->getLibStatut(5);
-               }
-               $label .= '<br>';
-               $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
-
-               $url = dol_buildpath('/mymodule/myobject_card.php', 1).'?id='.$this->id;
-
-               if ($option != 'nolink') {
-                       // Add param to save lastsearch_values or not
-                       $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
-                       if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
-                               $add_save_lastsearch_values = 1;
-                       }
-                       if ($url && $add_save_lastsearch_values) {
-                               $url .= '&save_lastsearch_values=1';
-                       }
-               }
-
-               $linkclose = '';
-               if (empty($notooltip)) {
-                       if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
-                               $label = $langs->trans("ShowMyObject");
-                               $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
-                       }
-                       $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
-                       $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
-               } else {
-                       $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
-               }
-
-               if ($option == 'nolink' || empty($url)) {
-                       $linkstart = '<span';
-               } else {
-                       $linkstart = '<a href="'.$url.'"';
-               }
-               $linkstart .= $linkclose.'>';
-               if ($option == 'nolink' || empty($url)) {
-                       $linkend = '</span>';
-               } else {
-                       $linkend = '</a>';
-               }
-
-               $result .= $linkstart;
-
-               if (empty($this->showphoto_on_popup)) {
-                       if ($withpicto) {
-                               $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
-                       }
-               } else {
-                       if ($withpicto) {
-                               require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-
-                               list($class, $module) = explode('@', $this->picto);
-                               $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref);
-                               $filearray = dol_dir_list($upload_dir, "files");
-                               $filename = $filearray[0]['name'];
-                               if (!empty($filename)) {
-                                       $pospoint = strpos($filearray[0]['name'], '.');
-
-                                       $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
-                                       if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) {
-                                               $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref"><img class="photo'.$module.'" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div></div>';
-                                       } else {
-                                               $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photouserphoto userphoto" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div>';
-                                       }
-
-                                       $result .= '</div>';
-                               } else {
-                                       $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
-                               }
-                       }
-               }
-
-               if ($withpicto != 2) {
-                       $result .= $this->ref;
-               }
-
-               $result .= $linkend;
-               //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
-
-               global $action, $hookmanager;
-               $hookmanager->initHooks(array($this->element.'dao'));
-               $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
-               $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
-               if ($reshook > 0) {
-                       $result = $hookmanager->resPrint;
-               } else {
-                       $result .= $hookmanager->resPrint;
-               }
-
-               return $result;
-       }
-
-       /**
-        *      Return a thumb for kanban views
-        *
-        *      @param      string          $option                 Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
-        *  @return             string                                                          HTML Code for Kanban thumb.
-        */
-       /*
-       public function getKanbanView($option = '')
-       {
-               $return = '<div class="box-flex-item box-flex-grow-zero">';
-               $return .= '<div class="info-box info-box-sm">';
-               $return .= '<span class="info-box-icon bg-infobox-action">';
-               $return .= img_picto('', $this->picto);
-               $return .= '</span>';
-               $return .= '<div class="info-box-content">';
-               $return .= '<span class="info-box-ref">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
-               if (property_exists($this, 'label')) {
-                       $return .= '<br><span class="info-box-label opacitymedium">'.$this->label.'</span>';
-               }
-               if (method_exists($this, 'getLibStatut')) {
-                       $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(5).'</div>';
-               }
-               $return .= '</div>';
-               $return .= '</div>';
-               $return .= '</div>';
-
-               return $return;
-       }
-       */
-
-       /**
-        *  Return the label of the status
-        *
-        *  @param  int         $mode          0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
-        *  @return     string                         Label of status
-        */
-       public function getLabelStatus($mode = 0)
-       {
-               return $this->LibStatut($this->status, $mode);
-       }
-
-       /**
-        *  Return the label of the status
-        *
-        *  @param  int         $mode          0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
-        *  @return     string                         Label of status
-        */
-       public function getLibStatut($mode = 0)
-       {
-               return $this->LibStatut($this->status, $mode);
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        *  Return the status
-        *
-        *  @param      int             $status        Id status
-        *  @param  int         $mode          0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
-        *  @return string                             Label of status
-        */
-       public function LibStatut($status, $mode = 0)
-       {
-               // phpcs:enable
-               if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
-                       global $langs;
-                       //$langs->load("mymodule@mymodule");
-                       $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
-                       $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
-                       $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
-                       $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
-                       $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
-                       $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
-               }
-
-               $statusType = 'status'.$status;
-               //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
-               if ($status == self::STATUS_CANCELED) {
-                       $statusType = 'status6';
-               }
-
-               return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
-       }
-
-       /**
-        *      Load the info information in the object
-        *
-        *      @param  int             $id       Id of object
-        *      @return void
-        */
-       public function info($id)
-       {
-               $sql = "SELECT rowid,";
-               $sql .= " date_creation as datec, tms as datem,";
-               $sql .= " fk_user_creat, fk_user_modif";
-               $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t";
-               $sql .= " WHERE t.rowid = ".((int) $id);
-
-               $result = $this->db->query($sql);
-               if ($result) {
-                       if ($this->db->num_rows($result)) {
-                               $obj = $this->db->fetch_object($result);
-
-                               $this->id = $obj->rowid;
-
-                               $this->user_creation_id = $obj->fk_user_creat;
-                               $this->user_modification_id = $obj->fk_user_modif;
-                               if (!empty($obj->fk_user_valid)) {
-                                       $this->user_validation_id = $obj->fk_user_valid;
-                               }
-                               $this->date_creation     = $this->db->jdate($obj->datec);
-                               $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
-                               if (!empty($obj->datev)) {
-                                       $this->date_validation   = empty($obj->datev) ? '' : $this->db->jdate($obj->datev);
-                               }
-                       }
-
-                       $this->db->free($result);
-               } else {
-                       dol_print_error($this->db);
-               }
-       }
-
-       /**
-        * Initialise object with example values
-        * Id must be 0 if object instance is a specimen
-        *
-        * @return void
-        */
-       public function initAsSpecimen()
-       {
-               // Set here init that are not commonf fields
-               // $this->property1 = ...
-               // $this->property2 = ...
-
-               $this->initAsSpecimenCommon();
-       }
-
-       /**
-        *      Create an array of lines
-        *
-        *      @return array|int               array of lines if OK, <0 if KO
-        */
-       public function getLinesArray()
-       {
-               $this->lines = array();
-
-               $objectline = new MyObjectLine($this->db);
-               $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_myobject = '.((int) $this->id)));
-
-               if (is_numeric($result)) {
-                       $this->error = $objectline->error;
-                       $this->errors = $objectline->errors;
-                       return $result;
-               } else {
-                       $this->lines = $result;
-                       return $this->lines;
-               }
-       }
-
-       /**
-        *  Returns the reference to the following non used object depending on the active numbering module.
-        *
-        *  @return string                      Object free reference
-        */
-       public function getNextNumRef()
-       {
-               global $langs, $conf;
-               $langs->load("mymodule@mymodule");
-
-               if (empty($conf->global->MYMODULE_MYOBJECT_ADDON)) {
-                       $conf->global->MYMODULE_MYOBJECT_ADDON = 'mod_myobject_standard';
-               }
-
-               if (!empty($conf->global->MYMODULE_MYOBJECT_ADDON)) {
-                       $mybool = false;
-
-                       $file = $conf->global->MYMODULE_MYOBJECT_ADDON.".php";
-                       $classname = $conf->global->MYMODULE_MYOBJECT_ADDON;
-
-                       // Include file with class
-                       $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
-                       foreach ($dirmodels as $reldir) {
-                               $dir = dol_buildpath($reldir."core/modules/mymodule/");
-
-                               // Load file with numbering class (if found)
-                               $mybool |= @include_once $dir.$file;
-                       }
-
-                       if ($mybool === false) {
-                               dol_print_error('', "Failed to include file ".$file);
-                               return '';
-                       }
-
-                       if (class_exists($classname)) {
-                               $obj = new $classname();
-                               $numref = $obj->getNextValue($this);
-
-                               if ($numref != '' && $numref != '-1') {
-                                       return $numref;
-                               } else {
-                                       $this->error = $obj->error;
-                                       //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
-                                       return "";
-                               }
-                       } else {
-                               print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
-                               return "";
-                       }
-               } else {
-                       print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
-                       return "";
-               }
-       }
-
-       /**
-        *  Create a document onto disk according to template module.
-        *
-        *  @param          string              $modele                 Force template to use ('' to not force)
-        *  @param              Translate       $outputlangs    objet lang a utiliser pour traduction
-        *  @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                                     0 if KO, 1 if OK
-        */
-       public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
-       {
-               global $conf, $langs;
-
-               $result = 0;
-               $includedocgeneration = 0;
-
-               $langs->load("mymodule@mymodule");
-
-               if (!dol_strlen($modele)) {
-                       $modele = 'standard_myobject';
-
-                       if (!empty($this->model_pdf)) {
-                               $modele = $this->model_pdf;
-                       } elseif (!empty($conf->global->MYOBJECT_ADDON_PDF)) {
-                               $modele = $conf->global->MYOBJECT_ADDON_PDF;
-                       }
-               }
-
-               $modelpath = "core/modules/mymodule/doc/";
-
-               if ($includedocgeneration && !empty($modele)) {
-                       $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
-               }
-
-               return $result;
-       }
-
-       /**
-        * Action executed by scheduler
-        * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters'
-        * Use public function doScheduledJob($param1, $param2, ...) to get parameters
-        *
-        * @return      int                     0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK)
-        */
-       public function doScheduledJob()
-       {
-               global $conf, $langs;
-
-               //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
-
-               $error = 0;
-               $this->output = '';
-               $this->error = '';
-
-               dol_syslog(__METHOD__, LOG_DEBUG);
-
-               $now = dol_now();
-
-               $this->db->begin();
-
-               // ...
-
-               $this->db->commit();
-
-               return $error;
-       }
-}
-
-
-require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
-
-/**
- * Class MyObjectLine. You can also remove this and generate a CRUD class for lines objects.
- */
-class MyObjectLine extends CommonObjectLine
-{
-       // To complete with content of an object MyObjectLine
-       // We should have a field rowid, fk_myobject and position
-
-       /**
-        * @var int  Does object support extrafields ? 0=No, 1=Yes
-        */
-       public $isextrafieldmanaged = 0;
-
-       /**
-        * Constructor
-        *
-        * @param DoliDb $db Database handler
-        */
-       public function __construct(DoliDB $db)
-       {
-               $this->db = $db;
-       }
-}
diff --git a/htdocs/modulebuilder/template/core/boxes/README.md b/htdocs/modulebuilder/template/core/boxes/README.md
deleted file mode 100644 (file)
index 3989bca..0000000
+++ /dev/null
@@ -1 +0,0 @@
-# Directory where widgets files are stored
diff --git a/htdocs/modulebuilder/template/core/boxes/mymodulewidget1.php b/htdocs/modulebuilder/template/core/boxes/mymodulewidget1.php
deleted file mode 100644 (file)
index 7ea4b55..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-<?php
-/* Copyright (C) 2004-2017  Laurent Destailleur <eldy@users.sourceforge.net>
- * Copyright (C) 2018-2021  Frédéric France     <frederic.france@netlogic.fr>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    htdocs/modulebuilder/template/core/boxes/mymodulewidget1.php
- * \ingroup mymodule
- * \brief   Widget provided by MyModule
- *
- * Put detailed description here.
- */
-
-include_once DOL_DOCUMENT_ROOT."/core/boxes/modules_boxes.php";
-
-
-/**
- * Class to manage the box
- *
- * Warning: for the box to be detected correctly by dolibarr,
- * the filename should be the lowercase classname
- */
-class mymodulewidget1 extends ModeleBoxes
-{
-       /**
-        * @var string Alphanumeric ID. Populated by the constructor.
-        */
-       public $boxcode = "mymodulebox";
-
-       /**
-        * @var string Box icon (in configuration page)
-        * Automatically calls the icon named with the corresponding "object_" prefix
-        */
-       public $boximg = "mymodule@mymodule";
-
-       /**
-        * @var string Box label (in configuration page)
-        */
-       public $boxlabel;
-
-       /**
-        * @var string[] Module dependencies
-        */
-       public $depends = array('mymodule');
-
-       /**
-        * @var DoliDb Database handler
-        */
-       public $db;
-
-       /**
-        * @var mixed More parameters
-        */
-       public $param;
-
-       /**
-        * @var array Header informations. Usually created at runtime by loadBox().
-        */
-       public $info_box_head = array();
-
-       /**
-        * @var array Contents informations. Usually created at runtime by loadBox().
-        */
-       public $info_box_contents = array();
-
-       /**
-        * @var string  Widget type ('graph' means the widget is a graph widget)
-        */
-       public $widgettype = 'graph';
-
-
-       /**
-        * Constructor
-        *
-        * @param DoliDB $db Database handler
-        * @param string $param More parameters
-        */
-       public function __construct(DoliDB $db, $param = '')
-       {
-               global $user, $conf, $langs;
-               // Translations
-               $langs->loadLangs(array("boxes", "mymodule@mymodule"));
-
-               parent::__construct($db, $param);
-
-               $this->boxlabel = $langs->transnoentitiesnoconv("MyWidget");
-
-               $this->param = $param;
-
-               //$this->enabled = $conf->global->FEATURES_LEVEL > 0;         // Condition when module is enabled or not
-               //$this->hidden = ! ($user->rights->mymodule->myobject->read);   // Condition when module is visible by user (test on permission)
-       }
-
-       /**
-        * Load data into info_box_contents array to show array later. Called by Dolibarr before displaying the box.
-        *
-        * @param int $max Maximum number of records to load
-        * @return void
-        */
-       public function loadBox($max = 5)
-       {
-               global $langs;
-
-               // Use configuration value for max lines count
-               $this->max = $max;
-
-               //dol_include_once("/mymodule/class/mymodule.class.php");
-
-               // Populate the head at runtime
-               $text = $langs->trans("MyModuleBoxDescription", $max);
-               $this->info_box_head = array(
-                       // Title text
-                       'text' => $text,
-                       // Add a link
-                       'sublink' => 'http://example.com',
-                       // Sublink icon placed after the text
-                       'subpicto' => 'object_mymodule@mymodule',
-                       // Sublink icon HTML alt text
-                       'subtext' => '',
-                       // Sublink HTML target
-                       'target' => '',
-                       // HTML class attached to the picto and link
-                       'subclass' => 'center',
-                       // Limit and truncate with "…" the displayed text lenght, 0 = disabled
-                       'limit' => 0,
-                       // Adds translated " (Graph)" to a hidden form value's input (?)
-                       'graph' => false
-               );
-
-               // Populate the contents at runtime
-               $this->info_box_contents = array(
-                       0 => array( // First line
-                               0 => array( // First Column
-                                       //  HTML properties of the TR element. Only available on the first column.
-                                       'tr' => 'class="left"',
-                                       // HTML properties of the TD element
-                                       'td' => '',
-
-                                       // Main text for content of cell
-                                       'text' => 'First cell of first line',
-                                       // Link on 'text' and 'logo' elements
-                                       'url' => 'http://example.com',
-                                       // Link's target HTML property
-                                       'target' => '_blank',
-                                       // Fist line logo (deprecated. Include instead logo html code into text or text2, and set asis property to true to avoid HTML cleaning)
-                                       //'logo' => 'monmodule@monmodule',
-                                       // Unformatted text, added after text. Usefull to add/load javascript code
-                                       'textnoformat' => '',
-
-                                       // Main text for content of cell (other method)
-                                       //'text2' => '<p><strong>Another text</strong></p>',
-
-                                       // Truncates 'text' element to the specified character length, 0 = disabled
-                                       'maxlength' => 0,
-                                       // Prevents HTML cleaning (and truncation)
-                                       'asis' => false,
-                                       // Same for 'text2'
-                                       'asis2' => true
-                               ),
-                               1 => array( // Another column
-                                       // No TR for n≠0
-                                       'td' => '',
-                                       'text' => 'Second cell',
-                               )
-                       ),
-                       1 => array( // Another line
-                               0 => array( // TR
-                                       'tr' => 'class="left"',
-                                       'text' => 'Another line'
-                               ),
-                               1 => array( // TR
-                                       'tr' => 'class="left"',
-                                       'text' => ''
-                               )
-                       ),
-                       2 => array( // Another line
-                               0 => array( // TR
-                                       'tr' => 'class="left"',
-                                       'text' => ''
-                               ),
-                               1 => array( // TR
-                                       'tr' => 'class="left"',
-                                       'text' => ''
-                               )
-                       ),
-               );
-       }
-
-       /**
-        * Method to show box. Called by Dolibarr eatch time it wants to display the box.
-        *
-        * @param array $head       Array with properties of box title
-        * @param array $contents   Array with properties of box lines
-        * @param int   $nooutput   No print, only return string
-        * @return string
-        */
-       public function showBox($head = null, $contents = null, $nooutput = 0)
-       {
-               // You may make your own code here…
-               // â€¦ or use the parent's class function using the provided head and contents templates
-               return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
-       }
-}
diff --git a/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php
deleted file mode 100644 (file)
index ad0814f..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-<?php
-/* Copyright (C) 2005-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
- *
- * This file is an example to follow to add your own email selector inside
- * the Dolibarr email tool.
- * Follow instructions given in README file to know what to change to build
- * your own emailing list selector.
- * Code that need to be changed in this file are marked by "CHANGE THIS" tag.
- */
-
-include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php';
-dol_include_once("/mymodule/class/myobject.class.php");
-
-
-/**
- * mailing_mailinglist_mymodule
- */
-class mailing_mailinglist_mymodule_myobject extends MailingTargets
-{
-       // CHANGE THIS: Put here a name not already used
-       public $name = 'mailinglist_mymodule_myobject';
-       // CHANGE THIS: Put here a description of your selector module
-       public $desc = 'My object emailing target selector';
-       // CHANGE THIS: Set to 1 if selector is available for admin users only
-       public $require_admin = 0;
-
-       public $enabled = 'isModEnabled("mymodule")';
-
-       public $require_module = array();
-
-       /**
-        * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
-        */
-       public $picto = 'mymodule@mymodule';
-
-       /**
-        * @var DoliDB Database handler.
-        */
-       public $db;
-
-
-       /**
-        *  Constructor
-        *
-        *  @param  DoliDB  $db     Database handler
-        */
-       public function __construct($db)
-       {
-               $this->db = $db;
-               $this->enabled = isModEnabled('mymodule');
-       }
-
-
-       /**
-        *  Displays the filter form that appears in the mailing recipient selection page
-        *
-        *  @return     string      Return select zone
-        */
-       public function formFilter()
-       {
-               global $langs;
-               $langs->load("members");
-
-               $form = new Form($this->db);
-
-               $arraystatus = array(1=>'Option 1', 2=>'Option 2');
-
-               $s = '';
-               $s .= $langs->trans("Status").': ';
-               $s .= '<select name="filter" class="flat">';
-               $s .= '<option value="none">&nbsp;</option>';
-               foreach ($arraystatus as $status) {
-                       $s .= '<option value="'.$status.'">'.$status.'</option>';
-               }
-               $s .= '</select>';
-               $s .= '<br>';
-
-               return $s;
-       }
-
-
-       /**
-        *  Returns url link to file of the source of the recipient of the mailing
-        *
-        *  @param      int         $id     ID
-        *  @return     string              Url lien
-        */
-       public function url($id)
-       {
-               return '<a href="'.dol_buildpath('/mymodule/myobject_card.php', 1).'?id='.$id.'">'.img_object('', "generic").'</a>';
-       }
-
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        *  This is the main function that returns the array of emails
-        *
-        *  @param  int     $mailing_id     Id of emailing
-        *  @return int                     <0 if error, number of emails added if ok
-        */
-       public function add_to_target($mailing_id)
-       {
-               // phpcs:enable
-               $target = array();
-               $j = 0;
-
-               $sql = " select rowid as id, label, firstname, lastname";
-               $sql .= " from ".MAIN_DB_PREFIX."myobject";
-               $sql .= " where email IS NOT NULL AND email <> ''";
-               if (GETPOSTISSET('filter') && GETPOST('filter', 'alphanohtml') != 'none') {
-                       $sql .= " AND status = '".$this->db->escape(GETPOST('filter', 'alphanohtml'))."'";
-               }
-               $sql .= " ORDER BY email";
-
-               // Store recipients in target
-               $result = $this->db->query($sql);
-               if ($result) {
-                       $num = $this->db->num_rows($result);
-                       $i = 0;
-
-                       dol_syslog("mailinglist_mymodule_myobject.modules.php: mailing ".$num." targets found");
-
-                       $old = '';
-                       while ($i < $num) {
-                               $obj = $this->db->fetch_object($result);
-                               if ($old <> $obj->email) {
-                                       $target[$j] = array(
-                                               'email' => $obj->email,
-                                               'name' => $obj->lastname,
-                                               'id' => $obj->id,
-                                               'firstname' => $obj->firstname,
-                                               'other' => $obj->label,
-                                               'source_url' => $this->url($obj->id),
-                                               'source_id' => $obj->id,
-                                               'source_type' => 'myobject@mymodule'
-                                       );
-                                       $old = $obj->email;
-                                       $j++;
-                               }
-
-                               $i++;
-                       }
-               } else {
-                       dol_syslog($this->db->error());
-                       $this->error = $this->db->error();
-                       return -1;
-               }
-
-               // You must fill the $target array with record like this
-               // $target[0]=array('email'=>'email_0','name'=>'name_0','firstname'=>'firstname_0');
-               // ...
-               // $target[n]=array('email'=>'email_n','name'=>'name_n','firstname'=>'firstname_n');
-
-               // Example: $target[0]=array('email'=>'myemail@mydomain.com','name'=>'Doe','firstname'=>'John');
-
-               // ----- Your code end here -----
-
-               return parent::addTargetsToDatabase($mailing_id, $target);
-       }
-
-
-       /**
-        *  On the main mailing area, there is a box with statistics.
-        *  If you want to add a line in this report you must provide an
-        *  array of SQL request that returns two field:
-        *  One called "label", One called "nb".
-        *
-        *  @return array
-        */
-       public function getSqlArrayForStats()
-       {
-               // CHANGE THIS: Optionnal
-
-               //var $statssql=array();
-               //$this->statssql[0]="SELECT field1 as label, count(distinct(email)) as nb FROM mytable WHERE email IS NOT NULL";
-
-               return array();
-       }
-
-
-       /**
-        *  Return here number of distinct emails returned by your selector.
-        *  For example if this selector is used to extract 500 different
-        *  emails from a text file, this function must return 500.
-        *
-        *  @param  string  $filter     Filter
-        *  @param  string      $option     Options
-        *  @return int                 Nb of recipients or -1 if KO
-        */
-       public function getNbOfRecipients($filter = 1, $option = '')
-       {
-               $a = parent::getNbOfRecipients("select count(distinct(email)) as nb from ".MAIN_DB_PREFIX."myobject as p where email IS NOT NULL AND email != ''");
-
-               if ($a < 0) {
-                       return -1;
-               }
-               return $a;
-       }
-}
diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
deleted file mode 100644 (file)
index 99cd900..0000000
+++ /dev/null
@@ -1,501 +0,0 @@
-<?php
-/* Copyright (C) 2004-2018  Laurent Destailleur     <eldy@users.sourceforge.net>
- * Copyright (C) 2018-2019  Nicolas ZABOURI         <info@inovea-conseil.com>
- * Copyright (C) 2019-2020  Frédéric France         <frederic.france@netlogic.fr>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \defgroup   mymodule     Module MyModule
- *  \brief      MyModule module descriptor.
- *
- *  \file       htdocs/mymodule/core/modules/modMyModule.class.php
- *  \ingroup    mymodule
- *  \brief      Description and activation file for module MyModule
- */
-include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
-
-/**
- *  Description and activation class for module MyModule
- */
-class modMyModule extends DolibarrModules
-{
-       /**
-        * Constructor. Define names, constants, directories, boxes, permissions
-        *
-        * @param DoliDB $db Database handler
-        */
-       public function __construct($db)
-       {
-               global $langs, $conf;
-               $this->db = $db;
-
-               // Id for module (must be unique).
-               // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
-               $this->numero = 500000; // TODO Go on page https://wiki.dolibarr.org/index.php/List_of_modules_id to reserve an id number for your module
-
-               // Key text used to identify module (for permissions, menus, etc...)
-               $this->rights_class = 'mymodule';
-
-               // Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...'
-               // It is used to group modules by family in module setup page
-               $this->family = "other";
-
-               // Module position in the family on 2 digits ('01', '10', '20', ...)
-               $this->module_position = '90';
-
-               // Gives the possibility for the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
-               //$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
-               // Module label (no space allowed), used if translation string 'ModuleMyModuleName' not found (MyModule is name of module).
-               $this->name = preg_replace('/^mod/i', '', get_class($this));
-
-               // Module description, used if translation string 'ModuleMyModuleDesc' not found (MyModule is name of module).
-               $this->description = "MyModuleDescription";
-               // Used only if file README.md and README-LL.md not found.
-               $this->descriptionlong = "MyModuleDescription";
-
-               // Author
-               $this->editor_name = 'Editor name';
-               $this->editor_url = 'https://www.example.com';
-
-               // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated', 'experimental_deprecated' or a version string like 'x.y.z'
-               $this->version = '1.0';
-               // Url to the file with your last numberversion of this module
-               //$this->url_last_version = 'http://www.example.com/versionmodule.txt';
-
-               // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase)
-               $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
-
-               // Name of image file used for this module.
-               // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
-               // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
-               // To use a supported fa-xxx css style of font awesome, use this->picto='xxx'
-               $this->picto = 'generic';
-
-               // Define some features supported by module (triggers, login, substitutions, menus, css, etc...)
-               $this->module_parts = array(
-                       // Set this to 1 if module has its own trigger directory (core/triggers)
-                       'triggers' => 0,
-                       // Set this to 1 if module has its own login method file (core/login)
-                       'login' => 0,
-                       // Set this to 1 if module has its own substitution function file (core/substitutions)
-                       'substitutions' => 0,
-                       // Set this to 1 if module has its own menus handler directory (core/menus)
-                       'menus' => 0,
-                       // Set this to 1 if module overwrite template dir (core/tpl)
-                       'tpl' => 0,
-                       // Set this to 1 if module has its own barcode directory (core/modules/barcode)
-                       'barcode' => 0,
-                       // Set this to 1 if module has its own models directory (core/modules/xxx)
-                       'models' => 0,
-                       // Set this to 1 if module has its own printing directory (core/modules/printing)
-                       'printing' => 0,
-                       // Set this to 1 if module has its own theme directory (theme)
-                       'theme' => 0,
-                       // Set this to relative path of css file if module has its own css file
-                       'css' => array(
-                               //    '/mymodule/css/mymodule.css.php',
-                       ),
-                       // Set this to relative path of js file if module must load a js on all pages
-                       'js' => array(
-                               //   '/mymodule/js/mymodule.js.php',
-                       ),
-                       // Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context to 'all'
-                       'hooks' => array(
-                               //   'data' => array(
-                               //       'hookcontext1',
-                               //       'hookcontext2',
-                               //   ),
-                               //   'entity' => '0',
-                       ),
-                       // Set this to 1 if features of module are opened to external users
-                       'moduleforexternal' => 0,
-               );
-
-               // Data directories to create when module is enabled.
-               // Example: this->dirs = array("/mymodule/temp","/mymodule/subdir");
-               $this->dirs = array("/mymodule/temp");
-
-               // Config pages. Put here list of php page, stored into mymodule/admin directory, to use to setup module.
-               $this->config_page_url = array("setup.php@mymodule");
-
-               // Dependencies
-               // A condition to hide module
-               $this->hidden = false;
-               // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...)
-               $this->depends = array();
-               $this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...)
-               $this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...)
-
-               // The language file dedicated to your module
-               $this->langfiles = array("mymodule@mymodule");
-
-               // Prerequisites
-               $this->phpmin = array(7, 0); // Minimum version of PHP required by module
-               $this->need_dolibarr_version = array(11, -3); // Minimum version of Dolibarr required by module
-
-               // Messages at activation
-               $this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','MX'='textmx'...)
-               $this->warnings_activation_ext = array(); // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','MX'='textmx'...)
-               //$this->automatic_activation = array('FR'=>'MyModuleWasAutomaticallyActivatedBecauseOfYourCountryChoice');
-               //$this->always_enabled = true;                                                         // If true, can't be disabled
-
-               // Constants
-               // List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
-               // Example: $this->const=array(1 => array('MYMODULE_MYNEWCONST1', 'chaine', 'myvalue', 'This is a constant to add', 1),
-               //                             2 => array('MYMODULE_MYNEWCONST2', 'chaine', 'myvalue', 'This is another constant to add', 0, 'current', 1)
-               // );
-               $this->const = array();
-
-               // Some keys to add into the overwriting translation tables
-               /*$this->overwrite_translation = array(
-                       'en_US:ParentCompany'=>'Parent company or reseller',
-                       'fr_FR:ParentCompany'=>'Maison mère ou revendeur'
-               )*/
-
-               if (!isset($conf->mymodule) || !isset($conf->mymodule->enabled)) {
-                       $conf->mymodule = new stdClass();
-                       $conf->mymodule->enabled = 0;
-               }
-
-               // Array to add new pages in new tabs
-               $this->tabs = array();
-               // Example:
-               // $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@mymodule:$user->rights->mymodule->read:/mymodule/mynewtab1.php?id=__ID__');                                    // To add a new tab identified by code tabname1
-               // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@mymodule:$user->rights->othermodule->read:/mymodule/mynewtab2.php?id=__ID__',     // To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
-               // $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove');                                                                                                                                   // To remove an existing tab identified by code tabname
-               //
-               // Where objecttype can be
-               // 'categories_x'         to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member)
-               // 'contact'          to add a tab in contact view
-               // 'contract'         to add a tab in contract view
-               // 'group'            to add a tab in group view
-               // 'intervention'     to add a tab in intervention view
-               // 'invoice'          to add a tab in customer invoice view
-               // 'invoice_supplier' to add a tab in supplier invoice view
-               // 'member'           to add a tab in fundation member view
-               // 'opensurveypoll'       to add a tab in opensurvey poll view
-               // 'order'            to add a tab in sale order view
-               // 'order_supplier'   to add a tab in supplier order view
-               // 'payment'              to add a tab in payment view
-               // 'payment_supplier' to add a tab in supplier payment view
-               // 'product'          to add a tab in product view
-               // 'propal'           to add a tab in propal view
-               // 'project'          to add a tab in project view
-               // 'stock'            to add a tab in stock view
-               // 'thirdparty'       to add a tab in third party view
-               // 'user'             to add a tab in user view
-
-               // Dictionaries
-               $this->dictionaries = array();
-               /* Example:
-               $this->dictionaries=array(
-                       'langs'=>'mymodule@mymodule',
-                       // List of tables we want to see into dictonnary editor
-                       'tabname'=>array("table1", "table2", "table3"),
-                       // Label of tables
-                       'tablib'=>array("Table1", "Table2", "Table3"),
-                       // Request to select fields
-                       'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f', 'SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f', 'SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'),
-                       // Sort order
-                       'tabsqlsort'=>array("label ASC", "label ASC", "label ASC"),
-                       // List of fields (result of select to show dictionary)
-                       'tabfield'=>array("code,label", "code,label", "code,label"),
-                       // List of fields (list of fields to edit a record)
-                       'tabfieldvalue'=>array("code,label", "code,label", "code,label"),
-                       // List of fields (list of fields for insert)
-                       'tabfieldinsert'=>array("code,label", "code,label", "code,label"),
-                       // Name of columns with primary key (try to always name it 'rowid')
-                       'tabrowid'=>array("rowid", "rowid", "rowid"),
-                       // Condition to show each dictionary
-                       'tabcond'=>array($conf->mymodule->enabled, $conf->mymodule->enabled, $conf->mymodule->enabled),
-                       // Tooltip for every fields of dictionaries: DO NOT PUT AN EMPTY ARRAY
-                       'tabhelp'=>array(array('code'=>$langs->trans('CodeTooltipHelp'), 'field2' => 'field2tooltip'), array('code'=>$langs->trans('CodeTooltipHelp'), 'field2' => 'field2tooltip'), ...),
-               );
-               */
-
-               // Boxes/Widgets
-               // Add here list of php file(s) stored in mymodule/core/boxes that contains a class to show a widget.
-               $this->boxes = array(
-                       //  0 => array(
-                       //      'file' => 'mymodulewidget1.php@mymodule',
-                       //      'note' => 'Widget provided by MyModule',
-                       //      'enabledbydefaulton' => 'Home',
-                       //  ),
-                       //  ...
-               );
-
-               // Cronjobs (List of cron jobs entries to add when module is enabled)
-               // unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
-               $this->cronjobs = array(
-                       //  0 => array(
-                       //      'label' => 'MyJob label',
-                       //      'jobtype' => 'method',
-                       //      'class' => '/mymodule/class/myobject.class.php',
-                       //      'objectname' => 'MyObject',
-                       //      'method' => 'doScheduledJob',
-                       //      'parameters' => '',
-                       //      'comment' => 'Comment',
-                       //      'frequency' => 2,
-                       //      'unitfrequency' => 3600,
-                       //      'status' => 0,
-                       //      'test' => '$conf->mymodule->enabled',
-                       //      'priority' => 50,
-                       //  ),
-               );
-               // Example: $this->cronjobs=array(
-               //    0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>'$conf->mymodule->enabled', 'priority'=>50),
-               //    1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>'$conf->mymodule->enabled', 'priority'=>50)
-               // );
-
-               // Permissions provided by this module
-               $this->rights = array();
-               $r = 0;
-               // Add here entries to declare new permissions
-               /* BEGIN MODULEBUILDER PERMISSIONS */
-               $this->rights[$r][0] = $this->numero . sprintf("%02d", $r + 1); // Permission id (must not be already used)
-               $this->rights[$r][1] = 'Read objects of MyModule'; // Permission label
-               $this->rights[$r][4] = 'myobject';
-               $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->mymodule->myobject->read)
-               $r++;
-               $this->rights[$r][0] = $this->numero . sprintf("%02d", $r + 1); // Permission id (must not be already used)
-               $this->rights[$r][1] = 'Create/Update objects of MyModule'; // Permission label
-               $this->rights[$r][4] = 'myobject';
-               $this->rights[$r][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->mymodule->myobject->write)
-               $r++;
-               $this->rights[$r][0] = $this->numero . sprintf("%02d", $r + 1); // Permission id (must not be already used)
-               $this->rights[$r][1] = 'Delete objects of MyModule'; // Permission label
-               $this->rights[$r][4] = 'myobject';
-               $this->rights[$r][5] = 'delete'; // In php code, permission will be checked by test if ($user->rights->mymodule->myobject->delete)
-               $r++;
-               /* END MODULEBUILDER PERMISSIONS */
-
-               // Main menu entries to add
-               $this->menu = array();
-               $r = 0;
-               // Add here entries to declare new menus
-               /* BEGIN MODULEBUILDER TOPMENU */
-               $this->menu[$r++] = array(
-                       'fk_menu'=>'', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
-                       'type'=>'top', // This is a Top menu entry
-                       'titre'=>'ModuleMyModuleName',
-                       'prefix' => img_picto('', $this->picto, 'class="paddingright pictofixedwidth valignmiddle"'),
-                       'mainmenu'=>'mymodule',
-                       'leftmenu'=>'',
-                       'url'=>'/mymodule/mymoduleindex.php',
-                       'langs'=>'mymodule@mymodule', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
-                       'position'=>1000 + $r,
-                       'enabled'=>'isModEnabled("mymodule")', // Define condition to show or hide menu entry. Use 'isModEnabled("mymodule")' if entry must be visible if module is enabled.
-                       'perms'=>'1', // Use 'perms'=>'$user->hasRight("mymodule", "myobject", "read")' if you want your menu with a permission rules
-                       'target'=>'',
-                       'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
-               );
-               /* END MODULEBUILDER TOPMENU */
-               /* BEGIN MODULEBUILDER LEFTMENU MYOBJECT
-               $this->menu[$r++]=array(
-                       'fk_menu'=>'fk_mainmenu=mymodule',      // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
-                       'type'=>'left',                          // This is a Left menu entry
-                       'titre'=>'MyObject',
-                       'prefix' => img_picto('', $this->picto, 'class="paddingright pictofixedwidth valignmiddle"'),
-                       'mainmenu'=>'mymodule',
-                       'leftmenu'=>'myobject',
-                       'url'=>'/mymodule/mymoduleindex.php',
-                       'langs'=>'mymodule@mymodule',           // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
-                       'position'=>1000+$r,
-                       'enabled'=>'isModEnabled("mymodule")', // Define condition to show or hide menu entry. Use 'isModEnabled("mymodule")' if entry must be visible if module is enabled.
-                       'perms'=>'$user->hasRight("mymodule", "myobject", "read")',
-                       'target'=>'',
-                       'user'=>2,                                              // 0=Menu for internal users, 1=external users, 2=both
-               );
-               $this->menu[$r++]=array(
-                       'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=myobject',     // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
-                       'type'=>'left',                                 // This is a Left menu entry
-                       'titre'=>'List_MyObject',
-                       'mainmenu'=>'mymodule',
-                       'leftmenu'=>'mymodule_myobject_list',
-                       'url'=>'/mymodule/myobject_list.php',
-                       'langs'=>'mymodule@mymodule',           // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
-                       'position'=>1000+$r,
-                       'enabled'=>'isModEnabled("mymodule")', // Define condition to show or hide menu entry. Use 'isModEnabled("mymodule")' if entry must be visible if module is enabled.
-                       'perms'=>'$user->hasRight("mymodule", "myobject", "read")'
-                       'target'=>'',
-                       'user'=>2,                                              // 0=Menu for internal users, 1=external users, 2=both
-               );
-               $this->menu[$r++]=array(
-                       'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=myobject',     // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
-                       'type'=>'left',                                 // This is a Left menu entry
-                       'titre'=>'New_MyObject',
-                       'mainmenu'=>'mymodule',
-                       'leftmenu'=>'mymodule_myobject_new',
-                       'url'=>'/mymodule/myobject_card.php?action=create',
-                       'langs'=>'mymodule@mymodule',           // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
-                       'position'=>1000+$r,
-                       'enabled'=>'isModEnabled("mymodule")', // Define condition to show or hide menu entry. Use 'isModEnabled("mymodule")' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
-                       'perms'=>'$user->hasRight("mymodule", "myobject", "write")'
-                       'target'=>'',
-                       'user'=>2,                                              // 0=Menu for internal users, 1=external users, 2=both
-               );
-               END MODULEBUILDER LEFTMENU MYOBJECT */
-               // Exports profiles provided by this module
-               $r = 1;
-               /* BEGIN MODULEBUILDER EXPORT MYOBJECT */
-               /*
-               $langs->load("mymodule@mymodule");
-               $this->export_code[$r]=$this->rights_class.'_'.$r;
-               $this->export_label[$r]='MyObjectLines';        // Translation key (used only if key ExportDataset_xxx_z not found)
-               $this->export_icon[$r]='myobject@mymodule';
-               // Define $this->export_fields_array, $this->export_TypeFields_array and $this->export_entities_array
-               $keyforclass = 'MyObject'; $keyforclassfile='/mymodule/class/myobject.class.php'; $keyforelement='myobject@mymodule';
-               include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
-               //$this->export_fields_array[$r]['t.fieldtoadd']='FieldToAdd'; $this->export_TypeFields_array[$r]['t.fieldtoadd']='Text';
-               //unset($this->export_fields_array[$r]['t.fieldtoremove']);
-               //$keyforclass = 'MyObjectLine'; $keyforclassfile='/mymodule/class/myobject.class.php'; $keyforelement='myobjectline@mymodule'; $keyforalias='tl';
-               //include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
-               $keyforselect='myobject'; $keyforaliasextra='extra'; $keyforelement='myobject@mymodule';
-               include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
-               //$keyforselect='myobjectline'; $keyforaliasextra='extraline'; $keyforelement='myobjectline@mymodule';
-               //include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
-               //$this->export_dependencies_array[$r] = array('myobjectline'=>array('tl.rowid','tl.ref')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
-               //$this->export_special_array[$r] = array('t.field'=>'...');
-               //$this->export_examplevalues_array[$r] = array('t.field'=>'Example');
-               //$this->export_help_array[$r] = array('t.field'=>'FieldDescHelp');
-               $this->export_sql_start[$r]='SELECT DISTINCT ';
-               $this->export_sql_end[$r]  =' FROM '.MAIN_DB_PREFIX.'myobject as t';
-               //$this->export_sql_end[$r]  =' LEFT JOIN '.MAIN_DB_PREFIX.'myobject_line as tl ON tl.fk_myobject = t.rowid';
-               $this->export_sql_end[$r] .=' WHERE 1 = 1';
-               $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('myobject').')';
-               $r++; */
-               /* END MODULEBUILDER EXPORT MYOBJECT */
-
-               // Imports profiles provided by this module
-               $r = 1;
-               /* BEGIN MODULEBUILDER IMPORT MYOBJECT */
-               /*
-               $langs->load("mymodule@mymodule");
-               $this->import_code[$r]=$this->rights_class.'_'.$r;
-               $this->import_label[$r]='MyObjectLines';        // Translation key (used only if key ExportDataset_xxx_z not found)
-               $this->import_icon[$r]='myobject@mymodule';
-               $this->import_tables_array[$r] = array('t' => MAIN_DB_PREFIX.'mymodule_myobject', 'extra' => MAIN_DB_PREFIX.'mymodule_myobject_extrafields');
-               $this->import_tables_creator_array[$r] = array('t' => 'fk_user_author'); // Fields to store import user id
-               $import_sample = array();
-               $keyforclass = 'MyObject'; $keyforclassfile='/mymodule/class/myobject.class.php'; $keyforelement='myobject@mymodule';
-               include DOL_DOCUMENT_ROOT.'/core/commonfieldsinimport.inc.php';
-               $import_extrafield_sample = array();
-               $keyforselect='myobject'; $keyforaliasextra='extra'; $keyforelement='myobject@mymodule';
-               include DOL_DOCUMENT_ROOT.'/core/extrafieldsinimport.inc.php';
-               $this->import_fieldshidden_array[$r] = array('extra.fk_object' => 'lastrowid-'.MAIN_DB_PREFIX.'mymodule_myobject');
-               $this->import_regex_array[$r] = array();
-               $this->import_examplevalues_array[$r] = array_merge($import_sample, $import_extrafield_sample);
-               $this->import_updatekeys_array[$r] = array('t.ref' => 'Ref');
-               $this->import_convertvalue_array[$r] = array(
-                       't.ref' => array(
-                               'rule'=>'getrefifauto',
-                               'class'=>(empty($conf->global->MYMODULE_MYOBJECT_ADDON) ? 'mod_myobject_standard' : $conf->global->MYMODULE_MYOBJECT_ADDON),
-                               'path'=>"/core/modules/commande/".(empty($conf->global->MYMODULE_MYOBJECT_ADDON) ? 'mod_myobject_standard' : $conf->global->MYMODULE_MYOBJECT_ADDON).'.php'
-                               'classobject'=>'MyObject',
-                               'pathobject'=>'/mymodule/class/myobject.class.php',
-                       ),
-                       't.fk_soc' => array('rule' => 'fetchidfromref', 'file' => '/societe/class/societe.class.php', 'class' => 'Societe', 'method' => 'fetch', 'element' => 'ThirdParty'),
-                       't.fk_user_valid' => array('rule' => 'fetchidfromref', 'file' => '/user/class/user.class.php', 'class' => 'User', 'method' => 'fetch', 'element' => 'user'),
-                       't.fk_mode_reglement' => array('rule' => 'fetchidfromcodeorlabel', 'file' => '/compta/paiement/class/cpaiement.class.php', 'class' => 'Cpaiement', 'method' => 'fetch', 'element' => 'cpayment'),
-               );
-               $r++; */
-               /* END MODULEBUILDER IMPORT MYOBJECT */
-       }
-
-       /**
-        *  Function called when module is enabled.
-        *  The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
-        *  It also creates data directories
-        *
-        *  @param      string  $options    Options when enabling module ('', 'noboxes')
-        *  @return     int                     1 if OK, 0 if KO
-        */
-       public function init($options = '')
-       {
-               global $conf, $langs;
-
-               //$result = $this->_load_tables('/install/mysql/', 'mymodule');
-               $result = $this->_load_tables('/mymodule/sql/');
-               if ($result < 0) {
-                       return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default')
-               }
-
-               // Create extrafields during init
-               //include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
-               //$extrafields = new ExtraFields($this->db);
-               //$result1=$extrafields->addExtraField('mymodule_myattr1', "New Attr 1 label", 'boolean', 1,  3, 'thirdparty',   0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule', '$conf->mymodule->enabled');
-               //$result2=$extrafields->addExtraField('mymodule_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project',      0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule', '$conf->mymodule->enabled');
-               //$result3=$extrafields->addExtraField('mymodule_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule', '$conf->mymodule->enabled');
-               //$result4=$extrafields->addExtraField('mymodule_myattr4', "New Attr 4 label", 'select',  1,  3, 'thirdparty',   0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', 0, 0, '', '', 'mymodule@mymodule', '$conf->mymodule->enabled');
-               //$result5=$extrafields->addExtraField('mymodule_myattr5', "New Attr 5 label", 'text',    1, 10, 'user',         0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule', '$conf->mymodule->enabled');
-
-               // Permissions
-               $this->remove($options);
-
-               $sql = array();
-
-               // Document templates
-               $moduledir = dol_sanitizeFileName('mymodule');
-               $myTmpObjects = array();
-               $myTmpObjects['MyObject'] = array('includerefgeneration'=>0, 'includedocgeneration'=>0);
-
-               foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
-                       if ($myTmpObjectKey == 'MyObject') {
-                               continue;
-                       }
-                       if ($myTmpObjectArray['includerefgeneration']) {
-                               $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/'.$moduledir.'/template_myobjects.odt';
-                               $dirodt = DOL_DATA_ROOT.'/doctemplates/'.$moduledir;
-                               $dest = $dirodt.'/template_myobjects.odt';
-
-                               if (file_exists($src) && !file_exists($dest)) {
-                                       require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-                                       dol_mkdir($dirodt);
-                                       $result = dol_copy($src, $dest, 0, 0);
-                                       if ($result < 0) {
-                                               $langs->load("errors");
-                                               $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest);
-                                               return 0;
-                                       }
-                               }
-
-                               $sql = array_merge($sql, array(
-                                       "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'standard_".strtolower($myTmpObjectKey)."' AND type = '".$this->db->escape(strtolower($myTmpObjectKey))."' AND entity = ".((int) $conf->entity),
-                                       "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('standard_".strtolower($myTmpObjectKey)."', '".$this->db->escape(strtolower($myTmpObjectKey))."', ".((int) $conf->entity).")",
-                                       "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'generic_".strtolower($myTmpObjectKey)."_odt' AND type = '".$this->db->escape(strtolower($myTmpObjectKey))."' AND entity = ".((int) $conf->entity),
-                                       "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('generic_".strtolower($myTmpObjectKey)."_odt', '".$this->db->escape(strtolower($myTmpObjectKey))."', ".((int) $conf->entity).")"
-                               ));
-                       }
-               }
-
-               return $this->_init($sql, $options);
-       }
-
-       /**
-        *  Function called when module is disabled.
-        *  Remove from database constants, boxes and permissions from Dolibarr database.
-        *  Data directories are not deleted
-        *
-        *  @param      string  $options    Options when enabling module ('', 'noboxes')
-        *  @return     int                 1 if OK, 0 if KO
-        */
-       public function remove($options = '')
-       {
-               $sql = array();
-               return $this->_remove($sql, $options);
-       }
-}
diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php
deleted file mode 100644 (file)
index 0548698..0000000
+++ /dev/null
@@ -1,1343 +0,0 @@
-<?php
-/* Copyright (C) 2004-2014  Laurent Destailleur     <eldy@users.sourceforge.net>
- * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@inodbox.com>
- * Copyright (C) 2008       Raphael Bertrand        <raphael.bertrand@resultic.fr>
- * Copyright (C) 2010-2014  Juanjo Menent           <jmenent@2byte.es>
- * Copyright (C) 2012       Christophe Battarel     <christophe.battarel@altairis.fr>
- * Copyright (C) 2012       Cédric Salvador         <csalvador@gpcsolutions.fr>
- * Copyright (C) 2012-2014  Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
- * Copyright (C) 2015       Marcos García           <marcosgdf@gmail.com>
- * Copyright (C) 2017       Ferran Marcet           <fmarcet@2byte.es>
- * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- * or see https://www.gnu.org/
- */
-
-/**
- *  \file       htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard.modules.php
- *  \ingroup    mymodule
- *  \brief      File of class to generate document from standard template
- */
-
-dol_include_once('/mymodule/core/modules/mymodule/modules_myobject.php');
-require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
-
-
-/**
- *     Class to manage PDF template standard_myobject
- */
-class pdf_standard_myobject extends ModelePDFMyObject
-{
-       /**
-        * @var DoliDb Database handler
-        */
-       public $db;
-
-       /**
-        * @var string model name
-        */
-       public $name;
-
-       /**
-        * @var string model description (short text)
-        */
-       public $description;
-
-       /**
-        * @var int     Save the name of generated file as the main doc when generating a doc with this template
-        */
-       public $update_main_doc_field;
-
-       /**
-        * @var string document type
-        */
-       public $type;
-
-       /**
-        * @var array Minimum version of PHP required by module.
-        * e.g.: PHP â‰¥ 7.0 = array(7, 0)
-        */
-       public $phpmin = array(7, 0);
-
-       /**
-        * Dolibarr version of the loaded document
-        * @var string
-        */
-       public $version = 'dolibarr';
-
-       /**
-        * Issuer
-        * @var Societe Object that emits
-        */
-       public $emetteur;
-
-       /**
-        * @var bool Situation invoice type
-        */
-       public $situationinvoice;
-
-
-       /**
-        * @var array of document table columns
-        */
-       public $cols;
-
-
-       /**
-        *      Constructor
-        *
-        *  @param              DoliDB          $db      Database handler
-        */
-       public function __construct($db)
-       {
-               global $conf, $langs, $mysoc;
-
-               // Translations
-               $langs->loadLangs(array("main", "bills"));
-
-               $this->db = $db;
-               $this->name = "standard";
-               $this->description = $langs->trans('DocumentModelStandardPDF');
-               $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
-
-               // Dimension page
-               $this->type = 'pdf';
-               $formatarray = pdf_getFormat();
-               $this->page_largeur = $formatarray['width'];
-               $this->page_hauteur = $formatarray['height'];
-               $this->format = array($this->page_largeur, $this->page_hauteur);
-               $this->marge_gauche = getDolGlobalInt('MAIN_PDF_MARGIN_LEFT', 10);
-               $this->marge_droite = getDolGlobalInt('MAIN_PDF_MARGIN_RIGHT', 10);
-               $this->marge_haute = getDolGlobalInt('MAIN_PDF_MARGIN_TOP', 10);
-               $this->marge_basse = getDolGlobalInt('MAIN_PDF_MARGIN_BOTTOM', 10);
-
-               // Get source company
-               $this->emetteur = $mysoc;
-               if (empty($this->emetteur->country_code)) {
-                       $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
-               }
-
-               // Define position of columns
-               $this->posxdesc = $this->marge_gauche + 1; // used for notes ans other stuff
-
-
-               $this->tabTitleHeight = 5; // default height
-
-               //  Use new system for position of columns, view  $this->defineColumnField()
-
-               $this->tva = array();
-               $this->localtax1 = array();
-               $this->localtax2 = array();
-               $this->atleastoneratenotnull = 0;
-               $this->atleastonediscount = 0;
-               $this->situationinvoice = false;
-       }
-
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        *  Function to build pdf onto disk
-        *
-        *  @param              Object          $object                         Object to generate
-        *  @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
-        *  @param              int                     $hidedesc                       Do not show desc
-        *  @param              int                     $hideref                        Do not show ref
-        *  @return     int                                     1=OK, 0=KO
-        */
-       public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
-       {
-               // phpcs:enable
-               global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblines;
-
-               dol_syslog("write_file outputlangs->defaultlang=".(is_object($outputlangs) ? $outputlangs->defaultlang : 'null'));
-
-               if (!is_object($outputlangs)) {
-                       $outputlangs = $langs;
-               }
-               // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
-               if (!empty($conf->global->MAIN_USE_FPDF)) {
-                       $outputlangs->charset_output = 'ISO-8859-1';
-               }
-
-               // Load translation files required by the page
-               $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies"));
-
-               if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && $outputlangs->defaultlang != $conf->global->PDF_USE_ALSO_LANGUAGE_CODE) {
-                       global $outputlangsbis;
-                       $outputlangsbis = new Translate('', $conf);
-                       $outputlangsbis->setDefaultLang($conf->global->PDF_USE_ALSO_LANGUAGE_CODE);
-                       $outputlangsbis->loadLangs(array("main", "bills", "products", "dict", "companies"));
-               }
-
-               $nblines = (is_array($object->lines) ? count($object->lines) : 0);
-
-               $hidetop = 0;
-               if (!empty($conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE)) {
-                       $hidetop = $conf->global->MAIN_PDF_DISABLE_COL_HEAD_TITLE;
-               }
-
-               // Loop on each lines to detect if there is at least one image to show
-               $realpatharray = array();
-               $this->atleastonephoto = false;
-               /*
-               if (!empty($conf->global->MAIN_GENERATE_MYOBJECT_WITH_PICTURE))
-               {
-                       $objphoto = new Product($this->db);
-
-                       for ($i = 0; $i < $nblines; $i++)
-                       {
-                               if (empty($object->lines[$i]->fk_product)) continue;
-
-                               //var_dump($objphoto->ref);exit;
-                               if (getDolGlobalInt('PRODUCT_USE_OLD_PATH_FOR_PHOTO')) {
-                                       $pdir[0] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/";
-                                       $pdir[1] = get_exdir(0, 0, 0, 0, $objphoto, 'product').dol_sanitizeFileName($objphoto->ref).'/';
-                               } else {
-                                       $pdir[0] = get_exdir(0, 0, 0, 0, $objphoto, 'product'); // default
-                                       $pdir[1] = get_exdir($objphoto->id, 2, 0, 0, $objphoto, 'product').$objphoto->id."/photos/"; // alternative
-                               }
-
-                               $arephoto = false;
-                               foreach ($pdir as $midir)
-                               {
-                                       if (!$arephoto)
-                                       {
-                                               $dir = $conf->product->dir_output.'/'.$midir;
-
-                                               foreach ($objphoto->liste_photos($dir, 1) as $key => $obj)
-                                               {
-                                                       if (!getDolGlobalInt('CAT_HIGH_QUALITY_IMAGES'))                // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
-                                                       {
-                                                               if ($obj['photo_vignette'])
-                                                               {
-                                                                       $filename = $obj['photo_vignette'];
-                                                               } else {
-                                                                       $filename = $obj['photo'];
-                                                               }
-                                                       } else {
-                                                               $filename = $obj['photo'];
-                                                       }
-
-                                                       $realpath = $dir.$filename;
-                                                       $arephoto = true;
-                                                       $this->atleastonephoto = true;
-                                               }
-                                       }
-                               }
-
-                               if ($realpath && $arephoto) $realpatharray[$i] = $realpath;
-                       }
-               }
-               */
-
-               //if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva;
-
-               if ($conf->mymodule->dir_output.'/myobject') {
-                       $object->fetch_thirdparty();
-
-                       // Definition of $dir and $file
-                       if ($object->specimen) {
-                               $dir = $conf->mymodule->dir_output.'/myobject';
-                               $file = $dir."/SPECIMEN.pdf";
-                       } else {
-                               $objectref = dol_sanitizeFileName($object->ref);
-                               $dir = $conf->mymodule->dir_output.'/myobject/'.$objectref;
-                               $file = $dir."/".$objectref.".pdf";
-                       }
-                       if (!file_exists($dir)) {
-                               if (dol_mkdir($dir) < 0) {
-                                       $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
-                                       return 0;
-                               }
-                       }
-
-                       if (file_exists($dir)) {
-                               // Add pdfgeneration hook
-                               if (!is_object($hookmanager)) {
-                                       include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
-                                       $hookmanager = new HookManager($this->db);
-                               }
-                               $hookmanager->initHooks(array('pdfgeneration'));
-                               $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
-                               global $action;
-                               $reshook = $hookmanager->executeHooks('beforePDFCreation', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
-
-                               // Set nblines with the new facture lines content after hook
-                               $nblines = (is_array($object->lines) ? count($object->lines) : 0);
-
-                               // Create pdf instance
-                               $pdf = pdf_getInstance($this->format);
-                               $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
-                               $pdf->SetAutoPageBreak(1, 0);
-
-                               $heightforinfotot = 50; // Height reserved to output the info and total part and payment part
-                               $heightforfreetext = (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT) ? $conf->global->MAIN_PDF_FREETEXT_HEIGHT : 5); // Height reserved to output the free text on last page
-                               $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 12 : 22); // Height reserved to output the footer (value include bottom margin)
-
-                               if (class_exists('TCPDF')) {
-                                       $pdf->setPrintHeader(false);
-                                       $pdf->setPrintFooter(false);
-                               }
-                               $pdf->SetFont(pdf_getPDFFont($outputlangs));
-
-                               // Set path to the background PDF File
-                               if (!empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) {
-                                       $pagecount = $pdf->setSourceFile($conf->mycompany->multidir_output[$object->entity].'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
-                                       $tplidx = $pdf->importPage(1);
-                               }
-
-                               $pdf->Open();
-                               $pagenb = 0;
-                               $pdf->SetDrawColor(128, 128, 128);
-
-                               $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
-                               $pdf->SetSubject($outputlangs->transnoentities("PdfTitle"));
-                               $pdf->SetCreator("Dolibarr ".DOL_VERSION);
-                               $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
-                               $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
-                               if (getDolGlobalString('MAIN_DISABLE_PDF_COMPRESSION')) {
-                                       $pdf->SetCompression(false);
-                               }
-
-                               // Set certificate
-                               $cert = empty($user->conf->CERTIFICATE_CRT) ? '' : $user->conf->CERTIFICATE_CRT;
-                               // If user has no certificate, we try to take the company one
-                               if (!$cert) {
-                                       $cert = empty($conf->global->CERTIFICATE_CRT) ? '' : $conf->global->CERTIFICATE_CRT;
-                               }
-                               // If a certificate is found
-                               if ($cert) {
-                                       $info = array(
-                                               'Name' => $this->emetteur->name,
-                                               'Location' => getCountry($this->emetteur->country_code, 0),
-                                               'Reason' => 'MYOBJECT',
-                                               'ContactInfo' => $this->emetteur->email
-                                       );
-                                       $pdf->setSignature($cert, $cert, $this->emetteur->name, '', 2, $info);
-                               }
-
-                               $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
-
-                               // New page
-                               $pdf->AddPage();
-                               if (!empty($tplidx)) {
-                                       $pdf->useTemplate($tplidx);
-                               }
-                               $pagenb++;
-
-                               $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, $outputlangsbis);
-                               $pdf->SetFont('', '', $default_font_size - 1);
-                               $pdf->MultiCell(0, 3, ''); // Set interline to 3
-                               $pdf->SetTextColor(0, 0, 0);
-
-                               $tab_top = 90 + $top_shift;
-                               $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD) ? 42 + $top_shift : 10);
-                               $tab_height = 130 - $top_shift;
-                               $tab_height_newpage = 150;
-                               if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
-                                       $tab_height_newpage -= $top_shift;
-                               }
-
-                               $nexY = $tab_top - 1;
-
-                               // Display notes
-                               $notetoshow = empty($object->note_public) ? '' : $object->note_public;
-                               // Extrafields in note
-                               $extranote = $this->getExtrafieldsInHtml($object, $outputlangs);
-                               if (!empty($extranote)) {
-                                       $notetoshow = dol_concatdesc($notetoshow, $extranote);
-                               }
-
-                               $pagenb = $pdf->getPage();
-                               if ($notetoshow) {
-                                       $tab_top -= 2;
-
-                                       $tab_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
-                                       $pageposbeforenote = $pagenb;
-
-                                       $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object);
-                                       complete_substitutions_array($substitutionarray, $outputlangs, $object);
-                                       $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
-                                       $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow);
-
-                                       $pdf->startTransaction();
-
-                                       $pdf->SetFont('', '', $default_font_size - 1);
-                                       $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
-                                       // Description
-                                       $pageposafternote = $pdf->getPage();
-                                       $posyafter = $pdf->GetY();
-
-                                       if ($pageposafternote > $pageposbeforenote) {
-                                               $pdf->rollbackTransaction(true);
-
-                                               // prepare pages to receive notes
-                                               while ($pagenb < $pageposafternote) {
-                                                       $pdf->AddPage();
-                                                       $pagenb++;
-                                                       if (!empty($tplidx)) {
-                                                               $pdf->useTemplate($tplidx);
-                                                       }
-                                                       if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
-                                                               $this->_pagehead($pdf, $object, 0, $outputlangs);
-                                                       }
-                                                       // $this->_pagefoot($pdf,$object,$outputlangs,1);
-                                                       $pdf->setTopMargin($tab_top_newpage);
-                                                       // The only function to edit the bottom margin of current page to set it.
-                                                       $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
-                                               }
-
-                                               // back to start
-                                               $pdf->setPage($pageposbeforenote);
-                                               $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
-                                               $pdf->SetFont('', '', $default_font_size - 1);
-                                               $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
-                                               $pageposafternote = $pdf->getPage();
-
-                                               $posyafter = $pdf->GetY();
-
-                                               if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {        // There is no space left for total+free text
-                                                       $pdf->AddPage('', '', true);
-                                                       $pagenb++;
-                                                       $pageposafternote++;
-                                                       $pdf->setPage($pageposafternote);
-                                                       $pdf->setTopMargin($tab_top_newpage);
-                                                       // The only function to edit the bottom margin of current page to set it.
-                                                       $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
-                                                       //$posyafter = $tab_top_newpage;
-                                               }
-
-
-                                               // apply note frame to previous pages
-                                               $i = $pageposbeforenote;
-                                               while ($i < $pageposafternote) {
-                                                       $pdf->setPage($i);
-
-
-                                                       $pdf->SetDrawColor(128, 128, 128);
-                                                       // Draw note frame
-                                                       if ($i > $pageposbeforenote) {
-                                                               $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
-                                                               $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
-                                                       } else {
-                                                               $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
-                                                               $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
-                                                       }
-
-                                                       // Add footer
-                                                       $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
-                                                       $this->_pagefoot($pdf, $object, $outputlangs, 1);
-
-                                                       $i++;
-                                               }
-
-                                               // apply note frame to last page
-                                               $pdf->setPage($pageposafternote);
-                                               if (!empty($tplidx)) {
-                                                       $pdf->useTemplate($tplidx);
-                                               }
-                                               if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
-                                                       $this->_pagehead($pdf, $object, 0, $outputlangs);
-                                               }
-                                               $height_note = $posyafter - $tab_top_newpage;
-                                               $pdf->Rect($this->marge_gauche, $tab_top_newpage - 1, $tab_width, $height_note + 1);
-                                       } else // No pagebreak
-                                       {
-                                               $pdf->commitTransaction();
-                                               $posyafter = $pdf->GetY();
-                                               $height_note = $posyafter - $tab_top;
-                                               $pdf->Rect($this->marge_gauche, $tab_top - 1, $tab_width, $height_note + 1);
-
-
-                                               if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + 20))) {
-                                                       // not enough space, need to add page
-                                                       $pdf->AddPage('', '', true);
-                                                       $pagenb++;
-                                                       $pageposafternote++;
-                                                       $pdf->setPage($pageposafternote);
-                                                       if (!empty($tplidx)) {
-                                                               $pdf->useTemplate($tplidx);
-                                                       }
-                                                       if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
-                                                               $this->_pagehead($pdf, $object, 0, $outputlangs);
-                                                       }
-
-                                                       $posyafter = $tab_top_newpage;
-                                               }
-                                       }
-
-                                       $tab_height = $tab_height - $height_note;
-                                       $tab_top = $posyafter + 6;
-                               } else {
-                                       $height_note = 0;
-                               }
-
-                               // Use new auto column system
-                               $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref);
-
-                               // Table simulation to know the height of the title line
-                               $pdf->startTransaction();
-                               $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
-                               $pdf->rollbackTransaction(true);
-
-                               $nexY = $tab_top + $this->tabTitleHeight;
-
-                               // Loop on each lines
-                               $pageposbeforeprintlines = $pdf->getPage();
-                               $pagenb = $pageposbeforeprintlines;
-                               for ($i = 0; $i < $nblines; $i++) {
-                                       $curY = $nexY;
-                                       $pdf->SetFont('', '', $default_font_size - 1); // Into loop to work with multipage
-                                       $pdf->SetTextColor(0, 0, 0);
-
-                                       // Define size of image if we need it
-                                       $imglinesize = array();
-                                       if (!empty($realpatharray[$i])) {
-                                               $imglinesize = pdf_getSizeForImage($realpatharray[$i]);
-                                       }
-
-                                       $pdf->setTopMargin($tab_top_newpage);
-                                       $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext + $heightforinfotot); // The only function to edit the bottom margin of current page to set it.
-                                       $pageposbefore = $pdf->getPage();
-
-                                       $showpricebeforepagebreak = 1;
-                                       $posYAfterImage = 0;
-
-                                       if ($this->getColumnStatus('photo')) {
-                                               // We start with Photo of product line
-                                               if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) {  // If photo too high, we moved completely on new page
-                                                       $pdf->AddPage('', '', true);
-                                                       if (!empty($tplidx)) {
-                                                               $pdf->useTemplate($tplidx);
-                                                       }
-                                                       $pdf->setPage($pageposbefore + 1);
-
-                                                       $curY = $tab_top_newpage;
-
-                                                       // Allows data in the first page if description is long enough to break in multiples pages
-                                                       if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
-                                                               $showpricebeforepagebreak = 1;
-                                                       } else {
-                                                               $showpricebeforepagebreak = 0;
-                                                       }
-                                               }
-
-                                               if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) {
-                                                       $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
-                                                       // $pdf->Image does not increase value return by getY, so we save it manually
-                                                       $posYAfterImage = $curY + $imglinesize['height'];
-                                               }
-                                       }
-
-                                       // Description of product line
-                                       if ($this->getColumnStatus('desc')) {
-                                               $pdf->startTransaction();
-
-                                               $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
-                                               $pageposafter = $pdf->getPage();
-
-                                               if ($pageposafter > $pageposbefore) {   // There is a pagebreak
-                                                       $pdf->rollbackTransaction(true);
-                                                       $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
-
-                                                       $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc);
-
-                                                       $pageposafter = $pdf->getPage();
-                                                       $posyafter = $pdf->GetY();
-                                                       //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
-                                                       if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) { // There is no space left for total+free text
-                                                               if ($i == ($nblines - 1)) {     // No more lines, and no space left to show total, so we create a new page
-                                                                       $pdf->AddPage('', '', true);
-                                                                       if (!empty($tplidx)) {
-                                                                               $pdf->useTemplate($tplidx);
-                                                                       }
-                                                                       $pdf->setPage($pageposafter + 1);
-                                                               }
-                                                       } else {
-                                                               // We found a page break
-                                                               // Allows data in the first page if description is long enough to break in multiples pages
-                                                               if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) {
-                                                                       $showpricebeforepagebreak = 1;
-                                                               } else {
-                                                                       $showpricebeforepagebreak = 0;
-                                                               }
-                                                       }
-                                               } else // No pagebreak
-                                               {
-                                                       $pdf->commitTransaction();
-                                               }
-                                       }
-
-                                       $nexY = $pdf->GetY();
-                                       $pageposafter = $pdf->getPage();
-                                       $pdf->setPage($pageposbefore);
-                                       $pdf->setTopMargin($this->marge_haute);
-                                       $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
-
-                                       // We suppose that a too long description or photo were moved completely on next page
-                                       if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
-                                               $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
-                                       }
-
-                                       $pdf->SetFont('', '', $default_font_size - 1); // On repositionne la police par defaut
-
-                                       // Quantity
-                                       // Enough for 6 chars
-                                       if ($this->getColumnStatus('qty')) {
-                                               $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
-                                               $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
-                                               $nexY = max($pdf->GetY(), $nexY);
-                                       }
-
-                                       // Extrafields
-                                       if (!empty($object->lines[$i]->array_options)) {
-                                               foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue) {
-                                                       if ($this->getColumnStatus($extrafieldColKey)) {
-                                                               $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey, $outputlangs);
-                                                               $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue);
-                                                               $nexY = max($pdf->GetY(), $nexY);
-                                                       }
-                                               }
-                                       }
-
-
-                                       $parameters = array(
-                                               'object' => $object,
-                                               'i' => $i,
-                                               'pdf' =>& $pdf,
-                                               'curY' =>& $curY,
-                                               'nexY' =>& $nexY,
-                                               'outputlangs' => $outputlangs,
-                                               'hidedetails' => $hidedetails
-                                       );
-                                       $reshook = $hookmanager->executeHooks('printPDFline', $parameters, $this); // Note that $object may have been modified by hook
-
-
-                                       $sign = 1;
-                                       // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
-                                       $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
-                                       if ($prev_progress > 0 && !empty($object->lines[$i]->situation_percent)) { // Compute progress from previous situation
-                                               if (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) {
-                                                       $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
-                                               } else {
-                                                       $tvaligne = $sign * $object->lines[$i]->total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
-                                               }
-                                       } else {
-                                               if (isModEnabled("multicurrency") && $object->multicurrency_tx != 1) {
-                                                       $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva;
-                                               } else {
-                                                       $tvaligne = $sign * $object->lines[$i]->total_tva;
-                                               }
-                                       }
-
-                                       $localtax1ligne = $object->lines[$i]->total_localtax1;
-                                       $localtax2ligne = $object->lines[$i]->total_localtax2;
-                                       $localtax1_rate = $object->lines[$i]->localtax1_tx;
-                                       $localtax2_rate = $object->lines[$i]->localtax2_tx;
-                                       $localtax1_type = $object->lines[$i]->localtax1_type;
-                                       $localtax2_type = $object->lines[$i]->localtax2_type;
-
-                                       if ($object->remise_percent) {
-                                               $tvaligne -= ($tvaligne * $object->remise_percent) / 100;
-                                       }
-                                       if ($object->remise_percent) {
-                                               $localtax1ligne -= ($localtax1ligne * $object->remise_percent) / 100;
-                                       }
-                                       if ($object->remise_percent) {
-                                               $localtax2ligne -= ($localtax2ligne * $object->remise_percent) / 100;
-                                       }
-
-                                       $vatrate = (string) $object->lines[$i]->tva_tx;
-
-                                       // Retrieve type from database for backward compatibility with old records
-                                       if ((!isset($localtax1_type) || $localtax1_type == '' || !isset($localtax2_type) || $localtax2_type == '') // if tax type not defined
-                                               && (!empty($localtax1_rate) || !empty($localtax2_rate))) { // and there is local tax
-                                               $localtaxtmp_array = getLocalTaxesFromRate($vatrate, 0, $object->thirdparty, $mysoc);
-                                               $localtax1_type = isset($localtaxtmp_array[0]) ? $localtaxtmp_array[0] : '';
-                                               $localtax2_type = isset($localtaxtmp_array[2]) ? $localtaxtmp_array[2] : '';
-                                       }
-
-                                       // retrieve global local tax
-                                       if ($localtax1_type && $localtax1ligne != 0) {
-                                               $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
-                                       }
-                                       if ($localtax2_type && $localtax2ligne != 0) {
-                                               $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
-                                       }
-
-                                       if (($object->lines[$i]->info_bits & 0x01) == 0x01) {
-                                               $vatrate .= '*';
-                                       }
-                                       if (!isset($this->tva[$vatrate])) {
-                                               $this->tva[$vatrate] = 0;
-                                       }
-                                       $this->tva[$vatrate] += $tvaligne;
-
-                                       $nexY = max($nexY, $posYAfterImage);
-
-                                       // Add line
-                                       if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) {
-                                               $pdf->setPage($pageposafter);
-                                               $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80)));
-                                               //$pdf->SetDrawColor(190,190,200);
-                                               $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY);
-                                               $pdf->SetLineStyle(array('dash'=>0));
-                                       }
-
-                                       // Detect if some page were added automatically and output _tableau for past pages
-                                       while ($pagenb < $pageposafter) {
-                                               $pdf->setPage($pagenb);
-                                               if ($pagenb == $pageposbeforeprintlines) {
-                                                       $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
-                                               } else {
-                                                       $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
-                                               }
-                                               $this->_pagefoot($pdf, $object, $outputlangs, 1);
-                                               $pagenb++;
-                                               $pdf->setPage($pagenb);
-                                               $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
-                                               if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
-                                                       $this->_pagehead($pdf, $object, 0, $outputlangs);
-                                               }
-                                               if (!empty($tplidx)) {
-                                                       $pdf->useTemplate($tplidx);
-                                               }
-                                       }
-
-                                       if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) {
-                                               if ($pagenb == $pageposafter) {
-                                                       $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis);
-                                               } else {
-                                                       $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis);
-                                               }
-                                               $this->_pagefoot($pdf, $object, $outputlangs, 1);
-                                               // New page
-                                               $pdf->AddPage();
-                                               if (!empty($tplidx)) {
-                                                       $pdf->useTemplate($tplidx);
-                                               }
-                                               $pagenb++;
-                                               if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) {
-                                                       $this->_pagehead($pdf, $object, 0, $outputlangs);
-                                               }
-                                       }
-                               }
-
-                               // Show square
-                               if ($pagenb == $pageposbeforeprintlines) {
-                                       $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis);
-                                       $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
-                               } else {
-                                       $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis);
-                                       $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
-                               }
-
-                               // Display infos area
-                               //$posy = $this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
-
-                               // Display total zone
-                               //$posy = $this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
-
-                               // Display payment area
-                               /*
-                               if (($deja_regle || $amount_credit_notes_included || $amount_deposits_included) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS))
-                               {
-                                       $posy = $this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
-                               }
-                               */
-
-                               // Pagefoot
-                               $this->_pagefoot($pdf, $object, $outputlangs);
-                               if (method_exists($pdf, 'AliasNbPages')) {
-                                       $pdf->AliasNbPages();
-                               }
-
-                               $pdf->Close();
-
-                               $pdf->Output($file, 'F');
-
-                               // Add pdfgeneration hook
-                               $hookmanager->initHooks(array('pdfgeneration'));
-                               $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) {
-                                       $this->error = $hookmanager->error;
-                                       $this->errors = $hookmanager->errors;
-                               }
-
-                               if (!empty($conf->global->MAIN_UMASK)) {
-                                       @chmod($file, octdec($conf->global->MAIN_UMASK));
-                               }
-
-                                       $this->result = array('fullpath'=>$file);
-
-                                       return 1; // No error
-                       } else {
-                               $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
-                               return 0;
-                       }
-               } else {
-                       $this->error = $langs->transnoentities("ErrorConstantNotDefined", "FAC_OUTPUTDIR");
-                       return 0;
-               }
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        *  Return list of active generation modules
-        *
-        *  @param      DoliDB  $db                             Database handler
-        *  @param  integer     $maxfilenamelength  Max length of value to show
-        *  @return     array                                           List of templates
-        */
-       public static function liste_modeles($db, $maxfilenamelength = 0)
-       {
-               // phpcs:enable
-               return parent::liste_modeles($db, $maxfilenamelength); // TODO: Change the autogenerated stub
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
-       /**
-        *   Show table for lines
-        *
-        *   @param             tcpdf                   $pdf                    Object PDF
-        *   @param             string          $tab_top                Top position of table
-        *   @param             string          $tab_height             Height of table (rectangle)
-        *   @param             int                     $nexY                   Y (not used)
-        *   @param             Translate       $outputlangs    Langs object
-        *   @param             int                     $hidetop                1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
-        *   @param             int                     $hidebottom             Hide bottom bar of array
-        *   @param             string          $currency               Currency code
-        *   @param             Translate       $outputlangsbis Langs object bis
-        *   @return    void
-        */
-       protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null)
-       {
-               global $conf;
-
-               // Force to disable hidetop and hidebottom
-               $hidebottom = 0;
-               if ($hidetop) {
-                       $hidetop = -1;
-               }
-
-               $currency = !empty($currency) ? $currency : $conf->currency;
-               $default_font_size = pdf_getPDFFontSize($outputlangs);
-
-               // Amount in (at tab_top - 1)
-               $pdf->SetTextColor(0, 0, 0);
-               $pdf->SetFont('', '', $default_font_size - 2);
-
-               if (empty($hidetop)) {
-                       $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency));
-                       if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
-                               $titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency));
-                       }
-
-                       $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4);
-                       $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
-
-                       //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
-                       if (!empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) {
-                               $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_droite - $this->marge_gauche, $this->tabTitleHeight, 'F', null, explode(',', $conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
-                       }
-               }
-
-               $pdf->SetDrawColor(128, 128, 128);
-               $pdf->SetFont('', '', $default_font_size - 1);
-
-               // Output Rect
-               $this->printRect($pdf, $this->marge_gauche, $tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect takes a length in 3rd parameter and 4th parameter
-
-
-               $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop);
-
-               if (empty($hidetop)) {
-                       $pdf->line($this->marge_gauche, $tab_top + $this->tabTitleHeight, $this->page_largeur - $this->marge_droite, $tab_top + $this->tabTitleHeight); // line takes a position y in 2nd parameter and 4th parameter
-               }
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
-       /**
-        *  Show top header of page.
-        *
-        *  @param      TCPDF           $pdf                    Object PDF
-        *  @param  Object              $object         Object to show
-        *  @param  int         $showaddress    0=no, 1=yes
-        *  @param  Translate   $outputlangs    Object lang for output
-        *  @param  Translate   $outputlangsbis Object lang for output bis
-        *  @return     void
-        */
-       protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null)
-       {
-               global $conf, $langs;
-
-               // Load traductions files required by page
-               $outputlangs->loadLangs(array("main", "bills", "propal", "companies"));
-
-               $default_font_size = pdf_getPDFFontSize($outputlangs);
-
-               pdf_pagehead($pdf, $outputlangs, $this->page_hauteur);
-
-               // Show Draft Watermark
-               if ($object->statut == $object::STATUS_DRAFT && getDolGlobalString('MYMODULE_DRAFT_WATERMARK')) {
-                       pdf_watermark($pdf, $outputlangs, $this->page_hauteur, $this->page_largeur, 'mm', dol_escape_htmltag(getDolGlobalString('MYMODULE_DRAFT_WATERMARK')));
-               }
-
-               $pdf->SetTextColor(0, 0, 60);
-               $pdf->SetFont('', 'B', $default_font_size + 3);
-
-               $w = 110;
-
-               $posy = $this->marge_haute;
-               $posx = $this->page_largeur - $this->marge_droite - $w;
-
-               $pdf->SetXY($this->marge_gauche, $posy);
-
-               // Logo
-               if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO)) {
-                       if ($this->emetteur->logo) {
-                               $logodir = $conf->mycompany->dir_output;
-                               if (!empty($conf->mycompany->multidir_output[$object->entity])) {
-                                       $logodir = $conf->mycompany->multidir_output[$object->entity];
-                               }
-                               if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) {
-                                       $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small;
-                               } else {
-                                       $logo = $logodir.'/logos/'.$this->emetteur->logo;
-                               }
-                               if (is_readable($logo)) {
-                                       $height = pdf_getHeightForLogo($logo);
-                                       $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
-                               } else {
-                                       $pdf->SetTextColor(200, 0, 0);
-                                       $pdf->SetFont('', 'B', $default_font_size - 2);
-                                       $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound", $logo), 0, 'L');
-                                       $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
-                               }
-                       } else {
-                               $text = $this->emetteur->name;
-                               $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
-                       }
-               }
-
-               $pdf->SetFont('', 'B', $default_font_size + 3);
-               $pdf->SetXY($posx, $posy);
-               $pdf->SetTextColor(0, 0, 60);
-               $title = $outputlangs->transnoentities("PdfTitle");
-               if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
-                       $title .= ' - ';
-                       $title .= $outputlangsbis->transnoentities("PdfTitle");
-               }
-               $pdf->MultiCell($w, 3, $title, '', 'R');
-
-               $pdf->SetFont('', 'B', $default_font_size);
-
-               $posy += 5;
-               $pdf->SetXY($posx, $posy);
-               $pdf->SetTextColor(0, 0, 60);
-               $textref = $outputlangs->transnoentities("Ref")." : ".$outputlangs->convToOutputCharset($object->ref);
-               if ($object->statut == $object::STATUS_DRAFT) {
-                       $pdf->SetTextColor(128, 0, 0);
-                       $textref .= ' - '.$outputlangs->transnoentities("NotValidated");
-               }
-               $pdf->MultiCell($w, 4, $textref, '', 'R');
-
-               $posy += 1;
-               $pdf->SetFont('', '', $default_font_size - 2);
-
-               if ($object->ref_client) {
-                       $posy += 4;
-                       $pdf->SetXY($posx, $posy);
-                       $pdf->SetTextColor(0, 0, 60);
-                       $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R');
-               }
-
-               if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) {
-                       $object->fetch_projet();
-                       if (!empty($object->project->ref)) {
-                               $posy += 3;
-                               $pdf->SetXY($posx, $posy);
-                               $pdf->SetTextColor(0, 0, 60);
-                               $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R');
-                       }
-               }
-
-               if (!empty($conf->global->PDF_SHOW_PROJECT)) {
-                       $object->fetch_projet();
-                       if (!empty($object->project->ref)) {
-                               $outputlangs->load("projects");
-                               $posy += 3;
-                               $pdf->SetXY($posx, $posy);
-                               $pdf->SetTextColor(0, 0, 60);
-                               $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R');
-                       }
-               }
-
-               $posy += 4;
-               $pdf->SetXY($posx, $posy);
-               $pdf->SetTextColor(0, 0, 60);
-
-               $title = $outputlangs->transnoentities("Date");
-               if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) {
-                       $title .= ' - '.$outputlangsbis->transnoentities("Date");
-               }
-               $pdf->MultiCell($w, 3, $title." : ".dol_print_date($object->date, "day", false, $outputlangs), '', 'R');
-
-               if ($object->thirdparty->code_client) {
-                       $posy += 3;
-                       $pdf->SetXY($posx, $posy);
-                       $pdf->SetTextColor(0, 0, 60);
-                       $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : ".$outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
-               }
-
-               // Get contact
-               if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) {
-                       $arrayidcontact = $object->getIdContact('internal', 'SALESREPFOLL');
-                       if (count($arrayidcontact) > 0) {
-                               $usertmp = new User($this->db);
-                               $usertmp->fetch($arrayidcontact[0]);
-                               $posy += 4;
-                               $pdf->SetXY($posx, $posy);
-                               $pdf->SetTextColor(0, 0, 60);
-                               $pdf->MultiCell($w, 3, $langs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
-                       }
-               }
-
-               $posy += 1;
-
-               $top_shift = 0;
-               // Show list of linked objects
-               $current_y = $pdf->getY();
-               $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
-               if ($current_y < $pdf->getY()) {
-                       $top_shift = $pdf->getY() - $current_y;
-               }
-
-               if ($showaddress) {
-                       // Sender properties
-                       $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
-
-                       // Show sender
-                       $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
-                       $posy += $top_shift;
-                       $posx = $this->marge_gauche;
-                       if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
-                               $posx = $this->page_largeur - $this->marge_droite - 80;
-                       }
-
-                       $hautcadre = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40;
-                       $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82;
-
-
-                       // Show sender frame
-                       $pdf->SetTextColor(0, 0, 0);
-                       $pdf->SetFont('', '', $default_font_size - 2);
-                       $pdf->SetXY($posx, $posy - 5);
-                       $pdf->MultiCell(66, 5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
-                       $pdf->SetXY($posx, $posy);
-                       $pdf->SetFillColor(230, 230, 230);
-                       $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1);
-                       $pdf->SetTextColor(0, 0, 60);
-
-                       // Show sender name
-                       $pdf->SetXY($posx + 2, $posy + 3);
-                       $pdf->SetFont('', 'B', $default_font_size);
-                       $pdf->MultiCell($widthrecbox - 2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
-                       $posy = $pdf->getY();
-
-                       // Show sender information
-                       $pdf->SetXY($posx + 2, $posy);
-                       $pdf->SetFont('', '', $default_font_size - 1);
-                       $pdf->MultiCell($widthrecbox - 2, 4, $carac_emetteur, 0, 'L');
-
-                       // If BILLING contact defined on invoice, we use it
-                       $usecontact = false;
-                       $arrayidcontact = $object->getIdContact('external', 'BILLING');
-                       if (count($arrayidcontact) > 0) {
-                               $usecontact = true;
-                               $result = $object->fetch_contact($arrayidcontact[0]);
-                       }
-
-                       // Recipient name
-                       if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) {
-                               $thirdparty = $object->contact;
-                       } else {
-                               $thirdparty = $object->thirdparty;
-                       }
-
-                       if (is_object($thirdparty)) {
-                               $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs);
-                       }
-
-                       $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, 'target', $object);
-
-                       // Show recipient
-                       $widthrecbox = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100;
-                       if ($this->page_largeur < 210) {
-                               $widthrecbox = 84; // To work with US executive format
-                       }
-                       $posy = !empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
-                       $posy += $top_shift;
-                       $posx = $this->page_largeur - $this->marge_droite - $widthrecbox;
-                       if (!empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
-                               $posx = $this->marge_gauche;
-                       }
-
-                       // Show recipient frame
-                       $pdf->SetTextColor(0, 0, 0);
-                       $pdf->SetFont('', '', $default_font_size - 2);
-                       $pdf->SetXY($posx + 2, $posy - 5);
-                       $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":", 0, 'L');
-                       $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
-
-                       // Show recipient name
-                       $pdf->SetXY($posx + 2, $posy + 3);
-                       $pdf->SetFont('', 'B', $default_font_size);
-                       $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L');
-
-                       $posy = $pdf->getY();
-
-                       // Show recipient information
-                       $pdf->SetFont('', '', $default_font_size - 1);
-                       $pdf->SetXY($posx + 2, $posy);
-                       $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
-               }
-
-               $pdf->SetTextColor(0, 0, 0);
-               return $top_shift;
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
-       /**
-        *      Show footer of page. Need this->emetteur object
-        *
-        *      @param  TCPDF           $pdf                            PDF
-        *              @param  Object          $object                         Object to show
-        *      @param  Translate       $outputlangs            Object lang for output
-        *      @param  int                     $hidefreetext           1=Hide free text
-        *      @return int                                                             Return height of bottom margin including footer text
-        */
-       protected function _pagefoot(&$pdf, $object, $outputlangs, $hidefreetext = 0)
-       {
-               global $conf;
-               $showdetails = empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? 0 : $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
-               return pdf_pagefoot($pdf, $outputlangs, 'INVOICE_FREE_TEXT', $this->emetteur, $this->marge_basse, $this->marge_gauche, $this->page_hauteur, $object, $showdetails, $hidefreetext);
-       }
-
-       /**
-        *  Define Array Column Field
-        *
-        *  @param      object                  $object                 common object
-        *  @param      Translate               $outputlangs    langs
-        *  @param      int                        $hidedetails         Do not show line details
-        *  @param      int                        $hidedesc            Do not show desc
-        *  @param      int                        $hideref                     Do not show ref
-        *  @return     null
-        */
-       public function defineColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
-       {
-               global $conf, $hookmanager;
-
-               // Default field style for content
-               $this->defaultContentsFieldsStyle = array(
-                       'align' => 'R', // R,C,L
-                       'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
-               );
-
-               // Default field style for content
-               $this->defaultTitlesFieldsStyle = array(
-                       'align' => 'C', // R,C,L
-                       'padding' => array(0.5, 0, 0.5, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
-               );
-
-               /*
-                * For exemple
-               $this->cols['theColKey'] = array(
-                       'rank' => $rank, // int : use for ordering columns
-                       'width' => 20, // the column width in mm
-                       'title' => array(
-                               'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
-                               'label' => ' ', // the final label : used fore final generated text
-                               'align' => 'L', // text alignement :  R,C,L
-                               'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
-                       ),
-                       'content' => array(
-                               'align' => 'L', // text alignement :  R,C,L
-                               'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
-                       ),
-               );
-               */
-
-               $rank = 0; // do not use negative rank
-               $this->cols['desc'] = array(
-                       'rank' => $rank,
-                       'width' => false, // only for desc
-                       'status' => true,
-                       'title' => array(
-                               'textkey' => 'Designation', // use lang key is usefull in somme case with module
-                               'align' => 'L',
-                               // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
-                               // 'label' => ' ', // the final label
-                               'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
-                       ),
-                       'content' => array(
-                               'align' => 'L',
-                               'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
-                       ),
-               );
-
-               // PHOTO
-               $rank = $rank + 10;
-               $this->cols['photo'] = array(
-                       'rank' => $rank,
-                       'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH) ? 20 : $conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
-                       'status' => false,
-                       'title' => array(
-                               'textkey' => 'Photo',
-                               'label' => ' '
-                       ),
-                       'content' => array(
-                               'padding' => array(0, 0, 0, 0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
-                       ),
-                       'border-left' => false, // remove left line separator
-               );
-
-               if (!empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE) && !empty($this->atleastonephoto)) {
-                       $this->cols['photo']['status'] = true;
-               }
-
-
-               $rank = $rank + 10;
-               $this->cols['vat'] = array(
-                       'rank' => $rank,
-                       'status' => false,
-                       'width' => 16, // in mm
-                       'title' => array(
-                               'textkey' => 'VAT'
-                       ),
-                       'border-left' => true, // add left line separator
-               );
-
-               if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) {
-                       $this->cols['vat']['status'] = true;
-               }
-
-               $rank = $rank + 10;
-               $this->cols['subprice'] = array(
-                       'rank' => $rank,
-                       'width' => 19, // in mm
-                       'status' => true,
-                       'title' => array(
-                               'textkey' => 'PriceUHT'
-                       ),
-                       'border-left' => true, // add left line separator
-               );
-
-               $rank = $rank + 10;
-               $this->cols['qty'] = array(
-                       'rank' => $rank,
-                       'width' => 16, // in mm
-                       'status' => true,
-                       'title' => array(
-                               'textkey' => 'Qty'
-                       ),
-                       'border-left' => true, // add left line separator
-               );
-
-               $rank = $rank + 10;
-               $this->cols['progress'] = array(
-                       'rank' => $rank,
-                       'width' => 19, // in mm
-                       'status' => false,
-                       'title' => array(
-                               'textkey' => 'Progress'
-                       ),
-                       'border-left' => true, // add left line separator
-               );
-
-               if ($this->situationinvoice) {
-                       $this->cols['progress']['status'] = true;
-               }
-
-               $rank = $rank + 10;
-               $this->cols['unit'] = array(
-                       'rank' => $rank,
-                       'width' => 11, // in mm
-                       'status' => false,
-                       'title' => array(
-                               'textkey' => 'Unit'
-                       ),
-                       'border-left' => true, // add left line separator
-               );
-               if (!empty($conf->global->PRODUCT_USE_UNITS)) {
-                       $this->cols['unit']['status'] = true;
-               }
-
-               $rank = $rank + 10;
-               $this->cols['discount'] = array(
-                       'rank' => $rank,
-                       'width' => 13, // in mm
-                       'status' => false,
-                       'title' => array(
-                               'textkey' => 'ReductionShort'
-                       ),
-                       'border-left' => true, // add left line separator
-               );
-               if ($this->atleastonediscount) {
-                       $this->cols['discount']['status'] = true;
-               }
-
-               $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100
-               $this->cols['totalexcltax'] = array(
-                       'rank' => $rank,
-                       'width' => 26, // in mm
-                       'status' => true,
-                       'title' => array(
-                               'textkey' => 'TotalHT'
-                       ),
-                       'border-left' => true, // add left line separator
-               );
-
-               // Add extrafields cols
-               if (!empty($object->lines)) {
-                       $line = reset($object->lines);
-                       $this->defineColumnExtrafield($line, $outputlangs, $hidedetails);
-               }
-
-               $parameters = array(
-                       'object' => $object,
-                       'outputlangs' => $outputlangs,
-                       'hidedetails' => $hidedetails,
-                       'hidedesc' => $hidedesc,
-                       'hideref' => $hideref
-               );
-
-               $reshook = $hookmanager->executeHooks('defineColumnField', $parameters, $this); // Note that $object may have been modified by hook
-               if ($reshook < 0) {
-                       setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
-               } elseif (empty($reshook)) {
-                       $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
-               } else {
-                       $this->cols = $hookmanager->resArray;
-               }
-       }
-}
diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php b/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php
deleted file mode 100644 (file)
index cce647d..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-/* Copyright (C) 2003-2007  Rodolphe Quiedeville        <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2007  Laurent Destailleur         <eldy@users.sourceforge.net>
- * Copyright (C) 2005-2009  Regis Houssin               <regis.houssin@inodbox.com>
- * Copyright (C) 2008       Raphael Bertrand (Resultic) <raphael.bertrand@resultic.fr>
- * Copyright (C) 2019       Frédéric France             <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- * or see https://www.gnu.org/
- */
-
-/**
- * \file       htdocs/core/modules/mymodule/mod_myobject_advanced.php
- * \ingroup    mymodule
- * \brief      File containing class for advanced numbering model of MyObject
- */
-
-dol_include_once('/mymodule/core/modules/mymodule/modules_myobject.php');
-
-
-/**
- *     Class to manage the Advanced numbering rule for MyObject
- */
-class mod_myobject_advanced extends ModeleNumRefMyObject
-{
-       /**
-        * Dolibarr version of the loaded document
-        * @var string
-        */
-       public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
-
-       /**
-        * @var string Error message
-        */
-       public $error = '';
-
-       /**
-        * @var string name
-        */
-       public $name = 'advanced';
-
-
-       /**
-        *  Returns the description of the numbering model
-        *
-        *  @return     string      Texte descripif
-        */
-       public function info()
-       {
-               global $conf, $langs, $db;
-
-               $langs->load("bills");
-
-               $form = new Form($db);
-
-               $texte = $langs->trans('GenericNumRefModelDesc')."<br>\n";
-               $texte .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
-               $texte .= '<input type="hidden" name="token" value="'.newToken().'">';
-               $texte .= '<input type="hidden" name="action" value="updateMask">';
-               $texte .= '<input type="hidden" name="maskconst" value="MYMODULE_MYOBJECT_ADVANCED_MASK">';
-               $texte .= '<table class="nobordernopadding centpercent">';
-
-               $tooltip = $langs->trans("GenericMaskCodes", $langs->transnoentities("MyObject"), $langs->transnoentities("MyObject"));
-               $tooltip .= $langs->trans("GenericMaskCodes2");
-               $tooltip .= $langs->trans("GenericMaskCodes3");
-               $tooltip .= $langs->trans("GenericMaskCodes4a", $langs->transnoentities("MyObject"), $langs->transnoentities("MyObject"));
-               $tooltip .= $langs->trans("GenericMaskCodes5");
-
-               // Parametrage du prefix
-               $texte .= '<tr><td>'.$langs->trans("Mask").':</td>';
-               $texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="maskvalue" value="'.getDolGlobalString('MYMODULE_MYOBJECT_ADVANCED_MASK').'">', $tooltip, 1, 1).'</td>';
-               $texte .= '<td class="left" rowspan="2">&nbsp; <input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'" name="Button"></td>';
-               $texte .= '</tr>';
-
-               $texte .= '</table>';
-               $texte .= '</form>';
-
-               return $texte;
-       }
-
-       /**
-        *  Return an example of numbering
-        *
-        *  @return     string      Example
-        */
-       public function getExample()
-       {
-               global $conf, $db, $langs, $mysoc;
-
-               $object = new MyObject($db);
-               $object->initAsSpecimen();
-
-               /*$old_code_client = $mysoc->code_client;
-               $old_code_type = $mysoc->typent_code;
-               $mysoc->code_client = 'CCCCCCCCCC';
-               $mysoc->typent_code = 'TTTTTTTTTT';*/
-
-               $numExample = $this->getNextValue($object);
-
-               /*$mysoc->code_client = $old_code_client;
-               $mysoc->typent_code = $old_code_type;*/
-
-               if (!$numExample) {
-                       $numExample = $langs->trans('NotConfigured');
-               }
-               return $numExample;
-       }
-
-       /**
-        *      Return next free value
-        *
-        *  @param  Object              $object         Object we need next value for
-        *  @return string                              Value if KO, <0 if KO
-        */
-       public function getNextValue($object)
-       {
-               global $db, $conf;
-
-               require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-
-               // We get cursor rule
-               $mask = getDolGlobalString('MYMODULE_MYOBJECT_ADVANCED_MASK');
-
-               if (!$mask) {
-                       $this->error = 'NotConfigured';
-                       return 0;
-               }
-
-               $date = $object->date;
-
-               $numFinal = get_next_value($db, $mask, 'mymodule_myobject', 'ref', '', null, $date);
-
-               return  $numFinal;
-       }
-}
diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_standard.php b/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_standard.php
deleted file mode 100644 (file)
index f21ffe8..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-<?php
-/* Copyright (C) 2005-2010 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@inodbox.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- * or see https://www.gnu.org/
- */
-
-/**
- *  \file       htdocs/core/modules/mymodule/mod_myobject_standard.php
- *  \ingroup    mymodule
- *  \brief      File of class to manage MyObject numbering rules standard
- */
-dol_include_once('/mymodule/core/modules/mymodule/modules_myobject.php');
-
-
-/**
- *     Class to manage the Standard numbering rule for MyObject
- */
-class mod_myobject_standard extends ModeleNumRefMyObject
-{
-       /**
-        * Dolibarr version of the loaded document
-        * @var string
-        */
-       public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
-
-       public $prefix = 'MYOBJECT';
-
-       /**
-        * @var string Error code (or message)
-        */
-       public $error = '';
-
-       /**
-        * @var string name
-        */
-       public $name = 'standard';
-
-
-       /**
-        *  Return description of numbering module
-        *
-        *  @return     string      Text with description
-        */
-       public function info()
-       {
-               global $langs;
-               return $langs->trans("SimpleNumRefModelDesc", $this->prefix);
-       }
-
-
-       /**
-        *  Return an example of numbering
-        *
-        *  @return     string      Example
-        */
-       public function getExample()
-       {
-               return $this->prefix."0501-0001";
-       }
-
-
-       /**
-        *  Checks if the numbers already in the database do not
-        *  cause conflicts that would prevent this numbering working.
-        *
-        *  @param  Object              $object         Object we need next value for
-        *  @return boolean                             false if conflict, true if ok
-        */
-       public function canBeActivated($object)
-       {
-               global $conf, $langs, $db;
-
-               $coyymm = ''; $max = '';
-
-               $posindice = strlen($this->prefix) + 6;
-               $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
-               $sql .= " FROM ".MAIN_DB_PREFIX."mymodule_myobject";
-               $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'";
-               if ($object->ismultientitymanaged == 1) {
-                       $sql .= " AND entity = ".$conf->entity;
-               } elseif ($object->ismultientitymanaged == 2) {
-                       // TODO
-               }
-
-               $resql = $db->query($sql);
-               if ($resql) {
-                       $row = $db->fetch_row($resql);
-                       if ($row) {
-                               $coyymm = substr($row[0], 0, 6); $max = $row[0];
-                       }
-               }
-               if ($coyymm && !preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i', $coyymm)) {
-                       $langs->load("errors");
-                       $this->error = $langs->trans('ErrorNumRefModel', $max);
-                       return false;
-               }
-
-               return true;
-       }
-
-       /**
-        *      Return next free value
-        *
-        *  @param  Object              $object         Object we need next value for
-        *  @return string                              Value if KO, <0 if KO
-        */
-       public function getNextValue($object)
-       {
-               global $db, $conf;
-
-               // first we get the max value
-               $posindice = strlen($this->prefix) + 6;
-               $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
-               $sql .= " FROM ".MAIN_DB_PREFIX."mymodule_myobject";
-               $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'";
-               if ($object->ismultientitymanaged == 1) {
-                       $sql .= " AND entity = ".$conf->entity;
-               } elseif ($object->ismultientitymanaged == 2) {
-                       // TODO
-               }
-
-               $resql = $db->query($sql);
-               if ($resql) {
-                       $obj = $db->fetch_object($resql);
-                       if ($obj) {
-                               $max = intval($obj->max);
-                       } else {
-                               $max = 0;
-                       }
-               } else {
-                       dol_syslog("mod_myobject_standard::getNextValue", LOG_DEBUG);
-                       return -1;
-               }
-
-               //$date=time();
-               $date = $object->date_creation;
-               $yymm = strftime("%y%m", $date);
-
-               if ($max >= (pow(10, 4) - 1)) {
-                       $num = $max + 1; // If counter > 9999, we do not format on 4 chars, we take number as it is
-               } else {
-                       $num = sprintf("%04s", $max + 1);
-               }
-
-               dol_syslog("mod_myobject_standard::getNextValue return ".$this->prefix.$yymm."-".$num);
-               return $this->prefix.$yymm."-".$num;
-       }
-}
diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/modules_myobject.php b/htdocs/modulebuilder/template/core/modules/mymodule/modules_myobject.php
deleted file mode 100644 (file)
index c2eeb23..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-<?php
-/* Copyright (C) 2003-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2004      Eric Seigne          <eric.seigne@ryxeo.com>
- * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@inodbox.com>
- * Copyright (C) 2006      Andre Cianfarani     <acianfa@free.fr>
- * Copyright (C) 2012      Juanjo Menent           <jmenent@2byte.es>
- * Copyright (C) 2014      Marcos García        <marcosgdf@gmail.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- * or see https://www.gnu.org/
- */
-
-/**
- *  \file                      htdocs/core/modules/mymodule/modules_myobject.php
- *  \ingroup           mymodule
- *  \brief                     File that contains parent class for myobjects document models and parent class for myobjects numbering models
- */
-
-require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
-require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // required for use by classes that inherit
-
-
-/**
- *     Parent class for documents models
- */
-abstract class ModelePDFMyObject extends CommonDocGenerator
-{
-
-       /**
-        * @var int page_largeur
-        */
-       public $page_largeur;
-
-       /**
-        * @var int page_hauteur
-        */
-       public $page_hauteur;
-
-       /**
-        * @var array format
-        */
-       public $format;
-
-       /**
-        * @var int marge_gauche
-        */
-       public $marge_gauche;
-
-       /**
-        * @var int marge_droite
-        */
-       public $marge_droite;
-
-       /**
-        * @var int marge_haute
-        */
-       public $marge_haute;
-
-       /**
-        * @var int marge_basse
-        */
-       public $marge_basse;
-
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        *  Return list of active generation modules
-        *
-        *  @param      DoliDB  $db                             Database handler
-        *  @param  integer     $maxfilenamelength  Max length of value to show
-        *  @return     array                                           List of templates
-        */
-       public static function liste_modeles($db, $maxfilenamelength = 0)
-       {
-               // phpcs:enable
-               global $conf;
-
-               $type = 'myobject';
-               $list = array();
-
-               include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-               $list = getListOfModels($db, $type, $maxfilenamelength);
-
-               return $list;
-       }
-}
-
-
-
-/**
- *  Parent class to manage numbering of MyObject
- */
-abstract class ModeleNumRefMyObject
-{
-       /**
-        * @var string Error code (or message)
-        */
-       public $error = '';
-
-       /**
-        *      Return if a module can be used or not
-        *
-        *      @return         boolean     true if module can be used
-        */
-       public function isEnabled()
-       {
-               return true;
-       }
-
-       /**
-        *      Returns the default description of the numbering template
-        *
-        *      @return     string      Texte descripif
-        */
-       public function info()
-       {
-               global $langs;
-               $langs->load("mymodule@mymodule");
-               return $langs->trans("NoDescription");
-       }
-
-       /**
-        *      Returns an example of numbering
-        *
-        *      @return     string      Example
-        */
-       public function getExample()
-       {
-               global $langs;
-               $langs->load("mymodule@mymodule");
-               return $langs->trans("NoExample");
-       }
-
-       /**
-        *  Checks if the numbers already in the database do not
-        *  cause conflicts that would prevent this numbering working.
-        *
-        *      @param  Object          $object         Object we need next value for
-        *      @return boolean                         false if conflict, true if ok
-        */
-       public function canBeActivated($object)
-       {
-               return true;
-       }
-
-       /**
-        *      Returns next assigned value
-        *
-        *      @param  Object          $object         Object we need next value for
-        *      @return string      Valeur
-        */
-       public function getNextValue($object)
-       {
-               global $langs;
-               return $langs->trans("NotAvailable");
-       }
-
-       /**
-        *      Returns version of numbering module
-        *
-        *      @return     string      Valeur
-        */
-       public function getVersion()
-       {
-               global $langs;
-               $langs->load("admin");
-
-               if ($this->version == 'development') {
-                       return $langs->trans("VersionDevelopment");
-               }
-               if ($this->version == 'experimental') {
-                       return $langs->trans("VersionExperimental");
-               }
-               if ($this->version == 'dolibarr') {
-                       return DOL_VERSION;
-               }
-               if ($this->version) {
-                       return $this->version;
-               }
-               return $langs->trans("NotAvailable");
-       }
-}
diff --git a/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php b/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php
deleted file mode 100644 (file)
index 21cb16c..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-/* Copyright (C) 2019 Laurent Destailleur <eldy@users.sourceforge.net>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-// Protection to avoid direct call of template
-if (empty($conf) || !is_object($conf)) {
-       print "Error, template page can't be called as URL";
-       exit;
-}
-
-
-print "<!-- BEGIN PHP TEMPLATE mymodule/core/tpl/linkedobjectblock_myobject.tpl.php  -->\n";
-
-
-global $user;
-global $noMoreLinkedObjectBlockAfter;
-
-$langs = $GLOBALS['langs'];
-$linkedObjectBlock = $GLOBALS['linkedObjectBlock'];
-
-// Load translation files required by the page
-$langs->load("mymodule");
-
-$total = 0; $ilink = 0;
-foreach ($linkedObjectBlock as $key => $objectlink) {
-       $ilink++;
-
-       $trclass = 'oddeven';
-       if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) {
-               $trclass .= ' liste_sub_total';
-       }
-       ?>
-<tr class="<?php echo $trclass; ?>">
-       <td><?php echo $langs->trans("MyObject"); ?></td>
-       <td><?php echo $objectlink->getNomUrl(1); ?></td>
-       <td></td>
-       <td class="center"><?php echo dol_print_date($objectlink->date, 'day'); ?></td>
-       <td class="right"><?php echo ''; ?></td>
-       <td class="right"><?php echo $objectlink->getLibStatut(7); ?></td>
-       <td class="right"><a class="reposition" href="<?php echo $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=dellink&token='.newToken().'&dellinkid='.$key; ?>"><?php echo img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink'); ?></a></td>
-</tr>
-       <?php
-}
-
-print "<!-- END PHP TEMPLATE -->\n";
diff --git a/htdocs/modulebuilder/template/core/triggers/README.md b/htdocs/modulebuilder/template/core/triggers/README.md
deleted file mode 100644 (file)
index 38d1b1d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Directory where triggers files are stored.
\ No newline at end of file
diff --git a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php
deleted file mode 100644 (file)
index 8f7764a..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-<?php
-/* Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php
- * \ingroup mymodule
- * \brief   Example trigger.
- *
- * Put detailed description here.
- *
- * \remarks You can create other triggers by copying this one.
- * - File name should be either:
- *      - interface_99_modMyModule_MyTrigger.class.php
- *      - interface_99_all_MyTrigger.class.php
- * - The file must stay in core/triggers
- * - The class name must be InterfaceMytrigger
- */
-
-require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
-
-
-/**
- *  Class of triggers for MyModule module
- */
-class InterfaceMyModuleTriggers extends DolibarrTriggers
-{
-       /**
-        * Constructor
-        *
-        * @param DoliDB $db Database handler
-        */
-       public function __construct($db)
-       {
-               $this->db = $db;
-
-               $this->name = preg_replace('/^Interface/i', '', get_class($this));
-               $this->family = "demo";
-               $this->description = "MyModule triggers.";
-               // 'development', 'experimental', 'dolibarr' or version
-               $this->version = 'development';
-               $this->picto = 'mymodule@mymodule';
-       }
-
-       /**
-        * Trigger name
-        *
-        * @return string Name of trigger file
-        */
-       public function getName()
-       {
-               return $this->name;
-       }
-
-       /**
-        * Trigger description
-        *
-        * @return string Description of trigger file
-        */
-       public function getDesc()
-       {
-               return $this->description;
-       }
-
-
-       /**
-        * Function called when a Dolibarrr business event is done.
-        * All functions "runTrigger" are triggered if file
-        * is inside directory core/triggers
-        *
-        * @param string                $action         Event action code
-        * @param CommonObject  $object         Object
-        * @param User                  $user           Object user
-        * @param Translate     $langs          Object langs
-        * @param Conf                  $conf           Object conf
-        * @return int                          <0 if KO, 0 if no triggered ran, >0 if OK
-        */
-       public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
-       {
-               if (empty($conf->mymodule) || empty($conf->mymodule->enabled)) {
-                       return 0; // If module is not enabled, we do nothing
-               }
-
-               // Put here code you want to execute when a Dolibarr business events occurs.
-               // Data and type of action are stored into $object and $action
-
-               // You can isolate code for each action in a separate method: this method should be named like the trigger in camelCase.
-               // For example : COMPANY_CREATE => public function companyCreate($action, $object, User $user, Translate $langs, Conf $conf)
-               $methodName = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($action)))));
-               $callback = array($this, $methodName);
-               if (is_callable($callback)) {
-                       dol_syslog(
-                               "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id
-                       );
-
-                       return call_user_func($callback, $action, $object, $user, $langs, $conf);
-               };
-
-               // Or you can execute some code here
-               switch ($action) {
-                       // Users
-                       //case 'USER_CREATE':
-                       //case 'USER_MODIFY':
-                       //case 'USER_NEW_PASSWORD':
-                       //case 'USER_ENABLEDISABLE':
-                       //case 'USER_DELETE':
-
-                       // Actions
-                       //case 'ACTION_MODIFY':
-                       //case 'ACTION_CREATE':
-                       //case 'ACTION_DELETE':
-
-                       // Groups
-                       //case 'USERGROUP_CREATE':
-                       //case 'USERGROUP_MODIFY':
-                       //case 'USERGROUP_DELETE':
-
-                       // Companies
-                       //case 'COMPANY_CREATE':
-                       //case 'COMPANY_MODIFY':
-                       //case 'COMPANY_DELETE':
-
-                       // Contacts
-                       //case 'CONTACT_CREATE':
-                       //case 'CONTACT_MODIFY':
-                       //case 'CONTACT_DELETE':
-                       //case 'CONTACT_ENABLEDISABLE':
-
-                       // Products
-                       //case 'PRODUCT_CREATE':
-                       //case 'PRODUCT_MODIFY':
-                       //case 'PRODUCT_DELETE':
-                       //case 'PRODUCT_PRICE_MODIFY':
-                       //case 'PRODUCT_SET_MULTILANGS':
-                       //case 'PRODUCT_DEL_MULTILANGS':
-
-                       //Stock mouvement
-                       //case 'STOCK_MOVEMENT':
-
-                       //MYECMDIR
-                       //case 'MYECMDIR_CREATE':
-                       //case 'MYECMDIR_MODIFY':
-                       //case 'MYECMDIR_DELETE':
-
-                       // Sales orders
-                       //case 'ORDER_CREATE':
-                       //case 'ORDER_MODIFY':
-                       //case 'ORDER_VALIDATE':
-                       //case 'ORDER_DELETE':
-                       //case 'ORDER_CANCEL':
-                       //case 'ORDER_SENTBYMAIL':
-                       //case 'ORDER_CLASSIFY_BILLED':
-                       //case 'ORDER_SETDRAFT':
-                       //case 'LINEORDER_INSERT':
-                       //case 'LINEORDER_UPDATE':
-                       //case 'LINEORDER_DELETE':
-
-                       // Supplier orders
-                       //case 'ORDER_SUPPLIER_CREATE':
-                       //case 'ORDER_SUPPLIER_MODIFY':
-                       //case 'ORDER_SUPPLIER_VALIDATE':
-                       //case 'ORDER_SUPPLIER_DELETE':
-                       //case 'ORDER_SUPPLIER_APPROVE':
-                       //case 'ORDER_SUPPLIER_REFUSE':
-                       //case 'ORDER_SUPPLIER_CANCEL':
-                       //case 'ORDER_SUPPLIER_SENTBYMAIL':
-                       //case 'ORDER_SUPPLIER_RECEIVE':
-                       //case 'LINEORDER_SUPPLIER_DISPATCH':
-                       //case 'LINEORDER_SUPPLIER_CREATE':
-                       //case 'LINEORDER_SUPPLIER_UPDATE':
-                       //case 'LINEORDER_SUPPLIER_DELETE':
-
-                       // Proposals
-                       //case 'PROPAL_CREATE':
-                       //case 'PROPAL_MODIFY':
-                       //case 'PROPAL_VALIDATE':
-                       //case 'PROPAL_SENTBYMAIL':
-                       //case 'PROPAL_CLOSE_SIGNED':
-                       //case 'PROPAL_CLOSE_REFUSED':
-                       //case 'PROPAL_DELETE':
-                       //case 'LINEPROPAL_INSERT':
-                       //case 'LINEPROPAL_UPDATE':
-                       //case 'LINEPROPAL_DELETE':
-
-                       // SupplierProposal
-                       //case 'SUPPLIER_PROPOSAL_CREATE':
-                       //case 'SUPPLIER_PROPOSAL_MODIFY':
-                       //case 'SUPPLIER_PROPOSAL_VALIDATE':
-                       //case 'SUPPLIER_PROPOSAL_SENTBYMAIL':
-                       //case 'SUPPLIER_PROPOSAL_CLOSE_SIGNED':
-                       //case 'SUPPLIER_PROPOSAL_CLOSE_REFUSED':
-                       //case 'SUPPLIER_PROPOSAL_DELETE':
-                       //case 'LINESUPPLIER_PROPOSAL_INSERT':
-                       //case 'LINESUPPLIER_PROPOSAL_UPDATE':
-                       //case 'LINESUPPLIER_PROPOSAL_DELETE':
-
-                       // Contracts
-                       //case 'CONTRACT_CREATE':
-                       //case 'CONTRACT_MODIFY':
-                       //case 'CONTRACT_ACTIVATE':
-                       //case 'CONTRACT_CANCEL':
-                       //case 'CONTRACT_CLOSE':
-                       //case 'CONTRACT_DELETE':
-                       //case 'LINECONTRACT_INSERT':
-                       //case 'LINECONTRACT_UPDATE':
-                       //case 'LINECONTRACT_DELETE':
-
-                       // Bills
-                       //case 'BILL_CREATE':
-                       //case 'BILL_MODIFY':
-                       //case 'BILL_VALIDATE':
-                       //case 'BILL_UNVALIDATE':
-                       //case 'BILL_SENTBYMAIL':
-                       //case 'BILL_CANCEL':
-                       //case 'BILL_DELETE':
-                       //case 'BILL_PAYED':
-                       //case 'LINEBILL_INSERT':
-                       //case 'LINEBILL_UPDATE':
-                       //case 'LINEBILL_DELETE':
-
-                       //Supplier Bill
-                       //case 'BILL_SUPPLIER_CREATE':
-                       //case 'BILL_SUPPLIER_UPDATE':
-                       //case 'BILL_SUPPLIER_DELETE':
-                       //case 'BILL_SUPPLIER_PAYED':
-                       //case 'BILL_SUPPLIER_UNPAYED':
-                       //case 'BILL_SUPPLIER_VALIDATE':
-                       //case 'BILL_SUPPLIER_UNVALIDATE':
-                       //case 'LINEBILL_SUPPLIER_CREATE':
-                       //case 'LINEBILL_SUPPLIER_UPDATE':
-                       //case 'LINEBILL_SUPPLIER_DELETE':
-
-                       // Payments
-                       //case 'PAYMENT_CUSTOMER_CREATE':
-                       //case 'PAYMENT_SUPPLIER_CREATE':
-                       //case 'PAYMENT_ADD_TO_BANK':
-                       //case 'PAYMENT_DELETE':
-
-                       // Online
-                       //case 'PAYMENT_PAYBOX_OK':
-                       //case 'PAYMENT_PAYPAL_OK':
-                       //case 'PAYMENT_STRIPE_OK':
-
-                       // Donation
-                       //case 'DON_CREATE':
-                       //case 'DON_UPDATE':
-                       //case 'DON_DELETE':
-
-                       // Interventions
-                       //case 'FICHINTER_CREATE':
-                       //case 'FICHINTER_MODIFY':
-                       //case 'FICHINTER_VALIDATE':
-                       //case 'FICHINTER_DELETE':
-                       //case 'LINEFICHINTER_CREATE':
-                       //case 'LINEFICHINTER_UPDATE':
-                       //case 'LINEFICHINTER_DELETE':
-
-                       // Members
-                       //case 'MEMBER_CREATE':
-                       //case 'MEMBER_VALIDATE':
-                       //case 'MEMBER_SUBSCRIPTION':
-                       //case 'MEMBER_MODIFY':
-                       //case 'MEMBER_NEW_PASSWORD':
-                       //case 'MEMBER_RESILIATE':
-                       //case 'MEMBER_DELETE':
-
-                       // Categories
-                       //case 'CATEGORY_CREATE':
-                       //case 'CATEGORY_MODIFY':
-                       //case 'CATEGORY_DELETE':
-                       //case 'CATEGORY_SET_MULTILANGS':
-
-                       // Projects
-                       //case 'PROJECT_CREATE':
-                       //case 'PROJECT_MODIFY':
-                       //case 'PROJECT_DELETE':
-
-                       // Project tasks
-                       //case 'TASK_CREATE':
-                       //case 'TASK_MODIFY':
-                       //case 'TASK_DELETE':
-
-                       // Task time spent
-                       //case 'TASK_TIMESPENT_CREATE':
-                       //case 'TASK_TIMESPENT_MODIFY':
-                       //case 'TASK_TIMESPENT_DELETE':
-                       //case 'PROJECT_ADD_CONTACT':
-                       //case 'PROJECT_DELETE_CONTACT':
-                       //case 'PROJECT_DELETE_RESOURCE':
-
-                       // Shipping
-                       //case 'SHIPPING_CREATE':
-                       //case 'SHIPPING_MODIFY':
-                       //case 'SHIPPING_VALIDATE':
-                       //case 'SHIPPING_SENTBYMAIL':
-                       //case 'SHIPPING_BILLED':
-                       //case 'SHIPPING_CLOSED':
-                       //case 'SHIPPING_REOPEN':
-                       //case 'SHIPPING_DELETE':
-
-                       // and more...
-
-                       default:
-                               dol_syslog("Trigger '".$this->name."' for action '".$action."' launched by ".__FILE__.". id=".$object->id);
-                               break;
-               }
-
-               return 0;
-       }
-}
diff --git a/htdocs/modulebuilder/template/css/mymodule.css.php b/htdocs/modulebuilder/template/css/mymodule.css.php
deleted file mode 100644 (file)
index 260868a..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-/* Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    htdocs/modulebuilder/template/css/mymodule.css.php
- * \ingroup mymodule
- * \brief   CSS file for module MyModule.
- */
-
-//if (!defined('NOREQUIREUSER')) define('NOREQUIREUSER','1');  // Not disabled because need to load personalized language
-//if (!defined('NOREQUIREDB'))   define('NOREQUIREDB','1');    // Not disabled. Language code is found on url.
-if (!defined('NOREQUIRESOC')) {
-       define('NOREQUIRESOC', '1');
-}
-//if (!defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');  // Not disabled because need to do translations
-//if (!defined('NOCSRFCHECK'))   define('NOCSRFCHECK', 1);             // Should be disable only for special situation
-if (!defined('NOTOKENRENEWAL')) {
-       define('NOTOKENRENEWAL', 1);
-}
-if (!defined('NOLOGIN')) {
-       define('NOLOGIN', 1); // File must be accessed by logon page so without login
-}
-//if (! defined('NOREQUIREMENU'))   define('NOREQUIREMENU',1);  // We need top menu content
-if (!defined('NOREQUIREHTML')) {
-       define('NOREQUIREHTML', 1);
-}
-if (!defined('NOREQUIREAJAX')) {
-       define('NOREQUIREAJAX', '1');
-}
-
-session_cache_limiter('public');
-// false or '' = keep cache instruction added by server
-// 'public'  = remove cache instruction added by server
-// and if no cache-control added later, a default cache delay (10800) will be added by PHP.
-
-// Load Dolibarr environment
-$res = 0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
-       $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-}
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--; $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/../main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/../main.inc.php";
-}
-// Try main.inc.php using relative path
-if (!$res && file_exists("../../main.inc.php")) {
-       $res = @include "../../main.inc.php";
-}
-if (!$res && file_exists("../../../main.inc.php")) {
-       $res = @include "../../../main.inc.php";
-}
-if (!$res) {
-       die("Include of main fails");
-}
-
-require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-
-// Load user to have $user->conf loaded (not done by default here because of NOLOGIN constant defined) and load permission if we need to use them in CSS
-/*if (empty($user->id) && !empty($_SESSION['dol_login'])) {
-       $user->fetch('',$_SESSION['dol_login']);
-       $user->getrights();
-}*/
-
-
-// Define css type
-header('Content-type: text/css');
-// Important: Following code is to cache this file to avoid page request by browser at each Dolibarr page access.
-// You can use CTRL+F5 to refresh your browser cache.
-if (empty($dolibarr_nocache)) {
-       header('Cache-Control: max-age=10800, public, must-revalidate');
-} else {
-       header('Cache-Control: no-cache');
-}
-
-?>
-
-div.mainmenu.mymodule::before {
-       content: "\f249";
-}
-div.mainmenu.mymodule {
-       background-image: none;
-}
-
-.myclasscss {
-       /* ... */
-}
-
-
diff --git a/htdocs/modulebuilder/template/doc/Documentation.asciidoc b/htdocs/modulebuilder/template/doc/Documentation.asciidoc
deleted file mode 100644 (file)
index 5a05c70..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-= MYMODULE =
-:subtitle: MYMODULE DOCUMENTATION
-:source-highlighter: rouge
-:companyname: __MYCOMPANY_NAME__
-:corpname: __MYCOMPANY_NAME__
-:orgname: __MYCOMPANY_NAME__
-:creator: __USER_FULLNAME__
-:title: Documentation of module MyModule
-:subject: This document is the document of module MyModule.
-:keywords: __KEYWORDS__
-// Date du document :
-:docdate: __YYYY-MM-DD__
-:toc: manual
-:toc-placement: preamble
-
-
-== TOPIC OF DOCUMENT
-
-This is the documentation of module MyModule
-
-
-*Log of versions of document*
-
-[options="header",format="csv"]
-|=== 
-Author, Date, Version
---- __USER_FULLNAME__  __USER_EMAIL__ ---, __YYYY-MM-DD__, Version 1.0
-|===
-
-
-[NOTE]
-==============
-This document was generated using Dolibarr ERP CRM process
-==============
-
-
-:toc: manual
-:toc-placement: preamble
-
-<<<
-
-== INTRODUCTION
-
-//include::README.md[]
-__README__
-
-== DATA SPECIFICATIONS
-
-__DATA_SPECIFICATION__
-
-
-== CHANGELOG
-
-//include::ChangeLog.md[]
-__CHANGELOG__
-
diff --git a/htdocs/modulebuilder/template/doc/Documentation_full_en.example.asciidoc b/htdocs/modulebuilder/template/doc/Documentation_full_en.example.asciidoc
deleted file mode 100644 (file)
index 4c74421..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-= MYMODULE =
-:subtitle: MYMODULE DOCUMENTATION
-:source-highlighter: rouge
-:companyname: __MYCOMPANY_NAME__
-:corpname: __MYCOMPANY_NAME__
-:orgname: __MYCOMPANY_NAME__
-:creator: __USER_FULLNAME__
-:title: Documentation of module MyModule
-:subject: This document is the document of module MyModule.
-:keywords: __KEYWORDS__
-// Date du document :
-:docdate: __YYYY-MM-DD__
-:toc: manual
-:toc-placement: preamble
-
-
-
-== TOPIC OF DOCUMENT
-
-This document was build from following input:
-
-* Date 1
-...
-
-* Date 2
-...
-
-
-The document includes an introductory chapter of functional specifications, presenting the different actors involved in the rebuild of the definitions
-of business terms that will be used (some of which may be new or different).
-The main following chapter will present the entire process, also known as *uses cases*, according to a principle of a description, in chronological sequence if possible,
-to present the actor and the action performed, as in the following example:
-
-* *X* Actor realizes Action A.
-* *Y* Actor communicates Info B to Actor *Z*
-* *Automaton* performs update of data for...
-* Etc ...
-
-Functional requirements are complemented by a chapter of technical requirements.
-The chapter on data lists key information specific to Presto that were identified at the time of writing specification. It will be enriched as
-iterations occurs.
-
-Finally, in the Appendix, the documents known when writing this document are centralized to illustrate the existing document or inspire the new expected one.
-These documents have their content directly integrated in this specification or have a reference to
-external documents stored in the *Appendices* directory accompanying this document.
-
-
-
-*Log of versions*
-
-[options="header",format="csv"]
-|=== 
-Author, Date, Version
---- __USER_FULLNAME__  __USER_EMAIL__ ---, __YYYY-MM-DD__, Version 1.0
-|===
-
-
-
-<<<
-
-
-== BUSINESS SPECIFICATIONS - INTRODUCTION
-
-=== List of actors [[actors]]
-
-Actors are physical people or moral entities working on at least one process.
-The following chart prensts list of actors or partners identified by the project for the defined scope of project. We will use then the name defined into first column to speak about roles in the rest of documents.
-
-[options="header",format="csv"]
-|===
-Actor/profil/role, Description of role, Access to system or not, Example of actor
-Customer Service, Receive and create Sales orders (SO), Yes, Mr Smith
-Purchase, Make puchase order (PO), Yes, 5 people
-Administrator - IT, Administration of users/groups and IT services, Yes, John Doe
-Automaton, Execute automatic data processing, Yes, NA
-|===
-
-
-=== Definitions [[definitions]]
-
-To understand the descriptions of the target process, it was necessary to define or redefine some vocabulary concepts. We must see these definitions as defined in the
-new system. Indeed, some terms are already being used but have either not a definition in line with standards, or even differs between services. To bring everyone, 
-and to consolidate the process, these terms are redefined here, and with their definition in the target objective.
-
-*Definition ABC*
-
-...
-
-*Definition DEF*
-
-...
-
-
-[NOTE]
-==============
-Important information will be noticed with a notice like this one.
-
-* Main information 1
-* Main information 2
-==============
-
-
-
-== BUSINESS SPECIFICATION - PROCESS
-
-Specifications were cut into different business process. We call a business process a workflow with a starting situation and ending situation. Between start and end, we will find actions
-done by actors to bring the value of the company. This actions are described using the syntax rule:
-*Actor X* do action Y, *Actor Z* do action W.
-
-_Each process/use case is described into a separate chapter._
-
-
-=== Use case / Process 1 [[process_1]]
-
-==== Title and goals
-
-...
-
-==== Actors or roles
-
-* Members of group *...*
-
-==== Standard flow
-
-* Members of Groupe *...*: Do ...
-* Members of Groupe *...*: Do ...
-* Members of Groupe *...*: Do ...
-
-==== Alternative flow
-
-* A user without role *...*: Can't do ...
-
-==== Business rules
-
-* Business rule 1
-* Business rule 2
-
-
diff --git a/htdocs/modulebuilder/template/img/README.md b/htdocs/modulebuilder/template/img/README.md
deleted file mode 100644 (file)
index 2fcb4af..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-
-Directory for module image files
---------------------------------
-
-You can put here the .png files of your module:
-
-
-If the picto of your module is an image (property $picto has been set to 'mymodule.png@mymodule', you can put into this
-directory a .png file called *object_mymodule.png* (16x16 or 32x32 pixels)
-
-
-If the picto of an object is an image (property $picto of the object.class.php has been set to 'myobject.png@mymodule', then you can put into this
-directory a .png file called *object_myobject.png* (16x16 or 32x32 pixels)
-
diff --git a/htdocs/modulebuilder/template/js/mymodule.js.php b/htdocs/modulebuilder/template/js/mymodule.js.php
deleted file mode 100644 (file)
index fe04cdc..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-<?php
-/* Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- *
- * Library javascript to enable Browser notifications
- */
-
-if (!defined('NOREQUIREUSER')) {
-       define('NOREQUIREUSER', '1');
-}
-if (!defined('NOREQUIREDB')) {
-       define('NOREQUIREDB', '1');
-}
-if (!defined('NOREQUIRESOC')) {
-       define('NOREQUIRESOC', '1');
-}
-if (!defined('NOREQUIRETRAN')) {
-       define('NOREQUIRETRAN', '1');
-}
-if (!defined('NOCSRFCHECK')) {
-       define('NOCSRFCHECK', 1);
-}
-if (!defined('NOTOKENRENEWAL')) {
-       define('NOTOKENRENEWAL', 1);
-}
-if (!defined('NOLOGIN')) {
-       define('NOLOGIN', 1);
-}
-if (!defined('NOREQUIREMENU')) {
-       define('NOREQUIREMENU', 1);
-}
-if (!defined('NOREQUIREHTML')) {
-       define('NOREQUIREHTML', 1);
-}
-if (!defined('NOREQUIREAJAX')) {
-       define('NOREQUIREAJAX', '1');
-}
-
-
-/**
- * \file    htdocs/modulebuilder/template/js/mymodule.js.php
- * \ingroup mymodule
- * \brief   JavaScript file for module MyModule.
- */
-
-// Load Dolibarr environment
-$res = 0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
-       $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-}
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--; $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/../main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/../main.inc.php";
-}
-// Try main.inc.php using relative path
-if (!$res && file_exists("../../main.inc.php")) {
-       $res = @include "../../main.inc.php";
-}
-if (!$res && file_exists("../../../main.inc.php")) {
-       $res = @include "../../../main.inc.php";
-}
-if (!$res) {
-       die("Include of main fails");
-}
-
-// Define js type
-header('Content-Type: application/javascript');
-// Important: Following code is to cache this file to avoid page request by browser at each Dolibarr page access.
-// You can use CTRL+F5 to refresh your browser cache.
-if (empty($dolibarr_nocache)) {
-       header('Cache-Control: max-age=3600, public, must-revalidate');
-} else {
-       header('Cache-Control: no-cache');
-}
-?>
-
-/* Javascript library of module MyModule */
-
-
diff --git a/htdocs/modulebuilder/template/langs/en_US/mymodule.lang b/htdocs/modulebuilder/template/langs/en_US/mymodule.lang
deleted file mode 100644 (file)
index cc51839..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (C) ---Put here your own copyright and developer email---
-#
-# 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 <https://www.gnu.org/licenses/>.
-
-#
-# Generic
-#
-
-# Module label 'ModuleMyModuleName'
-ModuleMyModuleName = MyModule
-# Module description 'ModuleMyModuleDesc'
-ModuleMyModuleDesc = MyModule description
-
-#
-# Admin page
-#
-MyModuleSetup = MyModule setup
-Settings = Settings
-MyModuleSetupPage = MyModule setup page
-MYMODULE_MYPARAM1 = My param 1
-MYMODULE_MYPARAM1Tooltip = My param 1 tooltip
-MYMODULE_MYPARAM2=My param 2
-MYMODULE_MYPARAM2Tooltip=My param 2 tooltip
-
-
-#
-# About page
-#
-About = About
-MyModuleAbout = About MyModule
-MyModuleAboutPage = MyModule about page
-
-#
-# Sample page
-#
-MyModuleArea = Home MyModule
-MyPageName = My page name
-
-#
-# Sample widget
-#
-MyWidget = My widget
-MyWidgetDescription = My widget description
diff --git a/htdocs/modulebuilder/template/lib/mymodule.lib.php b/htdocs/modulebuilder/template/lib/mymodule.lib.php
deleted file mode 100644 (file)
index 0ebae6e..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-/* Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    htdocs/modulebuilder/template/lib/mymodule.lib.php
- * \ingroup mymodule
- * \brief   Library files with common functions for MyModule
- */
-
-/**
- * Prepare admin pages header
- *
- * @return array
- */
-function mymoduleAdminPrepareHead()
-{
-       global $langs, $conf;
-
-       // global $db;
-       // $extrafields = new ExtraFields($db);
-       // $extrafields->fetch_name_optionals_label('myobject');
-
-       $langs->load("mymodule@mymodule");
-
-       $h = 0;
-       $head = array();
-
-       $head[$h][0] = dol_buildpath("/mymodule/admin/setup.php", 1);
-       $head[$h][1] = $langs->trans("Settings");
-       $head[$h][2] = 'settings';
-       $h++;
-
-       /*
-       $head[$h][0] = dol_buildpath("/mymodule/admin/myobject_extrafields.php", 1);
-       $head[$h][1] = $langs->trans("ExtraFields");
-       $nbExtrafields = is_countable($extrafields->attributes['myobject']['label']) ? count($extrafields->attributes['myobject']['label']) : 0;
-       if ($nbExtrafields > 0) {
-               $head[$h][1] .= ' <span class="badge">' . $nbExtrafields . '</span>';
-       }
-       $head[$h][2] = 'myobject_extrafields';
-       $h++;
-       */
-
-       $head[$h][0] = dol_buildpath("/mymodule/admin/about.php", 1);
-       $head[$h][1] = $langs->trans("About");
-       $head[$h][2] = 'about';
-       $h++;
-
-       // Show more tabs from modules
-       // Entries must be declared in modules descriptor with line
-       //$this->tabs = array(
-       //      'entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'
-       //); // to add new tab
-       //$this->tabs = array(
-       //      'entity:-tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'
-       //); // to remove a tab
-       complete_head_from_modules($conf, $langs, null, $head, $h, 'mymodule@mymodule');
-
-       complete_head_from_modules($conf, $langs, null, $head, $h, 'mymodule@mymodule', 'remove');
-
-       return $head;
-}
diff --git a/htdocs/modulebuilder/template/lib/mymodule_myobject.lib.php b/htdocs/modulebuilder/template/lib/mymodule_myobject.lib.php
deleted file mode 100644 (file)
index d75f69a..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-/* Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    htdocs/modulebuilder/template/lib/mymodule_myobject.lib.php
- * \ingroup mymodule
- * \brief   Library files with common functions for MyObject
- */
-
-/**
- * Prepare array of tabs for MyObject
- *
- * @param      MyObject        $object         MyObject
- * @return     array                                   Array of tabs
- */
-function myobjectPrepareHead($object)
-{
-       global $db, $langs, $conf;
-
-       $langs->load("mymodule@mymodule");
-
-       $showtabofpagecontact = 1;
-       $showtabofpagenote = 1;
-       $showtabofpagedocument = 1;
-       $showtabofpageagenda = 1;
-
-       $h = 0;
-       $head = array();
-
-       $head[$h][0] = dol_buildpath("/mymodule/myobject_card.php", 1).'?id='.$object->id;
-       $head[$h][1] = $langs->trans("Card");
-       $head[$h][2] = 'card';
-       $h++;
-
-       if ($showtabofpagecontact) {
-               $head[$h][0] = dol_buildpath("/mymodule/myobject_contact.php", 1).'?id='.$object->id;
-               $head[$h][1] = $langs->trans("Contacts");
-               $head[$h][2] = 'contact';
-               $h++;
-       }
-
-       if ($showtabofpagenote) {
-               if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) {
-                       $nbNote = 0;
-                       if (!empty($object->note_private)) {
-                               $nbNote++;
-                       }
-                       if (!empty($object->note_public)) {
-                               $nbNote++;
-                       }
-                       $head[$h][0] = dol_buildpath('/mymodule/myobject_note.php', 1).'?id='.$object->id;
-                       $head[$h][1] = $langs->trans('Notes');
-                       if ($nbNote > 0) {
-                               $head[$h][1] .= (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? '<span class="badge marginleftonlyshort">'.$nbNote.'</span>' : '');
-                       }
-                       $head[$h][2] = 'note';
-                       $h++;
-               }
-       }
-
-       if ($showtabofpagedocument) {
-               require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-               require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
-               $upload_dir = $conf->mymodule->dir_output."/myobject/".dol_sanitizeFileName($object->ref);
-               $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
-               $nbLinks = Link::count($db, $object->element, $object->id);
-               $head[$h][0] = dol_buildpath("/mymodule/myobject_document.php", 1).'?id='.$object->id;
-               $head[$h][1] = $langs->trans('Documents');
-               if (($nbFiles + $nbLinks) > 0) {
-                       $head[$h][1] .= '<span class="badge marginleftonlyshort">'.($nbFiles + $nbLinks).'</span>';
-               }
-               $head[$h][2] = 'document';
-               $h++;
-       }
-
-       if ($showtabofpageagenda) {
-               $head[$h][0] = dol_buildpath("/mymodule/myobject_agenda.php", 1).'?id='.$object->id;
-               $head[$h][1] = $langs->trans("Events");
-               $head[$h][2] = 'agenda';
-               $h++;
-       }
-
-       // Show more tabs from modules
-       // Entries must be declared in modules descriptor with line
-       //$this->tabs = array(
-       //      'entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'
-       //); // to add new tab
-       //$this->tabs = array(
-       //      'entity:-tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'
-       //); // to remove a tab
-       complete_head_from_modules($conf, $langs, $object, $head, $h, 'myobject@mymodule');
-
-       complete_head_from_modules($conf, $langs, $object, $head, $h, 'myobject@mymodule', 'remove');
-
-       return $head;
-}
diff --git a/htdocs/modulebuilder/template/modulebuilder.txt b/htdocs/modulebuilder/template/modulebuilder.txt
deleted file mode 100644 (file)
index 670a177..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# DO NOT DELETE THIS FILE MANUALLY
-# File to flag module built using official module template.
-# When this file is present into a module directory, you can edit it with the module builder tool. 
\ No newline at end of file
diff --git a/htdocs/modulebuilder/template/mymoduleindex.php b/htdocs/modulebuilder/template/mymoduleindex.php
deleted file mode 100644 (file)
index 3b7b1b1..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-<?php
-/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2004-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@inodbox.com>
- * Copyright (C) 2015      Jean-François Ferry        <jfefe@aternatik.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file       htdocs/modulebuilder/template/mymoduleindex.php
- *     \ingroup    mymodule
- *     \brief      Home page of mymodule top menu
- */
-
-// Load Dolibarr environment
-$res = 0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
-       $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-}
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--; $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
-}
-if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
-       $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
-}
-// Try main.inc.php using relative path
-if (!$res && file_exists("../main.inc.php")) {
-       $res = @include "../main.inc.php";
-}
-if (!$res && file_exists("../../main.inc.php")) {
-       $res = @include "../../main.inc.php";
-}
-if (!$res && file_exists("../../../main.inc.php")) {
-       $res = @include "../../../main.inc.php";
-}
-if (!$res) {
-       die("Include of main fails");
-}
-
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
-
-// Load translation files required by the page
-$langs->loadLangs(array("mymodule@mymodule"));
-
-$action = GETPOST('action', 'aZ09');
-
-$max = 5;
-$now = dol_now();
-
-// Security check - Protection if external user
-$socid = GETPOST('socid', 'int');
-if (isset($user->socid) && $user->socid > 0) {
-       $action = '';
-       $socid = $user->socid;
-}
-
-// Security check (enable the most restrictive one)
-//if ($user->socid > 0) accessforbidden();
-//if ($user->socid > 0) $socid = $user->socid;
-//if (!isModEnabled('mymodule')) {
-//     accessforbidden('Module not enabled');
-//}
-//if (! $user->hasRight('mymodule', 'myobject', 'read')) {
-//     accessforbidden();
-//}
-//restrictedArea($user, 'mymodule', 0, 'mymodule_myobject', 'myobject', '', 'rowid');
-//if (empty($user->admin)) {
-//     accessforbidden('Must be admin');
-//}
-
-
-/*
- * Actions
- */
-
-// None
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-$formfile = new FormFile($db);
-
-llxHeader("", $langs->trans("MyModuleArea"));
-
-print load_fiche_titre($langs->trans("MyModuleArea"), '', 'mymodule.png@mymodule');
-
-print '<div class="fichecenter"><div class="fichethirdleft">';
-
-
-/* BEGIN MODULEBUILDER DRAFT MYOBJECT
-// Draft MyObject
-if (isModEnabled('mymodule') && $user->rights->mymodule->read)
-{
-       $langs->load("orders");
-
-       $sql = "SELECT c.rowid, c.ref, c.ref_client, c.total_ht, c.tva as total_tva, c.total_ttc, s.rowid as socid, s.nom as name, s.client, s.canvas";
-       $sql.= ", s.code_client";
-       $sql.= " FROM ".MAIN_DB_PREFIX."commande as c";
-       $sql.= ", ".MAIN_DB_PREFIX."societe as s";
-       if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
-       $sql.= " WHERE c.fk_soc = s.rowid";
-       $sql.= " AND c.fk_statut = 0";
-       $sql.= " AND c.entity IN (".getEntity('commande').")";
-       if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
-       if ($socid)     $sql.= " AND c.fk_soc = ".((int) $socid);
-
-       $resql = $db->query($sql);
-       if ($resql)
-       {
-               $total = 0;
-               $num = $db->num_rows($resql);
-
-               print '<table class="noborder centpercent">';
-               print '<tr class="liste_titre">';
-               print '<th colspan="3">'.$langs->trans("DraftMyObjects").($num?'<span class="badge marginleftonlyshort">'.$num.'</span>':'').'</th></tr>';
-
-               $var = true;
-               if ($num > 0)
-               {
-                       $i = 0;
-                       while ($i < $num)
-                       {
-
-                               $obj = $db->fetch_object($resql);
-                               print '<tr class="oddeven"><td class="nowrap">';
-
-                               $myobjectstatic->id=$obj->rowid;
-                               $myobjectstatic->ref=$obj->ref;
-                               $myobjectstatic->ref_client=$obj->ref_client;
-                               $myobjectstatic->total_ht = $obj->total_ht;
-                               $myobjectstatic->total_tva = $obj->total_tva;
-                               $myobjectstatic->total_ttc = $obj->total_ttc;
-
-                               print $myobjectstatic->getNomUrl(1);
-                               print '</td>';
-                               print '<td class="nowrap">';
-                               print '</td>';
-                               print '<td class="right" class="nowrap">'.price($obj->total_ttc).'</td></tr>';
-                               $i++;
-                               $total += $obj->total_ttc;
-                       }
-                       if ($total>0)
-                       {
-
-                               print '<tr class="liste_total"><td>'.$langs->trans("Total").'</td><td colspan="2" class="right">'.price($total)."</td></tr>";
-                       }
-               }
-               else
-               {
-
-                       print '<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("NoOrder").'</td></tr>';
-               }
-               print "</table><br>";
-
-               $db->free($resql);
-       }
-       else
-       {
-               dol_print_error($db);
-       }
-}
-END MODULEBUILDER DRAFT MYOBJECT */
-
-
-print '</div><div class="fichetwothirdright">';
-
-
-$NBMAX = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT;
-$max = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT;
-
-/* BEGIN MODULEBUILDER LASTMODIFIED MYOBJECT
-// Last modified myobject
-if (isModEnabled('mymodule') && $user->rights->mymodule->read)
-{
-       $sql = "SELECT s.rowid, s.ref, s.label, s.date_creation, s.tms";
-       $sql.= " FROM ".MAIN_DB_PREFIX."mymodule_myobject as s";
-       //if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
-       $sql.= " WHERE s.entity IN (".getEntity($myobjectstatic->element).")";
-       //if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
-       //if ($socid)   $sql.= " AND s.rowid = $socid";
-       $sql .= " ORDER BY s.tms DESC";
-       $sql .= $db->plimit($max, 0);
-
-       $resql = $db->query($sql);
-       if ($resql)
-       {
-               $num = $db->num_rows($resql);
-               $i = 0;
-
-               print '<table class="noborder centpercent">';
-               print '<tr class="liste_titre">';
-               print '<th colspan="2">';
-               print $langs->trans("BoxTitleLatestModifiedMyObjects", $max);
-               print '</th>';
-               print '<th class="right">'.$langs->trans("DateModificationShort").'</th>';
-               print '</tr>';
-               if ($num)
-               {
-                       while ($i < $num)
-                       {
-                               $objp = $db->fetch_object($resql);
-
-                               $myobjectstatic->id=$objp->rowid;
-                               $myobjectstatic->ref=$objp->ref;
-                               $myobjectstatic->label=$objp->label;
-                               $myobjectstatic->status = $objp->status;
-
-                               print '<tr class="oddeven">';
-                               print '<td class="nowrap">'.$myobjectstatic->getNomUrl(1).'</td>';
-                               print '<td class="right nowrap">';
-                               print "</td>";
-                               print '<td class="right nowrap">'.dol_print_date($db->jdate($objp->tms), 'day')."</td>";
-                               print '</tr>';
-                               $i++;
-                       }
-
-                       $db->free($resql);
-               } else {
-                       print '<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
-               }
-               print "</table><br>";
-       }
-}
-*/
-
-print '</div></div>';
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/modulebuilder/template/myobject_agenda.php b/htdocs/modulebuilder/template/myobject_agenda.php
deleted file mode 100644 (file)
index 6abb64d..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-<?php
-/* Copyright (C) 2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *  \file       htdocs/modulebuilder/template/myobject_agenda.php
- *  \ingroup    mymodule
- *  \brief      Tab of events on MyObject
- */
-
-//if (! defined('NOREQUIREDB'))              define('NOREQUIREDB', '1');                               // Do not create database handler $db
-//if (! defined('NOREQUIREUSER'))            define('NOREQUIREUSER', '1');                             // Do not load object $user
-//if (! defined('NOREQUIRESOC'))             define('NOREQUIRESOC', '1');                              // Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN'))            define('NOREQUIRETRAN', '1');                             // Do not load object $langs
-//if (! defined('NOSCANGETFORINJECTION'))    define('NOSCANGETFORINJECTION', '1');             // Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION'))   define('NOSCANPOSTFORINJECTION', '1');            // Do not check injection attack on POST parameters
-//if (! defined('NOTOKENRENEWAL'))           define('NOTOKENRENEWAL', '1');                            // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-//if (! defined('NOSTYLECHECK'))             define('NOSTYLECHECK', '1');                              // Do not check style html tag into posted data
-//if (! defined('NOREQUIREMENU'))            define('NOREQUIREMENU', '1');                             // If there is no need to load and show top and left menu
-//if (! defined('NOREQUIREHTML'))            define('NOREQUIREHTML', '1');                             // If we don't need to load the html.form.class.php
-//if (! defined('NOREQUIREAJAX'))            define('NOREQUIREAJAX', '1');                     // Do not load ajax.lib.php library
-//if (! defined("NOLOGIN"))                  define("NOLOGIN", '1');                                   // If this page is public (can be called outside logged session). This include the NOIPCHECK too.
-//if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');                                 // Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');                                      // Force lang to a particular value
-//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');       // Force authentication handler
-//if (! defined("MAIN_SECURITY_FORCECSP"))   define('MAIN_SECURITY_FORCECSP', 'none'); // Disable all Content Security Policies
-//if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');              // Force use of CSRF protection with tokens even for GET
-//if (! defined('NOBROWSERNOTIF'))                      define('NOBROWSERNOTIF', '1');                         // Disable browser notification
-
-// Load Dolibarr environment
-$res = 0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
-       $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-}
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--; $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
-}
-if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
-       $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
-}
-// Try main.inc.php using relative path
-if (!$res && file_exists("../main.inc.php")) {
-       $res = @include "../main.inc.php";
-}
-if (!$res && file_exists("../../main.inc.php")) {
-       $res = @include "../../main.inc.php";
-}
-if (!$res && file_exists("../../../main.inc.php")) {
-       $res = @include "../../../main.inc.php";
-}
-if (!$res) {
-       die("Include of main fails");
-}
-
-require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-dol_include_once('/mymodule/class/myobject.class.php');
-dol_include_once('/mymodule/lib/mymodule_myobject.lib.php');
-
-// Load translation files required by the page
-$langs->loadLangs(array("mymodule@mymodule", "other"));
-
-// Get parameters
-$id = GETPOST('id', 'int');
-$ref = GETPOST('ref', 'alpha');
-$action = GETPOST('action', 'aZ09');
-$cancel = GETPOST('cancel', 'aZ09');
-$backtopage = GETPOST('backtopage', 'alpha');
-
-if (GETPOST('actioncode', 'array')) {
-       $actioncode = GETPOST('actioncode', 'array', 3);
-       if (!count($actioncode)) {
-               $actioncode = '0';
-       }
-} else {
-       $actioncode = GETPOST("actioncode", "alpha", 3) ? GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT));
-}
-$search_rowid = GETPOST('search_rowid');
-$search_agenda_label = GETPOST('search_agenda_label');
-
-$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
-$sortfield = GETPOST('sortfield', 'aZ09comma');
-$sortorder = GETPOST('sortorder', 'aZ09comma');
-$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
-if (empty($page) || $page == -1) {
-       $page = 0;
-}     // If $page is not defined, or '' or -1
-$offset = $limit * $page;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-if (!$sortfield) {
-       $sortfield = 'a.datep,a.id';
-}
-if (!$sortorder) {
-       $sortorder = 'DESC,DESC';
-}
-
-// Initialize technical objects
-$object = new MyObject($db);
-$extrafields = new ExtraFields($db);
-$diroutputmassaction = $conf->mymodule->dir_output.'/temp/massgeneration/'.$user->id;
-$hookmanager->initHooks(array('myobjectagenda', 'globalcard')); // Note that conf->hooks_modules contains array
-// Fetch optionals attributes and labels
-$extrafields->fetch_name_optionals_label($object->table_element);
-
-// Load object
-include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once  // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
-if ($id > 0 || !empty($ref)) {
-       $upload_dir = $conf->mymodule->multidir_output[!empty($object->entity) ? $object->entity : $conf->entity]."/".$object->id;
-}
-
-// There is several ways to check permission.
-// Set $enablepermissioncheck to 1 to enable a minimum low level of checks
-$enablepermissioncheck = 0;
-if ($enablepermissioncheck) {
-       $permissiontoread = $user->rights->mymodule->myobject->read;
-       $permissiontoadd = $user->rights->mymodule->myobject->write;
-} else {
-       $permissiontoread = 1;
-       $permissiontoadd = 1;
-}
-
-// Security check (enable the most restrictive one)
-//if ($user->socid > 0) accessforbidden();
-//if ($user->socid > 0) $socid = $user->socid;
-//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
-//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
-if (!isModEnabled("mymodule")) {
-       accessforbidden();
-}
-if (!$permissiontoread) accessforbidden();
-
-
-/*
- *  Actions
- */
-
-$parameters = array('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');
-}
-
-if (empty($reshook)) {
-       // Cancel
-       if (GETPOST('cancel', 'alpha') && !empty($backtopage)) {
-               header("Location: ".$backtopage);
-               exit;
-       }
-
-       // Purge search criteria
-       if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
-               $actioncode = '';
-               $search_agenda_label = '';
-       }
-}
-
-
-
-/*
- *     View
- */
-
-$form = new Form($db);
-
-if ($object->id > 0) {
-       $title = $langs->trans("Agenda");
-       //if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name." - ".$title;
-       $help_url = 'EN:Module_Agenda_En';
-       llxHeader('', $title, $help_url);
-
-       if (isModEnabled('notification')) {
-               $langs->load("mails");
-       }
-       $head = myobjectPrepareHead($object);
-
-
-       print dol_get_fiche_head($head, 'agenda', $langs->trans("MyObject"), -1, $object->picto);
-
-       // Object card
-       // ------------------------------------------------------------
-       $linkback = '<a href="'.dol_buildpath('/mymodule/myobject_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
-
-       $morehtmlref = '<div class="refidno">';
-       /*
-       // Ref customer
-       $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
-       $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
-       // Thirdparty
-       $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : '');
-       // Project
-       if (!empty($conf->project->enabled)) {
-               $langs->load("projects");
-               $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
-               if ($permissiontoadd) {
-                       if ($action != 'classify') {
-                               //$morehtmlref.='<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token='.newToken().'&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
-                       }
-                       $morehtmlref.=' : ';
-                       if ($action == 'classify') {
-                               //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
-                               $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
-                               $morehtmlref.='<input type="hidden" name="action" value="classin">';
-                               $morehtmlref.='<input type="hidden" name="token" value="'.newToken().'">';
-                               $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
-                               $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
-                               $morehtmlref.='</form>';
-                       } else {
-                               $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
-                       }
-               } else {
-                       if (!empty($object->fk_project)) {
-                               $proj = new Project($db);
-                               $proj->fetch($object->fk_project);
-                               $morehtmlref .= ': '.$proj->getNomUrl();
-                       } else {
-                               $morehtmlref .= '';
-                       }
-               }
-       }*/
-       $morehtmlref .= '</div>';
-
-
-       dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
-
-       print '<div class="fichecenter">';
-       print '<div class="underbanner clearboth"></div>';
-
-       $object->info($object->id);
-       dol_print_object_info($object, 1);
-
-       print '</div>';
-
-       print dol_get_fiche_end();
-
-
-
-       // Actions buttons
-
-       $objthirdparty = $object;
-       $objcon = new stdClass();
-
-       $out = '&origin='.urlencode($object->element.'@'.$object->module).'&originid='.urlencode($object->id);
-       $urlbacktopage = $_SERVER['PHP_SELF'].'?id='.$object->id;
-       $out .= '&backtopage='.urlencode($urlbacktopage);
-       $permok = $user->rights->agenda->myactions->create;
-       if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) {
-               //$out.='<a href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create';
-               if (get_class($objthirdparty) == 'Societe') {
-                       $out .= '&socid='.urlencode($objthirdparty->id);
-               }
-               $out .= (!empty($objcon->id) ? '&contactid='.urlencode($objcon->id) : '').'&percentage=-1';
-               //$out.=$langs->trans("AddAnAction").' ';
-               //$out.=img_picto($langs->trans("AddAnAction"),'filenew');
-               //$out.="</a>";
-       }
-
-       $morehtmlright = '';
-
-       //$messagingUrl = DOL_URL_ROOT.'/societe/messaging.php?socid='.$object->id;
-       //$morehtmlright .= dolGetButtonTitle($langs->trans('ShowAsConversation'), '', 'fa fa-comments imgforviewmode', $messagingUrl, '', 1);
-       //$messagingUrl = DOL_URL_ROOT.'/societe/agenda.php?socid='.$object->id;
-       //$morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-bars imgforviewmode', $messagingUrl, '', 2);
-
-       if (isModEnabled('agenda')) {
-               if (!empty($user->rights->agenda->myactions->create) || !empty($user->rights->agenda->allactions->create)) {
-                       $morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out);
-               } else {
-                       $morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out, '', 0);
-               }
-       }
-
-
-       if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
-               print '<br>';
-
-               $param = '&id='.$object->id.(!empty($socid) ? '&socid='.$socid : '');
-               if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
-                       $param .= '&contextpage='.urlencode($contextpage);
-               }
-               if ($limit > 0 && $limit != $conf->liste_limit) {
-                       $param .= '&limit='.urlencode($limit);
-               }
-
-               //print load_fiche_titre($langs->trans("ActionsOnMyObject"), '', '');
-               print_barre_liste($langs->trans("ActionsOnMyObject"), 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1);
-
-               // List of all actions
-               $filters = array();
-               $filters['search_agenda_label'] = $search_agenda_label;
-               $filters['search_rowid'] = $search_rowid;
-
-               // TODO Replace this with same code than into list.php
-               show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, $object->module);
-       }
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php
deleted file mode 100644 (file)
index dc8dafd..0000000
+++ /dev/null
@@ -1,621 +0,0 @@
-<?php
-/* Copyright (C) 2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file       htdocs/modulebuilder/template/myobject_card.php
- *             \ingroup    mymodule
- *             \brief      Page to create/edit/view myobject
- */
-
-//if (! defined('NOREQUIREDB'))              define('NOREQUIREDB', '1');                               // Do not create database handler $db
-//if (! defined('NOREQUIREUSER'))            define('NOREQUIREUSER', '1');                             // Do not load object $user
-//if (! defined('NOREQUIRESOC'))             define('NOREQUIRESOC', '1');                              // Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN'))            define('NOREQUIRETRAN', '1');                             // Do not load object $langs
-//if (! defined('NOSCANGETFORINJECTION'))    define('NOSCANGETFORINJECTION', '1');             // Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION'))   define('NOSCANPOSTFORINJECTION', '1');            // Do not check injection attack on POST parameters
-//if (! defined('NOTOKENRENEWAL'))           define('NOTOKENRENEWAL', '1');                            // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-//if (! defined('NOSTYLECHECK'))             define('NOSTYLECHECK', '1');                              // Do not check style html tag into posted data
-//if (! defined('NOREQUIREMENU'))            define('NOREQUIREMENU', '1');                             // If there is no need to load and show top and left menu
-//if (! defined('NOREQUIREHTML'))            define('NOREQUIREHTML', '1');                             // If we don't need to load the html.form.class.php
-//if (! defined('NOREQUIREAJAX'))            define('NOREQUIREAJAX', '1');                     // Do not load ajax.lib.php library
-//if (! defined("NOLOGIN"))                  define("NOLOGIN", '1');                                   // If this page is public (can be called outside logged session). This include the NOIPCHECK too.
-//if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');                                 // Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');                                      // Force lang to a particular value
-//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');       // Force authentication handler
-//if (! defined("MAIN_SECURITY_FORCECSP"))   define('MAIN_SECURITY_FORCECSP', 'none'); // Disable all Content Security Policies
-//if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');              // Force use of CSRF protection with tokens even for GET
-//if (! defined('NOBROWSERNOTIF'))                      define('NOBROWSERNOTIF', '1');                         // Disable browser notification
-//if (! defined('NOSESSION'))                       define('NOSESSION', '1');                              // Disable session
-
-// Load Dolibarr environment
-$res = 0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
-       $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-}
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--; $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
-}
-if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
-       $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
-}
-// Try main.inc.php using relative path
-if (!$res && file_exists("../main.inc.php")) {
-       $res = @include "../main.inc.php";
-}
-if (!$res && file_exists("../../main.inc.php")) {
-       $res = @include "../../main.inc.php";
-}
-if (!$res && file_exists("../../../main.inc.php")) {
-       $res = @include "../../../main.inc.php";
-}
-if (!$res) {
-       die("Include of main fails");
-}
-
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
-dol_include_once('/mymodule/class/myobject.class.php');
-dol_include_once('/mymodule/lib/mymodule_myobject.lib.php');
-
-// Load translation files required by the page
-$langs->loadLangs(array("mymodule@mymodule", "other"));
-
-// Get parameters
-$id = GETPOST('id', 'int');
-$ref = GETPOST('ref', 'alpha');
-$lineid   = GETPOST('lineid', 'int');
-
-$action = GETPOST('action', 'aZ09');
-$confirm = GETPOST('confirm', 'alpha');
-$cancel = GETPOST('cancel', 'aZ09');
-$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
-$backtopage = GETPOST('backtopage', 'alpha');
-$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
-$dol_openinpopup = GETPOST('dol_openinpopup', 'aZ09');
-
-// Initialize technical objects
-$object = new MyObject($db);
-$extrafields = new ExtraFields($db);
-$diroutputmassaction = $conf->mymodule->dir_output.'/temp/massgeneration/'.$user->id;
-$hookmanager->initHooks(array('myobjectcard', 'globalcard')); // Note that conf->hooks_modules contains array
-
-// Fetch optionals attributes and labels
-$extrafields->fetch_name_optionals_label($object->table_element);
-
-$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
-
-// Initialize array of search criterias
-$search_all = GETPOST("search_all", 'alpha');
-$search = array();
-foreach ($object->fields as $key => $val) {
-       if (GETPOST('search_'.$key, 'alpha')) {
-               $search[$key] = GETPOST('search_'.$key, 'alpha');
-       }
-}
-
-if (empty($action) && empty($id) && empty($ref)) {
-       $action = 'view';
-}
-
-// Load object
-include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
-
-// There is several ways to check permission.
-// Set $enablepermissioncheck to 1 to enable a minimum low level of checks
-$enablepermissioncheck = 0;
-if ($enablepermissioncheck) {
-       $permissiontoread = $user->hasRight('mymodule', 'myobject', 'read');
-       $permissiontoadd = $user->hasRight('mymodule', 'myobject', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
-       $permissiontodelete = $user->hasRight('mymodule', 'myobject', 'delete') || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
-       $permissionnote = $user->hasRight('mymodule', 'myobject', 'write'); // Used by the include of actions_setnotes.inc.php
-       $permissiondellink = $user->hasRight('mymodule', 'myobject', 'write'); // Used by the include of actions_dellink.inc.php
-} else {
-       $permissiontoread = 1;
-       $permissiontoadd = 1; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
-       $permissiontodelete = 1;
-       $permissionnote = 1;
-       $permissiondellink = 1;
-}
-
-$upload_dir = $conf->mymodule->multidir_output[isset($object->entity) ? $object->entity : 1].'/myobject';
-
-// Security check (enable the most restrictive one)
-//if ($user->socid > 0) accessforbidden();
-//if ($user->socid > 0) $socid = $user->socid;
-//$isdraft = (isset($object->status) && ($object->status == $object::STATUS_DRAFT) ? 1 : 0);
-//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
-if (!isModEnabled("mymodule")) {
-       accessforbidden();
-}
-if (!$permissiontoread) {
-       accessforbidden();
-}
-
-
-/*
- * Actions
- */
-
-$parameters = array();
-$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');
-}
-
-if (empty($reshook)) {
-       $error = 0;
-
-       $backurlforlist = dol_buildpath('/mymodule/myobject_list.php', 1);
-
-       if (empty($backtopage) || ($cancel && empty($id))) {
-               if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
-                       if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
-                               $backtopage = $backurlforlist;
-                       } else {
-                               $backtopage = dol_buildpath('/mymodule/myobject_card.php', 1).'?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
-                       }
-               }
-       }
-
-       $triggermodname = 'MYMODULE_MYOBJECT_MODIFY'; // Name of trigger action code to execute when we modify record
-
-       // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
-       include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
-
-       // Actions when linking object each other
-       include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
-
-       // Actions when printing a doc from card
-       include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
-
-       // Action to move up and down lines of object
-       //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php';
-
-       // Action to build doc
-       include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
-
-       if ($action == 'set_thirdparty' && $permissiontoadd) {
-               $object->setValueFrom('fk_soc', GETPOST('fk_soc', 'int'), '', '', 'date', '', $user, $triggermodname);
-       }
-       if ($action == 'classin' && $permissiontoadd) {
-               $object->setProject(GETPOST('projectid', 'int'));
-       }
-
-       // Actions to send emails
-       $triggersendname = 'MYMODULE_MYOBJECT_SENTBYMAIL';
-       $autocopy = 'MAIN_MAIL_AUTOCOPY_MYOBJECT_TO';
-       $trackid = 'myobject'.$object->id;
-       include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
-}
-
-
-
-
-/*
- * View
- *
- * Put here all code to build page
- */
-
-$form = new Form($db);
-$formfile = new FormFile($db);
-$formproject = new FormProjets($db);
-
-$title = $langs->trans("MyObject");
-$help_url = '';
-llxHeader('', $title, $help_url);
-
-// Example : Adding jquery code
-// print '<script type="text/javascript">
-// jQuery(document).ready(function() {
-//     function init_myfunc()
-//     {
-//             jQuery("#myid").removeAttr(\'disabled\');
-//             jQuery("#myid").attr(\'disabled\',\'disabled\');
-//     }
-//     init_myfunc();
-//     jQuery("#mybutton").click(function() {
-//             init_myfunc();
-//     });
-// });
-// </script>';
-
-
-// Part to create
-if ($action == 'create') {
-       if (empty($permissiontoadd)) {
-               accessforbidden('NotEnoughPermissions', 0, 1);
-       }
-
-       print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("MyObject")), '', 'object_'.$object->picto);
-
-       print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
-       print '<input type="hidden" name="token" value="'.newToken().'">';
-       print '<input type="hidden" name="action" value="add">';
-       if ($backtopage) {
-               print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
-       }
-       if ($backtopageforcancel) {
-               print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
-       }
-
-       print dol_get_fiche_head(array(), '');
-
-       // Set some default values
-       //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue';
-
-       print '<table class="border centpercent tableforfieldcreate">'."\n";
-
-       // Common attributes
-       include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php';
-
-       // Other attributes
-       include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
-
-       print '</table>'."\n";
-
-       print dol_get_fiche_end();
-
-       print $form->buttonsSaveCancel("Create");
-
-       print '</form>';
-
-       //dol_set_focus('input[name="ref"]');
-}
-
-// Part to edit record
-if (($id || $ref) && $action == 'edit') {
-       print load_fiche_titre($langs->trans("MyObject"), '', 'object_'.$object->picto);
-
-       print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
-       print '<input type="hidden" name="token" value="'.newToken().'">';
-       print '<input type="hidden" name="action" value="update">';
-       print '<input type="hidden" name="id" value="'.$object->id.'">';
-       if ($backtopage) {
-               print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
-       }
-       if ($backtopageforcancel) {
-               print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
-       }
-
-       print dol_get_fiche_head();
-
-       print '<table class="border centpercent tableforfieldedit">'."\n";
-
-       // Common attributes
-       include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php';
-
-       // Other attributes
-       include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php';
-
-       print '</table>';
-
-       print dol_get_fiche_end();
-
-       print $form->buttonsSaveCancel();
-
-       print '</form>';
-}
-
-// Part to show record
-if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
-       $head = myobjectPrepareHead($object);
-
-       print dol_get_fiche_head($head, 'card', $langs->trans("MyObject"), -1, $object->picto);
-
-       $formconfirm = '';
-
-       // Confirmation to delete
-       if ($action == 'delete') {
-               $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteMyObject'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1);
-       }
-       // Confirmation to delete line
-       if ($action == 'deleteline') {
-               $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
-       }
-
-       // Clone confirmation
-       if ($action == 'clone') {
-               // Create an array for form
-               $formquestion = array();
-               $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
-       }
-
-       // Confirmation of action xxxx (You can use it for xxx = 'close', xxx = 'reopen', ...)
-       if ($action == 'xxx') {
-               $text = $langs->trans('ConfirmActionMyObject', $object->ref);
-               /*if (isModEnabled('notification'))
-               {
-                       require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
-                       $notify = new Notify($db);
-                       $text .= '<br>';
-                       $text .= $notify->confirmMessage('MYOBJECT_CLOSE', $object->socid, $object);
-               }*/
-
-               $formquestion = array();
-
-               /*
-               $forcecombo=0;
-               if ($conf->browser->name == 'ie') $forcecombo = 1;      // There is a bug in IE10 that make combo inside popup crazy
-               $formquestion = array(
-                       // 'text' => $langs->trans("ConfirmClone"),
-                       // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
-                       // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
-                       // array('type' => 'other',    'name' => 'idwarehouse',   'label' => $langs->trans("SelectWarehouseForStockDecrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse')?GETPOST('idwarehouse'):'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
-               );
-               */
-               $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('XXX'), $text, 'confirm_xxx', $formquestion, 0, 1, 220);
-       }
-
-       // Call Hook formConfirm
-       $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;
-       } elseif ($reshook > 0) {
-               $formconfirm = $hookmanager->resPrint;
-       }
-
-       // Print form confirm
-       print $formconfirm;
-
-
-       // Object card
-       // ------------------------------------------------------------
-       $linkback = '<a href="'.dol_buildpath('/mymodule/myobject_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
-
-       $morehtmlref = '<div class="refidno">';
-       /*
-               // Ref customer
-               $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $usercancreate, 'string', '', 0, 1);
-               $morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $usercancreate, 'string'.(isset($conf->global->THIRDPARTY_REF_INPUT_SIZE) ? ':'.$conf->global->THIRDPARTY_REF_INPUT_SIZE : ''), '', null, null, '', 1);
-               // Thirdparty
-               $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'customer');
-               if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) {
-                       $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
-               }
-               // Project
-               if (isModEnabled('project')) {
-                       $langs->load("projects");
-                       $morehtmlref .= '<br>';
-                       if ($permissiontoadd) {
-                               $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
-                               if ($action != 'classify') {
-                                       $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
-                               }
-                               $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
-                       } else {
-                               if (!empty($object->fk_project)) {
-                                       $proj = new Project($db);
-                                       $proj->fetch($object->fk_project);
-                                       $morehtmlref .= $proj->getNomUrl(1);
-                                       if ($proj->title) {
-                                               $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
-                                       }
-                               }
-                       }
-               }
-       */
-       $morehtmlref .= '</div>';
-
-
-       dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
-
-
-       print '<div class="fichecenter">';
-       print '<div class="fichehalfleft">';
-       print '<div class="underbanner clearboth"></div>';
-       print '<table class="border centpercent tableforfield">'."\n";
-
-       // Common attributes
-       //$keyforbreak='fieldkeytoswitchonsecondcolumn';        // We change column just before this field
-       //unset($object->fields['fk_project']);                         // Hide field already shown in banner
-       //unset($object->fields['fk_soc']);                                     // Hide field already shown in banner
-       include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
-
-       // Other attributes. Fields from hook formObjectOptions and Extrafields.
-       include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
-
-       print '</table>';
-       print '</div>';
-       print '</div>';
-
-       print '<div class="clearboth"></div>';
-
-       print dol_get_fiche_end();
-
-
-       /*
-        * Lines
-        */
-
-       if (!empty($object->table_element_line)) {
-               // Show object lines
-               $result = $object->getLinesArray();
-
-               print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOST('lineid', 'int')).'" method="POST">
-               <input type="hidden" name="token" value="' . newToken().'">
-               <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
-               <input type="hidden" name="mode" value="">
-               <input type="hidden" name="page_y" value="">
-               <input type="hidden" name="id" value="' . $object->id.'">
-               ';
-
-               if (!empty($conf->use_javascript_ajax) && $object->status == 0) {
-                       include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
-               }
-
-               print '<div class="div-table-responsive-no-min">';
-               if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
-                       print '<table id="tablelines" class="noborder noshadow" width="100%">';
-               }
-
-               if (!empty($object->lines)) {
-                       $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1);
-               }
-
-               // Form to add new line
-               if ($object->status == 0 && $permissiontoadd && $action != 'selectlines') {
-                       if ($action != 'editline') {
-                               // Add products/services form
-
-                               $parameters = array();
-                               $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
-                               if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
-                               if (empty($reshook))
-                                       $object->formAddObjectLine(1, $mysoc, $soc);
-                       }
-               }
-
-               if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
-                       print '</table>';
-               }
-               print '</div>';
-
-               print "</form>\n";
-       }
-
-
-       // Buttons for actions
-
-       if ($action != 'presend' && $action != 'editline') {
-               print '<div class="tabsAction">'."\n";
-               $parameters = array();
-               $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
-               if ($reshook < 0) {
-                       setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
-               }
-
-               if (empty($reshook)) {
-                       // Send
-                       if (empty($user->socid)) {
-                               print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&token='.newToken().'&mode=init#formmailbeforetitle');
-                       }
-
-                       // Back to draft
-                       if ($object->status == $object::STATUS_VALIDATED) {
-                               print dolGetButtonAction('', $langs->trans('SetToDraft'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_setdraft&confirm=yes&token='.newToken(), '', $permissiontoadd);
-                       }
-
-                       print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken(), '', $permissiontoadd);
-
-                       // Validate
-                       if ($object->status == $object::STATUS_DRAFT) {
-                               if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) {
-                                       print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_validate&confirm=yes&token='.newToken(), '', $permissiontoadd);
-                               } else {
-                                       $langs->load("errors");
-                                       print dolGetButtonAction($langs->trans("ErrorAddAtLeastOneLineFirst"), $langs->trans("Validate"), 'default', '#', '', 0);
-                               }
-                       }
-
-                       // Clone
-                       if ($permissiontoadd) {
-                               print dolGetButtonAction('', $langs->trans('ToClone'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.(!empty($object->socid)?'&socid='.$object->socid:'').'&action=clone&token='.newToken(), '', $permissiontoadd);
-                       }
-
-                       /*
-                       if ($permissiontoadd) {
-                               if ($object->status == $object::STATUS_ENABLED) {
-                                       print dolGetButtonAction('', $langs->trans('Disable'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=disable&token='.newToken(), '', $permissiontoadd);
-                               } else {
-                                       print dolGetButtonAction('', $langs->trans('Enable'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=enable&token='.newToken(), '', $permissiontoadd);
-                               }
-                       }
-                       if ($permissiontoadd) {
-                               if ($object->status == $object::STATUS_VALIDATED) {
-                                       print dolGetButtonAction('', $langs->trans('Cancel'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=close&token='.newToken(), '', $permissiontoadd);
-                               } else {
-                                       print dolGetButtonAction('', $langs->trans('Re-Open'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=reopen&token='.newToken(), '', $permissiontoadd);
-                               }
-                       }
-                       */
-
-                       // Delete
-                       $params = array();
-                       print dolGetButtonAction('', $langs->trans("Delete"), 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', $permissiontodelete, $params);
-               }
-               print '</div>'."\n";
-       }
-
-
-       // Select mail models is same action as presend
-       if (GETPOST('modelselected')) {
-               $action = 'presend';
-       }
-
-       if ($action != 'presend') {
-               print '<div class="fichecenter"><div class="fichehalfleft">';
-               print '<a name="builddoc"></a>'; // ancre
-
-               $includedocgeneration = 0;
-
-               // Documents
-               if ($includedocgeneration) {
-                       $objref = dol_sanitizeFileName($object->ref);
-                       $relativepath = $objref.'/'.$objref.'.pdf';
-                       $filedir = $conf->mymodule->dir_output.'/'.$object->element.'/'.$objref;
-                       $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
-                       $genallowed = $permissiontoread; // If you can read, you can build the PDF to read content
-                       $delallowed = $permissiontoadd; // If you can create/edit, you can remove a file on card
-                       print $formfile->showdocuments('mymodule:MyObject', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang);
-               }
-
-               // Show links to link elements
-               $linktoelem = $form->showLinkToObjectBlock($object, null, array('myobject'));
-               $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
-
-
-               print '</div><div class="fichehalfright">';
-
-               $MAXEVENT = 10;
-
-               $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', dol_buildpath('/mymodule/myobject_agenda.php', 1).'?id='.$object->id);
-
-               // List of actions on element
-               include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
-               $formactions = new FormActions($db);
-               $somethingshown = $formactions->showactions($object, $object->element.'@'.$object->module, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter);
-
-               print '</div></div>';
-       }
-
-       //Select mail models is same action as presend
-       if (GETPOST('modelselected')) {
-               $action = 'presend';
-       }
-
-       // Presend form
-       $modelmail = 'myobject';
-       $defaulttopic = 'InformationMessage';
-       $diroutput = $conf->mymodule->dir_output;
-       $trackid = 'myobject'.$object->id;
-
-       include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/modulebuilder/template/myobject_contact.php b/htdocs/modulebuilder/template/myobject_contact.php
deleted file mode 100644 (file)
index 9568201..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-<?php
-/* Copyright (C) 2007-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *  \file       htdocs/modulebuilder/template/myobject_contact.php
- *  \ingroup    mymodule
- *  \brief      Tab for contacts linked to MyObject
- */
-
-// Load Dolibarr environment
-$res = 0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
-       $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-}
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--; $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
-}
-if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
-       $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
-}
-// Try main.inc.php using relative path
-if (!$res && file_exists("../main.inc.php")) {
-       $res = @include "../main.inc.php";
-}
-if (!$res && file_exists("../../main.inc.php")) {
-       $res = @include "../../main.inc.php";
-}
-if (!$res && file_exists("../../../main.inc.php")) {
-       $res = @include "../../../main.inc.php";
-}
-if (!$res) {
-       die("Include of main fails");
-}
-
-require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
-dol_include_once('/mymodule/class/myobject.class.php');
-dol_include_once('/mymodule/lib/mymodule_myobject.lib.php');
-
-// Load translation files required by the page
-$langs->loadLangs(array("mymodule@mymodule", "companies", "other", "mails"));
-
-$id     = (GETPOST('id') ?GETPOST('id', 'int') : GETPOST('facid', 'int')); // For backward compatibility
-$ref    = GETPOST('ref', 'alpha');
-$lineid = GETPOST('lineid', 'int');
-$socid  = GETPOST('socid', 'int');
-$action = GETPOST('action', 'aZ09');
-
-// Initialize technical objects
-$object = new MyObject($db);
-$extrafields = new ExtraFields($db);
-$diroutputmassaction = $conf->mymodule->dir_output.'/temp/massgeneration/'.$user->id;
-$hookmanager->initHooks(array('myobjectcontact', 'globalcard')); // Note that conf->hooks_modules contains array
-// Fetch optionals attributes and labels
-$extrafields->fetch_name_optionals_label($object->table_element);
-
-// Load object
-include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once  // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
-
-// There is several ways to check permission.
-// Set $enablepermissioncheck to 1 to enable a minimum low level of checks
-$enablepermissioncheck = 0;
-if ($enablepermissioncheck) {
-       $permissiontoread = $user->rights->mymodule->myobject->read;
-       $permission = $user->rights->mymodule->myobject->write;
-} else {
-       $permissiontoread = 1;
-       $permission = 1;
-}
-
-// Security check (enable the most restrictive one)
-//if ($user->socid > 0) accessforbidden();
-//if ($user->socid > 0) $socid = $user->socid;
-//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
-//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
-if (!isModEnabled("mymodule")) {
-       accessforbidden();
-}
-if (!$permissiontoread) accessforbidden();
-
-
-/*
- * Add a new contact
- */
-
-if ($action == 'addcontact' && $permission) {
-       $contactid = (GETPOST('userid') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int'));
-       $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
-       $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
-
-       if ($result >= 0) {
-               header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
-               exit;
-       } else {
-               if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
-                       $langs->load("errors");
-                       setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
-               } else {
-                       setEventMessages($object->error, $object->errors, 'errors');
-               }
-       }
-} elseif ($action == 'swapstatut' && $permission) {
-       // Toggle the status of a contact
-       $result = $object->swapContactStatus(GETPOST('ligne', 'int'));
-} elseif ($action == 'deletecontact' && $permission) {
-       // Deletes a contact
-       $result = $object->delete_contact($lineid);
-
-       if ($result >= 0) {
-               header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
-               exit;
-       } else {
-               dol_print_error($db);
-       }
-}
-
-
-/*
- * View
- */
-
-$title = $langs->trans('MyObject')." - ".$langs->trans('ContactsAddresses');
-$help_url = '';
-//$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas';
-llxHeader('', $title, $help_url);
-
-$form = new Form($db);
-$formcompany = new FormCompany($db);
-$contactstatic = new Contact($db);
-$userstatic = new User($db);
-
-
-/* *************************************************************************** */
-/*                                                                             */
-/* View and edit mode                                                         */
-/*                                                                             */
-/* *************************************************************************** */
-
-if ($object->id) {
-       /*
-        * Show tabs
-        */
-       $head = myobjectPrepareHead($object);
-
-       print dol_get_fiche_head($head, 'contact', $langs->trans("MyObject"), -1, $object->picto);
-
-       $linkback = '<a href="'.dol_buildpath('/mymodule/myobject_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
-
-       $morehtmlref = '<div class="refidno">';
-       /*
-        // Ref customer
-        $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
-        $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
-        // Thirdparty
-        $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : '');
-        // Project
-        if (!empty($conf->project->enabled))
-        {
-        $langs->load("projects");
-        $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
-        if ($permissiontoadd)
-        {
-        if ($action != 'classify')
-        //$morehtmlref.='<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token='.newToken().'&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
-        $morehtmlref.=' : ';
-        if ($action == 'classify') {
-        //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
-        $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
-        $morehtmlref.='<input type="hidden" name="action" value="classin">';
-        $morehtmlref.='<input type="hidden" name="token" value="'.newToken().'">';
-        $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
-        $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
-        $morehtmlref.='</form>';
-        } else {
-        $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
-        }
-        } else {
-        if (!empty($object->fk_project)) {
-        $proj = new Project($db);
-        $proj->fetch($object->fk_project);
-        $morehtmlref .= ': '.$proj->getNomUrl();
-        } else {
-        $morehtmlref .= '';
-        }
-        }
-        }*/
-       $morehtmlref .= '</div>';
-
-       dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0, '', '', 1);
-
-       print dol_get_fiche_end();
-
-       print '<br>';
-
-       // Contacts lines (modules that overwrite templates must declare this into descriptor)
-       $dirtpls = array_merge($conf->modules_parts['tpl'], array('/core/tpl'));
-       foreach ($dirtpls as $reldir) {
-               $res = @include dol_buildpath($reldir.'/contacts.tpl.php');
-               if ($res) {
-                       break;
-               }
-       }
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/modulebuilder/template/myobject_document.php b/htdocs/modulebuilder/template/myobject_document.php
deleted file mode 100644 (file)
index ff1756e..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-<?php
-/* Copyright (C) 2007-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *  \file       htdocs/modulebuilder/template/myobject_document.php
- *  \ingroup    mymodule
- *  \brief      Tab for documents linked to MyObject
- */
-
-//if (! defined('NOREQUIREDB'))              define('NOREQUIREDB', '1');                               // Do not create database handler $db
-//if (! defined('NOREQUIREUSER'))            define('NOREQUIREUSER', '1');                             // Do not load object $user
-//if (! defined('NOREQUIRESOC'))             define('NOREQUIRESOC', '1');                              // Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN'))            define('NOREQUIRETRAN', '1');                             // Do not load object $langs
-//if (! defined('NOSCANGETFORINJECTION'))    define('NOSCANGETFORINJECTION', '1');             // Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION'))   define('NOSCANPOSTFORINJECTION', '1');            // Do not check injection attack on POST parameters
-//if (! defined('NOTOKENRENEWAL'))           define('NOTOKENRENEWAL', '1');                            // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-//if (! defined('NOSTYLECHECK'))             define('NOSTYLECHECK', '1');                              // Do not check style html tag into posted data
-//if (! defined('NOREQUIREMENU'))            define('NOREQUIREMENU', '1');                             // If there is no need to load and show top and left menu
-//if (! defined('NOREQUIREHTML'))            define('NOREQUIREHTML', '1');                             // If we don't need to load the html.form.class.php
-//if (! defined('NOREQUIREAJAX'))            define('NOREQUIREAJAX', '1');                     // Do not load ajax.lib.php library
-//if (! defined("NOLOGIN"))                  define("NOLOGIN", '1');                                   // If this page is public (can be called outside logged session). This include the NOIPCHECK too.
-//if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');                                 // Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');                                      // Force lang to a particular value
-//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');       // Force authentication handler
-//if (! defined("MAIN_SECURITY_FORCECSP"))   define('MAIN_SECURITY_FORCECSP', 'none');                         // Disable all Content Security Policies
-//if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');              // Force use of CSRF protection with tokens even for GET
-//if (! defined('NOBROWSERNOTIF'))                      define('NOBROWSERNOTIF', '1');                         // Disable browser notification
-
-// Load Dolibarr environment
-$res = 0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
-       $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-}
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--; $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
-}
-if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
-       $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
-}
-// Try main.inc.php using relative path
-if (!$res && file_exists("../main.inc.php")) {
-       $res = @include "../main.inc.php";
-}
-if (!$res && file_exists("../../main.inc.php")) {
-       $res = @include "../../main.inc.php";
-}
-if (!$res && file_exists("../../../main.inc.php")) {
-       $res = @include "../../../main.inc.php";
-}
-if (!$res) {
-       die("Include of main fails");
-}
-
-require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
-dol_include_once('/mymodule/class/myobject.class.php');
-dol_include_once('/mymodule/lib/mymodule_myobject.lib.php');
-
-// Load translation files required by the page
-$langs->loadLangs(array("mymodule@mymodule", "companies", "other", "mails"));
-
-
-$action = GETPOST('action', 'aZ09');
-$confirm = GETPOST('confirm');
-$id = (GETPOST('socid', 'int') ? GETPOST('socid', 'int') : GETPOST('id', 'int'));
-$ref = GETPOST('ref', 'alpha');
-
-// Get parameters
-$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
-$sortfield = GETPOST('sortfield', 'aZ09comma');
-$sortorder = GETPOST('sortorder', 'aZ09comma');
-$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
-if (empty($page) || $page == -1) {
-       $page = 0;
-}     // If $page is not defined, or '' or -1
-$offset = $limit * $page;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-if (!$sortorder) {
-       $sortorder = "ASC";
-}
-if (!$sortfield) {
-       $sortfield = "name";
-}
-//if (! $sortfield) $sortfield="position_name";
-
-// Initialize technical objects
-$object = new MyObject($db);
-$extrafields = new ExtraFields($db);
-$diroutputmassaction = $conf->mymodule->dir_output.'/temp/massgeneration/'.$user->id;
-$hookmanager->initHooks(array('myobjectdocument', 'globalcard')); // Note that conf->hooks_modules contains array
-// Fetch optionals attributes and labels
-$extrafields->fetch_name_optionals_label($object->table_element);
-
-// Load object
-include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once  // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
-
-if ($id > 0 || !empty($ref)) {
-       $upload_dir = $conf->mymodule->multidir_output[$object->entity ? $object->entity : $conf->entity]."/myobject/".get_exdir(0, 0, 0, 1, $object);
-}
-
-// There is several ways to check permission.
-// Set $enablepermissioncheck to 1 to enable a minimum low level of checks
-$enablepermissioncheck = 0;
-if ($enablepermissioncheck) {
-       $permissiontoread = $user->rights->mymodule->myobject->read;
-       $permissiontoadd = $user->rights->mymodule->myobject->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php
-} else {
-       $permissiontoread = 1;
-       $permissiontoadd = 1;
-}
-
-// Security check (enable the most restrictive one)
-//if ($user->socid > 0) accessforbidden();
-//if ($user->socid > 0) $socid = $user->socid;
-//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
-//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
-if (!isModEnabled("mymodule")) {
-       accessforbidden();
-}
-if (!$permissiontoread) {
-       accessforbidden();
-}
-if (empty($object->id)) {
-       accessforbidden();
-}
-
-
-
-/*
- * Actions
- */
-
-include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-$title = $langs->trans("MyObject").' - '.$langs->trans("Files");
-$help_url = '';
-//$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas';
-llxHeader('', $title, $help_url);
-
-// Show tabs
-$head = myobjectPrepareHead($object);
-
-print dol_get_fiche_head($head, 'document', $langs->trans("MyObject"), -1, $object->picto);
-
-
-// Build file list
-$filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ?SORT_DESC:SORT_ASC), 1);
-$totalsize = 0;
-foreach ($filearray as $key => $file) {
-       $totalsize += $file['size'];
-}
-
-// Object card
-// ------------------------------------------------------------
-$linkback = '<a href="'.dol_buildpath('/mymodule/myobject_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
-
-$morehtmlref = '<div class="refidno">';
-/*
- // Ref customer
- $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
- $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
- // Thirdparty
- $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : '');
- // Project
- if (!empty($conf->project->enabled))
- {
- $langs->load("projects");
- $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
- if ($permissiontoadd)
- {
- if ($action != 'classify')
- //$morehtmlref.='<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token='.newToken().'&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
- $morehtmlref.=' : ';
- if ($action == 'classify') {
- //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
- $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
- $morehtmlref.='<input type="hidden" name="action" value="classin">';
- $morehtmlref.='<input type="hidden" name="token" value="'.newToken().'">';
- $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
- $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
- $morehtmlref.='</form>';
- } else {
- $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
- }
- } else {
- if (!empty($object->fk_project)) {
- $proj = new Project($db);
- $proj->fetch($object->fk_project);
- $morehtmlref .= ': '.$proj->getNomUrl();
- } else {
- $morehtmlref .= '';
- }
- }
- }*/
-$morehtmlref .= '</div>';
-
-dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
-
-print '<div class="fichecenter">';
-
-print '<div class="underbanner clearboth"></div>';
-print '<table class="border centpercent tableforfield">';
-
-// Number of files
-print '<tr><td class="titlefield">'.$langs->trans("NbOfAttachedFiles").'</td><td colspan="3">'.count($filearray).'</td></tr>';
-
-// Total size
-print '<tr><td>'.$langs->trans("TotalSizeOfAttachedFiles").'</td><td colspan="3">'.$totalsize.' '.$langs->trans("bytes").'</td></tr>';
-
-print '</table>';
-
-print '</div>';
-
-print dol_get_fiche_end();
-
-$modulepart = 'mymodule';
-//$permissiontoadd = $user->rights->mymodule->myobject->write;
-$permissiontoadd = 1;
-//$permtoedit = $user->rights->mymodule->myobject->write;
-$permtoedit = 1;
-$param = '&id='.$object->id;
-
-//$relativepathwithnofile='myobject/' . dol_sanitizeFileName($object->id).'/';
-$relativepathwithnofile = 'myobject/'.dol_sanitizeFileName($object->ref).'/';
-
-include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php';
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php
deleted file mode 100644 (file)
index abef03f..0000000
+++ /dev/null
@@ -1,850 +0,0 @@
-<?php
-/* Copyright (C) 2007-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file       htdocs/modulebuilder/template/myobject_list.php
- *             \ingroup    mymodule
- *             \brief      List page for myobject
- */
-
-//if (! defined('NOREQUIREDB'))              define('NOREQUIREDB', '1');                               // Do not create database handler $db
-//if (! defined('NOREQUIREUSER'))            define('NOREQUIREUSER', '1');                             // Do not load object $user
-//if (! defined('NOREQUIRESOC'))             define('NOREQUIRESOC', '1');                              // Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN'))            define('NOREQUIRETRAN', '1');                             // Do not load object $langs
-//if (! defined('NOSCANGETFORINJECTION'))    define('NOSCANGETFORINJECTION', '1');             // Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION'))   define('NOSCANPOSTFORINJECTION', '1');            // Do not check injection attack on POST parameters
-//if (! defined('NOTOKENRENEWAL'))           define('NOTOKENRENEWAL', '1');                            // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-//if (! defined('NOSTYLECHECK'))             define('NOSTYLECHECK', '1');                              // Do not check style html tag into posted data
-//if (! defined('NOREQUIREMENU'))            define('NOREQUIREMENU', '1');                             // If there is no need to load and show top and left menu
-//if (! defined('NOREQUIREHTML'))            define('NOREQUIREHTML', '1');                             // If we don't need to load the html.form.class.php
-//if (! defined('NOREQUIREAJAX'))            define('NOREQUIREAJAX', '1');                     // Do not load ajax.lib.php library
-//if (! defined("NOLOGIN"))                  define("NOLOGIN", '1');                                   // If this page is public (can be called outside logged session). This include the NOIPCHECK too.
-//if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');                                 // Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');                                      // Force lang to a particular value
-//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');       // Force authentication handler
-//if (! defined("MAIN_SECURITY_FORCECSP"))   define('MAIN_SECURITY_FORCECSP', 'none'); // Disable all Content Security Policies
-//if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');              // Force use of CSRF protection with tokens even for GET
-//if (! defined('NOBROWSERNOTIF'))                      define('NOBROWSERNOTIF', '1');                         // Disable browser notification
-//if (! defined('NOSESSION'))                define('NOSESSION', '1');                                 // On CLI mode, no need to use web sessions
-
-// Load Dolibarr environment
-$res = 0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
-       $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-}
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--;
-       $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
-}
-if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
-       $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
-}
-// Try main.inc.php using relative path
-if (!$res && file_exists("../main.inc.php")) {
-       $res = @include "../main.inc.php";
-}
-if (!$res && file_exists("../../main.inc.php")) {
-       $res = @include "../../main.inc.php";
-}
-if (!$res && file_exists("../../../main.inc.php")) {
-       $res = @include "../../../main.inc.php";
-}
-if (!$res) {
-       die("Include of main fails");
-}
-
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
-
-// load mymodule libraries
-require_once __DIR__.'/class/myobject.class.php';
-
-// for other modules
-//dol_include_once('/othermodule/class/otherobject.class.php');
-
-// Load translation files required by the page
-$langs->loadLangs(array("mymodule@mymodule", "other"));
-
-$action     = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'create'/'add', 'edit'/'update', 'view', ...
-$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
-$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ?
-$confirm    = GETPOST('confirm', 'alpha'); // Result of a confirmation
-$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') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
-$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
-$optioncss  = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
-$mode       = GETPOST('mode', 'aZ'); // The output mode ('list', 'kanban', 'hierarchy', 'calendar', ...)
-
-$id = GETPOST('id', 'int');
-$ref = GETPOST('ref', 'alpha');
-
-// Load variable for pagination
-$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
-$sortfield = GETPOST('sortfield', 'aZ09comma');
-$sortorder = GETPOST('sortorder', 'aZ09comma');
-$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
-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;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-
-// Initialize technical objects
-$object = new MyObject($db);
-$extrafields = new ExtraFields($db);
-$diroutputmassaction = $conf->mymodule->dir_output.'/temp/massgeneration/'.$user->id;
-$hookmanager->initHooks(array('myobjectlist')); // Note that conf->hooks_modules contains array
-
-// Fetch optionals attributes and labels
-$extrafields->fetch_name_optionals_label($object->table_element);
-//$extrafields->fetch_name_optionals_label($object->table_element_line);
-
-$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
-
-// Default sort order (if not yet defined by previous GETPOST)
-if (!$sortfield) {
-       reset($object->fields);                                 // Reset is required to avoid key() to return null.
-       $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition.
-}
-if (!$sortorder) {
-       $sortorder = "ASC";
-}
-
-// Initialize array of search criterias
-$search_all = GETPOST('search_all', 'alphanohtml') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml');
-$search = array();
-foreach ($object->fields as $key => $val) {
-       if (GETPOST('search_'.$key, 'alpha') !== '') {
-               $search[$key] = GETPOST('search_'.$key, 'alpha');
-       }
-       if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
-               $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int'));
-               $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int'));
-       }
-}
-
-// List of fields to search into when doing a "search in all"
-$fieldstosearchall = array();
-foreach ($object->fields as $key => $val) {
-       if (!empty($val['searchall'])) {
-               $fieldstosearchall['t.'.$key] = $val['label'];
-       }
-}
-
-// Definition of array of fields for columns
-$arrayfields = array();
-foreach ($object->fields as $key => $val) {
-       // If $val['visible']==0, then we never show the field
-       if (!empty($val['visible'])) {
-               $visible = (int) dol_eval($val['visible'], 1);
-               $arrayfields['t.'.$key] = array(
-                       'label'=>$val['label'],
-                       'checked'=>(($visible < 0) ? 0 : 1),
-                       'enabled'=>(abs($visible) != 3 && dol_eval($val['enabled'], 1)),
-                       'position'=>$val['position'],
-                       'help'=> isset($val['help']) ? $val['help'] : ''
-               );
-       }
-}
-// Extra fields
-include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
-
-$object->fields = dol_sort_array($object->fields, 'position');
-//$arrayfields['anotherfield'] = array('type'=>'integer', 'label'=>'AnotherField', 'checked'=>1, 'enabled'=>1, 'position'=>90, 'csslist'=>'right');
-$arrayfields = dol_sort_array($arrayfields, 'position');
-
-// There is several ways to check permission.
-// Set $enablepermissioncheck to 1 to enable a minimum low level of checks
-$enablepermissioncheck = 0;
-if ($enablepermissioncheck) {
-       $permissiontoread = $user->hasRight('mymodule', 'myobject', 'read');
-       $permissiontoadd = $user->hasRight('mymodule', 'myobject', 'write');
-       $permissiontodelete = $user->hasRight('mymodule', 'myobject', 'delete');
-} else {
-       $permissiontoread = 1;
-       $permissiontoadd = 1;
-       $permissiontodelete = 1;
-}
-
-// Security check (enable the most restrictive one)
-if ($user->socid > 0) accessforbidden();
-//if ($user->socid > 0) accessforbidden();
-//$socid = 0; if ($user->socid > 0) $socid = $user->socid;
-//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
-//restrictedArea($user, $object->module, 0, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
-if (!isModEnabled("mymodule")) {
-       accessforbidden('Module mymodule not enabled');
-}
-if (!$permissiontoread) accessforbidden();
-
-
-/*
- * Actions
- */
-
-if (GETPOST('cancel', 'alpha')) {
-       $action = 'list';
-       $massaction = '';
-}
-if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
-       $massaction = '';
-}
-
-$parameters = array();
-$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');
-}
-
-if (empty($reshook)) {
-       // Selection of new fields
-       include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
-
-       // Purge search criteria
-       if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
-               foreach ($object->fields as $key => $val) {
-                       $search[$key] = '';
-                       if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
-                               $search[$key.'_dtstart'] = '';
-                               $search[$key.'_dtend'] = '';
-                       }
-               }
-               $toselect = array();
-               $search_array_options = array();
-       }
-       if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
-               || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
-               $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
-       }
-
-       // Mass actions
-       $objectclass = 'MyObject';
-       $objectlabel = 'MyObject';
-       $uploaddir = $conf->mymodule->dir_output;
-       include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
-
-       // You can add more action here
-       // if ($action == 'xxx' && $permissiontoxxx) ...
-}
-
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-$now = dol_now();
-
-//$help_url = "EN:Module_MyObject|FR:Module_MyObject_FR|ES:Módulo_MyObject";
-$help_url = '';
-$title = $langs->trans("MyObjects");
-$morejs = array();
-$morecss = array();
-
-
-// Build and execute select
-// --------------------------------------------------------------------
-$sql = 'SELECT ';
-$sql .= $object->getFieldList('t');
-// Add fields from extrafields
-if (!empty($extrafields->attributes[$object->table_element]['label'])) {
-       foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
-               $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
-       }
-}
-// Add fields from hooks
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
-$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
-$sql = preg_replace('/,\s*$/', '', $sql);
-//$sql .= ", COUNT(rc.rowid) as anotherfield";
-
-$sqlfields = $sql; // $sql fields to remove for count total
-
-$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
-//$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."anothertable as rc ON rc.parent = t.rowid";
-if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
-       $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
-}
-// Add table from hooks
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
-$sql .= $hookmanager->resPrint;
-if ($object->ismultientitymanaged == 1) {
-       $sql .= " WHERE t.entity IN (".getEntity($object->element).")";
-} else {
-       $sql .= " WHERE 1 = 1";
-}
-foreach ($search as $key => $val) {
-       if (array_key_exists($key, $object->fields)) {
-               if ($key == 'status' && $search[$key] == -1) {
-                       continue;
-               }
-               $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
-               if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
-                       if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
-                               $search[$key] = '';
-                       }
-                       $mode_search = 2;
-               }
-               if ($search[$key] != '') {
-                       $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
-               }
-       } else {
-               if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
-                       $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
-                       if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
-                               if (preg_match('/_dtstart$/', $key)) {
-                                       $sql .= " AND t.".$db->escape($columnName)." >= '".$db->idate($search[$key])."'";
-                               }
-                               if (preg_match('/_dtend$/', $key)) {
-                                       $sql .= " AND t.".$db->escape($columnName)." <= '".$db->idate($search[$key])."'";
-                               }
-                       }
-               }
-       }
-}
-if ($search_all) {
-       $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
-}
-//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear);
-// Add where from extra fields
-include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
-// Add where from hooks
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
-$sql .= $hookmanager->resPrint;
-
-/* If a group by is required
-$sql .= " GROUP BY ";
-foreach($object->fields as $key => $val) {
-       $sql .= "t.".$db->escape($key).", ";
-}
-// Add fields from extrafields
-if (!empty($extrafields->attributes[$object->table_element]['label'])) {
-       foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
-               $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
-       }
-}
-// Add where from hooks
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object);    // Note that $action and $object may have been modified by hook
-$sql .= $hookmanager->resPrint;
-$sql = preg_replace('/,\s*$/', '', $sql);
-*/
-
-// Add HAVING from hooks
-/*
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook
-$sql .= empty($hookmanager->resPrint) ? "" : " HAVING 1=1 ".$hookmanager->resPrint;
-*/
-
-// Count total nb of records
-$nbtotalofrecords = '';
-if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
-       /* The fast and low memory method to get and count full list converts the sql into a sql count */
-       $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
-       $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
-       $resql = $db->query($sqlforcount);
-       if ($resql) {
-               $objforcount = $db->fetch_object($resql);
-               $nbtotalofrecords = $objforcount->nbtotalofrecords;
-       } else {
-               dol_print_error($db);
-       }
-
-       if (($page * $limit) > $nbtotalofrecords) {     // if total resultset is smaller then paging size (filtering), goto and load page 0
-               $page = 0;
-               $offset = 0;
-       }
-       $db->free($resql);
-}
-
-// Complete request and execute it with limit
-$sql .= $db->order($sortfield, $sortorder);
-if ($limit) {
-       $sql .= $db->plimit($limit + 1, $offset);
-}
-
-$resql = $db->query($sql);
-if (!$resql) {
-       dol_print_error($db);
-       exit;
-}
-
-$num = $db->num_rows($resql);
-
-
-// Direct jump if only one record found
-if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) {
-       $obj = $db->fetch_object($resql);
-       $id = $obj->rowid;
-       header("Location: ".dol_buildpath('/mymodule/myobject_card.php', 1).'?id='.$id);
-       exit;
-}
-
-
-// Output page
-// --------------------------------------------------------------------
-
-llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'bodyforlist');      // Can use also classforhorizontalscrolloftabs instead of bodyforlist for no horizontal scroll
-
-// Example : Adding jquery code
-// print '<script type="text/javascript">
-// jQuery(document).ready(function() {
-//     function init_myfunc()
-//     {
-//             jQuery("#myid").removeAttr(\'disabled\');
-//             jQuery("#myid").attr(\'disabled\',\'disabled\');
-//     }
-//     init_myfunc();
-//     jQuery("#mybutton").click(function() {
-//             init_myfunc();
-//     });
-// });
-// </script>';
-
-$arrayofselected = is_array($toselect) ? $toselect : array();
-
-$param = '';
-if (!empty($mode)) {
-       $param .= '&mode='.urlencode($mode);
-}
-if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
-       $param .= '&contextpage='.urlencode($contextpage);
-}
-if ($limit > 0 && $limit != $conf->liste_limit) {
-       $param .= '&limit='.urlencode($limit);
-}
-foreach ($search as $key => $val) {
-       if (is_array($search[$key])) {
-               foreach ($search[$key] as $skey) {
-                       if ($skey != '') {
-                               $param .= '&search_'.$key.'[]='.urlencode($skey);
-                       }
-               }
-       } elseif (preg_match('/(_dtstart|_dtend)$/', $key) && !empty($val)) {
-               $param .= '&search_'.$key.'month='.((int) GETPOST('search_'.$key.'month', 'int'));
-               $param .= '&search_'.$key.'day='.((int) GETPOST('search_'.$key.'day', 'int'));
-               $param .= '&search_'.$key.'year='.((int) GETPOST('search_'.$key.'year', 'int'));
-       } elseif ($search[$key] != '') {
-               $param .= '&search_'.$key.'='.urlencode($search[$key]);
-       }
-}
-if ($optioncss != '') {
-       $param .= '&optioncss='.urlencode($optioncss);
-}
-// Add $param from extra fields
-include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
-// Add $param from hooks
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook
-$param .= $hookmanager->resPrint;
-
-// List of mass actions available
-$arrayofmassactions = array(
-       //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
-       //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
-       //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
-       //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
-);
-if (!empty($permissiontodelete)) {
-       $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
-}
-if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) {
-       $arrayofmassactions = array();
-}
-$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
-
-print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
-if ($optioncss != '') {
-       print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
-}
-print '<input type="hidden" name="token" value="'.newToken().'">';
-print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
-print '<input type="hidden" name="action" value="list">';
-print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
-print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
-print '<input type="hidden" name="page" value="'.$page.'">';
-print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
-print '<input type="hidden" name="page_y" value="">';
-print '<input type="hidden" name="mode" value="'.$mode.'">';
-
-
-$newcardbutton = '';
-$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition'));
-$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition'));
-$newcardbutton .= dolGetButtonTitleSeparator();
-$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/mymodule/myobject_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd);
-
-print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
-
-// Add code for pre mass action (confirmation or email presend form)
-$topicmail = "SendMyObjectRef";
-$modelmail = "myobject";
-$objecttmp = new MyObject($db);
-$trackid = 'xxxx'.$object->id;
-include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
-
-if ($search_all) {
-       $setupstring = '';
-       foreach ($fieldstosearchall as $key => $val) {
-               $fieldstosearchall[$key] = $langs->trans($val);
-               $setupstring .= $key."=".$val.";";
-       }
-       print '<!-- Search done like if PRODUCT_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
-       print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'</div>'."\n";
-}
-
-$moreforfilter = '';
-/*$moreforfilter.='<div class="divsearchfield">';
-$moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
-$moreforfilter.= '</div>';*/
-
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
-if (empty($reshook)) {
-       $moreforfilter .= $hookmanager->resPrint;
-} else {
-       $moreforfilter = $hookmanager->resPrint;
-}
-
-if (!empty($moreforfilter)) {
-       print '<div class="liste_titre liste_titre_bydiv centpercent">';
-       print $moreforfilter;
-       print '</div>';
-}
-
-$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
-$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields
-$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
-
-print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
-print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
-
-// Fields title search
-// --------------------------------------------------------------------
-print '<tr class="liste_titre">';
-// Action column
-if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
-       print '<td class="liste_titre maxwidthsearch">';
-       $searchpicto = $form->showFilterButtons('left');
-       print $searchpicto;
-       print '</td>';
-}
-foreach ($object->fields as $key => $val) {
-       $searchkey = empty($search[$key]) ? '' : $search[$key];
-       $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
-       if ($key == 'status') {
-               $cssforfield .= ($cssforfield ? ' ' : '').'center';
-       } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
-               $cssforfield .= ($cssforfield ? ' ' : '').'center';
-       } elseif (in_array($val['type'], array('timestamp'))) {
-               $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
-       } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'rowid' && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
-               $cssforfield .= ($cssforfield ? ' ' : '').'right';
-       }
-       if (!empty($arrayfields['t.'.$key]['checked'])) {
-               print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').'">';
-               if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
-                       print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100'.($key == 'status' ? ' search_status onrightofpage' : ''), 1);
-               } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
-                       print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth250', 1);
-               } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
-                       print '<div class="nowrap">';
-                       print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
-                       print '</div>';
-                       print '<div class="nowrap">';
-                       print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
-                       print '</div>';
-               } elseif ($key == 'lang') {
-                       require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
-                       $formadmin = new FormAdmin($db);
-                       print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2);
-               } else {
-                       print '<input type="text" class="flat maxwidth75" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
-               }
-               print '</td>';
-       }
-}
-// 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); // Note that $action and $object may have been modified by hook
-print $hookmanager->resPrint;
-/*if (!empty($arrayfields['anotherfield']['checked'])) {
-       print '<td class="liste_titre"></td>';
-}*/
-// Action column
-if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
-       print '<td class="liste_titre maxwidthsearch">';
-       $searchpicto = $form->showFilterButtons();
-       print $searchpicto;
-       print '</td>';
-}
-print '</tr>'."\n";
-
-$totalarray = array();
-$totalarray['nbfield'] = 0;
-
-// Fields title label
-// --------------------------------------------------------------------
-print '<tr class="liste_titre">';
-if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
-       print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
-       $totalarray['nbfield']++;
-}
-foreach ($object->fields as $key => $val) {
-       $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
-       if ($key == 'status') {
-               $cssforfield .= ($cssforfield ? ' ' : '').'center';
-       } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
-               $cssforfield .= ($cssforfield ? ' ' : '').'center';
-       } elseif (in_array($val['type'], array('timestamp'))) {
-               $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
-       } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'rowid' && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) {
-               $cssforfield .= ($cssforfield ? ' ' : '').'right';
-       }
-       $cssforfield = preg_replace('/small\s*/', '', $cssforfield);    // the 'small' css must not be used for the title label
-       if (!empty($arrayfields['t.'.$key]['checked'])) {
-               print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n";
-               $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); // Note that $action and $object may have been modified by hook
-print $hookmanager->resPrint;
-/*if (!empty($arrayfields['anotherfield']['checked'])) {
-       print '<th class="liste_titre right">'.$langs->trans("AnotherField").'</th>';
-       $totalarray['nbfield']++;
-}*/
-// Action column
-if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
-       print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
-       $totalarray['nbfield']++;
-}
-print '</tr>'."\n";
-
-$totalarray = array();
-$totalarray['nbfield'] = 0;
-
-// Detect if we need a fetch on each output line
-$needToFetchEachLine = 0;
-if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) {
-       foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) {
-               if (preg_match('/\$object/', $val)) {
-                       $needToFetchEachLine++; // There is at least one compute field that use $object
-               }
-       }
-}
-
-
-// Loop on record
-// --------------------------------------------------------------------
-$i = 0;
-$savnbfield = $totalarray['nbfield'];
-$totalarray = array();
-$totalarray['nbfield'] = 0;
-$imaxinloop = ($limit ? min($num, $limit) : $num);
-while ($i < $imaxinloop) {
-       $obj = $db->fetch_object($resql);
-       if (empty($obj)) {
-               break; // Should not happen
-       }
-
-       // Store properties in $object
-       $object->setVarsFromFetchObj($obj);
-
-       if ($mode == 'kanban') {
-               if ($i == 0) {
-                       print '<tr><td colspan="'.$savnbfield.'">';
-                       print '<div class="box-flex-container">';
-               }
-               // Output Kanban
-               print $object->getKanbanView('');
-               if ($i == ($imaxinloop - 1)) {
-                       print '</div>';
-                       print '</td></tr>';
-               }
-       } else {
-               // Show here line of result
-               $j = 0;
-               print '<tr data-rowid="'.$object->id.'" class="oddeven">';
-               // Action column
-               if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
-                       print '<td class="nowrap center">';
-                       if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
-                               $selected = 0;
-                               if (in_array($object->id, $arrayofselected)) {
-                                       $selected = 1;
-                               }
-                               print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
-                       }
-                       print '</td>';
-                       if (!$i) {
-                               $totalarray['nbfield']++;
-                       }
-               }
-               foreach ($object->fields as $key => $val) {
-                       $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
-                       if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
-                               $cssforfield .= ($cssforfield ? ' ' : '').'center';
-                       } elseif ($key == 'status') {
-                               $cssforfield .= ($cssforfield ? ' ' : '').'center';
-                       }
-
-                       if (in_array($val['type'], array('timestamp'))) {
-                               $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
-                       } elseif ($key == 'ref') {
-                               $cssforfield .= ($cssforfield ? ' ' : '').'nowrap';
-                       }
-
-                       if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) {
-                               $cssforfield .= ($cssforfield ? ' ' : '').'right';
-                       }
-                       //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100';
-
-                       if (!empty($arrayfields['t.'.$key]['checked'])) {
-                               print '<td'.($cssforfield ? ' class="'.$cssforfield.(preg_match('/tdoverflow/', $cssforfield) ? ' classfortooltip' : '').'"' : '');
-                               if (preg_match('/tdoverflow/', $cssforfield)) {
-                                       print ' title="'.dol_escape_htmltag($object->$key).'"';
-                               }
-                               print '>';
-                               if ($key == 'status') {
-                                       print $object->getLibStatut(5);
-                               } elseif ($key == 'rowid') {
-                                       print $object->showOutputField($val, $key, $object->id, '');
-                               } else {
-                                       print $object->showOutputField($val, $key, $object->$key, '');
-                               }
-                               print '</td>';
-                               if (!$i) {
-                                       $totalarray['nbfield']++;
-                               }
-                               if (!empty($val['isameasure']) && $val['isameasure'] == 1) {
-                                       if (!$i) {
-                                               $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key;
-                                       }
-                                       if (!isset($totalarray['val'])) {
-                                               $totalarray['val'] = array();
-                                       }
-                                       if (!isset($totalarray['val']['t.'.$key])) {
-                                               $totalarray['val']['t.'.$key] = 0;
-                                       }
-                                       $totalarray['val']['t.'.$key] += $object->$key;
-                               }
-                       }
-               }
-               // Extra fields
-               include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
-               // Fields from hook
-               $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
-               $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook
-               print $hookmanager->resPrint;
-               /*if (!empty($arrayfields['anotherfield']['checked'])) {
-                       print '<td class="right">'.$obj->anotherfield.'</td>';
-               }*/
-               // Action column
-               if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
-                       print '<td class="nowrap center">';
-                       if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
-                               $selected = 0;
-                               if (in_array($object->id, $arrayofselected)) {
-                                       $selected = 1;
-                               }
-                               print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
-                       }
-                       print '</td>';
-                       if (!$i) {
-                               $totalarray['nbfield']++;
-                       }
-               }
-
-               print '</tr>'."\n";
-       }
-
-       $i++;
-}
-
-// Show total line
-include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
-
-// If no record found
-if ($num == 0) {
-       $colspan = 1;
-       foreach ($arrayfields as $key => $val) {
-               if (!empty($val['checked'])) {
-                       $colspan++;
-               }
-       }
-       print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
-}
-
-
-$db->free($resql);
-
-$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
-$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
-print $hookmanager->resPrint;
-
-print '</table>'."\n";
-print '</div>'."\n";
-
-print '</form>'."\n";
-
-if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
-       $hidegeneratedfilelistifempty = 1;
-       if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
-               $hidegeneratedfilelistifempty = 0;
-       }
-
-       require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
-       $formfile = new FormFile($db);
-
-       // Show list of available documents
-       $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
-       $urlsource .= str_replace('&amp;', '&', $param);
-
-       $filedir = $diroutputmassaction;
-       $genallowed = $permissiontoread;
-       $delallowed = $permissiontoadd;
-
-       print $formfile->showdocuments('massfilesarea_mymodule', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/modulebuilder/template/myobject_note.php b/htdocs/modulebuilder/template/myobject_note.php
deleted file mode 100644 (file)
index 1f3bf7c..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-<?php
-/* Copyright (C) 2007-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *  \file       htdocs/modulebuilder/template/myobject_note.php
- *  \ingroup    mymodule
- *  \brief      Tab for notes on MyObject
- */
-
-//if (! defined('NOREQUIREDB'))              define('NOREQUIREDB', '1');                               // Do not create database handler $db
-//if (! defined('NOREQUIREUSER'))            define('NOREQUIREUSER', '1');                             // Do not load object $user
-//if (! defined('NOREQUIRESOC'))             define('NOREQUIRESOC', '1');                              // Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN'))            define('NOREQUIRETRAN', '1');                             // Do not load object $langs
-//if (! defined('NOSCANGETFORINJECTION'))    define('NOSCANGETFORINJECTION', '1');             // Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION'))   define('NOSCANPOSTFORINJECTION', '1');            // Do not check injection attack on POST parameters
-//if (! defined('NOTOKENRENEWAL'))           define('NOTOKENRENEWAL', '1');                            // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-//if (! defined('NOSTYLECHECK'))             define('NOSTYLECHECK', '1');                              // Do not check style html tag into posted data
-//if (! defined('NOREQUIREMENU'))            define('NOREQUIREMENU', '1');                             // If there is no need to load and show top and left menu
-//if (! defined('NOREQUIREHTML'))            define('NOREQUIREHTML', '1');                             // If we don't need to load the html.form.class.php
-//if (! defined('NOREQUIREAJAX'))            define('NOREQUIREAJAX', '1');                     // Do not load ajax.lib.php library
-//if (! defined("NOLOGIN"))                  define("NOLOGIN", '1');                                   // If this page is public (can be called outside logged session). This include the NOIPCHECK too.
-//if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');                                 // Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');                                      // Force lang to a particular value
-//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');       // Force authentication handler
-//if (! defined("MAIN_SECURITY_FORCECSP"))   define('MAIN_SECURITY_FORCECSP', 'none');                         // Disable all Content Security Policies
-//if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');              // Force use of CSRF protection with tokens even for GET
-//if (! defined('NOBROWSERNOTIF'))                      define('NOBROWSERNOTIF', '1');                         // Disable browser notification
-
-// Load Dolibarr environment
-$res = 0;
-// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
-if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
-       $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
-}
-// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--; $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
-}
-if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
-       $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
-}
-// Try main.inc.php using relative path
-if (!$res && file_exists("../main.inc.php")) {
-       $res = @include "../main.inc.php";
-}
-if (!$res && file_exists("../../main.inc.php")) {
-       $res = @include "../../main.inc.php";
-}
-if (!$res && file_exists("../../../main.inc.php")) {
-       $res = @include "../../../main.inc.php";
-}
-if (!$res) {
-       die("Include of main fails");
-}
-
-dol_include_once('/mymodule/class/myobject.class.php');
-dol_include_once('/mymodule/lib/mymodule_myobject.lib.php');
-
-// Load translation files required by the page
-$langs->loadLangs(array("mymodule@mymodule", "companies"));
-
-// Get parameters
-$id = GETPOST('id', 'int');
-$ref        = GETPOST('ref', 'alpha');
-$action = GETPOST('action', 'aZ09');
-$cancel     = GETPOST('cancel', 'aZ09');
-$backtopage = GETPOST('backtopage', 'alpha');
-
-// Initialize technical objects
-$object = new MyObject($db);
-$extrafields = new ExtraFields($db);
-$diroutputmassaction = $conf->mymodule->dir_output.'/temp/massgeneration/'.$user->id;
-$hookmanager->initHooks(array('myobjectnote', 'globalcard')); // Note that conf->hooks_modules contains array
-// Fetch optionals attributes and labels
-$extrafields->fetch_name_optionals_label($object->table_element);
-
-// Load object
-include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once  // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
-if ($id > 0 || !empty($ref)) {
-       $upload_dir = $conf->mymodule->multidir_output[empty($object->entity) ? $conf->entity : $object->entity]."/".$object->id;
-}
-
-
-// There is several ways to check permission.
-// Set $enablepermissioncheck to 1 to enable a minimum low level of checks
-$enablepermissioncheck = 0;
-if ($enablepermissioncheck) {
-       $permissiontoread = $user->rights->mymodule->myobject->read;
-       $permissiontoadd = $user->rights->mymodule->myobject->write;
-       $permissionnote = $user->rights->mymodule->myobject->write; // Used by the include of actions_setnotes.inc.php
-} else {
-       $permissiontoread = 1;
-       $permissiontoadd = 1;
-       $permissionnote = 1;
-}
-
-// Security check (enable the most restrictive one)
-//if ($user->socid > 0) accessforbidden();
-//if ($user->socid > 0) $socid = $user->socid;
-//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
-//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
-if (!isModEnabled("mymodule")) {
-       accessforbidden();
-}
-if (!$permissiontoread) accessforbidden();
-
-
-/*
- * Actions
- */
-
-$parameters = array();
-$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');
-}
-if (empty($reshook)) {
-       include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once
-}
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-//$help_url='EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes';
-$help_url = '';
-$title = $langs->trans('MyObject').' - '.$langs->trans("Notes");
-llxHeader('', $title, $help_url);
-
-if ($id > 0 || !empty($ref)) {
-       $object->fetch_thirdparty();
-
-       $head = myobjectPrepareHead($object);
-
-       print dol_get_fiche_head($head, 'note', $langs->trans("MyObject"), -1, $object->picto);
-
-       // Object card
-       // ------------------------------------------------------------
-       $linkback = '<a href="'.dol_buildpath('/mymodule/myobject_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
-
-       $morehtmlref = '<div class="refidno">';
-       /*
-        // Ref customer
-        $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
-        $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
-        // Thirdparty
-        $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : '');
-        // Project
-        if (!empty($conf->project->enabled))
-        {
-        $langs->load("projects");
-        $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
-        if ($permissiontoadd)
-        {
-        if ($action != 'classify')
-        //$morehtmlref.='<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token='.newToken().'&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
-        $morehtmlref.=' : ';
-        if ($action == 'classify') {
-        //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
-        $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
-        $morehtmlref.='<input type="hidden" name="action" value="classin">';
-        $morehtmlref.='<input type="hidden" name="token" value="'.newToken().'">';
-        $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
-        $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
-        $morehtmlref.='</form>';
-        } else {
-        $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
-        }
-        } else {
-        if (!empty($object->fk_project)) {
-        $proj = new Project($db);
-        $proj->fetch($object->fk_project);
-        $morehtmlref .= ': '.$proj->getNomUrl();
-        } else {
-        $morehtmlref .= '';
-        }
-        }
-        }*/
-        $morehtmlref .= '</div>';
-
-
-       dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
-
-
-       print '<div class="fichecenter">';
-       print '<div class="underbanner clearboth"></div>';
-
-
-       $cssclass = "titlefield";
-       include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php';
-
-       print '</div>';
-
-       print dol_get_fiche_end();
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/modulebuilder/template/scripts/mymodule.php b/htdocs/modulebuilder/template/scripts/mymodule.php
deleted file mode 100644 (file)
index e335eb0..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-#!/usr/bin/env php
-<?php
-/* Copyright (C) 2007-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *      \file       htdocs/modulebuilder/template/scripts/mymodule.php
- *             \ingroup    mymodule
- *      \brief      This file is an example for a command line script for module MyModule
- */
-
-//if (! defined('NOREQUIREDB'))              define('NOREQUIREDB', '1');                               // Do not create database handler $db
-//if (! defined('NOREQUIREUSER'))            define('NOREQUIREUSER', '1');                             // Do not load object $user
-//if (! defined('NOREQUIRESOC'))             define('NOREQUIRESOC', '1');                              // Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN'))            define('NOREQUIRETRAN', '1');                             // Do not load object $langs
-//if (! defined('NOSCANGETFORINJECTION'))    define('NOSCANGETFORINJECTION', '1');             // Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION'))   define('NOSCANPOSTFORINJECTION', '1');            // Do not check injection attack on POST parameters
-//if (! defined('NOTOKENRENEWAL'))           define('NOTOKENRENEWAL', '1');                            // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-//if (! defined('NOSTYLECHECK'))             define('NOSTYLECHECK', '1');                              // Do not check style html tag into posted data
-//if (! defined('NOREQUIREMENU'))            define('NOREQUIREMENU', '1');                             // If there is no need to load and show top and left menu
-//if (! defined('NOREQUIREHTML'))            define('NOREQUIREHTML', '1');                             // If we don't need to load the html.form.class.php
-//if (! defined('NOREQUIREAJAX'))            define('NOREQUIREAJAX', '1');                     // Do not load ajax.lib.php library
-//if (! defined("NOLOGIN"))                  define("NOLOGIN", '1');                                   // If this page is public (can be called outside logged session). This include the NOIPCHECK too.
-//if (! defined('NOIPCHECK'))                define('NOIPCHECK', '1');                                 // Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined("MAIN_LANG_DEFAULT"))        define('MAIN_LANG_DEFAULT', 'auto');                                      // Force lang to a particular value
-//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule');       // Force authentication handler
-//if (! defined('CSRFCHECK_WITH_TOKEN'))     define('CSRFCHECK_WITH_TOKEN', '1');              // Force use of CSRF protection with tokens even for GET
-//if (! defined('NOBROWSERNOTIF'))                      define('NOBROWSERNOTIF', '1');                         // Disable browser notification
-if (!defined('NOSESSION')) define('NOSESSION', '1');   // On CLI mode, no need to use web sessions
-
-
-$sapi_type = php_sapi_name();
-$script_file = basename(__FILE__);
-$path = __DIR__.'/';
-
-// Test if batch mode
-if (substr($sapi_type, 0, 3) == 'cgi') {
-       echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n";
-       exit(-1);
-}
-
-// Global variables
-$version = '1.0';
-$error = 0;
-
-
-// -------------------- START OF YOUR CODE HERE --------------------
-@set_time_limit(0); // No timeout for this script
-define('EVEN_IF_ONLY_LOGIN_ALLOWED', 1); // Set this define to 0 if you want to lock your script when dolibarr setup is "locked to admin user only".
-
-// Load Dolibarr environment
-$res = 0;
-// Try master.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
-$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
-while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
-       $i--; $j--;
-}
-if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/master.inc.php")) {
-       $res = @include substr($tmp, 0, ($i + 1))."/master.inc.php";
-}
-if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/master.inc.php")) {
-       $res = @include dirname(substr($tmp, 0, ($i + 1)))."/master.inc.php";
-}
-// Try master.inc.php using relative path
-if (!$res && file_exists("../master.inc.php")) {
-       $res = @include "../master.inc.php";
-}
-if (!$res && file_exists("../../master.inc.php")) {
-       $res = @include "../../master.inc.php";
-}
-if (!$res && file_exists("../../../master.inc.php")) {
-       $res = @include "../../../master.inc.php";
-}
-if (!$res) {
-       print "Include of master fails";
-       exit(-1);
-}
-// After this $db, $mysoc, $langs, $conf and $hookmanager are defined (Opened $db handler to database will be closed at end of file).
-// $user is created but empty.
-
-//$langs->setDefaultLang('en_US');     // To change default language of $langs
-$langs->load("main"); // To load language file for default language
-
-// Load user and its permissions
-$result = $user->fetch('', 'admin'); // Load user for login 'admin'. Comment line to run as anonymous user.
-if (!($result > 0)) {
-       dol_print_error('', $user->error); exit;
-}
-$user->getrights();
-
-
-print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n";
-if (!isset($argv[1])) {        // Check parameters
-       print "Usage: ".$script_file." param1 param2 ...\n";
-       exit(-1);
-}
-print '--- start'."\n";
-print 'Argument 1='.$argv[1]."\n";
-print 'Argument 2='.$argv[2]."\n";
-
-
-// Start of transaction
-$db->begin();
-
-
-// Examples for manipulating class MyObject
-//dol_include_once("/mymodule/class/myobject.class.php");
-//$myobject=new MyObject($db);
-
-// Example for inserting creating object in database
-/*
-dol_syslog($script_file." CREATE", LOG_DEBUG);
-$myobject->prop1='value_prop1';
-$myobject->prop2='value_prop2';
-$id=$myobject->create($user);
-if ($id < 0) { $error++; dol_print_error($db,$myobject->error); }
-else print "Object created with id=".$id."\n";
-*/
-
-// Example for reading object from database
-/*
-dol_syslog($script_file." FETCH", LOG_DEBUG);
-$result=$myobject->fetch($id);
-if ($result < 0) { $error; dol_print_error($db,$myobject->error); }
-else print "Object with id=".$id." loaded\n";
-*/
-
-// Example for updating object in database ($myobject must have been loaded by a fetch before)
-/*
-dol_syslog($script_file." UPDATE", LOG_DEBUG);
-$myobject->prop1='newvalue_prop1';
-$myobject->prop2='newvalue_prop2';
-$result=$myobject->update($user);
-if ($result < 0) { $error++; dol_print_error($db,$myobject->error); }
-else print "Object with id ".$myobject->id." updated\n";
-*/
-
-// Example for deleting object in database ($myobject must have been loaded by a fetch before)
-/*
-dol_syslog($script_file." DELETE", LOG_DEBUG);
-$result=$myobject->delete($user);
-if ($result < 0) { $error++; dol_print_error($db,$myobject->error); }
-else print "Object with id ".$myobject->id." deleted\n";
-*/
-
-
-// An example of a direct SQL read without using the fetch method
-/*
-$sql = "SELECT field1, field2";
-$sql.= " FROM ".MAIN_DB_PREFIX."myobject";
-$sql.= " WHERE field3 = 'xxx'";
-$sql.= " ORDER BY field1 ASC";
-
-dol_syslog($script_file, LOG_DEBUG);
-$resql=$db->query($sql);
-if ($resql)
-{
-       $num = $db->num_rows($resql);
-       $i = 0;
-       if ($num)
-       {
-               while ($i < $num)
-               {
-                       $obj = $db->fetch_object($resql);
-                       if ($obj)
-                       {
-                               // You can use here results
-                               print $obj->field1;
-                               print $obj->field2;
-                       }
-                       $i++;
-               }
-       }
-}
-else
-{
-       $error++;
-       dol_print_error($db);
-}
-*/
-
-
-// -------------------- END OF YOUR CODE --------------------
-
-if (!$error) {
-       $db->commit();
-       print '--- end ok'."\n";
-} else {
-       print '--- end error code='.$error."\n";
-       $db->rollback();
-}
-
-$db->close(); // Close $db database opened handler
-
-exit($error);
diff --git a/htdocs/modulebuilder/template/sql/data.sql b/htdocs/modulebuilder/template/sql/data.sql
deleted file mode 100644 (file)
index 37860e8..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
--- Copyright (C) ---Put here your own copyright and developer email---
---
--- 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 <https://www.gnu.org/licenses/>.
-
-
--- delete from llx_mymodule_myobject;
---INSERT INTO llx_mymodule_myobject VALUES (1, 1, 'mydata');
-
-
--- delete from llx_c_mydictionarytabme;
---INSERT INTO llx_c_mydictionarytabme (code,label,active) VALUES ('ABC', 'Label ABC',   1);
---INSERT INTO llx_c_mydictionarytabme (code,label,active) VALUES ('DEF', 'Label DEF', 1);
-
-
--- new types of automatic events to record in agenda
--- 'code' must be a value matching 'MYOBJECT_ACTION'
--- 'elementtype' must be value 'mymodule' ('myobject@mymodule' may be possible but should not be required)
---insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MYOBJECT_VALIDATE','MyObject validated','Executed when myobject is validated', 'mymodule', 1000);
---insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MYOBJECT_UNVALIDATE','MyObject unvalidated','Executed when myobject is unvalidated', 'mymodule', 1001);
---insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MYOBJECT_DELETE','MyObject deleted','Executed when myobject deleted', 'mymodule', 1004);
-
diff --git a/htdocs/modulebuilder/template/sql/dolibarr_allversions.sql b/htdocs/modulebuilder/template/sql/dolibarr_allversions.sql
deleted file mode 100644 (file)
index 5026bb4..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
---
--- Script run when an upgrade of Dolibarr is done. Whatever is the Dolibarr version.
---
diff --git a/htdocs/modulebuilder/template/sql/llx_mymodule_myobject.key.sql b/htdocs/modulebuilder/template/sql/llx_mymodule_myobject.key.sql
deleted file mode 100644 (file)
index fc6b7b0..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
--- Copyright (C) ---Put here your own copyright and developer email---
---
--- 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 https://www.gnu.org/licenses/.
-
-
--- BEGIN MODULEBUILDER INDEXES
-ALTER TABLE llx_mymodule_myobject ADD INDEX idx_mymodule_myobject_fieldobject (fieldobject);
--- END MODULEBUILDER INDEXES
-
---ALTER TABLE llx_mymodule_myobject ADD UNIQUE INDEX uk_mymodule_myobject_fieldxy(fieldx, fieldy);
-
---ALTER TABLE llx_mymodule_myobject ADD CONSTRAINT llx_mymodule_myobject_fk_field FOREIGN KEY (fk_field) REFERENCES llx_mymodule_myotherobject(rowid);
-
diff --git a/htdocs/modulebuilder/template/sql/llx_mymodule_myobject.sql b/htdocs/modulebuilder/template/sql/llx_mymodule_myobject.sql
deleted file mode 100644 (file)
index cc9cca0..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
--- Copyright (C) ---Put here your own copyright and developer email---
---
--- 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 https://www.gnu.org/licenses/.
-
-
-CREATE TABLE llx_mymodule_myobject(
-       -- BEGIN MODULEBUILDER FIELDS
-       rowid INTEGER AUTO_INCREMENT PRIMARY KEY,
-       entity INTEGER DEFAULT 1 NOT NULL,
-       label VARCHAR(255),
-       qty INTEGER,
-       date_creation DATETIME NOT NULL,
-       tms TIMESTAMP,
-       fk_user_create INTEGER,
-       fk_user_modif INTEGER,
-       status INTEGER,
-       import_key VARCHAR(14)
-       -- END MODULEBUILDER FIELDS
-) ENGINE=innodb;
diff --git a/htdocs/modulebuilder/template/sql/llx_mymodule_myobject_extrafields.key.sql b/htdocs/modulebuilder/template/sql/llx_mymodule_myobject_extrafields.key.sql
deleted file mode 100644 (file)
index 4c005e9..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
--- Copyright (C) ---Put here your own copyright and developer email---
---
--- 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 https://www.gnu.org/licenses/.
-
-
--- BEGIN MODULEBUILDER INDEXES
-ALTER TABLE llx_mymodule_myobject_extrafields ADD INDEX idx_myobject_fk_object(fk_object);
--- END MODULEBUILDER INDEXES
diff --git a/htdocs/modulebuilder/template/sql/llx_mymodule_myobject_extrafields.sql b/htdocs/modulebuilder/template/sql/llx_mymodule_myobject_extrafields.sql
deleted file mode 100644 (file)
index e0fc9ff..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
--- Copyright (C) ---Put here your own copyright and developer email---
---
--- 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 https://www.gnu.org/licenses/.
-
-create table llx_mymodule_myobject_extrafields
-(
-  rowid                     integer AUTO_INCREMENT PRIMARY KEY,
-  tms                       timestamp,
-  fk_object                 integer NOT NULL,
-  import_key                varchar(14)                                        -- import key
-) ENGINE=innodb;
-
diff --git a/htdocs/modulebuilder/template/sql/update_x.x.x-y.y.y.sql b/htdocs/modulebuilder/template/sql/update_x.x.x-y.y.y.sql
deleted file mode 100644 (file)
index 2988bd7..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
---
--- Script run to make a migration of module version x.x.x to module version y.y.y
---
\ No newline at end of file
diff --git a/htdocs/modulebuilder/template/test/phpunit/MyModuleFunctionalTest.php b/htdocs/modulebuilder/template/test/phpunit/MyModuleFunctionalTest.php
deleted file mode 100644 (file)
index 9701e27..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-<?php
-/* Copyright (C) 2007-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    test/phpunit/MyModuleFunctionalTest.php
- * \ingroup mymodule
- * \brief   Example Selenium test.
- *
- * Put detailed description here.
- */
-
-namespace test\functional;
-
-use PHPUnit_Extensions_Selenium2TestCase_WebDriverException;
-
-/**
- * Class MyModuleFunctionalTest
- *
- * Requires chromedriver for Google Chrome
- * Requires geckodriver for Mozilla Firefox
- *
- * @fixme Firefox (Geckodriver/Marionette) support
- * @todo Opera linux support
- * @todo Windows support (IE, Google Chrome, Mozilla Firefox, Safari)
- * @todo OSX support (Safari, Google Chrome, Mozilla Firefox)
- *
- * @package Testmymodule
- */
-class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
-{
-       // TODO: move to a global configuration file?
-       /** @var string Base URL of the webserver under test */
-       protected static $base_url = 'http://dev.zenfusion.fr';
-       /**
-        * @var string Dolibarr admin username
-        * @see authenticate
-        */
-       protected static $dol_admin_user = 'admin';
-       /**
-        * @var string Dolibarr admin password
-        * @see authenticate
-        */
-       protected static $dol_admin_pass = 'admin';
-       /** @var int Dolibarr module ID */
-       private static $module_id = 500000; // TODO: autodetect?
-
-       /** @var array Browsers to test with */
-       public static $browsers = array(
-               array(
-                       'browser' => 'Google Chrome on Linux',
-                       'browserName' => 'chrome',
-                       'sessionStrategy' => 'shared',
-                       'desiredCapabilities' => array()
-               ),
-               // Geckodriver does not keep the session at the moment?!
-               // XPath selectors also don't seem to work
-               //array(
-               //    'browser' => 'Mozilla Firefox on Linux',
-               //    'browserName' => 'firefox',
-               //    'sessionStrategy' => 'shared',
-               //    'desiredCapabilities' => array(
-               //        'marionette' => true,
-               //    ),
-               //)
-       );
-
-       /**
-        * Helper function to select links by href
-        *
-        * @param  string  $value      Href
-        * @return mixed               Helper string
-        */
-       protected function byHref($value)
-       {
-               $anchor = null;
-               $anchors = $this->elements($this->using('tag name')->value('a'));
-               foreach ($anchors as $anchor) {
-                       if (strstr($anchor->attribute('href'), $value)) {
-                               break;
-                       }
-               }
-               return $anchor;
-       }
-
-       /**
-        * Global test setup
-        * @return void
-        */
-       public static function setUpBeforeClass()
-       {
-       }
-
-       /**
-        * Unit test setup
-        * @return void
-        */
-       public function setUp()
-       {
-               $this->setSeleniumServerRequestsTimeout(3600);
-               $this->setBrowserUrl(self::$base_url);
-       }
-
-       /**
-        * Verify pre conditions
-        * @return void
-        */
-       protected function assertPreConditions()
-       {
-       }
-
-       /**
-        * Handle Dolibarr authentication
-        * @return void
-        */
-       private function authenticate()
-       {
-               try {
-                       if ($this->byId('login')) {
-                               $login = $this->byId('username');
-                               $login->clear();
-                               $login->value('admin');
-                               $password = $this->byId('password');
-                               $password->clear();
-                               $password->value('admin');
-                               $this->byId('login')->submit();
-                       }
-               } catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
-                       // Login does not exist. Assume we are already authenticated
-               }
-       }
-
-       /**
-        * Test enabling developer mode
-        * @return bool
-        */
-       public function testEnableDeveloperMode()
-       {
-               $this->url('/admin/const.php');
-               $this->authenticate();
-               $main_features_level_path = '//input[@value="MAIN_FEATURES_LEVEL"]/following::input[@type="text"]';
-               $main_features_level = $this->byXPath($main_features_level_path);
-               $main_features_level->clear();
-               $main_features_level->value('2');
-               $this->byName('update')->click();
-               // Page reloaded, we need a new XPath
-               $main_features_level = $this->byXPath($main_features_level_path);
-               return $this->assertEquals('2', $main_features_level->value(), "MAIN_FEATURES_LEVEL value is 2");
-       }
-
-       /**
-        * Test enabling the module
-        *
-        * @depends testEnableDeveloperMode
-        * @return bool
-        */
-       public function testModuleEnabled()
-       {
-               $this->url('/admin/modules.php');
-               $this->authenticate();
-               $module_status_image_path = '//a[contains(@href, "'.self::$module_id.'")]/img';
-               $module_status_image = $this->byXPath($module_status_image_path);
-               if (strstr($module_status_image->attribute('src'), 'switch_off.png')) {
-                       // Enable the module
-                       $this->byHref('modMyModule')->click();
-               } else {
-                       // Disable the module
-                       $this->byHref('modMyModule')->click();
-                       // Reenable the module
-                       $this->byHref('modMyModule')->click();
-               }
-               // Page reloaded, we need a new Xpath
-               $module_status_image = $this->byXPath($module_status_image_path);
-               return $this->assertContains('switch_on.png', $module_status_image->attribute('src'), "Module enabled");
-       }
-
-       /**
-        * Test access to the configuration page
-        *
-        * @depends testModuleEnabled
-        * @return bool
-        */
-       public function testConfigurationPage()
-       {
-               $this->url('/custom/mymodule/admin/setup.php');
-               $this->authenticate();
-               return $this->assertContains('mymodule/admin/setup.php', $this->url(), 'Configuration page');
-       }
-
-       /**
-        * Test access to the about page
-        *
-        * @depends testConfigurationPage
-        * @return bool
-        */
-       public function testAboutPage()
-       {
-               $this->url('/custom/mymodule/admin/about.php');
-               $this->authenticate();
-               return $this->assertContains('mymodule/admin/about.php', $this->url(), 'About page');
-       }
-
-       /**
-        * Test about page is rendering Markdown
-        *
-        * @depends testAboutPage
-        * @return bool
-        */
-       public function testAboutPageRendersMarkdownReadme()
-       {
-               $this->url('/custom/mymodule/admin/about.php');
-               $this->authenticate();
-               return $this->assertEquals(
-                       'Dolibarr Module Template (aka My Module)',
-                       $this->byTag('h1')->text(),
-                       "Readme title"
-               );
-       }
-
-       /**
-        * Test box is properly declared
-        *
-        * @depends testModuleEnabled
-        * @return bool
-        */
-       public function testBoxDeclared()
-       {
-               $this->url('/admin/boxes.php');
-               $this->authenticate();
-               return $this->assertContains('mymodulewidget1', $this->source(), "Box enabled");
-       }
-
-       /**
-        * Test trigger is properly enabled
-        *
-        * @depends testModuleEnabled
-        * @return bool
-        */
-       public function testTriggerDeclared()
-       {
-               $this->url('/admin/triggers.php');
-               $this->authenticate();
-               return $this->assertContains(
-                       'interface_99_modMyModule_MyModuleTriggers.class.php',
-                       $this->byTag('body')->text(),
-                       "Trigger declared"
-               );
-       }
-
-       /**
-        * Test trigger is properly declared
-        *
-        * @depends testTriggerDeclared
-        * @return bool
-        */
-       public function testTriggerEnabled()
-       {
-               $this->url('/admin/triggers.php');
-               $this->authenticate();
-               return $this->assertContains(
-                       'tick.png',
-                       $this->byXPath('//td[text()="interface_99_modMyModule_MyTrigger.class.php"]/following::img')->attribute('src'),
-                       "Trigger enabled"
-               );
-       }
-
-       /**
-        * Verify post conditions
-        * @return void
-        */
-       protected function assertPostConditions()
-       {
-       }
-
-       /**
-        * Unit test teardown
-        * @return void
-        */
-       public function tearDown()
-       {
-       }
-
-       /**
-        * Global test teardown
-        * @return void
-        */
-       public static function tearDownAfterClass()
-       {
-       }
-}
diff --git a/htdocs/modulebuilder/template/test/phpunit/MyObjectTest.php b/htdocs/modulebuilder/template/test/phpunit/MyObjectTest.php
deleted file mode 100644 (file)
index 31084cf..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-<?php
-/* Copyright (C) 2007-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) ---Put here your own copyright and developer email---
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    test/phpunit/MyObjectTest.php
- * \ingroup mymodule
- * \brief   PHPUnit test for MyObject class.
- */
-
-global $conf, $user, $langs, $db;
-//define('TEST_DB_FORCE_TYPE','mysql');        // This is to force using mysql driver
-
-//require_once 'PHPUnit/Autoload.php';
-require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
-require_once dirname(__FILE__).'/../../htdocs/mymodule/class/myobject.class.php';
-
-if (empty($user->id)) {
-       print "Load permissions for admin user nb 1\n";
-       $user->fetch(1);
-       $user->getrights();
-}
-$conf->global->MAIN_DISABLE_ALL_MAILS = 1;
-
-$langs->load("main");
-
-
-/**
- * Class MyObjectTest
- *
- * @backupGlobals disabled
- * @backupStaticAttributes enabled
- * @remarks    backupGlobals must be disabled to have db,conf,user and lang not erased.
- */
-class MyObjectTest extends PHPUnit\Framework\TestCase
-{
-       protected $savconf;
-       protected $savuser;
-       protected $savlangs;
-       protected $savdb;
-
-       /**
-        * Constructor
-        * We save global variables into local variables
-        *
-        * @return MyObjectTest
-        */
-       public function __construct()
-       {
-               parent::__construct();
-
-               //$this->sharedFixture
-               global $conf, $user, $langs, $db;
-               $this->savconf = $conf;
-               $this->savuser = $user;
-               $this->savlangs = $langs;
-               $this->savdb = $db;
-
-               print __METHOD__." db->type=".$db->type." user->id=".$user->id;
-               //print " - db ".$db->db;
-               print "\n";
-       }
-
-       /**
-        * Global test setup
-        *
-        * @return void
-        */
-       public static function setUpBeforeClass()
-       {
-               global $conf, $user, $langs, $db;
-               $db->begin(); // This is to have all actions inside a transaction even if test launched without suite.
-
-               print __METHOD__."\n";
-       }
-
-       /**
-        * Unit test setup
-        *
-        * @return void
-        */
-       protected function setUp()
-       {
-               global $conf, $user, $langs, $db;
-               $conf = $this->savconf;
-               $user = $this->savuser;
-               $langs = $this->savlangs;
-               $db = $this->savdb;
-
-               print __METHOD__."\n";
-       }
-
-       /**
-        * Unit test teardown
-        *
-        * @return void
-        */
-       protected function tearDown()
-       {
-               print __METHOD__."\n";
-       }
-
-       /**
-        * Global test teardown
-        *
-        * @return void
-        */
-       public static function tearDownAfterClass()
-       {
-               global $conf, $user, $langs, $db;
-               $db->rollback();
-
-               print __METHOD__."\n";
-       }
-
-
-       /**
-        * A sample test
-        *
-        * @return bool
-        */
-       public function testSomething()
-       {
-               global $conf, $user, $langs, $db;
-               $conf = $this->savconf;
-               $user = $this->savuser;
-               $langs = $this->savlangs;
-               $db = $this->savdb;
-
-               $result = true;
-
-               print __METHOD__." result=".$result."\n";
-               $this->assertTrue($result);
-
-               return $result;
-       }
-
-       /**
-        * testMyObjectCreate
-        *
-        * @return int
-        */
-       public function testMyObjectCreate()
-       {
-               global $conf, $user, $langs, $db;
-               $conf = $this->savconf;
-               $user = $this->savuser;
-               $langs = $this->savlangs;
-               $db = $this->savdb;
-
-               $localobject = new MyObject($this->savdb);
-               $localobject->initAsSpecimen();
-               $result = $localobject->create($user);
-
-               print __METHOD__." result=".$result."\n";
-               $this->assertLessThan($result, 0);
-
-               return $result;
-       }
-
-       /**
-        * testMyObjectDelete
-        *
-        * @param       int             $id             Id of object
-        * @return      int
-        *
-        * @depends     testMyObjectCreate
-        * The depends says test is run only if previous is ok
-        */
-       public function testMyObjectDelete($id)
-       {
-               global $conf, $user, $langs, $db;
-               $conf = $this->savconf;
-               $user = $this->savuser;
-               $langs = $this->savlangs;
-               $db = $this->savdb;
-
-               $localobject = new MyObject($this->savdb);
-               $result = $localobject->fetch($id);
-               $result = $localobject->delete($user);
-
-               print __METHOD__." id=".$id." result=".$result."\n";
-               $this->assertLessThan($result, 0);
-               return $result;
-       }
-}
diff --git a/htdocs/opensurvey/card.php b/htdocs/opensurvey/card.php
deleted file mode 100644 (file)
index 36c5b2e..0000000
+++ /dev/null
@@ -1,438 +0,0 @@
-<?php
-/* Copyright (C) 2013-2015  Laurent Destailleur     <eldy@users.sourceforge.net>
- * Copyright (C) 2014       Marcos García           <marcosgdf@gmail.com>
- * Copyright (C) 2018-2020  Frédéric France         <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *    \file       htdocs/opensurvey/card.php
- *    \ingroup    opensurvey
- *    \brief      Page to edit survey
- */
-
-// Load Dolibarr environment
-require '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT."/core/class/doleditor.class.php";
-require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
-require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
-require_once DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php";
-require_once DOL_DOCUMENT_ROOT."/opensurvey/lib/opensurvey.lib.php";
-
-
-// Security check
-if (empty($user->rights->opensurvey->read)) {
-       accessforbidden();
-}
-
-// Initialize Variables
-$action = GETPOST('action', 'aZ09');
-$cancel = GETPOST('cancel', 'alpha');
-
-$numsondage = '';
-
-if (GETPOST('id')) {
-       $numsondage = (string) GETPOST('id', 'alpha');
-}
-
-// Initialize objects
-$object = new Opensurveysondage($db);
-
-$result = $object->fetch(0, $numsondage);
-if ($result <= 0) {
-       dol_print_error($db, $object->error);
-       exit;
-}
-
-// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
-$hookmanager->initHooks(array('surveycard', 'globalcard'));
-
-$expiredate = dol_mktime(0, 0, 0, GETPOST('expiremonth'), GETPOST('expireday'), GETPOST('expireyear'));
-
-$permissiontoread = $user->rights->opensurvey->read;
-$permissiontoadd = $user->rights->opensurvey->write;
-// permission delete doesn't exists
-$permissiontodelete = $user->rights->opensurvey->write;
-
-
-/*
- * Actions
- */
-
-$parameters = array('id' => $numsondage);
-$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');
-}
-
-if (empty($reshook)) {
-       if ($cancel) {
-               $action = '';
-       }
-
-       // Delete
-       if ($action == 'delete_confirm') {
-               // Security check
-               if (!$user->rights->opensurvey->write) {
-                       accessforbidden();
-               }
-
-               $result = $object->delete($user, '', $numsondage);
-
-               header('Location: '.dol_buildpath('/opensurvey/list.php', 1));
-               exit();
-       }
-
-       // Close
-       if ($action == 'close') {
-               $object->status = Opensurveysondage::STATUS_CLOSED;
-               $object->update($user);
-       }
-
-       // Reopend
-       if ($action == 'reopen') {
-               $object->status = Opensurveysondage::STATUS_VALIDATED;
-               $object->update($user);
-       }
-
-       // Update
-       if ($action == 'update') {
-               // Security check
-               if (!$user->rights->opensurvey->write) {
-                       accessforbidden();
-               }
-
-               $error = 0;
-
-               if (!GETPOST('nouveautitre')) {
-                       setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Title")), null, 'errors');
-                       $error++;
-                       $action = 'edit';
-               }
-
-               if (!$error) {
-                       $object->title = (string) GETPOST('nouveautitre', 'alphanohtml');
-                       $object->description = (string) GETPOST('nouveauxcommentaires', 'restricthtml');
-                       $object->mail_admin = (string) GETPOST('nouvelleadresse', 'alpha');
-                       $object->date_fin = $expiredate;
-                       $object->allow_comments = GETPOST('cancomment', 'aZ09') == 'on' ? 1 : 0;
-                       $object->allow_spy = GETPOST('canseeothersvote', 'aZ09') == 'on' ? 1 : 0;
-                       $object->mailsonde = GETPOST('mailsonde', 'aZ09') == 'on' ? 1 : 0;
-
-                       $res = $object->update($user);
-                       if ($res < 0) {
-                               setEventMessages($object->error, $object->errors, 'errors');
-                               $action = 'edit';
-                       }
-               }
-       }
-
-       // Add comment
-       if (GETPOST('ajoutcomment')) {
-               $error = 0;
-
-               if (!GETPOST('comment', "alphanohtml")) {
-                       $error++;
-                       setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Comment")), null, 'errors');
-               }
-               if (!GETPOST('commentuser', "alphanohtml")) {
-                       $error++;
-                       setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("User")), null, 'errors');
-               }
-
-               if (!$error) {
-                       $comment = (string) GETPOST("comment", "alphanohtml");
-                       $comment_user = (string) GETPOST('commentuser', "alphanohtml");
-
-                       $resql = $object->addComment($comment, $comment_user);
-
-                       if (!$resql) {
-                               setEventMessages($langs->trans('ErrorInsertingComment'), null, 'errors');
-                       }
-               }
-       }
-
-       // Delete comment
-       if ($action == 'deletecomment') {
-               $idcomment = GETPOST('idcomment', 'int');
-               if ($idcomment > 0) {
-                       // Security check
-                       if (!$user->rights->opensurvey->write) {
-                               accessforbidden();
-                       }
-
-                       $resql = $object->deleteComment($idcomment);
-               }
-       }
-
-       if ($action == 'edit') {
-               // Security check
-               if (!$user->rights->opensurvey->write) {
-                       accessforbidden();
-               }
-       }
-}
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-if ($object->fk_user_creat) {
-       $userstatic = new User($db);
-       $userstatic->fetch($object->fk_user_creat);
-}
-
-$title = $object->title." - ".$langs->trans('Card');
-$helpurl = '';
-$arrayofjs = array();
-$arrayofcss = array('/opensurvey/css/style.css');
-llxHeader('', $title, $helpurl, 0, 0, 0, $arrayofjs, $arrayofcss);
-
-
-// Define format of choices
-$toutsujet = explode(",", $object->sujet);
-$listofanswers = array();
-foreach ($toutsujet as $value) {
-       $tmp = explode('@', $value);
-       $listofanswers[] = array('label'=>$tmp[0], 'format'=>(!empty($tmp[1]) ? $tmp[1] : 'checkbox'));
-}
-$toutsujet = str_replace("@", "<br>", $toutsujet);
-$toutsujet = str_replace("°", "'", $toutsujet);
-
-print '<form name="updatesurvey" action="'.$_SERVER["PHP_SELF"].'?id='.$numsondage.'" method="POST">'."\n";
-print '<input type="hidden" name="token" value="'.newToken().'">';
-print '<input type="hidden" name="action" value="update">';
-
-$head = opensurvey_prepare_head($object);
-
-
-print dol_get_fiche_head($head, 'general', $langs->trans("Survey"), -1, 'poll');
-
-$morehtmlref = '';
-
-$linkback = '<a href="'.DOL_URL_ROOT.'/opensurvey/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
-
-dol_banner_tab($object, 'id', $linkback, 1, 'id_sondage', 'id_sondage', $morehtmlref);
-
-
-print '<div class="fichecenter">';
-
-print '<div class="fichehalfleft">';
-print '<div class="underbanner clearboth"></div>';
-print '<table class="border tableforfield centpercent">';
-
-// Type
-$type = ($object->format == "A") ? 'classic' : 'date';
-print '<tr><td class="titlefieldmax45">'.$langs->trans("Type").'</td><td>';
-print img_picto('', dol_buildpath('/opensurvey/img/'.($type == 'classic' ? 'chart-32.png' : 'calendar-32.png'), 1), 'width="16"', 1);
-print ' '.$langs->trans($type == 'classic' ? "TypeClassic" : "TypeDate").'</td></tr>';
-
-// Title
-print '<tr><td>';
-$adresseadmin = $object->mail_admin;
-print $langs->trans("Title").'</td><td>';
-if ($action == 'edit') {
-       print '<input type="text" name="nouveautitre" style="width: 95%" value="'.dol_escape_htmltag(dol_htmlentities($object->title)).'">';
-} else {
-       print dol_htmlentities($object->title);
-}
-print '</td></tr>';
-
-// Description
-print '<tr><td class="tdtop">'.$langs->trans("Description").'</td><td>';
-if ($action == 'edit') {
-       $doleditor = new DolEditor('nouveauxcommentaires', $object->description, '', 120, 'dolibarr_notes', 'In', 1, 1, 1, ROWS_7, '90%');
-       $doleditor->Create(0, '');
-} else {
-       print (dol_textishtml($object->description) ? $object->description : dol_nl2br($object->description, 1, true));
-}
-print '</td></tr>';
-
-// Receive an email with each vote
-print '<tr><td>'.$langs->trans('ToReceiveEMailForEachVote').'</td><td>';
-if ($action == 'edit') {
-       print '<input type="checkbox" name="mailsonde" '.($object->mailsonde ? 'checked="checked"' : '').'">';
-} else {
-       print yn($object->mailsonde);
-
-       //If option is active and linked user does not have an email, we show a warning
-       if ($object->fk_user_creat && $object->mailsonde) {
-               if (!$userstatic->email) {
-                       print ' '.img_warning($langs->trans('NoEMail'));
-               }
-       }
-}
-print '</td></tr>';
-
-// Users can comment
-print '<tr><td>'.$langs->trans('CanComment').'</td><td>';
-if ($action == 'edit') {
-       print '<input type="checkbox" name="cancomment" '.($object->allow_comments ? 'checked="checked"' : '').'">';
-} else {
-       print yn($object->allow_comments);
-}
-print '</td></tr>';
-
-// Users can see others vote
-print '<tr><td>'.$langs->trans('CanSeeOthersVote').'</td><td>';
-if ($action == 'edit') {
-       print '<input type="checkbox" name="canseeothersvote" '.($object->allow_spy ? 'checked="checked"' : '').'">';
-} else {
-       print yn($object->allow_spy);
-}
-print '</td></tr>';
-
-print '</table>';
-
-print '</div>';
-print '<div class="fichehalfright">';
-print '<div class="underbanner clearboth"></div>';
-
-print '<table class="border tableforfield centpercent">';
-
-// Expire date
-print '<tr><td>'.$langs->trans('ExpireDate').'</td><td>';
-if ($action == 'edit') {
-       print $form->selectDate($expiredate ? $expiredate : $object->date_fin, 'expire', 0, 0, 0, '', 1, 0);
-} else {
-       print dol_print_date($object->date_fin, 'day');
-       if ($object->date_fin && $object->date_fin < dol_now() && $object->status == Opensurveysondage::STATUS_VALIDATED) {
-               print img_warning($langs->trans("Expired"));
-       }
-}
-print '</td></tr>';
-
-// Author
-print '<tr><td>';
-print $langs->trans("Author").'</td><td>';
-if ($object->fk_user_creat > 0) {
-       print $userstatic->getLoginUrl(1);
-} else {
-       if ($action == 'edit') {
-               print '<input type="text" name="nouvelleadresse" class="minwith200" value="'.$object->mail_admin.'">';
-       } else {
-               print dol_print_email($object->mail_admin, 0, 0, 1, 0, 1, 1);
-       }
-}
-print '</td></tr>';
-
-// Link
-print '<tr><td>'.$langs->trans("UrlForSurvey", '').'</td><td>';
-
-// Define $urlwithroot
-$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
-$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
-//$urlwithroot=DOL_MAIN_URL_ROOT;                                      // This is to use same domain name than current
-
-$url = $urlwithroot.'/public/opensurvey/studs.php?sondage='.$object->id_sondage;
-print '<input type="text" class="quatrevingtpercent" '.($action == 'edit' ? 'disabled' : '').' id="opensurveyurl" name="opensurveyurl" value="'.$url.'">';
-if ($action != 'edit') {
-       print ajax_autoselect("opensurveyurl", $url, 'image');
-}
-
-print '</td></tr>';
-
-// Other attributes
-$parameters = array();
-$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
-print $hookmanager->resPrint;
-
-print '</table>';
-print '</div>';
-
-print '</div>';
-print '<div class="clearboth"></div>';
-
-print dol_get_fiche_end();
-
-if ($action == 'edit') {
-       print $form->buttonsSaveCancel();
-}
-
-print '</form>'."\n";
-
-
-
-// Action bar
-
-print '<div class="tabsAction">';
-
-if ($action != 'edit' && $user->rights->opensurvey->write) {
-       // Modify button
-       print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'&id='.urlencode($numsondage).'">'.$langs->trans("Modify").'</a>';
-
-       if ($object->status == Opensurveysondage::STATUS_VALIDATED) {
-               // Close button
-               print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=close&token='.newToken().'&id='.urlencode($numsondage).'">'.$langs->trans("Close").'</a>';
-       }
-       if ($object->status == Opensurveysondage::STATUS_CLOSED) {
-               // Re-Open
-               print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=reopen&token='.newToken().'&id='.urlencode($numsondage).'">'.$langs->trans("ReOpen").'</a>';
-       }
-
-       // Delete
-       print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?suppressionsondage=1&id='.urlencode($numsondage).'&action=delete&token='.newToken(), 'delete', $permissiontodelete);
-}
-
-print '</div>';
-
-if ($action == 'delete') {
-       print $form->formconfirm($_SERVER["PHP_SELF"].'?&id='.urlencode($numsondage), $langs->trans("RemovePoll"), $langs->trans("ConfirmRemovalOfPoll", $id), 'delete_confirm', '', '', 1);
-}
-
-
-
-
-print '<form name="formulaire5" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
-print '<input type="hidden" name="token" value="'.newToken().'">';
-print '<input type="hidden" name="action" value="addcomment">';
-print '<input type="hidden" name="id" value="'.urlencode($numsondage).'">';
-print '<input type="hidden" name="page_y" value="">';
-
-print load_fiche_titre($langs->trans("CommentsOfVoters"), '', '');
-
-// Comment list
-$comments = $object->getComments();
-
-if (!empty($comments)) {
-       foreach ($comments as $comment) {
-               if ($user->rights->opensurvey->write) {
-                       print '<a class="reposition" href="'.DOL_URL_ROOT.'/opensurvey/card.php?action=deletecomment&token='.newToken().'&idcomment='.((int) $comment->id_comment).'&id='.urlencode($numsondage).'"> '.img_picto('', 'delete.png', '', false, 0, 0, '', '', 0).'</a> ';
-               }
-
-               print dol_htmlentities($comment->usercomment).': '.dol_nl2br(dol_htmlentities($comment->comment))." <br>";
-       }
-} else {
-       print '<span class="opacitymedium">'.$langs->trans("NoCommentYet").'</span><br>';
-}
-
-print '<br>';
-
-// Add comment
-if ($object->allow_comments) {
-       print $langs->trans("AddACommentForPoll").'<br>';
-       print '<textarea name="comment" rows="2" class="quatrevingtpercent"></textarea><br>'."\n";
-       print $langs->trans("Name").': <input type="text" class="minwidth300" name="commentuser" value="'.dol_escape_htmltag($user->getFullName($langs)).'"> '."\n";
-       print '<input type="submit" class="button reposition" name="ajoutcomment" value="'.dol_escape_htmltag($langs->trans("AddComment")).'"><br>'."\n";
-}
-
-print '</form>';
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/opensurvey/class/opensurveysondage.class.php b/htdocs/opensurvey/class/opensurveysondage.class.php
deleted file mode 100644 (file)
index f5dadd9..0000000
+++ /dev/null
@@ -1,708 +0,0 @@
-<?php
-/* Copyright (C) 2013-2014 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2014      Marcos García          <marcosgdf@gmail.com>
- * Copyright (C) 2020          Frédéric France               <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *  \file       htdocs/opensurvey/class/opensurveysondage.class.php
- *  \ingroup    opensurvey
- *  \brief      This file is an example for a CRUD class file (Create/Read/Update/Delete)
- *                             Initialy built by build_class_from_table on 2013-03-10 00:32
- */
-
-// Put here all includes required by your class file
-require_once DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php";
-//require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php";
-//require_once DOL_DOCUMENT_ROOT."/product/class/product.class.php";
-
-
-/**
- *     Put here description of your class
- */
-class Opensurveysondage extends CommonObject
-{
-       /**
-        * @var string ID to identify managed object
-        */
-       public $element = 'opensurvey_sondage';
-
-       /**
-        * @var string Name of table without prefix where object is stored
-        */
-       public $table_element = 'opensurvey_sondage';
-
-       /**
-        * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
-        */
-       public $picto = 'poll';
-
-       /**
-        * @var string  ID survey
-        */
-       public $id_sondage;
-
-       /**
-        * @var string description
-        */
-       public $description;
-
-       /**
-        * @var string email admin
-        */
-       public $mail_admin;
-
-       /**
-        * @var string admin name
-        */
-       public $nom_admin;
-
-       /**
-        * Id of user author of the poll
-        * @var int
-        */
-       public $fk_user_creat;
-
-       /**
-        * @var string  Title
-        */
-       public $title;
-
-       public $date_fin = '';
-
-       public $date_m;
-
-       /**
-        * @var int status
-        */
-       public $status = 1;
-
-       /**
-        * @var string format of survey
-        */
-       public $format;
-
-       /**
-        * @var int mailsonde
-        */
-       public $mailsonde;
-
-       /**
-        * @var string subject
-        */
-       public $sujet;
-
-       /**
-        * @var int             Allow comments on this poll
-        */
-       public $allow_comments;
-
-       /**
-        * @var int             Allow users see others vote
-        */
-       public $allow_spy;
-
-
-       /**
-        * Draft status (not used)
-        */
-       const STATUS_DRAFT = 0;
-       /**
-        * Validated/Opened status
-        */
-       const STATUS_VALIDATED = 1;
-       /**
-        * Closed
-        */
-       const STATUS_CLOSED = 2;
-
-
-       /**
-        *  Constructor
-        *
-        *  @param      DoliDb          $db      Database handler
-        */
-       public function __construct($db)
-       {
-               $this->db = $db;
-       }
-
-
-       /**
-        *  Create object into database
-        *
-        *  @param      User    $user        User that creates
-        *  @param  int     $notrigger   0=launch triggers after, 1=disable triggers
-        *  @return int                  <0 if KO, Id of created object if OK
-        */
-       public function create(User $user, $notrigger = 0)
-       {
-               global $conf;
-
-               $error = 0;
-
-               // Clean parameters
-               $this->cleanParameters();
-
-               // Check parameters
-               if (!$this->date_fin > 0) {
-                       $this->error = 'BadValueForEndDate';
-                       dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
-                       return -1;
-               }
-
-               // Insert request
-               $sql = "INSERT INTO ".MAIN_DB_PREFIX."opensurvey_sondage(";
-               $sql .= "id_sondage,";
-               $sql .= "commentaires,";
-               $sql .= "fk_user_creat,";
-               $sql .= "titre,";
-               $sql .= "date_fin,";
-               $sql .= "status,";
-               $sql .= "format,";
-               $sql .= "mailsonde,";
-               $sql .= "allow_comments,";
-               $sql .= "allow_spy,";
-               $sql .= "sujet,";
-               $sql .= "entity";
-               $sql .= ") VALUES (";
-               $sql .= "'".$this->db->escape($this->id_sondage)."',";
-               $sql .= " ".(empty($this->description) ? 'NULL' : "'".$this->db->escape($this->description)."'").",";
-               $sql .= " ".(int) $user->id.",";
-               $sql .= " '".$this->db->escape($this->title)."',";
-               $sql .= " '".$this->db->idate($this->date_fin)."',";
-               $sql .= " ".(int) $this->status.",";
-               $sql .= " '".$this->db->escape($this->format)."',";
-               $sql .= " ".((int) $this->mailsonde).",";
-               $sql .= " ".((int) $this->allow_comments).",";
-               $sql .= " ".((int) $this->allow_spy).",";
-               $sql .= " '".$this->db->escape($this->sujet)."',";
-               $sql .= " ".((int) $conf->entity);
-               $sql .= ")";
-
-               $this->db->begin();
-
-                  dol_syslog(get_class($this)."::create", LOG_DEBUG);
-               $resql = $this->db->query($sql);
-               if (!$resql) {
-                       $error++; $this->errors[] = "Error ".$this->db->lasterror();
-               }
-
-               if (!$error && !$notrigger) {
-                       global $langs, $conf;
-
-                       // Call trigger
-                       $result = $this->call_trigger('OPENSURVEY_CREATE', $user);
-                       if ($result < 0) {
-                               $error++;
-                       }
-                       // End call triggers
-               }
-
-               // Commit or rollback
-               if ($error) {
-                       foreach ($this->errors as $errmsg) {
-                               dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
-                               $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
-                       }
-                       $this->db->rollback();
-                       return -1 * $error;
-               } else {
-                       $this->db->commit();
-                       return $this->id;
-               }
-       }
-
-
-       /**
-        *  Load object in memory from the database
-        *
-        *  @param      int             $id                             Id object
-        *  @param      string  $numsurvey                      Ref of survey (admin or not)
-        *  @return int                                         <0 if KO, >0 if OK
-        */
-       public function fetch($id, $numsurvey = '')
-       {
-               $sql = "SELECT";
-               $sql .= " t.id_sondage,";
-               $sql .= " t.titre as title,";
-               $sql .= " t.commentaires as description,";
-               $sql .= " t.mail_admin,";
-               $sql .= " t.nom_admin,";
-               $sql .= " t.fk_user_creat,";
-               $sql .= " t.date_fin,";
-               $sql .= " t.status,";
-               $sql .= " t.format,";
-               $sql .= " t.mailsonde,";
-               $sql .= " t.allow_comments,";
-               $sql .= " t.allow_spy,";
-               $sql .= " t.sujet,";
-               $sql .= " t.tms";
-               $sql .= " FROM ".MAIN_DB_PREFIX."opensurvey_sondage as t";
-               $sql .= " WHERE t.id_sondage = '".$this->db->escape($id ? $id : $numsurvey)."'";
-
-               dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
-               $resql = $this->db->query($sql);
-               if ($resql) {
-                       if ($this->db->num_rows($resql)) {
-                               $obj = $this->db->fetch_object($resql);
-
-                               $this->id_sondage = $obj->id_sondage;
-                               $this->ref = $this->id_sondage; //For compatibility
-
-                               $this->description = $obj->description;
-                               $this->mail_admin = $obj->mail_admin;
-                               $this->nom_admin = $obj->nom_admin;
-                               $this->title = $obj->title;
-                               $this->date_fin = $this->db->jdate($obj->date_fin);
-                               $this->status = $obj->status;
-                               $this->format = $obj->format;
-                               $this->mailsonde = $obj->mailsonde;
-                               $this->allow_comments = $obj->allow_comments;
-                               $this->allow_spy = $obj->allow_spy;
-                               $this->sujet = $obj->sujet;
-                               $this->fk_user_creat = $obj->fk_user_creat;
-
-                               $this->date_m = $this->db->jdate(!empty($obj->tls) ? $obj->tls : "");
-                               $ret = 1;
-                       } else {
-                               $sondage = ($id ? 'id='.$id : 'sondageid='.$numsurvey);
-                               $this->error = 'Fetch no poll found for '.$sondage;
-                               dol_syslog($this->error, LOG_ERR);
-                               $ret = 0;
-                       }
-
-                       $this->db->free($resql);
-               } else {
-                         $this->error = "Error ".$this->db->lasterror();
-                       $ret = -1;
-               }
-
-               return $ret;
-       }
-
-
-       /**
-        *  Update object into database
-        *
-        *  @param      User    $user        User that modifies
-        *  @param  int     $notrigger   0=launch triggers after, 1=disable triggers
-        *  @return int                          <0 if KO, >0 if OK
-        */
-       public function update(User $user, $notrigger = 0)
-       {
-               global $conf, $langs;
-               $error = 0;
-
-               // Clean parameters
-               $this->cleanParameters();
-
-               // Check parameters
-               // Put here code to add a control on parameters values
-
-               // Update request
-               $sql = "UPDATE ".MAIN_DB_PREFIX."opensurvey_sondage SET";
-               $sql .= " id_sondage=".(isset($this->id_sondage) ? "'".$this->db->escape($this->id_sondage)."'" : "null").",";
-               $sql .= " commentaires=".(isset($this->description) ? "'".$this->db->escape($this->description)."'" : "null").",";
-               $sql .= " mail_admin=".(isset($this->mail_admin) ? "'".$this->db->escape($this->mail_admin)."'" : "null").",";
-               $sql .= " nom_admin=".(isset($this->nom_admin) ? "'".$this->db->escape($this->nom_admin)."'" : "null").",";
-               $sql .= " titre=".(isset($this->title) ? "'".$this->db->escape($this->title)."'" : "null").",";
-               $sql .= " date_fin=".(dol_strlen($this->date_fin) != 0 ? "'".$this->db->idate($this->date_fin)."'" : 'null').",";
-               $sql .= " status=".(isset($this->status) ? "'".$this->db->escape($this->status)."'" : "null").",";
-               $sql .= " format=".(isset($this->format) ? "'".$this->db->escape($this->format)."'" : "null").",";
-               $sql .= " mailsonde=".(isset($this->mailsonde) ? ((int) $this->mailsonde) : "null").",";
-               $sql .= " allow_comments=".((int) $this->allow_comments).",";
-               $sql .= " allow_spy=".((int) $this->allow_spy);
-               $sql .= " WHERE id_sondage='".$this->db->escape($this->id_sondage)."'";
-
-               $this->db->begin();
-
-               dol_syslog(get_class($this)."::update", LOG_DEBUG);
-               $resql = $this->db->query($sql);
-               if (!$resql) {
-                       $error++;
-                       $this->errors[] = "Error ".$this->db->lasterror();
-               }
-
-               if (!$error && !$notrigger) {
-                       // Call trigger
-                       $result = $this->call_trigger('OPENSURVEY_MODIFY', $user);
-                       if ($result < 0) {
-                               $error++;
-                       }
-                       // End call triggers
-               }
-
-               // Commit or rollback
-               if ($error) {
-                       foreach ($this->errors as $errmsg) {
-                               dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
-                               $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
-                       }
-                       $this->db->rollback();
-                       return -1 * $error;
-               } else {
-                       $this->db->commit();
-                       return 1;
-               }
-       }
-
-       /**
-        *  Delete object in database
-        *
-        *      @param  User    $user                   User that deletes
-        *  @param  int         $notrigger                      0=launch triggers after, 1=disable triggers
-        *  @param      string  $numsondage                     Num sondage admin to delete
-        *  @return     int                                                     <0 if KO, >0 if OK
-        */
-       public function delete(User $user, $notrigger = 0, $numsondage = '')
-       {
-               global $conf, $langs;
-               $error = 0;
-
-               if (empty($numsondage)) {
-                       $numsondage = $this->id_sondage;
-               }
-
-               $this->db->begin();
-
-               if (!$error && !$notrigger) {
-                       // Call trigger
-                       $result = $this->call_trigger('OPENSURVEY_DELETE', $user);
-                       if ($result < 0) {
-                               $error++;
-                       }
-                       // End call triggers
-               }
-
-               if (!$error) {
-                       $sql = 'DELETE FROM '.MAIN_DB_PREFIX."opensurvey_comments WHERE id_sondage = '".$this->db->escape($numsondage)."'";
-                       dol_syslog(get_class($this)."::delete", LOG_DEBUG);
-                       $resql = $this->db->query($sql);
-                       $sql = 'DELETE FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage = '".$this->db->escape($numsondage)."'";
-                       dol_syslog(get_class($this)."::delete", LOG_DEBUG);
-                       $resql = $this->db->query($sql);
-
-                       $sql = "DELETE FROM ".MAIN_DB_PREFIX."opensurvey_sondage";
-                       $sql .= " WHERE id_sondage = '".$this->db->escape($numsondage)."'";
-
-                       dol_syslog(get_class($this)."::delete", LOG_DEBUG);
-                       $resql = $this->db->query($sql);
-                       if (!$resql) {
-                               $error++; $this->errors[] = "Error ".$this->db->lasterror();
-                       }
-               }
-
-               // Commit or rollback
-               if ($error) {
-                       foreach ($this->errors as $errmsg) {
-                               dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
-                               $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
-                       }
-                       $this->db->rollback();
-                       return -1 * $error;
-               } else {
-                       $this->db->commit();
-                       return 1;
-               }
-       }
-
-       /**
-        *  Return a link to the object card (with optionaly the picto)
-        *
-        *      @param  int             $withpicto                                      Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
-        *  @param      int     $notooltip                                      1=Disable tooltip
-        *  @param  string  $morecss                            Add more css on link
-        *  @param  int     $save_lastsearch_value      -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
-        *      @return string                                                          String with URL
-        */
-       public function getNomUrl($withpicto = 0, $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
-       {
-               global $db, $conf, $langs;
-               global $dolibarr_main_authentication, $dolibarr_main_demo;
-               global $menumanager;
-
-               if (!empty($conf->dol_no_mouse_hover)) {
-                       $notooltip = 1; // Force disable tooltips
-               }
-
-               $result = '';
-
-               $label = img_picto('', $this->picto).' <u>'.$langs->trans("ShowSurvey").'</u>';
-               $label .= '<br>';
-               $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref.'<br>';
-               $label .= '<b>'.$langs->trans('Title').':</b> '.$this->title.'<br>';
-
-               $url = DOL_URL_ROOT.'/opensurvey/card.php?id='.$this->id;
-
-               // Add param to save lastsearch_values or not
-               $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
-               if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
-                       $add_save_lastsearch_values = 1;
-               }
-               if ($add_save_lastsearch_values) {
-                       $url .= '&save_lastsearch_values=1';
-               }
-
-               $linkclose = '';
-               if (empty($notooltip)) {
-                       if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
-                               $label = $langs->trans("ShowMyObject");
-                               $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
-                       }
-                       $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
-                       $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
-               } else {
-                       $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
-               }
-
-               $linkstart = '<a href="'.$url.'"';
-               $linkstart .= $linkclose.'>';
-               $linkend = '</a>';
-
-               $result .= $linkstart;
-               if ($withpicto) {
-                       $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
-               }
-               if ($withpicto != 2) {
-                       $result .= $this->ref;
-               }
-               $result .= $linkend;
-
-               return $result;
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        * Return array of lines
-        *
-        * @return      int             <0 if KO, >0 if OK
-        */
-       public function fetch_lines()
-       {
-               // phpcs:enable
-               $this->lines = array();
-
-               $sql = "SELECT id_users, nom as name, reponses";
-               $sql .= " FROM ".MAIN_DB_PREFIX."opensurvey_user_studs";
-               $sql .= " WHERE id_sondage = '".$this->db->escape($this->id_sondage)."'";
-
-               $resql = $this->db->query($sql);
-
-               if ($resql) {
-                       $num = $this->db->num_rows($resql);
-                       $i = 0;
-                       while ($i < $num) {
-                               $obj = $this->db->fetch_object($resql);
-                               $tmp = array('id_users'=>$obj->id_users, 'nom'=>$obj->name, 'reponses'=>$obj->reponses);
-
-                               $this->lines[] = $tmp;
-                               $i++;
-                       }
-               } else {
-                       dol_print_error($this->db);
-               }
-
-               return count($this->lines);
-       }
-
-       /**
-        *      Initialise object with example values
-        *      Id must be 0 if object instance is a specimen
-        *
-        *      @return void
-        */
-       public function initAsSpecimen()
-       {
-               $this->id = 0;
-
-               $this->id_sondage = 'a12d5g';
-               $this->description = 'Description of the specimen survey';
-               $this->mail_admin = 'email@email.com';
-               $this->nom_admin = 'surveyadmin';
-               $this->title = 'This is a specimen survey';
-               $this->date_fin = dol_now() + 3600 * 24 * 10;
-               $this->status = 1;
-               $this->format = 'classic';
-               $this->mailsonde = 0;
-       }
-
-       /**
-        * Returns all comments for the current opensurvey poll
-        *
-        * @return Object[]
-        */
-       public function getComments()
-       {
-               $comments = array();
-
-               $sql = 'SELECT id_comment, usercomment, comment';
-               $sql .= ' FROM '.MAIN_DB_PREFIX.'opensurvey_comments';
-               $sql .= " WHERE id_sondage='".$this->db->escape($this->id_sondage)."'";
-               $sql .= " ORDER BY id_comment";
-               $resql = $this->db->query($sql);
-
-               if ($resql) {
-                       $num_rows = $this->db->num_rows($resql);
-
-                       if ($num_rows > 0) {
-                               while ($obj = $this->db->fetch_object($resql)) {
-                                       $comments[] = $obj;
-                               }
-                       }
-               }
-
-               return $comments;
-       }
-
-       /**
-        * Adds a comment to the poll
-        *
-        * @param string $comment Comment content
-        * @param string $comment_user Comment author
-        * @param string $user_ip Comment author IP
-        * @return boolean False in case of the query fails, true if it was successful
-        */
-       public function addComment($comment, $comment_user, $user_ip = '')
-       {
-               $now = dol_now();
-               $sql = "INSERT INTO ".MAIN_DB_PREFIX."opensurvey_comments (id_sondage, comment, usercomment, date_creation, ip)";
-               $sql .= " VALUES ('".$this->db->escape($this->id_sondage)."','".$this->db->escape($comment)."','".$this->db->escape($comment_user)."','".$this->db->idate($now)."'".($user_ip ? ",'".$this->db->escape($user_ip)."'" : '').")";
-               $resql = $this->db->query($sql);
-
-               if (!$resql) {
-                       return false;
-               }
-
-               return true;
-       }
-
-       /**
-        * Deletes a comment of the poll
-        *
-        * @param int $id_comment Id of the comment
-        * @return boolean False in case of the query fails, true if it was successful
-        */
-       public function deleteComment($id_comment)
-       {
-               $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'opensurvey_comments WHERE id_comment = '.((int) $id_comment).' AND id_sondage = "'.$this->db->escape($this->id_sondage).'"';
-               $resql = $this->db->query($sql);
-
-               if (!$resql) {
-                       return false;
-               }
-
-               return true;
-       }
-
-       /**
-        * Cleans all the class variables before doing an update or an insert
-        *
-        * @return void
-        */
-       private function cleanParameters()
-       {
-               $this->id_sondage = trim($this->id_sondage);
-               $this->description = trim($this->description);
-               $this->mail_admin = trim($this->mail_admin);
-               $this->nom_admin = trim($this->nom_admin);
-               $this->title = trim($this->title);
-               $this->status = (int) $this->status;
-               $this->format = trim($this->format);
-               $this->mailsonde = ($this->mailsonde ? 1 : 0);
-               $this->allow_comments = ($this->allow_comments ? 1 : 0);
-               $this->allow_spy = ($this->allow_spy ? 1 : 0);
-               $this->sujet = trim($this->sujet);
-       }
-
-
-       /**
-        *      Return status label of Order
-        *
-        *      @param      int     $mode       0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
-        *      @return     string              Libelle
-        */
-       public function getLibStatut($mode)
-       {
-               return $this->LibStatut($this->status, $mode);
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        *  Return label of status
-        *
-        *  @param              int             $status           Id statut
-        *  @param      int             $mode             0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
-        *  @return     string                                    Label of status
-        */
-       public function LibStatut($status, $mode)
-       {
-               // phpcs:enable
-               global $langs, $conf;
-
-               if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
-                       global $langs;
-                       //$langs->load("mymodule");
-                       $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
-                       $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Opened');
-                       $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Closed');
-                       $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
-                       $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Opened');
-                       $this->labelStatusShort[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Closed');
-               }
-
-               $statusType = 'status'.$status;
-               if ($status == self::STATUS_VALIDATED) {
-                       if (0) {
-                               $statusType = 'status1';
-                       } else {
-                               $statusType = 'status4';
-                       }
-               }
-               if ($status == self::STATUS_CLOSED) {
-                       $statusType = 'status6';
-               }
-
-               return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
-       }
-
-
-       /**
-        *      Return number of votes done for this survey.
-        *
-        *      @return     int                 Number of votes
-        */
-       public function countVotes()
-       {
-               $result = 0;
-
-               $sql = " SELECT COUNT(id_users) as nb FROM ".MAIN_DB_PREFIX."opensurvey_user_studs";
-               $sql .= " WHERE id_sondage = '".$this->db->escape($this->ref)."'";
-
-               $resql = $this->db->query($sql);
-               if ($resql) {
-                       $obj = $this->db->fetch_object($resql);
-                       if ($obj) {
-                               $result = $obj->nb;
-                       }
-               } else {
-                       $this->error = $this->db->lasterror();
-                       $this->errors[] = $this->error;
-               }
-
-               return $result;
-       }
-}
diff --git a/htdocs/opensurvey/css/style.css b/htdocs/opensurvey/css/style.css
deleted file mode 100644 (file)
index e7f0d27..0000000
+++ /dev/null
@@ -1,531 +0,0 @@
-/* Copyright (C) 2004-2015     Laurent Destailleur             <eldy@users.sourceforge.net>
- * Copyright (C) 2006          Rodolphe Quiedeville    <rodolphe@quiedeville.org>
- * Copyright (C) 2007-2012     Regis Houssin                   <regis.houssin@inodbox.com>
- * Copyright (C) 2011          Philippe Grand                  <philippe.grand@atoo-net.com>
- * Copyright (C) 2012          Juanjo Menent                   <jmenent@2byte.es>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-.survey_invitation
-{
-       color: #445566;
-       font-weight: bold;
-}
-
-.corps {
-font-family: "Lucida Grande",Verdana,Arial,sans-serif;
-font-size: 14px;
-margin: auto;
-padding: 20px;
-overflow-x: auto;
-border: 2px solid #999999;
-background-color: #fff;
-box-shadow: 2px 2px 2px #F5F5F5;
--moz-border-radius: 10px;
-border-radius: 10px;
-}
-
-
-.index_date, .index_sondage {
-float: left;
-width: 50%;
-text-align: center;
-}
-
-.orange {
-color: #fef4e9;
-border: solid 1px #da7c0c;
-background: #f78d1d;
-background: -webkit-gradient(linear, left top, left bottom, from(#faa51a), to(#f47a20));
-background: -moz-linear-gradient(top, #faa51a, #f47a20);
-filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#faa51a', endColorstr='#f47a20');
-margin-left: 4px;
-margin-right: 4px;
-}
-.orange:active {
-color: #fcd3a5;
-background: -webkit-gradient(linear, left top, left bottom, from(#f47a20), to(#faa51a));
-background: -moz-linear-gradient(top, #f47a20, #faa51a);
-filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f47a20', endColorstr='#faa51a');
-}
-.orange:hover {
-background: #f47c20;
-background: -webkit-gradient(linear, left top, left bottom, from(#f88e11), to(#f06015));
-background: -moz-linear-gradient(top, #f88e11, #f06015);
-filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f88e11', endColorstr='#f06015');
-}
-
-
-.blue {
-color: #d9eef7;
-border: solid 1px #0076a3;
-background: #0095cd;
-background: -webkit-gradient(linear, left top, left bottom, from(#00adee), to(#0078a5));
-background: -moz-linear-gradient(top, #00adee, #0078a5);
-filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00adee', endColorstr='#0078a5');
-margin-left: 4px;
-margin-right: 4px;
-}
-.blue:active {
-color: #80bed6;
-background: -webkit-gradient(linear, left top, left bottom, from(#0078a5), to(#00adee));
-background: -moz-linear-gradient(top, #0078a5, #00adee);
-filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0078a5', endColorstr='#00adee');
-}
-.blue:hover {
-background: #007ead;
-background: -webkit-gradient(linear, left top, left bottom, from(#0095cc), to(#00678e));
-background: -moz-linear-gradient(top, #0095cc, #00678e);
-filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0095cc', endColorstr='#00678e');
-}
-
-
-/*
-==========================================================================
-
-Université de Strasbourg - Direction Informatique
-Auteur : Guilhem BORGHESI
-Création : Février 2008
-
-borghesi@unistra.fr
-
-Ce logiciel est régi par la licence CeCILL-B soumise au droit français et
-respectant les principes de diffusion des logiciels libres. Vous pouvez
-utiliser, modifier et/ou redistribuer ce programme sous les conditions
-de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA
-sur le site "http://www.cecill.info".
-
-Le fait que vous puissiez accéder Ã  cet en-tête signifie que vous avez
-pris connaissance de la licence CeCILL-B, et que vous en avez accepté les
-termes. Vous pouvez trouver une copie de la licence dans le fichier LICENCE.
-
-==========================================================================
-
-Université de Strasbourg - Direction Informatique
-Author : Guilhem BORGHESI
-Creation : Feb 2008
-
-borghesi@unistra.fr
-
-This software is governed by the CeCILL-B license under French law and
-abiding by the rules of distribution of free software. You can  use,
-modify and/ or redistribute the software under the terms of the CeCILL-B
-license as circulated by CEA, CNRS and INRIA at the following URL
-"http://www.cecill.info".
-
-The fact that you are presently reading this means that you have had
-knowledge of the CeCILL-B license and that you accept its terms. You can
-find a copy of this license in the file LICENSE.
-
-==========================================================================
-*/
-
-/*
-Le fichier style.css est le fichier de style de studs. Il se trouve Ã  la racine
-du répertoire studs. Il contient toutes les mises en forme des fichiers PHP
-de Studs.
-*/
-/*bandeau de titre*/
-div.bandeau{
-       line-height:35px;
-       text-align:center;
-       background-color: #0b419b;
-       color:white;
-       vertical-align:middle;
-       font-size:35px;
-       font-family:arial, sans-serif;
-       padding:8px;
-       height:35px;
-       position:static;
-       top:6px;
-       left:6px;
-       right:6px;
-
-}
-div.logo{
-       height:64px;
-       float:right;
-       top:8px;
-       right:8px;
-       margin-left: 0;
-       margin-right:0;
-       margin-bottom:auto;
-}
-/*Sous bandeau avec bouton de navigation*/
-div.bandeautitre{
-       height:17px;
-       font-size:14px;
-       font-weight:bold;
-       text-align:center;
-       vertical-align:middle;
-       font-family:arial, sans-serif;
-       padding:3px;
-       position:static;
-       top:57px;
-       left:6px;
-       right:6px;
-}
-div.sousbandeau{
-       height:17px;
-       background-color: #DDDDDD;
-       font-size:11px;
-       color:black;
-       vertical-align:middle;
-       font-family:arial, sans-serif;
-       padding:3px;
-       position:static;
-       top:80px;
-       left:6px;
-       right:6px;
-}
-/*bandeau de pied*/
-div.surbandeaupied{
-       background-color: #0077DD;
-       position:absolute;
-       bottom:30px;
-       left:6px;
-       right:6px;
-       height:6px;
-}
-div.bandeaupied{
-       text-align:center;
-       background-color: #0b419b;
-       color:white;
-       font-size:11px;
-       font-family:arial, sans-serif;
-       padding:6px;
-       position:fixed;
-       bottom:6px;
-       left:6px;
-       right:6px;
-       margin:2px;
-}
-div.surbandeaupiedmobile{
-       background-color: #0077DD;
-       position:static;
-       bottom:32px;
-       left:6px;
-       right:6px;
-       height:6px;
-}
-div.bandeaupiedmobile{
-       text-align:center;
-       background-color: #0b419b;
-       color:white;
-       font-size:11px;
-       font-family:arial, sans-serif;
-       padding:6px;
-       position:static;
-}
-/*les boutons se trouvant dans le sousbandeau*/
-div.sousbandeau a, div.sousbandeau span.sousbandeaulangue a {
-       background-color: #0b419b;
-       height:16px;
-       padding: 2px 6px 2px 6px;
-       vertical-align:middle;
-       text-align:center;
-       margin-left:10px;
-       margin-right:10px;
-       font-family:arial, sans-serif;
-       color:white;
-       font-size:10px;
-       text-decoration:none;
-}
-span.sousbandeaulangue {
-       margin-left:6px;
-       margin-right:6px;
-       float:right;
-}
-/*corps de la page index.php*/
-div.corps{
-       font-size:12px;
-       font-family:arial, sans-serif;
-       position:static;
-       padding:15px;
-}
-div.corps  table{
-       font-family:arial, sans-serif;
-       font-size:12px;
-       font-weight:bold;
-}
-div.corpscentre{
-       font-size:12px;
-       font-family:arial, sans-serif;
-       text-align:center;
-       position:absolute;
-       top:150px;
-       margin-right:10%;
-       margin-left:10%;
-       width:80%;
-}
-/*affichage des jours*/
-div.jourschoisis {
-       background-color: #DDD;
-       padding:10px;
-       text-align: center;
-       position:static;
-       left:700px;
-       top:170px;
-       font-size:12px;
-       width:100%;
-}
-/*presenation des pages*/
-div.bodydate {
-       padding:10px;
-       font-family:arial, sans-serif;
-       font-size:12px;
-       text-align:center;
-       position:static;
-       top:330px;
-       left:20px;
-       right:20px;
-}
-div.bodydate table{
-       font-family:arial, sans-serif;
-       font-size:12px;
-       font-weight:bold;
-}
-/*cadre de commentaires*/
-div.presentationdate {
-       width:100%;
-       font-family:arial, sans-serif;
-       text-align:center;
-       font-size:12px;
-       border-top:1px solid;
-       border-bottom:1px solid;
-       border-left: none;
-       border-right: none;
-       border-color:#969696;
-       position:static;
-       top:110px;
-       margin-top:10px;
-}
-div.presentationdatefin {
-       width:40%;
-       padding:10px;
-       font-family:arial, sans-serif;
-       text-align:center;
-       font-size:12px;
-    border: 1px solid;
-    margin-top: 10px;
-       margin-left: 30%;
-    margin-right: 30%;
-       position:static;
-}
-/*cadre principal de studs.php*/
-div.cadre {
-       padding:10px;
-       font-family:arial, sans-serif;
-       font-size:12px;
-       position:static;
-       top:235px;
-       text-align:center;
-       margin:0 auto;
-}
-/*la table des résultats dans l'affichage de sondage*/
-div.cadre table.resultats {
-       text-align: center;
-       margin:0 auto;
-}
-td.nom {
-       min-width: 160px;
-}
-@media only screen and (max-width: 767px)
-{
-       td.nom {
-               min-width: 100px;
-       }
-}
-
-td.vide {
-       min-width: 60px;
-}
-div.cadre td {
-       height:21px;
-}
-/*case de tableau OK dans affichage de sondage*/
-div.cadre td.ok {
-       background-color: #66FF99;
-       font-size:12px;
-       text-align:center;
-}
-/*Case de tableau NON dans affichage de sondage*/
-div.cadre td.non {
-       background-color: #FF7777;
-       min-width: 60px;
-}
-/*Case de tableau VIDE dans affichage de sondage*/
-div.cadre td.vide {
-       background-color: #DDDDDD;
-       text-align:center;
-       padding: 4px;
-}
-/*Case de tableau contenant les noms dans affichage de sondage*/
-div.cadre td.nom {
-       background-color: #DDDDDD;
-       text-align:center;
-       padding: 8px;
-}
-div.cadre td.casevide {
-       background-color: white;
-       text-align:center;
-}
-/*les cases contenant les sommes de chaque colonne dans l'affichage de calendrier*/
-div.cadre td.somme {
-       font-weight:  bold;
-       font-size:14px;
-}
-
-/*Case de tableau SUJET dans affichage de sondage*/
-div.cadre td.sujet, div.cadre td.jour, div.cadre td.heure {
-       border: 2px;
-       background-color: #DDDDDD;
-       font-size:14px;
-       padding:1px 5px;
-}
-
-div.cadre td.annee {
-       border: 2px;
-       background-color: #969696;
-       font-weight: bold;
-       font-size:14px;
-       padding:1px 5px;
-}
-div.cadre td.mois {
-       border: 2px;
-       background-color: #C0C0C0;
-       font-weight: bold;
-       font-size:14px;
-       padding:1px 5px;
-}
-
-/*jour de la semaine dans calendrier*/
-div.calendrier td.joursemaine {
-       width:65px;
-       text-align: center;
-       font-family:arial, sans-serif;
-       font-size:14px;
-       border: 2px;
-       background-color: white;
-}
-div.calendrier td.jourwe {
-       width:65px;
-       text-align: center;
-       font-family:arial, sans-serif;
-       font-size:14px;
-       border: 2px;
-       background-color: #C0C0C0;
-}
-/*jour avant le premier jour du mois dans calendrier*/
-div.calendrier td.avant, div.calendrier td.libre {
-       width:65px;
-       text-align: center;
-       border: 2px;
-       font-family:arial, sans-serif;
-       font-size: 1.1em;
-       background-color: #DDDDDD;
-}
-/*jour libre dans calendrier*/
-div.calendrier td.libre {
-       background-color: #66FF99;
-}
-/*jour deja selectionné dans calendrier*/
-div.calendrier td.choisi {
-       width:65px;
-       text-align: center;
-       border: 2px;
-       background-color: #0077DD;
-}
-/* Le paragraphe de fin */
-p.affichageresultats{
-       text-align: center;
-       font-family:arial, sans-serif;
-}
-
-div.comment{
-       width:100%;
-}
-
-div.comment span.usercomment{
-       font-weight:bold;
-}
-
-a.affichageexport{
-       text-align: center;
-       font-family:arial, sans-serif;
-       font-size:10px;
-       margin-left:10px;
-       text-decoration: none;
-}
-div.titregestionadmin{
-       text-align: center;
-       font-weight:bold;
-       font-size:18px;
-       padding:10px;
-}
-
-
-.bouton {
-       /* width: 65px; */
-       border:0;
-       padding:0 0 0 0;
-       margin:0;
-       cursor:pointer;
-       font-family:arial, sans-serif;
-       background: transparent !important;
-}
-.choisi .bouton {
-       color: #fff;
-}
-/*les boutons pour choisir un jour non selectionné*/
-.ON {
-    background-color: #BBBBCC;
-}
-
-/*les boutons pour deselectionner un jour deja choisi*/
-.OFF {
-    background-color: #AAFFAA;
-}
-
-div.nouveau_sondage a {
-    text-decoration: none;
-}
-div.nouveau_sondage span img {
-    vertical-align: middle;
-    border: 0;
-}
-div.nouveau_sondage span {
-    margin-left: 20px;
-}
-
-div.error, div.addcomment {
-    text-align:center;
-    border: 1px;
-    font-family: arial, sans-serif;
-    font-size: 13px;
-}
-ul.exports {
-    text-align:center;
-    list-style-type : none ;
-}
-li.error {
-    color: red;
-}
-
-.half {
-    -moz-transform:scale(0.5);
-    -webkit-transform:scale(0.5);
-    transform:scale(0.5);
-}
diff --git a/htdocs/opensurvey/exportcsv.php b/htdocs/opensurvey/exportcsv.php
deleted file mode 100644 (file)
index a8a2317..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-<?php
-/* Copyright (C) 2013      Laurent Destailleur        <eldy@users.sourceforge.net>
- * Copyright (C) 2014      Marcos García              <marcosgdf@gmail.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *    \file       htdocs/opensurvey/exportcsv.php
- *    \ingroup    opensurvey
- *    \brief      Page to list surveys
- */
-
-
-// Load Dolibarr environment
-require '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
-require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
-require_once DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php";
-
-
-$action = GETPOST('action', 'aZ09');
-$numsondage = '';
-if (GETPOST('id')) {
-       $numsondage = GETPOST("id", 'alpha');
-}
-
-// Initialize Objects
-$object = new Opensurveysondage($db);
-$result = $object->fetch(0, $numsondage);
-if ($result <= 0) {
-       dol_print_error('', 'Failed to get survey id '.$numsondage);
-}
-
-// Security check
-if (empty($user->rights->opensurvey->read)) {
-       accessforbidden();
-}
-
-
-/*
- * Actions
- */
-
-
-
-/*
- * View
- */
-
-$now = dol_now();
-
-$nbcolonnes = substr_count($object->sujet, ',') + 1;
-$toutsujet = explode(",", $object->sujet);
-$somme = array();
-// affichage des sujets du sondage
-$input = $langs->trans("Name").";";
-for ($i = 0; $toutsujet[$i]; $i++) {
-       if ($object->format == "D") {
-               $input .= ''.dol_print_date($toutsujet[$i], 'dayhour').';';
-       } else {
-               $input .= ''.$toutsujet[$i].';';
-       }
-}
-
-$input .= "\r\n";
-
-if (strpos($object->sujet, '@') !== false) {
-       $input .= ";";
-       for ($i = 0; $toutsujet[$i]; $i++) {
-               $heures = explode("@", $toutsujet[$i]);
-               $input .= ''.$heures[1].';';
-       }
-
-       $input .= "\r\n";
-}
-
-
-$sql = 'SELECT nom as name, reponses';
-$sql .= ' FROM '.MAIN_DB_PREFIX."opensurvey_user_studs";
-$sql .= " WHERE id_sondage='".$db->escape($numsondage)."'";
-$sql .= " ORDER BY id_users";
-$resql = $db->query($sql);
-if ($resql) {
-       $num = $db->num_rows($resql);
-       $i = 0;
-       while ($i < $num) {
-               $obj = $db->fetch_object($resql);
-
-               // Le name de l'utilisateur
-               $nombase = str_replace("°", "'", $obj->name);
-               $input .= $nombase.';';
-
-               //affichage des resultats
-               $ensemblereponses = $obj->reponses;
-               for ($k = 0; $k < $nbcolonnes; $k++) {
-                       if (empty($somme[$k])) {
-                               $somme[$k] = 0;
-                       }
-                       $car = substr($ensemblereponses, $k, 1);
-                       if ($car == "1") {
-                               $input .= 'OK;';
-                               $somme[$k]++;
-                       } elseif ($car == "2") {
-                               $input .= ';';
-                               $somme[$k]++;
-                       } else {
-                               $input .= 'KO;';
-                       }
-               }
-
-               $input .= "\r\n";
-               $i++;
-       }
-} else {
-       dol_print_error($db);
-}
-
-
-$filesize = strlen($input);
-$filename = $numsondage."_".dol_print_date($now, '%Y%m%d%H%M').".csv";
-
-
-
-header('Content-Type: text/csv; charset=utf-8');
-header('Content-Length: '.$filesize);
-header('Content-Disposition: attachment; filename="'.$filename.'"');
-header('Cache-Control: max-age=10');
-echo $input;
-
-exit;
diff --git a/htdocs/opensurvey/img/accept-24.png b/htdocs/opensurvey/img/accept-24.png
deleted file mode 100644 (file)
index e70c50c..0000000
Binary files a/htdocs/opensurvey/img/accept-24.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/accept.png b/htdocs/opensurvey/img/accept.png
deleted file mode 100644 (file)
index 98f0526..0000000
Binary files a/htdocs/opensurvey/img/accept.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/add-16.png b/htdocs/opensurvey/img/add-16.png
deleted file mode 100644 (file)
index 2574105..0000000
Binary files a/htdocs/opensurvey/img/add-16.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/add-24.png b/htdocs/opensurvey/img/add-24.png
deleted file mode 100644 (file)
index 068a232..0000000
Binary files a/htdocs/opensurvey/img/add-24.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/calendar-32.png b/htdocs/opensurvey/img/calendar-32.png
deleted file mode 100644 (file)
index 9ba72ef..0000000
Binary files a/htdocs/opensurvey/img/calendar-32.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/chart-32.png b/htdocs/opensurvey/img/chart-32.png
deleted file mode 100644 (file)
index 4759abe..0000000
Binary files a/htdocs/opensurvey/img/chart-32.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/date.png b/htdocs/opensurvey/img/date.png
deleted file mode 100644 (file)
index 8f3d9e8..0000000
Binary files a/htdocs/opensurvey/img/date.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/fforward.png b/htdocs/opensurvey/img/fforward.png
deleted file mode 100644 (file)
index 8295e6e..0000000
Binary files a/htdocs/opensurvey/img/fforward.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/medaille.png b/htdocs/opensurvey/img/medaille.png
deleted file mode 100644 (file)
index 269ab63..0000000
Binary files a/htdocs/opensurvey/img/medaille.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/next.png b/htdocs/opensurvey/img/next.png
deleted file mode 100644 (file)
index daf6bef..0000000
Binary files a/htdocs/opensurvey/img/next.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/object_opensurvey.png b/htdocs/opensurvey/img/object_opensurvey.png
deleted file mode 100644 (file)
index b2257c3..0000000
Binary files a/htdocs/opensurvey/img/object_opensurvey.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/opensurvey.png b/htdocs/opensurvey/img/opensurvey.png
deleted file mode 100644 (file)
index 4cb8481..0000000
Binary files a/htdocs/opensurvey/img/opensurvey.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/previous.png b/htdocs/opensurvey/img/previous.png
deleted file mode 100644 (file)
index 0344414..0000000
Binary files a/htdocs/opensurvey/img/previous.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/rewind.png b/htdocs/opensurvey/img/rewind.png
deleted file mode 100644 (file)
index 3f29b48..0000000
Binary files a/htdocs/opensurvey/img/rewind.png and /dev/null differ
diff --git a/htdocs/opensurvey/img/sondage2.png b/htdocs/opensurvey/img/sondage2.png
deleted file mode 100644 (file)
index cc5e8f4..0000000
Binary files a/htdocs/opensurvey/img/sondage2.png and /dev/null differ
diff --git a/htdocs/opensurvey/index.php b/htdocs/opensurvey/index.php
deleted file mode 100644 (file)
index 35e2b01..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-<?php
-/* Copyright (C) 2013-2014 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2019      Nicolas ZABOURI      <info@inovea-conseil.com>
- * Copyright (C) 2019      Frédéric France      <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file       htdocs/opensurvey/index.php
- *     \ingroup    opensurvey
- *     \brief      Home page of opensurvey area
- */
-
-// Load Dolibarr environment
-require '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
-require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
-
-// Load translation files required by the page
-$langs->load("opensurvey");
-
-// Security check
-if (empty($user->rights->opensurvey->read)) {
-       accessforbidden();
-}
-
-$hookmanager = new HookManager($db);
-
-// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
-$hookmanager->initHooks(array('opensurveyindex'));
-
-
-/*
- * View
- */
-
-$nbsondages = 0;
-$sql = 'SELECT COUNT(*) as nb';
-$sql .= ' FROM '.MAIN_DB_PREFIX.'opensurvey_sondage';
-$sql .= ' WHERE entity IN ('.getEntity('survey').')';
-$resql = $db->query($sql);
-if ($resql) {
-       $obj = $db->fetch_object($resql);
-       $nbsondages = $obj->nb;
-} else {
-       dol_print_error($db, '');
-}
-
-
-$title = $langs->trans("OpenSurveyArea");
-llxHeader('', $title);
-
-print load_fiche_titre($title, '', 'poll');
-
-
-print '<div class="fichecenter"><div class="fichethirdleft">';
-
-print '<div class="div-table-responsive-no-min">';
-print '<table class="noborder centpercent">';
-print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("OpenSurveyArea").'</td></tr>';
-print '<tr class="oddeven">';
-print '<td>'.$langs->trans("NbOfSurveys").'</td><td class="right"><a href="list.php">'.$nbsondages.'</a></td>';
-print "</tr>";
-//print '<tr class="liste_total"><td>'.$langs->trans("Total").'</td><td class="right">';
-//print $total;
-//print '</td></tr>';
-print '</table>';
-print '</div>';
-
-print '</div></div>';
-
-$parameters = array('user' => $user);
-$reshook = $hookmanager->executeHooks('dashboardOpenSurvey', $parameters, $object); // Note that $action and $object may have been modified by hook
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/opensurvey/lib/opensurvey.lib.php b/htdocs/opensurvey/lib/opensurvey.lib.php
deleted file mode 100644 (file)
index c9c75b0..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-<?php
-/* Copyright (C) 2013 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2014 Marcos García                   <marcosgdf@gmail.com>
- *
-* 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 <https://www.gnu.org/licenses/>.
-*/
-
-/**
- *     \file       htdocs/opensurvey/fonctions.php
- *     \ingroup    opensurvey
- *     \brief      Functions for module
- */
-
-/**
- * Returns an array with the tabs for the "Opensurvey poll" section
- * It loads tabs from modules looking for the entity Opensurveyso
- *
- * @param Opensurveysondage $object Current viewing poll
- * @return array Tabs for the opensurvey section
- */
-function opensurvey_prepare_head(Opensurveysondage $object)
-{
-       global $langs, $conf;
-
-       $h = 0;
-       $head = array();
-
-       $head[0][0] = 'card.php?id='.$object->id_sondage;
-       $head[0][1] = $langs->trans("Survey");
-       $head[0][2] = 'general';
-       $h++;
-
-       $head[1][0] = 'results.php?id='.$object->id_sondage;
-       $head[1][1] = $langs->trans("SurveyResults");
-       $nbVotes = $object->countVotes();
-       if ($nbVotes > 0) {
-               $head[$h][1] .= '<span class="badge marginleftonlyshort">'.($nbVotes).'</span>';
-       }
-       $head[1][2] = 'preview';
-       $h++;
-
-       // Show more tabs from modules
-       // Entries must be declared in modules descriptor with line
-       // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab
-       // $this->tabs = array('entity:-tabname);                                                                                               to remove a tab
-       complete_head_from_modules($conf, $langs, $object, $head, $h, 'opensurveypoll');
-
-       complete_head_from_modules($conf, $langs, $object, $head, $h, 'opensurveypoll', 'remove');
-
-       return $head;
-}
-
-/**
- * Show header for new member
- *
- * @param      string          $title                          Title
- * @param      string          $head                           Head array
- * @param      int             $disablejs                      More content into html header
- * @param      int             $disablehead            More content into html header
- * @param      array           $arrayofjs                      Array of complementary js files
- * @param      array           $arrayofcss                     Array of complementary css files
- * @param      string          $numsondage                     Num survey
- * @return     void
- */
-function llxHeaderSurvey($title, $head = "", $disablejs = 0, $disablehead = 0, $arrayofjs = '', $arrayofcss = '', $numsondage = '')
-{
-       global $conf, $langs, $mysoc;
-       global $dolibarr_main_url_root;
-
-       //$replacemainarea = (empty($conf->dol_hide_leftmenu) ? '<div>' : '').'<div>';
-
-       top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss, 0, 1); // Show html headers
-
-       print '<body id="mainbody" class="publicnewmemberform">';
-
-       print '<span id="dolpaymentspan"></span>'."\n";
-       print '<div class="center">'."\n";
-       print '<form name="formulaire" action="studs.php?sondage='.urlencode($numsondage).'#bas" method="POST">'."\n";
-       print '<input type="hidden" name="sondage" value="'.$numsondage.'"/>';
-       print '<input type="hidden" name="token" value="'.newToken().'">'."\n";
-       print "\n";
-
-       // Show logo (search order: logo defined by PAYMENT_LOGO_suffix, then PAYMENT_LOGO, then small company logo, large company logo, theme logo, common logo)
-       // Define logo and logosmall
-       $logosmall = $mysoc->logo_small;
-       $logo = $mysoc->logo;
-       //print '<!-- Show logo (logosmall='.$logosmall.' logo='.$logo.') -->'."\n";
-       // Define urllogo
-       $urllogo = '';
-       $urllogofull = '';
-       if (!empty($logosmall) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall)) {
-               $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/thumbs/'.$logosmall);
-               $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/thumbs/'.$logosmall);
-       } elseif (!empty($logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo)) {
-               $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/'.$logo);
-               $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/'.$logo);
-       }
-
-       // Output html code for logo
-       if ($urllogo) {
-               print '<div class="backgreypublicpayment">';
-               print '<div class="logopublicpayment">';
-               print '<img id="dolpaymentlogo" src="'.$urllogo.'"';
-               print '>';
-               print '</div>';
-               if (empty($conf->global->MAIN_HIDE_POWERED_BY)) {
-                       print '<div class="poweredbypublicpayment opacitymedium right"><a class="poweredbyhref" href="https://www.dolibarr.org?utm_medium=website&utm_source=poweredby" target="dolibarr" rel="noopener">'.$langs->trans("PoweredBy").'<br><img src="'.DOL_URL_ROOT.'/theme/dolibarr_logo.svg" width="80px"></a></div>';
-               }
-               print '</div>';
-       }
-
-       if (!empty($conf->global->OPENSURVEY_IMAGE_PUBLIC_INTERFACE)) {
-               print '<div class="backimagepublicopensurvey">';
-               print '<img id="idOPENSURVEY_IMAGE_PUBLIC_INTERFACE" src="'.$conf->global->OPENSURVEY_IMAGE_PUBLIC_INTERFACE.'">';
-               print '</div>';
-       }
-
-       print '<div style="margin-left: 50px; margin-right: 50px; text-align: start;"><br>';
-}
-
-/**
- * Show footer for new member
- *
- * @return     void
- */
-function llxFooterSurvey()
-{
-       print '</div>';
-       print '</form>';
-       print '</div>';
-
-       printCommonFooter('public');
-
-       dol_htmloutput_events();
-
-       print "</body>\n";
-       print "</html>\n";
-}
-
-
-/**
- * get_server_name
- *
- * @return     string          URL to use
- */
-function get_server_name()
-{
-       global $dolibarr_main_url_root;
-
-       $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
-       //$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT;         // This is to use external domain name found into config file
-       //$urlwithroot=DOL_MAIN_URL_ROOT;                                       // This is to use same domain name than current
-
-       $url = $urlwithouturlroot.dol_buildpath('/opensurvey/', 1);
-
-       if (!preg_match("|/$|", $url)) {
-               $url = $url."/";
-       }
-
-       return $url;
-}
-
-/**
- * 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
- */
-function issetAndNoEmpty($name, $tableau = null)
-{
-       if ($tableau === null) {
-               $tableau = $_POST;
-       }
-
-       return (isset($tableau[$name]) === true && empty($tableau[$name]) === false);
-}
-
-
-/**
- * Fonction permettant de générer les URL pour les sondage
- *
- * @param   string    $id     L'identifiant du sondage
- * @param   bool      $admin  True pour générer une URL pour l'administration d'un sondage, False pour un URL publique
- * @return  string            L'url pour le sondage
- */
-function getUrlSondage($id, $admin = false)
-{
-       if ($admin === true) {
-               $url = get_server_name().'results.php?id='.$id;
-       } else {
-               $url = get_server_name().'/public/studs.php?sondage='.$id;
-       }
-
-       return $url;
-}
-
-
-/**
- *     Generate a random id
- *
- *     @param  int             $car    Length of string to generate key
- *     @return string
- */
-function dol_survey_random($car)
-{
-       $string = "";
-       $chaine = "abcdefghijklmnopqrstuvwxyz123456789";
-       mt_srand((double) microtime() * 1000000);
-       for ($i = 0; $i < $car; $i++) {
-               $string .= $chaine[mt_rand() % strlen($chaine)];
-       }
-       return $string;
-}
-
-/**
- * Add a poll
- *
- * @return     void
- */
-function ajouter_sondage()
-{
-       global $db, $user;
-
-       require_once DOL_DOCUMENT_ROOT.'/opensurvey/class/opensurveysondage.class.php';
-
-       $sondage = dol_survey_random(16);
-
-       $allow_comments = empty($_SESSION['allow_comments']) ? 0 : 1;
-       $allow_spy = empty($_SESSION['allow_spy']) ? 0 : 1;
-
-       // Insert survey
-       $opensurveysondage = new Opensurveysondage($db);
-       $opensurveysondage->id_sondage = $sondage;
-       $opensurveysondage->description = $_SESSION['description'];
-       $opensurveysondage->mail_admin = $_SESSION['adresse'];
-       $opensurveysondage->nom_admin = $_SESSION['nom'];
-       $opensurveysondage->title = $_SESSION['title'];
-       $opensurveysondage->date_fin = $_SESSION['champdatefin'];
-       $opensurveysondage->format = $_SESSION['formatsondage'];
-       $opensurveysondage->mailsonde = $_SESSION['mailsonde'];
-       $opensurveysondage->allow_comments = $allow_comments;
-       $opensurveysondage->allow_spy = $allow_spy;
-       $opensurveysondage->sujet = $_SESSION['toutchoix'];
-
-       $res = $opensurveysondage->create($user);
-
-       if ($res < 0) {
-               dol_print_error($db);
-       }
-
-       unset($_SESSION["title"]);
-       unset($_SESSION["nom"]);
-       unset($_SESSION["adresse"]);
-       unset($_SESSION["description"]);
-       unset($_SESSION["mailsonde"]);
-       unset($_SESSION['allow_comments']);
-       unset($_SESSION['allow_spy']);
-       unset($_SESSION['toutchoix']);
-       unset($_SESSION['totalchoixjour']);
-       unset($_SESSION['champdatefin']);
-
-       $urlback = dol_buildpath('/opensurvey/card.php', 1).'?id='.$sondage;
-
-       header("Location: ".$urlback);
-       exit();
-}
diff --git a/htdocs/opensurvey/list.php b/htdocs/opensurvey/list.php
deleted file mode 100644 (file)
index 5700909..0000000
+++ /dev/null
@@ -1,576 +0,0 @@
-<?php
-/* Copyright (C) 2013-2017 Laurent Destailleur <eldy@users.sourceforge.net>
- * Copyright (C) 2014      Marcos García       <marcosgdf@gmail.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file       htdocs/opensurvey/list.php
- *     \ingroup    opensurvey
- *     \brief      Page to list surveys
- */
-
-// Load Dolibarr environment
-require '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
-require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
-require_once DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php";
-
-// Load translation files required by the page
-$langs->load("opensurvey");
-
-$action     = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ...
-$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
-$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ?
-$confirm    = GETPOST('confirm', 'alpha'); // Result of a confirmation
-$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') : 'opensurveylist'; // To manage different context of search
-$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
-$optioncss  = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
-$sall = trim((GETPOST('search_all', 'alphanohtml') != '') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
-
-$id = GETPOST('id', 'alpha');
-$search_ref = GETPOST('search_ref', 'alpha');
-$search_title = GETPOST('search_title', 'alpha');
-$search_status = GETPOST('search_status', 'alpha');
-
-// Load variable for pagination
-$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
-$sortfield = GETPOST('sortfield', 'aZ09comma');
-$sortorder = GETPOST('sortorder', 'aZ09comma');
-$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
-if (empty($page) || $page == -1 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) {
-       $page = 0;
-}     // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
-$offset = $limit * $page;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-
-// Initialize technical objects
-$object = new Opensurveysondage($db);
-$opensurvey_static = new Opensurveysondage($db);
-
-$extrafields = new ExtraFields($db);
-$diroutputmassaction = $conf->opensurvey->dir_output.'/temp/massgeneration/'.$user->id;
-$hookmanager->initHooks(array('surveylist')); // Note that conf->hooks_modules contains array
-// Fetch optionals attributes and labels
-$extrafields->fetch_name_optionals_label($object->table_element);
-$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
-
-// Default sort order (if not yet defined by previous GETPOST)
-if (!$sortfield) {
-       $sortfield = "p.date_fin";
-}
-if (!$sortorder) {
-       $sortorder = "DESC";
-}
-
-// Security check
-if (!$user->rights->opensurvey->read) {
-       accessforbidden();
-}
-
-// Definition of fields for list
-$arrayfields = array();
-foreach ($arrayfields as $key => $val) {
-       // If $val['visible']==0, then we never show the field
-       if (!empty($val['visible'])) {
-               $arrayfields['t.'.$key] = array('label'=>$val['label'], 'checked'=>(($val['visible'] < 0) ? 0 : 1), 'enabled'=>$val['enabled'], 'position'=>$val['position']);
-       }
-}
-// Extra fields
-if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) {
-       foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
-               if (!empty($extrafields->attributes[$object->table_element]['list'][$key])) {
-                       $arrayfields["ef.".$key] = array(
-                               'label'=>$extrafields->attributes[$object->table_element]['label'][$key],
-                               'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1),
-                               'position'=>$extrafields->attributes[$object->table_element]['pos'][$key],
-                               'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key])
-                       );
-               }
-       }
-}
-$object->fields = dol_sort_array($object->fields, 'position');
-$arrayfields = dol_sort_array($arrayfields, 'position');
-
-$permissiontoread = $user->rights->opensurvey->read;
-$permissiontoadd = $user->rights->opensurvey->write;
-// permission delete doesn't exists
-$permissiontodelete = $user->rights->opensurvey->write;
-
-
-/*
- * Actions
- */
-
-if (GETPOST('cancel', 'alpha')) {
-       $action = 'list'; $massaction = '';
-}
-if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
-       $massaction = '';
-}
-
-$parameters = array();
-$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');
-}
-
-if (empty($reshook)) {
-       // Selection of new fields
-       include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
-
-       // Purge search criteria
-       if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
-               $search_status = '';
-               $search_title = '';
-               $search_ref = '';
-               $toselect = array();
-               $search_array_options = array();
-       }
-       if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
-               || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
-               $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
-       }
-
-       // Mass actions
-       $objectclass = 'Opensurveysondage';
-       $objectlabel = 'Opensurveysondage';
-       $uploaddir = $conf->opensurvey->dir_output;
-       include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
-}
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-$now = dol_now();
-
-//$help_url="EN:Module_MyObject|FR:Module_MyObject_FR|ES:Módulo_MyObject";
-$help_url = '';
-$title = $langs->trans('OpenSurveyArea');
-
-
-$sql = "SELECT p.id_sondage as rowid, p.fk_user_creat, p.format, p.date_fin, p.status, p.titre as title, p.nom_admin, p.tms,";
-$sql .= " u.login, u.firstname, u.lastname";
-$sql .= " FROM ".MAIN_DB_PREFIX."opensurvey_sondage as p";
-$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user u ON u.rowid = p.fk_user_creat";
-$sql .= " WHERE p.entity IN (".getEntity('survey').")";
-if ($search_status != '-1' && $search_status != '') {
-       $sql .= natural_search("p.status", $search_status, 2);
-}
-if (!empty($search_expired) && $search_expired == 'expired') {
-       $sql .= " AND p.date_fin < '".$db->idate($now)."'";
-}
-if (!empty($search_expired) && $search_expired == 'opened') {
-       $sql .= " AND p.date_fin >= '".$db->idate($now)."'";
-}
-if (!empty($search_ref)) {
-       $sql .= natural_search("p.id_sondage", $search_ref);
-}
-if (!empty($search_title)) {
-       $sql .= natural_search("p.titre", $search_title);
-}
-// Add where from extra fields
-include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
-// Add where from hooks
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
-$sql .= $hookmanager->resPrint;
-
-$sql .= $db->order($sortfield, $sortorder);
-
-// Count total nb of records
-$nbtotalofrecords = '';
-if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
-       $resql = $db->query($sql);
-       $nbtotalofrecords = $db->num_rows($resql);
-       if (($page * $limit) > $nbtotalofrecords) {     // if total of record found is smaller than page * limit, goto and load page 0
-               $page = 0;
-               $offset = 0;
-       }
-}
-// if total of record found is smaller than limit, no need to do paging and to restart another select with limits set.
-if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) {
-       $num = $nbtotalofrecords;
-} else {
-       $sql .= $db->plimit($limit + 1, $offset);
-
-       $resql = $db->query($sql);
-       if (!$resql) {
-               dol_print_error($db);
-               exit;
-       }
-
-       $num = $db->num_rows($resql);
-}
-
-// Direct jump if only one record found
-if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all) {
-       $obj = $db->fetch_object($resql);
-       $id = $obj->rowid;
-       header("Location: ".dol_buildpath('/opensurvey/card.php', 1).'?id='.$id);
-       exit;
-}
-
-
-// Output page
-// --------------------------------------------------------------------
-
-llxHeader('', $title, $help_url);
-
-$arrayofselected = is_array($toselect) ? $toselect : array();
-
-$param = '';
-if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
-       $param .= '&contextpage='.urlencode($contextpage);
-}
-if ($limit > 0 && $limit != $conf->liste_limit) {
-       $param .= '&limit='.urlencode($limit);
-}
-$fieldtosortuser = empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION) ? 'firstname' : 'lastname';
-
-if ($optioncss != '') {
-       $param .= '&optioncss='.urlencode($optioncss);
-}
-// Add $param from extra fields
-include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
-
-// List of mass actions available
-$arrayofmassactions = array(
-       //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
-       //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
-);
-if ($permissiontodelete) {
-       $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
-}
-if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) {
-       $arrayofmassactions = array();
-}
-$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
-
-
-// List of surveys into database
-
-print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
-if ($optioncss != '') {
-       print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
-}
-print '<input type="hidden" name="token" value="'.newToken().'">';
-print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
-print '<input type="hidden" name="action" value="list">';
-print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
-print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
-print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
-
-$newcardbutton = dolGetButtonTitle($langs->trans('NewSurvey'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/opensurvey/wizard/index.php', '', $user->rights->opensurvey->write);
-
-print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'poll', 0, $newcardbutton, '', $limit, 0, 0, 1);
-
-// Add code for pre mass action (confirmation or email presend form)
-$topicmail = "SendOpenSurveyRef";
-$modelmail = "opensurvey";
-$objecttmp = new Opensurveysondage($db);
-$trackid = 'surv'.$object->id;
-include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
-
-if ($sall) {
-       foreach ($fieldstosearchall as $key => $val) {
-               $fieldstosearchall[$key] = $langs->trans($val);
-       }
-       print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'</div>';
-}
-
-$moreforfilter = '';
-/*$moreforfilter.='<div class="divsearchfield">';
-$moreforfilter.= $langs->trans('MyFilter') . ': <input type="text" name="search_myfield" value="'.dol_escape_htmltag($search_myfield).'">';
-$moreforfilter.= '</div>';*/
-
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
-if (empty($reshook)) {
-       $moreforfilter .= $hookmanager->resPrint;
-} else {
-       $moreforfilter = $hookmanager->resPrint;
-}
-
-if (!empty($moreforfilter)) {
-       print '<div class="liste_titre liste_titre_bydiv centpercent">';
-       print $moreforfilter;
-       print '</div>';
-}
-
-$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
-//$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);       // This also change content of $arrayfields
-$selectedfields = '';
-$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
-
-print '<div class="div-table-responsive">';
-print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
-
-// Fields title search
-// --------------------------------------------------------------------
-print '<tr class="liste_titre_filter">';
-// Action column
-if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
-       print '<td class="liste_titre maxwidthsearch">';
-       $searchpicto = $form->showFilterButtons('left');
-       print $searchpicto;
-       print '</td>';
-}
-print '<td class="liste_titre"><input type="text" class="maxwidth100" name="search_ref" value="'.dol_escape_htmltag($search_ref).'"></td>';
-print '<td class="liste_titre"><input type="text" class="maxwidth100onsmartphone" name="search_title" value="'.dol_escape_htmltag($search_title).'"></td>';
-print '<td class="liste_titre"></td>';
-print '<td class="liste_titre"></td>';
-print '<td class="liste_titre"></td>';
-print '<td class="liste_titre"></td>';
-print '<td class="liste_titre"></td>';
-$arraystatus = array('-1'=>'&nbsp;', '0'=>$langs->trans("Draft"), '1'=>$langs->trans("Opened"), '2'=>$langs->trans("Closed"));
-print '<td class="liste_titre" align="center">'.$form->selectarray('search_status', $arraystatus, $search_status, 0, 0, 0, '', 0, 0, 0, '', 'onroghtofpage').'</td>';
-// 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); // Note that $action and $object may have been modified by hook
-print $hookmanager->resPrint;
-// Action column
-if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
-       print '<td class="liste_titre maxwidthsearch">';
-       $searchpicto = $form->showFilterButtons();
-       print $searchpicto;
-       print '</td>';
-}
-print '</tr>'."\n";
-
-
-// Fields title label
-// --------------------------------------------------------------------
-print '<tr class="liste_titre">';
-// Action column
-if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
-       print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', 'align="center"', $sortfield, $sortorder, 'maxwidthsearch ')."\n";
-}
-print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "p.id_sondage", $param, "", "", $sortfield, $sortorder);
-print_liste_field_titre("Title", $_SERVER["PHP_SELF"], "p.titre", $param, "", "", $sortfield, $sortorder);
-print_liste_field_titre("Type", $_SERVER["PHP_SELF"], "p.format", $param, "", "", $sortfield, $sortorder);
-print_liste_field_titre("Author", $_SERVER["PHP_SELF"], "u.".$fieldtosortuser, $param, "", "", $sortfield, $sortorder);
-print_liste_field_titre("NbOfVoters", $_SERVER["PHP_SELF"], "", $param, "", 'align="right"', $sortfield, $sortorder);
-print_liste_field_titre("ExpireDate", $_SERVER["PHP_SELF"], "p.date_fin", $param, "", 'align="center"', $sortfield, $sortorder);
-print_liste_field_titre("DateLastModification", $_SERVER["PHP_SELF"], "p.tms", $param, "", 'align="center"', $sortfield, $sortorder);
-print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "p.status", $param, "", 'align="center"', $sortfield, $sortorder);
-// 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);
-$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
-print $hookmanager->resPrint;
-// Action column
-if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
-       print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', 'align="center"', $sortfield, $sortorder, 'maxwidthsearch ')."\n";
-}
-print '</tr>'."\n";
-
-
-
-// Loop on record
-// --------------------------------------------------------------------
-$i = 0;
-$totalarray = array();
-$totalarray['nbfield'] = 0;
-while ($i < min($num, $limit)) {
-       $obj = $db->fetch_object($resql);
-       if (empty($obj)) {
-               break; // Should not happen
-       }
-
-       $sql2 = 'select COUNT(*) as nb from '.MAIN_DB_PREFIX."opensurvey_user_studs where id_sondage='".$db->escape($obj->rowid)."'";
-       $resql2 = $db->query($sql2);
-       if ($resql2) {
-               $obj2 = $db->fetch_object($resql2);
-               $nbuser = $obj2->nb;
-       } else {
-               dol_print_error($db);
-       }
-
-       $opensurvey_static->id = $obj->rowid;
-       $opensurvey_static->ref = $obj->rowid;
-       $opensurvey_static->title = $obj->title;
-       $opensurvey_static->status = $obj->status;
-       $opensurvey_static->date_fin = $db->jdate($obj->date_fin);
-
-       // Show here line of result
-       print '<tr class="oddeven">';
-       // Action column
-       if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
-               print '<td class="nowrap center">';
-               if ($massactionbutton || $massaction) {   // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
-                       $selected = 0;
-                       if (in_array($obj->rowid, $arrayofselected)) {
-                               $selected = 1;
-                       }
-                       print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
-               }
-               print '</td>';
-       }
-       // Ref
-       print '<td>';
-       print $opensurvey_static->getNomUrl(1);
-       print '</td>';
-       if (!$i) {
-               $totalarray['nbfield']++;
-       }
-
-       // Title
-       print '<td>'.dol_htmlentities($obj->title).'</td>';
-       if (!$i) {
-               $totalarray['nbfield']++;
-       }
-
-       // Type
-       print '<td>';
-       $type = ($obj->format == 'A') ? 'classic' : 'date';
-       print img_picto('', dol_buildpath('/opensurvey/img/'.($type == 'classic' ? 'chart-32.png' : 'calendar-32.png'), 1), 'width="16"', 1);
-       print ' '.$langs->trans($type == 'classic' ? "TypeClassic" : "TypeDate");
-       print '</td>';
-       if (!$i) {
-               $totalarray['nbfield']++;
-       }
-
-       print '<td>';
-       // Author
-       if ($obj->fk_user_creat) {
-               $userstatic = new User($db);
-               $userstatic->id = $obj->fk_user_creat;
-               $userstatic->firstname = $obj->firstname;
-               $userstatic->lastname = $obj->lastname;
-               $userstatic->login = $userstatic->getFullName($langs, 0, -1, 48);
-
-               print $userstatic->getLoginUrl(1);
-       } else {
-               print dol_htmlentities($obj->nom_admin);
-       }
-       print '</td>';
-       if (!$i) {
-               $totalarray['nbfield']++;
-       }
-
-       // Nb of voters
-       print'<td class="right">'.$nbuser.'</td>'."\n";
-       if (!$i) {
-               $totalarray['nbfield']++;
-       }
-
-       print '<td class="center">'.dol_print_date($db->jdate($obj->date_fin), 'day');
-       if ($db->jdate($obj->date_fin) < $now && $obj->status == Opensurveysondage::STATUS_VALIDATED) {
-               print img_warning($langs->trans("Expired"));
-       }
-       print '</td>';
-       if (!$i) {
-               $totalarray['nbfield']++;
-       }
-
-       print '<td class="center">'.dol_print_date($db->jdate($obj->tms), 'dayhour');
-       print '</td>';
-       if (!$i) {
-               $totalarray['nbfield']++;
-       }
-
-       print '<td class="center">'.$opensurvey_static->getLibStatut(5).'</td>'."\n";
-       if (!$i) {
-               $totalarray['nbfield']++;
-       }
-
-       // 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); // Note that $action and $object may have been modified by hook
-       print $hookmanager->resPrint;
-       // Action column
-       if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
-               print '<td class="nowrap center">';
-               if ($massactionbutton || $massaction) {   // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
-                       $selected = 0;
-                       if (in_array($obj->rowid, $arrayofselected)) {
-                               $selected = 1;
-                       }
-                       print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
-               }
-               print '</td>';
-       }
-       if (!$i) {
-               $totalarray['nbfield']++;
-       }
-
-       print '</tr>'."\n";
-       $i++;
-}
-
-// Show total line
-include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
-
-
-// If no record found
-if ($num == 0) {
-       $colspan = 8;
-       foreach ($arrayfields as $key => $val) {
-               if (!empty($val['checked'])) {
-                       $colspan++;
-               }
-       }
-       print '<tr><td colspan="'.$colspan.'" class="opacitymedium">'.$langs->trans("NoRecordFound").'</td></tr>';
-}
-
-
-$db->free($resql);
-
-$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
-$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook
-print $hookmanager->resPrint;
-
-print '</table>'."\n";
-print '</div>'."\n";
-
-print '</form>'."\n";
-
-if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
-       $hidegeneratedfilelistifempty = 1;
-       if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
-               $hidegeneratedfilelistifempty = 0;
-       }
-
-       require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
-       $formfile = new FormFile($db);
-
-       // Show list of available documents
-       $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
-       $urlsource .= str_replace('&amp;', '&', $param);
-
-       $filedir = $diroutputmassaction;
-       $genallowed = $permissiontoread;
-       $delallowed = $permissiontoadd;
-
-       print $formfile->showdocuments('massfilesarea_mymodule', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/opensurvey/results.php b/htdocs/opensurvey/results.php
deleted file mode 100644 (file)
index d8405c3..0000000
+++ /dev/null
@@ -1,1170 +0,0 @@
-<?php
-/* Copyright (C) 2013-2020  Laurent Destailleur     <eldy@users.sourceforge.net>
- * Copyright (C) 2014       Marcos García           <marcosgdf@gmail.com>
- * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file       htdocs/opensurvey/results.php
- *     \ingroup    opensurvey
- *     \brief      Page to preview votes of a survey
- */
-
-// Load Dolibarr environment
-require '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
-require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
-require_once DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php";
-require_once DOL_DOCUMENT_ROOT."/opensurvey/lib/opensurvey.lib.php";
-
-// Security check
-if (empty($user->rights->opensurvey->read)) {
-       accessforbidden();
-}
-
-// Init vars
-$action = GETPOST('action', 'aZ09');
-$numsondage = GETPOST("id");
-
-$object = new Opensurveysondage($db);
-$result = $object->fetch(0, $numsondage);
-if ($result <= 0) {
-       dol_print_error('', 'Failed to get survey id '.$numsondage);
-}
-
-$nblines = $object->fetch_lines();
-
-
-/*
- * Actions
- */
-
-// Return to the results
-if (GETPOST('retoursondage')) {
-       header('Location: results.php?id='.(GETPOSTISSET('id_sondage') ? GETPOST('id_sondage', 'aZ09') : GETPOST('id', 'int')));
-       exit;
-}
-
-$nbcolonnes = substr_count($object->sujet, ',') + 1;
-
-// Add vote
-if (GETPOST("boutonp") || GETPOST("boutonp.x") || GETPOST("boutonp_x")) {              // boutonp for chrome, boutonp.x for firefox
-       if (GETPOST('nom')) {
-               $erreur_prenom = false;
-
-               $nouveauchoix = '';
-               for ($i = 0; $i < $nbcolonnes; $i++) {
-                       if (GETPOSTISSET("choix$i") && GETPOST("choix$i") == '1') {
-                               $nouveauchoix .= "1";
-                       } elseif (GETPOSTISSET("choix$i") && GETPOST("choix$i") == '2') {
-                               $nouveauchoix .= "2";
-                       } else { // sinon c'est 0
-                               $nouveauchoix .= "0";
-                       }
-               }
-
-               $nom = substr(GETPOST("nom", 'alphanohtml'), 0, 64);
-
-               // Check if vote already exists
-               $sql = 'SELECT id_users, nom as name';
-               $sql .= ' FROM '.MAIN_DB_PREFIX.'opensurvey_user_studs';
-               $sql .= " WHERE id_sondage='".$db->escape($numsondage)."' AND nom = '".$db->escape($nom)."'";
-               $sql .= ' ORDER BY id_users';
-               $resql = $db->query($sql);
-               $num_rows = $db->num_rows($resql);
-               if ($num_rows > 0) {
-                       setEventMessages($langs->trans("VoteNameAlreadyExists"), null, 'errors');
-                       $error++;
-               } else {
-                       $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'opensurvey_user_studs (nom, id_sondage, reponses)';
-                       $sql .= " VALUES ('".$db->escape($nom)."', '".$db->escape($numsondage)."','".$db->escape($nouveauchoix)."')";
-                       $resql = $db->query($sql);
-                       if (!$resql) {
-                               dol_print_error($db);
-                       }
-               }
-       }
-}
-
-// Update vote
-$testmodifier = false;
-$testligneamodifier = false;
-$ligneamodifier = -1;
-for ($i = 0; $i < $nblines; $i++) {
-       if (GETPOSTISSET('modifierligne'.$i)) {
-               $ligneamodifier = $i;
-               $testligneamodifier = true;
-       }
-
-       //test pour voir si une ligne est a modifier
-       if (GETPOSTISSET('validermodifier'.$i)) {
-               $modifier = $i;
-               $testmodifier = true;
-       }
-}
-if ($testmodifier) {
-       // Security check
-       if (!$user->rights->opensurvey->write) {
-               accessforbidden();
-       }
-
-       $nouveauchoix = '';
-       for ($i = 0; $i < $nbcolonnes; $i++) {
-               if (GETPOSTISSET("choix$i") && GETPOST("choix$i") == '1') {
-                       $nouveauchoix .= "1";
-               } elseif (GETPOSTISSET("choix$i") && GETPOST("choix$i") == '2') {
-                       $nouveauchoix .= "2";
-               } else { // sinon c'est 0
-                       $nouveauchoix .= "0";
-               }
-       }
-
-       $idtomodify = GETPOST("idtomodify".$modifier);
-       $sql = 'UPDATE '.MAIN_DB_PREFIX."opensurvey_user_studs";
-       $sql .= " SET reponses = '".$db->escape($nouveauchoix)."'";
-       $sql .= " WHERE id_users = '".$db->escape($idtomodify)."'";
-
-       $resql = $db->query($sql);
-       if (!$resql) {
-               dol_print_error($db);
-       }
-}
-
-// Add column (not for date)
-if (GETPOST("ajoutercolonne") && GETPOST('nouvellecolonne') && $object->format == "A") {
-       // Security check
-       if (!$user->rights->opensurvey->write) {
-               accessforbidden();
-       }
-
-       $nouveauxsujets = $object->sujet;
-
-       //on rajoute la valeur a la fin de tous les sujets deja entrés
-       $nouveauxsujets .= ',';
-       $nouveauxsujets .= str_replace(array(",", "@"), " ", GETPOST("nouvellecolonne")).(!GETPOST("typecolonne") ? '' : '@'.GETPOST("typecolonne"));
-
-       //mise a jour avec les nouveaux sujets dans la base
-       $sql = 'UPDATE '.MAIN_DB_PREFIX."opensurvey_sondage";
-       $sql .= " SET sujet = '".$db->escape($nouveauxsujets)."'";
-       $sql .= " WHERE id_sondage = '".$db->escape($numsondage)."'";
-       $resql = $db->query($sql);
-       if (!$resql) {
-               dol_print_error($db);
-       } else {
-               header('Location: results.php?id='.$object->id_sondage);
-       }
-}
-
-// Add column (with format date)
-if (GETPOSTISSET("ajoutercolonne") && $object->format == "D") {
-       // Security check
-       if (!$user->rights->opensurvey->write) {
-               accessforbidden();
-       }
-
-       $nouveauxsujets = $object->sujet;
-
-       if (GETPOSTISSET("nouveaujour") && GETPOST("nouveaujour") != "vide" &&
-               GETPOSTISSET("nouveaumois") && GETPOST("nouveaumois") != "vide" &&
-               GETPOSTISSET("nouvelleannee") && GETPOST("nouvelleannee") != "vide") {
-               $nouvelledate = dol_mktime(0, 0, 0, GETPOST("nouveaumois"), GETPOST("nouveaujour"), GETPOST("nouvelleannee"));
-
-               if (GETPOSTISSET("nouvelleheuredebut") && GETPOST("nouvelleheuredebut") != "vide") {
-                       $nouvelledate .= "@";
-                       $nouvelledate .= GETPOST("nouvelleheuredebut");
-                       $nouvelledate .= "h";
-
-                       if (GETPOST("nouvelleminutedebut") != "vide") {
-                               $nouvelledate .= GETPOST("nouvelleminutedebut");
-                       }
-               }
-
-               if (GETPOSTISSET("nouvelleheurefin") && GETPOST("nouvelleheurefin") != "vide") {
-                       $nouvelledate .= "-";
-                       $nouvelledate .= GETPOST("nouvelleheurefin");
-                       $nouvelledate .= "h";
-
-                       if (GETPOST("nouvelleminutefin") != "vide") {
-                               $nouvelledate .= GETPOST("nouvelleminutefin");
-                       }
-               }
-
-               if (GETPOST("nouvelleheuredebut") == "vide" || (GETPOSTISSET("nouvelleheuredebut") && GETPOSTISSET("nouvelleheurefin")
-                       && (GETPOST("nouvelleheuredebut") < GETPOST("nouvelleheurefin") || (GETPOST("nouvelleheuredebut") == GETPOST("nouvelleheurefin")
-                               && (GETPOST("nouvelleminutedebut") < GETPOST("nouvelleminutefin")))))) {
-                       $erreur_ajout_date = false;
-               } else {
-                       $erreur_ajout_date = "yes";
-               }
-
-               //on rajoute la valeur dans les valeurs
-               $datesbase = explode(",", $object->sujet);
-               $taillebase = count($datesbase);
-
-               //recherche de l'endroit de l'insertion de la nouvelle date dans les dates deja entrées dans le tableau
-               if ($nouvelledate < $datesbase[0]) {
-                       $cleinsertion = 0;
-               } elseif ($nouvelledate > $datesbase[$taillebase - 1]) {
-                       $cleinsertion = count($datesbase);
-               } else {
-                       $nbdatesbase = count($datesbase);
-                       for ($i = 0; $i < $nbdatesbase; $i++) {
-                               $j = $i + 1;
-                               if ($nouvelledate > $datesbase[$i] && $nouvelledate < $datesbase[$j]) {
-                                       $cleinsertion = $j;
-                               }
-                       }
-               }
-
-               array_splice($datesbase, $cleinsertion, 0, $nouvelledate);
-               $cle = array_search($nouvelledate, $datesbase);
-               $dateinsertion = '';
-               $nbofdates = count($datesbase);
-               for ($i = 0; $i < $nbofdates; $i++) {
-                       $dateinsertion .= ",";
-                       $dateinsertion .= $datesbase[$i];
-               }
-
-               $dateinsertion = substr("$dateinsertion", 1);
-
-               // update with new topics into database
-               if (isset($erreur_ajout_date) && empty($erreur_ajout_date)) {
-                       $sql = 'UPDATE '.MAIN_DB_PREFIX."opensurvey_sondage";
-                       $sql .= " SET sujet = '".$db->escape($dateinsertion)."'";
-                       $sql .= " WHERE id_sondage = '".$db->escape($numsondage)."'";
-                       $resql = $db->query($sql);
-                       if (!$resql) {
-                               dol_print_error($db);
-                       } else {
-                               header('Location: results.php?id='.$object->id_sondage);
-                       }
-               }
-               if ($cleinsertion >= 0) {
-                       $sql = 'SELECT s.reponses';
-                       $sql .= " FROM ".MAIN_DB_PREFIX."opensurvey_user_studs as s";
-                       $sql .= " WHERE id_sondage = '".$db->escape($numsondage)."'";
-                       $resql = $db->query($sql);
-                       if (!$resql) {
-                               dol_print_error($db);
-                       } else {
-                               $num = $db->num_rows($resql);
-                               $compteur = 0;
-                               while ($compteur < $num) {
-                                       $obj = $db->fetch_object($resql);
-                                       $sql = 'UPDATE '.MAIN_DB_PREFIX."opensurvey_user_studs";
-                                       if ($cleinsertion == 0) {
-                                               $sql .= " SET reponses = '0".$db->escape($obj->reponses)."'";
-                                       } else {
-                                               $reponsesadd = str_split($obj->reponses);
-                                               $lengthresponses = count($reponsesadd);
-                                               for ($cpt = $lengthresponses; $cpt > $cleinsertion; $cpt--) {
-                                                       $reponsesadd[$cpt] = $reponsesadd[$cpt-1];
-                                               }
-                                               $reponsesadd[$cleinsertion] = '0';
-                                               $reponsesadd = implode($reponsesadd);
-                                               $sql .= " SET reponses = '".$db->escape($reponsesadd)."'";
-                                       }
-                                       $sql .= " WHERE id_sondage = '".$db->escape($numsondage)."'";
-                                       $resql = $db->query($sql);
-                                       if (!$resql) {
-                                               dol_print_error($db);
-                                       }
-                                       $compteur++;
-                               }
-                       }
-               }
-               $adresseadmin = $object->mail_admin;
-       } else {
-               $erreur_ajout_date = "yes";
-       }
-}
-
-// Delete line
-for ($i = 0; $i < $nblines; $i++) {
-       if (GETPOST("effaceligne".$i) || GETPOST("effaceligne".$i."_x") || GETPOST("effaceligne".$i.".x")) {    // effacelignei for chrome, effacelignei_x for firefox
-               // Security check
-               if (!$user->rights->opensurvey->write) {
-                       accessforbidden();
-               }
-
-               $compteur = 0;
-
-               // Loop on each answer
-               $compteur = 0;
-               $sql = "SELECT id_users, nom as name, id_sondage, reponses";
-               $sql .= " FROM ".MAIN_DB_PREFIX."opensurvey_user_studs";
-               $sql .= " WHERE id_sondage = '".$db->escape($numsondage)."'";
-               $resql = $db->query($sql);
-               if (!$resql) {
-                       dol_print_error($db);
-               }
-               $num = $db->num_rows($resql);
-               while ($compteur < $num) {
-                       $obj = $db->fetch_object($resql);
-
-                       if ($compteur == $i) {
-                               $sql2 = 'DELETE FROM '.MAIN_DB_PREFIX.'opensurvey_user_studs';
-                               $sql2 .= " WHERE id_users = ".((int) $obj->id_users);
-                               $resql2 = $db->query($sql2);
-                       }
-
-                       $compteur++;
-               }
-       }
-}
-
-// Delete column
-for ($i = 0; $i < $nbcolonnes; $i++) {
-       if ((GETPOST("effacecolonne".$i) || GETPOST("effacecolonne".$i."_x") || GETPOST("effacecolonne".$i.".x"))
-               && $nbcolonnes > 1) {   // effacecolonnei for chrome, effacecolonnei_x for firefox
-               // Security check
-               if (!$user->rights->opensurvey->write) {
-                       accessforbidden();
-               }
-
-               $db->begin();
-
-               $toutsujet = explode(",", $object->sujet);
-               $j = 0;
-               $nouveauxsujets = '';
-
-               //parcours de tous les sujets actuels
-               while (isset($toutsujet[$j])) {
-                       //si le sujet n'est pas celui qui a Ã©té effacé alors on concatene
-                       if ($i != $j) {
-                               if (!empty($nouveauxsujets)) {
-                                       $nouveauxsujets .= ',';
-                               }
-                               $nouveauxsujets .= $toutsujet[$j];
-                       }
-
-                       $j++;
-               }
-
-               // Mise a jour des sujets dans la base
-               $sql = 'UPDATE '.MAIN_DB_PREFIX."opensurvey_sondage";
-               $sql .= " SET sujet = '".$db->escape($nouveauxsujets)."' WHERE id_sondage = '".$db->escape($numsondage)."'";
-               $resql = $db->query($sql);
-               if (!$resql) {
-                       dol_print_error($db);
-               }
-
-               // Clean current answer to remove deleted columns
-               $compteur = 0;
-               $sql = "SELECT id_users, nom as name, id_sondage, reponses";
-               $sql .= " FROM ".MAIN_DB_PREFIX."opensurvey_user_studs";
-               $sql .= " WHERE id_sondage = '".$db->escape($numsondage)."'";
-               dol_syslog('sql='.$sql);
-               $resql = $db->query($sql);
-               if (!$resql) {
-                       dol_print_error($db);
-                       exit;
-               }
-               $num = $db->num_rows($resql);
-               while ($compteur < $num) {
-                       $obj = $db->fetch_object($resql);
-
-                       $newcar = '';
-                       $ensemblereponses = $obj->reponses;
-
-                       // parcours de toutes les réponses actuelles
-                       for ($j = 0; $j < $nbcolonnes; $j++) {
-                               $car = substr($ensemblereponses, $j, 1);
-                               //si les reponses ne concerne pas la colonne effacée, on concatene
-                               if ($i != $j) {
-                                       $newcar .= $car;
-                               }
-                       }
-
-                       // mise a jour des reponses utilisateurs dans la base
-                       $sql2 = 'UPDATE '.MAIN_DB_PREFIX.'opensurvey_user_studs';
-                       $sql2 .= " SET reponses = '".$db->escape($newcar)."'";
-                       $sql2 .= " WHERE id_users = '".$db->escape($obj->id_users)."'";
-                       //print $sql2;
-                       dol_syslog('sql='.$sql2);
-                       $resql2 = $db->query($sql2);
-
-                       $compteur++;
-               }
-
-               $db->commit();
-       }
-}
-
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-if ($object->fk_user_creat) {
-       $userstatic = new User($db);
-       $userstatic->fetch($object->fk_user_creat);
-}
-
-$result = $object->fetch(0, $numsondage);
-if ($result <= 0) {
-       dol_print_error($db, $object->error);
-       exit;
-}
-
-$title = $object->title." - ".$langs->trans('Card');
-$helpurl = '';
-$arrayofjs = array();
-$arrayofcss = array('/opensurvey/css/style.css');
-llxHeader('', $title, $helpurl, 0, 0, 0, $arrayofjs, $arrayofcss);
-
-
-// Define format of choices
-$toutsujet = explode(",", $object->sujet);
-$listofanswers = array();
-foreach ($toutsujet as $value) {
-       $tmp = explode('@', $value);
-       $listofanswers[] = array('label'=>$tmp[0], 'format'=>(!empty($tmp[1]) ? $tmp[1] : 'checkbox'));
-}
-$toutsujet = str_replace("@", "<br>", $toutsujet);
-$toutsujet = str_replace("°", "'", $toutsujet);
-
-
-print '<form name="formulaire4" action="#" method="POST">'."\n";
-print '<input type="hidden" name="token" value="'.newToken().'">';
-
-$head = opensurvey_prepare_head($object);
-
-print dol_get_fiche_head($head, 'preview', $langs->trans("Survey"), -1, 'poll');
-
-$morehtmlref = '';
-
-$linkback = '<a href="'.DOL_URL_ROOT.'/opensurvey/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
-
-dol_banner_tab($object, 'id', $linkback, 1, 'id_sondage', 'id_sondage', $morehtmlref);
-
-
-print '<div class="fichecenter">';
-
-print '<div class="fichehalfleft">';
-print '<div class="underbanner clearboth"></div>';
-print '<table class="border tableforfield centpercent">';
-
-// Type
-$type = ($object->format == "A") ? 'classic' : 'date';
-print '<tr><td class="titlefield">'.$langs->trans("Type").'</td><td>';
-print img_picto('', dol_buildpath('/opensurvey/img/'.($type == 'classic' ? 'chart-32.png' : 'calendar-32.png'), 1), 'width="16"', 1);
-print ' '.$langs->trans($type == 'classic' ? "TypeClassic" : "TypeDate").'</td></tr>';
-
-// Title
-print '<tr><td>';
-$adresseadmin = $object->mail_admin;
-print $langs->trans("Title").'</td><td>';
-if ($action == 'edit') {
-       print '<input type="text" name="nouveautitre" size="40" value="'.dol_escape_htmltag($object->title).'">';
-} else {
-       print dol_htmlentities($object->title);
-}
-print '</td></tr>';
-
-// Description
-print '<tr><td class="tdtop">'.$langs->trans("Description").'</td><td>';
-if ($action == 'edit') {
-       $doleditor = new DolEditor('nouveauxcommentaires', $object->description, '', 120, 'dolibarr_notes', 'In', 1, 1, 1, ROWS_7, '90%');
-       $doleditor->Create(0, '');
-} else {
-       print (dol_textishtml($object->description) ? $object->description : dol_nl2br($object->description, 1, true));
-}
-print '</td></tr>';
-
-// EMail
-//If linked user, then emails are going to be sent to users' email
-if (!$object->fk_user_creat) {
-       print '<tr><td>'.$langs->trans("EMail").'</td><td>';
-       if ($action == 'edit') {
-               print '<input type="text" name="nouvelleadresse" class="minwith200" value="'.$object->mail_admin.'">';
-       } else {
-               print dol_print_email($object->mail_admin, 0, 0, 1, 0, 1, 1);
-       }
-       print '</td></tr>';
-}
-
-print '</table>';
-
-print '</div>';
-print '<div class="fichehalfright">';
-print '<div class="underbanner clearboth"></div>';
-
-print '<table class="border tableforfield centpercent">';
-
-
-// Expire date
-print '<tr><td>'.$langs->trans('ExpireDate').'</td><td>';
-if ($action == 'edit') {
-       print $form->selectDate($expiredate ? $expiredate : $object->date_fin, 'expire', 0, 0, 0, '', 1, 0);
-} else {
-       print dol_print_date($object->date_fin, 'day');
-       if ($object->date_fin && $object->date_fin < dol_now() && $object->status == Opensurveysondage::STATUS_VALIDATED) {
-               print img_warning($langs->trans("Expired"));
-       }
-}
-print '</td></tr>';
-
-// Author
-print '<tr><td>';
-print $langs->trans("Author").'</td><td>';
-if ($object->fk_user_creat) {
-       print $userstatic->getLoginUrl(1);
-} else {
-       print dol_htmlentities($object->nom_admin);
-}
-print '</td></tr>';
-
-// Link
-print '<tr><td>'.$langs->trans("UrlForSurvey", '').'</td><td>';
-
-// Define $urlwithroot
-$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
-$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
-//$urlwithroot=DOL_MAIN_URL_ROOT;                                      // This is to use same domain name than current
-
-$url = $urlwithouturlroot.dol_buildpath('/public/opensurvey/studs.php', 1).'?sondage='.$object->id_sondage;
-$urllink = '<input type="text" class="quatrevingtpercent" '.($action == 'edit' ? 'disabled' : '').' id="opensurveyurl" name="opensurveyurl" value="'.$url.'">';
-print $urllink;
-if ($action != 'edit') {
-       print ajax_autoselect("opensurveyurl", $url, 'image');
-}
-
-print '</td></tr>';
-
-print '</table>';
-print '</div>';
-
-print '</div>';
-print '<div class="clearboth"></div>';
-
-print dol_get_fiche_end();
-
-print '</form>'."\n";
-
-
-// Buttons
-
-print '<div class="tabsAction">';
-
-print '<a class="butAction" href="exportcsv.php?id='.urlencode($numsondage).'">'.$langs->trans("ExportSpreadsheet").' (.CSV)</a>';
-
-print '</div>';
-
-
-// Show form to add a new field/column
-if (GETPOST('ajoutsujet')) {
-       // Security check
-       if (!$user->rights->opensurvey->write) {
-               accessforbidden();
-       }
-
-       print '<form name="formulaire" action="" method="POST">'."\n";
-       print '<input type="hidden" name="token" value="'.newToken().'">';
-       print '<input type="hidden" name="backtopage" value="'.GETPOST('backtopage', 'alpha').'">';
-
-       print '<div class="center">'."\n";
-       print "<br><br>\n";
-
-       // Add new column
-       if ($object->format == "A") {
-               print $langs->trans("AddNewColumn").':<br><br>';
-               print $langs->trans("Title").' <input type="text" name="nouvellecolonne" size="40"><br>';
-               $tmparray = array('checkbox'=>$langs->trans("CheckBox"), 'yesno'=>$langs->trans("YesNoList"), 'foragainst'=>$langs->trans("PourContreList"));
-               print $langs->trans("Type").' '.$form->selectarray("typecolonne", $tmparray, GETPOST('typecolonne')).'<br><br>';
-               print '<input type="submit" class="button" name="ajoutercolonne" value="'.dol_escape_htmltag($langs->trans("Add")).'">';
-               print '<input type="hidden" name="id_sondage" value="'.dol_escape_htmltag($object->id_sondage).'">';
-               print ' &nbsp; &nbsp; ';
-               print '<input type="submit" class="button button-cancel" name="retoursondage" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
-               print '<br><br>'."\n";
-       } else {
-               require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
-
-               $formother = new FormOther($db);
-               //ajout d'une date avec creneau horaire
-               print $langs->trans("AddADate").':<br><br>'."\n";
-               print '<select name="nouveaujour"> '."\n";
-               print '<OPTION VALUE="vide">&nbsp;</OPTION>'."\n";
-               for ($i = 1; $i < 32; $i++) {
-                       print '<OPTION VALUE="'.$i.'">'.$i.'</OPTION>'."\n";
-               }
-               print '</select>'."\n";
-
-               print $formother->select_month('', 'nouveaumois', 1);
-
-               print '&nbsp;';
-
-               print $formother->selectyear('', 'nouvelleannee', 1, 0, 5, 0, 1);
-
-               print '<br><br>'.$langs->trans("AddStartHour").': <br><br>'."\n";
-               print '<select name="nouvelleheuredebut"> '."\n";
-               print '<OPTION VALUE="vide">&nbsp;</OPTION>'."\n";
-               for ($i = 0; $i < 24; $i++) {
-                       print '<OPTION VALUE="'.$i.'">'.$i.' H</OPTION>'."\n";
-               }
-               print '</select>'."\n";
-               print '<select name="nouvelleminutedebut"> '."\n";
-               print '<OPTION VALUE="vide">&nbsp;</OPTION>'."\n";
-               print '<OPTION VALUE="00">00</OPTION>'."\n";
-               print '<OPTION VALUE="15">15</OPTION>'."\n";
-               print '<OPTION VALUE="30">30</OPTION>'."\n";
-               print '<OPTION VALUE="45">45</OPTION>'."\n";
-               print '</select>'."\n";
-               print '<br><br>'.$langs->trans("AddEndHour").': <br><br>'."\n";
-               print '<select name="nouvelleheurefin"> '."\n";
-               print '<OPTION VALUE="vide">&nbsp;</OPTION>'."\n";
-               for ($i = 0; $i < 24; $i++) {
-                       print '<OPTION VALUE="'.$i.'">'.$i.' H</OPTION>'."\n";
-               }
-               print '</SELECT>'."\n";
-               print '<select name="nouvelleminutefin"> '."\n";
-               print '<OPTION VALUE="vide">&nbsp;</OPTION>'."\n";
-               print '<OPTION VALUE="00">00</OPTION>'."\n";
-               print '<OPTION VALUE="15">15</OPTION>'."\n";
-               print '<OPTION VALUE="30">30</OPTION>'."\n";
-               print '<OPTION VALUE="45">45</OPTION>'."\n";
-               print '</select>'."\n";
-
-               print '<br><br>';
-               print' <input type="submit" class="button" name="ajoutercolonne" value="'.dol_escape_htmltag($langs->trans("Add")).'">'."\n";
-               print '&nbsp; &nbsp;';
-               print '<input type="submit" class="button button-cancel" name="retoursondage" value="'.$langs->trans("Cancel").'">';
-       }
-
-       print '</form>'."\n";
-       print '<br><br><br><br>'."\n";
-       print '</div>'."\n";
-
-       exit;
-}
-
-if ($user->rights->opensurvey->write) {
-       print '<span class="opacitymedium">';
-       $s = $langs->trans("PollAdminDesc", '{s1}', $langs->trans("Add"));
-       print str_replace('{s1}', img_picto('', 'delete'), $s);
-       print '</span><br>';
-}
-
-$nbcolonnes = substr_count($object->sujet, ',') + 1;
-
-print '<form name="formulaire" action="" method="POST">'."\n";
-print '<input type="hidden" name="token" value="'.newToken().'">';
-print '<input type="hidden" name="page_y" value="">';
-
-print '<div class="cadre div-table-responsive-no-min"> '."\n";
-
-// Start to show survey result
-print '<table class="resultats">'."\n";
-
-//reformatage des données des sujets du sondage
-$toutsujet = explode(",", $object->sujet);
-$toutsujet = str_replace("°", "'", $toutsujet);
-
-print '<tr>'."\n";
-print '<td></td>'."\n";
-print '<td></td>'."\n";
-
-// loop to show the delete link
-if ($user->rights->opensurvey->write) {
-       for ($i = 0; isset($toutsujet[$i]); $i++) {
-               print '<td class=somme><input type="image" name="effacecolonne'.$i.'" src="'.img_picto('', 'delete.png', '', false, 1).'"></td>'."\n";
-       }
-}
-
-print '</tr>'."\n";
-
-
-// Show choice titles
-if ($object->format == "D") {
-       //affichage des sujets du sondage
-       print '<tr>'."\n";
-       print '<td></td>'."\n";
-       print '<td></td>'."\n";
-
-       //affichage des années
-       $colspan = 1;
-       $nbofsujet = count($toutsujet);
-       for ($i = 0; $i < $nbofsujet; $i++) {
-               if (isset($toutsujet[$i + 1]) && date('Y', intval($toutsujet[$i])) == date('Y', intval($toutsujet[$i + 1]))) {
-                       $colspan++;
-               } else {
-                       print '<td colspan='.$colspan.' class="annee">'.date('Y', intval($toutsujet[$i])).'</td>'."\n";
-                       $colspan = 1;
-               }
-       }
-
-       if ($user->rights->opensurvey->write) {
-               print '<td class="annee">';
-               print '<a href="'.$_SERVER["PHP_SELF"].'?ajoutsujet=1&id='.$object->id_sondage.'">'.$langs->trans("Add").'</a></td>'."\n";
-       }
-
-       print '</tr>'."\n";
-       print '<tr>'."\n";
-       print '<td></td>'."\n";
-       print '<td></td>'."\n";
-
-       //affichage des mois
-       $colspan = 1;
-       for ($i = 0; $i < $nbofsujet; $i++) {
-               $cur = intval($toutsujet[$i]); // intval() est utiliser pour supprimer le suffixe @* qui déplaît logiquement Ã  strftime()
-
-               if (isset($toutsujet[$i + 1]) === false) {
-                       $next = false;
-               } else {
-                       $next = intval($toutsujet[$i + 1]);
-               }
-
-               if ($next && dol_print_date($cur, "%B") == dol_print_date($next, "%B") && dol_print_date($cur, "%Y") == dol_print_date($next, "%Y")) {
-                       $colspan++;
-               } else {
-                       print '<td colspan='.$colspan.' class="mois">'.dol_print_date($cur, "%B").'</td>'."\n";
-
-                       $colspan = 1;
-               }
-       }
-
-       if ($user->rights->opensurvey->write) {
-               print '<td class="mois"><a href="'.$_SERVER["PHP_SELF"].'?ajoutsujet=1&id='.$object->id_sondage.'">'.$langs->trans("Add").'</a></td>'."\n";
-       }
-
-       print '</tr>'."\n";
-       print '<tr>'."\n";
-       print '<td></td>'."\n";
-       print '<td></td>'."\n";
-
-       //affichage des jours
-       $colspan = 1;
-       for ($i = 0; $i < $nbofsujet; $i++) {
-               $cur = intval($toutsujet[$i]);
-               if (isset($toutsujet[$i + 1]) === false) {
-                       $next = false;
-               } else {
-                       $next = intval($toutsujet[$i + 1]);
-               }
-               if ($next && dol_print_date($cur, "%a %e") == dol_print_date($next, "%a %e") && dol_print_date($cur, "%B") == dol_print_date($next, "%B")) {
-                       $colspan++;
-               } else {
-                       print '<td colspan='.$colspan.' class="jour">'.dol_print_date($cur, "%a %e").'</td>'."\n";
-
-                       $colspan = 1;
-               }
-       }
-
-       if ($user->rights->opensurvey->write) {
-               print '<td class="jour"><a href="'.$_SERVER["PHP_SELF"].'?ajoutsujet=1&id='.$object->id_sondage.'">'.$langs->trans("Add").'</a></td>'."\n";
-       }
-       print '</tr>'."\n";
-
-       //affichage des horaires
-       if (strpos($object->sujet, '@') !== false) {
-               print '<tr>'."\n";
-               print '<td></td>'."\n";
-               print '<td></td>'."\n";
-
-               for ($i = 0; isset($toutsujet[$i]); $i++) {
-                       $heures = explode('@', $toutsujet[$i]);
-                       if (isset($heures[1])) {
-                               print '<td class="heure">'.dol_htmlentities($heures[1]).'</td>'."\n";
-                       } else {
-                               print '<td class="heure"></td>'."\n";
-                       }
-               }
-
-               if ($user->rights->opensurvey->write) {
-                       print '<td class="heure"><a href="'.$_SERVER["PHP_SELF"].'?ajoutsujet=1&id='.$object->id_sondage.'">'.$langs->trans("Add").'</a></td>'."\n";
-               }
-
-               print '</tr>'."\n";
-       }
-} else {
-       // Show titles
-       print '<tr>'."\n";
-       print '<td></td>'."\n";
-       print '<td></td>'."\n";
-
-       for ($i = 0; isset($toutsujet[$i]); $i++) {
-               $tmp = explode('@', $toutsujet[$i]);
-               print '<td class="sujet">'.dol_htmlentities($tmp[0]).'</td>'."\n";
-       }
-
-       print '<td class="sujet"><a href="'.$_SERVER["PHP_SELF"].'?id='.$numsondage.'&ajoutsujet=1&backtopage='.urlencode($_SERVER["PHP_SELF"]).'"><span class="fa fa-plus-circle valignmiddle btnTitle-icon"></span></a></td>'."\n";
-       print '</tr>'."\n";
-}
-
-
-// Loop on each answer
-$sumfor = array();
-$sumagainst = array();
-$compteur = 0;
-$sql = "SELECT id_users, nom as name, id_sondage, reponses";
-$sql .= " FROM ".MAIN_DB_PREFIX."opensurvey_user_studs";
-$sql .= " WHERE id_sondage = '".$db->escape($numsondage)."'";
-dol_syslog('sql='.$sql);
-$resql = $db->query($sql);
-if (!$resql) {
-       dol_print_error($db);
-       exit;
-}
-$num = $db->num_rows($resql);
-while ($compteur < $num) {
-       $obj = $db->fetch_object($resql);
-
-       $ensemblereponses = $obj->reponses;
-
-       print '<tr><td>'."\n";
-
-       if ($user->rights->opensurvey->write) {
-               print '<input type="image" class="reposition" name="effaceligne'.$compteur.'" src="'.img_picto('', 'delete.png', '', false, 1).'">'."\n";
-       }
-
-       // Name
-       print '</td><td class="nom">'.dol_htmlentities($obj->name).'</td>'."\n";
-
-       // si la ligne n'est pas a changer, on affiche les données
-       if (!$testligneamodifier) {
-               for ($i = 0; $i < $nbcolonnes; $i++) {
-                       $car = substr($ensemblereponses, $i, 1);
-                       //print 'xx'.$i."-".$car.'-'.$listofanswers[$i]['format'].'zz';
-
-                       if (empty($listofanswers[$i]['format']) || !in_array($listofanswers[$i]['format'], array('yesno', 'foragainst'))) {
-                               if (((string) $car) == "1") {
-                                       print '<td class="ok">OK</td>'."\n";
-                               } else {
-                                       print '<td class="non">KO</td>'."\n";
-                               }
-                               // Total
-                               if (!isset($sumfor[$i])) {
-                                       $sumfor[$i] = 0;
-                               }
-                               if (((string) $car) == "1") {
-                                       $sumfor[$i]++;
-                               }
-                       }
-                       if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') {
-                               if (((string) $car) == "1") {
-                                       print '<td class="ok">'.$langs->trans("Yes").'</td>'."\n";
-                               } elseif (((string) $car) == "0") {
-                                       print '<td class="non">'.$langs->trans("No").'</td>'."\n";
-                               } else {
-                                       print '<td class="vide">&nbsp;</td>'."\n";
-                               }
-                               // Total
-                               if (!isset($sumfor[$i])) {
-                                       $sumfor[$i] = 0;
-                               }
-                               if (!isset($sumagainst[$i])) {
-                                       $sumagainst[$i] = 0;
-                               }
-                               if (((string) $car) == "1") {
-                                       $sumfor[$i]++;
-                               }
-                               if (((string) $car) == "0") {
-                                       $sumagainst[$i]++;
-                               }
-                       }
-                       if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') {
-                               if (((string) $car) == "1") {
-                                       print '<td class="ok">'.$langs->trans("For").'</td>'."\n";
-                               } elseif (((string) $car) == "0") {
-                                       print '<td class="non">'.$langs->trans("Against").'</td>'."\n";
-                               } else {
-                                       print '<td class="vide">&nbsp;</td>'."\n";
-                               }
-                               // Total
-                               if (!isset($sumfor[$i])) {
-                                       $sumfor[$i] = 0;
-                               }
-                               if (!isset($sumagainst[$i])) {
-                                       $sumagainst[$i] = 0;
-                               }
-                               if (((string) $car) == "1") {
-                                       $sumfor[$i]++;
-                               }
-                               if (((string) $car) == "0") {
-                                       $sumagainst[$i]++;
-                               }
-                       }
-               }
-       } else {
-               //sinon on remplace les choix de l'utilisateur par une ligne de checkbox pour recuperer de nouvelles valeurs
-               if ($compteur == $ligneamodifier) {
-                       for ($i = 0; $i < $nbcolonnes; $i++) {
-                               $car = substr($ensemblereponses, $i, 1);
-                               print '<td class="vide">';
-                               if (empty($listofanswers[$i]['format']) || !in_array($listofanswers[$i]['format'], array('yesno', 'foragainst'))) {
-                                       print '<input type="checkbox" name="choix'.$i.'" value="1" ';
-                                       if ($car == '1') {
-                                               print 'checked';
-                                       }
-                                       print '>';
-                               }
-                               if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') {
-                                       $arraychoice = array('2'=>'&nbsp;', '0'=>$langs->trans("No"), '1'=>$langs->trans("Yes"));
-                                       print $form->selectarray("choix".$i, $arraychoice, $car);
-                               }
-                               if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') {
-                                       $arraychoice = array('2'=>'&nbsp;', '0'=>$langs->trans("Against"), '1'=>$langs->trans("For"));
-                                       print $form->selectarray("choix".$i, $arraychoice, $car);
-                               }
-                               print '</td>'."\n";
-                       }
-               } else {
-                       for ($i = 0; $i < $nbcolonnes; $i++) {
-                               $car = substr($ensemblereponses, $i, 1);
-                               if (empty($listofanswers[$i]['format']) || !in_array($listofanswers[$i]['format'], array('yesno', 'foragainst'))) {
-                                       if (((string) $car) == "1") {
-                                               print '<td class="ok">OK</td>'."\n";
-                                       } else {
-                                               print '<td class="non">KO</td>'."\n";
-                                       }
-                                       // Total
-                                       if (!isset($sumfor[$i])) {
-                                               $sumfor[$i] = 0;
-                                       }
-                                       if (((string) $car) == "1") {
-                                               $sumfor[$i]++;
-                                       }
-                               }
-                               if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') {
-                                       if (((string) $car) == "1") {
-                                               print '<td class="ok">'.$langs->trans("For").'</td>'."\n";
-                                       } elseif (((string) $car) == "0") {
-                                               print '<td class="non">'.$langs->trans("Against").'</td>'."\n";
-                                       } else {
-                                               print '<td class="vide">&nbsp;</td>'."\n";
-                                       }
-                                       // Total
-                                       if (!isset($sumfor[$i])) {
-                                               $sumfor[$i] = 0;
-                                       }
-                                       if (!isset($sumagainst[$i])) {
-                                               $sumagainst[$i] = 0;
-                                       }
-                                       if (((string) $car) == "1") {
-                                               $sumfor[$i]++;
-                                       }
-                                       if (((string) $car) == "0") {
-                                               $sumagainst[$i]++;
-                                       }
-                               }
-                               if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') {
-                                       if (((string) $car) == "1") {
-                                               print '<td class="ok">'.$langs->trans("For").'</td>'."\n";
-                                       } elseif (((string) $car) == "0") {
-                                               print '<td class="non">'.$langs->trans("Against").'</td>'."\n";
-                                       } else {
-                                               print '<td class="vide">&nbsp;</td>'."\n";
-                                       }
-                                       // Total
-                                       if (!isset($sumfor[$i])) {
-                                               $sumfor[$i] = 0;
-                                       }
-                                       if (!isset($sumagainst[$i])) {
-                                               $sumagainst[$i] = 0;
-                                       }
-                                       if (((string) $car) == "1") {
-                                               $sumfor[$i]++;
-                                       }
-                                       if (((string) $car) == "0") {
-                                               $sumagainst[$i]++;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       // Button edit at end of line
-       if ($compteur != $ligneamodifier && ($user->rights->opensurvey->write)) {
-               print '<td class="casevide"><input type="submit" class="button reposition" name="modifierligne'.$compteur.'" value="'.dol_escape_htmltag($langs->trans("Edit")).'"></td>'."\n";
-       }
-
-       //demande de confirmation pour modification de ligne
-       for ($i = 0; $i < $nblines; $i++) {
-               if (GETPOSTISSET("modifierligne".$i)) {
-                       if ($compteur == $i) {
-                               print '<td class="casevide">';
-                               print '<input type="hidden" name="idtomodify'.$compteur.'" value="'.$obj->id_users.'">';
-                               print '<input type="submit" class="button button-save reposition" name="validermodifier'.$compteur.'" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
-                               print '</td>'."\n";
-                       }
-               }
-       }
-
-       $compteur++;
-       print '</tr>'."\n";
-}
-
-// Add line to add new record
-if (empty($testligneamodifier)) {
-       print '<tr>'."\n";
-       print '<td></td>'."\n";
-       print '<td class="nom">'."\n";
-       print '<input type="text" class="maxwidthonsmartphone" placeholder="'.dol_escape_htmltag($langs->trans("Name")).'" name="nom" maxlength="64">'."\n";
-       print '</td>'."\n";
-
-       for ($i = 0; $i < $nbcolonnes; $i++) {
-               print '<td class="vide">';
-               if (empty($listofanswers[$i]['format']) || !in_array($listofanswers[$i]['format'], array('yesno', 'foragainst'))) {
-                       print '<input type="checkbox" name="choix'.$i.'" value="1"';
-                       if (GETPOSTISSET('choix'.$i) && GETPOST('choix'.$i) == '1') {
-                               print ' checked';
-                       }
-                       print '>';
-               }
-               if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') {
-                       $arraychoice = array('2'=>'&nbsp;', '0'=>$langs->trans("No"), '1'=>$langs->trans("Yes"));
-                       print $form->selectarray("choix".$i, $arraychoice);
-               }
-               if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') {
-                       $arraychoice = array('2'=>'&nbsp;', '0'=>$langs->trans("Against"), '1'=>$langs->trans("For"));
-                       print $form->selectarray("choix".$i, $arraychoice);
-               }
-               print '</td>'."\n";
-       }
-
-       // Affichage du bouton de formulaire pour inscrire un nouvel utilisateur dans la base
-       print '<td><input type="image" name="boutonp" class="borderimp" value="'.$langs->trans("Vote").'" src="'.img_picto('', 'edit_add', '', false, 1).'"></td>'."\n";
-       print '</tr>'."\n";
-}
-
-// Select value of best choice (for checkbox columns only)
-$nbofcheckbox = 0;
-for ($i = 0; $i < $nbcolonnes + 1; $i++) {
-       if (empty($listofanswers[$i]['format']) || !in_array($listofanswers[$i]['format'], array('yesno', 'foragainst'))) {
-               $nbofcheckbox++;
-       }
-       if (isset($sumfor[$i])) {
-               if ($i == 0) {
-                       $meilleurecolonne = $sumfor[$i];
-               }
-               if (isset($sumfor[$i]) && $sumfor[$i] > $meilleurecolonne) {
-                       $meilleurecolonne = $sumfor[$i];
-               }
-       }
-}
-
-
-// Show line total
-print '<tr>'."\n";
-print '<td></td>'."\n";
-print '<td class="center">'.$langs->trans("Total").'</td>'."\n";
-for ($i = 0; $i < $nbcolonnes; $i++) {
-       $showsumfor = isset($sumfor[$i]) ? $sumfor[$i] : '';
-       $showsumagainst = isset($sumagainst[$i]) ? $sumagainst[$i] : '';
-       if (empty($showsumfor)) {
-               $showsumfor = 0;
-       }
-       if (empty($showsumagainst)) {
-               $showsumagainst = 0;
-       }
-
-       print '<td>';
-       if (empty($listofanswers[$i]['format']) || !in_array($listofanswers[$i]['format'], array('yesno', 'foragainst'))) {
-               print $showsumfor;
-       }
-       if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') {
-               print $langs->trans("Yes").': '.$showsumfor.'<br>'.$langs->trans("No").': '.$showsumagainst;
-       }
-       if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') {
-               print $langs->trans("For").': '.$showsumfor.'<br>'.$langs->trans("Against").': '.$showsumagainst;
-       }
-       print '</td>'."\n";
-}
-print '</tr>';
-// Show picto winner
-if ($nbofcheckbox >= 2) {
-       print '<tr>'."\n";
-       print '<td></td>'."\n";
-       print '<td></td>'."\n";
-       for ($i = 0; $i < $nbcolonnes; $i++) {
-               if (empty($listofanswers[$i]['format']) || !in_array($listofanswers[$i]['format'], array('yesno', 'foragainst')) && isset($sumfor[$i]) && isset($meilleurecolonne) && $sumfor[$i] == $meilleurecolonne) {
-                       print '<td class="somme"><img src="'.dol_buildpath('/opensurvey/img/medaille.png', 1).'"></td>'."\n";
-               } else {
-                       print '<td class="somme"></td>'."\n";
-               }
-       }
-       print '</tr>'."\n";
-}
-
-// S'il a oublié de remplir un nom
-if (GETPOSTISSET("boutonp") && GETPOST("nom") == "") {
-       setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Name")), null, 'errors');
-}
-
-if (isset($erreur_prenom) && $erreur_prenom) {
-       setEventMessages($langs->trans('VoteNameAlreadyExists'), null, 'errors');
-}
-
-if (isset($erreur_ajout_date) && $erreur_ajout_date) {
-       setEventMessages($langs->trans("ErrorWrongDate"), null, 'errors');
-}
-
-//fin du tableau
-print '</table>'."\n";
-print '</div>'."\n";
-
-
-$toutsujet = explode(",", $object->sujet); // With old versions, this field was not set
-
-$compteursujet = 0;
-$meilleursujet = '';
-for ($i = 0; $i < $nbcolonnes; $i++) {
-       if (isset($sumfor[$i]) === true && isset($meilleurecolonne) === true && $sumfor[$i] == $meilleurecolonne) {
-               $meilleursujet .= ($meilleursujet ? ", " : "");
-
-               if ($object->format == "D") {
-                       $meilleursujetexport = $toutsujet[$i];
-                       //var_dump($toutsujet);
-                       if (strpos($toutsujet[$i], '@') !== false) {
-                               $toutsujetdate = explode("@", $toutsujet[$i]);
-                               $meilleursujet .= dol_print_date($toutsujetdate[0], 'daytext').($toutsujetdate[0] ? ' ('.dol_print_date($toutsujetdate[0], '%A').')' : '').' - '.$toutsujetdate[1];
-                       } else {
-                               $meilleursujet .= dol_print_date((empty($toutsujet[$i]) ? 0 : $toutsujet[$i]), 'daytext').' ('.dol_print_date((empty($toutsujet[$i]) ? 0 : $toutsujet[$i]), '%A').')';
-                       }
-               } else {
-                       $tmps = explode('@', $toutsujet[$i]);
-                       $meilleursujet .= dol_htmlentities($tmps[0]);
-               }
-
-               $compteursujet++;
-       }
-}
-$meilleursujet = substr($meilleursujet, 1);
-$meilleursujet = str_replace("°", "'", $meilleursujet);
-
-// Show best choice
-if ($nbofcheckbox >= 2) {
-       $vote_str = $langs->trans('votes');
-       print '<p class="affichageresultats">'."\n";
-
-       if (isset($meilleurecolonne) && $compteursujet == "1") {
-               print "<img src=\"".DOL_URL_ROOT.'/opensurvey/img/medaille.png'."\"> ".$langs->trans('TheBestChoice').": <b>".$meilleursujet." </b>".$langs->trans("with")." <b>".$meilleurecolonne."</b> ".$vote_str.".\n";
-       } elseif (isset($meilleurecolonne)) {
-               print "<img src=\"".DOL_URL_ROOT.'/opensurvey/img/medaille.png'."\"> ".$langs->trans('TheBestChoices').": <b>".$meilleursujet." </b>".$langs->trans("with")." <b>".$meilleurecolonne."</b> ".$vote_str.".\n";
-       }
-       print '<br></p><br>'."\n";
-}
-
-print '</form>'."\n";
-
-print '<a name="bas"></a>'."\n";
-
-llxFooter();
-
-$db->close();
diff --git a/htdocs/opensurvey/wizard/choix_autre.php b/htdocs/opensurvey/wizard/choix_autre.php
deleted file mode 100644 (file)
index bbc13d5..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-<?php
-/* Copyright (C) 2013-2015 Laurent Destailleur <eldy@users.sourceforge.net>
- * Copyright (C) 2014      Marcos García       <marcosgdf@gmail.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file       htdocs/opensurvey/wizard/choix_autre.php
- *     \ingroup    opensurvey
- *     \brief      Page to create a new survey (choice selection)
- */
-
-// Load Dolibarr environment
-require '../../main.inc.php';
-require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
-require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
-require_once DOL_DOCUMENT_ROOT."/opensurvey/lib/opensurvey.lib.php";
-
-// Security check
-if (!$user->rights->opensurvey->write) {
-       accessforbidden();
-}
-
-
-
-/*
- * Action
- */
-
-$arrayofchoices = GETPOST('choix', 'array');
-$arrayoftypecolumn = GETPOST('typecolonne', 'array');
-
-// Set session vars
-if (isset($_SESSION["nbrecases"])) {
-       for ($i = 0; $i < $_SESSION["nbrecases"]; $i++) {
-               if (isset($arrayofchoices[$i])) {
-                       $_SESSION["choix".$i] = $arrayofchoices[$i];
-               }
-               if (isset($arrayoftypecolumn[$i])) {
-                       $_SESSION["typecolonne".$i] = $arrayoftypecolumn[$i];
-               }
-       }
-} else { //nombre de cases par défaut
-       $_SESSION["nbrecases"] = 5;
-}
-
-if (GETPOST("ajoutcases") || GETPOST("ajoutcases_x")) {
-       $_SESSION["nbrecases"] = $_SESSION["nbrecases"] + 5;
-}
-
-// Create survey into database
-if (GETPOSTISSET("confirmecreation")) {
-       //recuperation des données de champs textes
-       $toutchoix = '';
-       for ($i = 0; $i < $_SESSION["nbrecases"] + 1; $i++) {
-               if (!empty($arrayofchoices[$i])) {
-                       $toutchoix .= ',';
-                       $toutchoix .= str_replace(array(",", "@"), " ", $arrayofchoices[$i]).(empty($arrayoftypecolumn[$i]) ? '' : '@'.$arrayoftypecolumn[$i]);
-               }
-       }
-
-       $toutchoix = substr("$toutchoix", 1);
-       $_SESSION["toutchoix"] = $toutchoix;
-
-       //test de remplissage des cases
-       $testremplissage = '';
-       for ($i = 0; $i < $_SESSION["nbrecases"]; $i++) {
-               if (isset($arrayofchoices[$i])) {
-                       $testremplissage = "ok";
-               }
-       }
-
-       //message d'erreur si aucun champ renseigné
-       if ($testremplissage != "ok" || (!$toutchoix)) {
-               setEventMessages($langs->trans("ErrorOpenSurveyOneChoice"), null, 'errors');
-       } else {
-               //format du sondage AUTRE
-               $_SESSION["formatsondage"] = "A";
-
-               // Add into database
-               ajouter_sondage();
-       }
-}
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-$arrayofjs = array();
-$arrayofcss = array('/opensurvey/css/style.css');
-llxHeader('', $langs->trans("OpenSurvey"), "", '', 0, 0, $arrayofjs, $arrayofcss);
-
-if (empty($_SESSION['title'])) {
-       dol_print_error('', $langs->trans('ErrorOpenSurveyFillFirstSection'));
-       llxFooter();
-       exit;
-}
-
-
-//partie creation du sondage dans la base SQL
-//On prépare les données pour les inserer dans la base
-
-print '<form name="formulaire" action="#bas" method="POST">'."\n";
-print '<input type="hidden" name="token" value="'.newToken().'">';
-
-print load_fiche_titre($langs->trans("CreatePoll").' (2 / 2)');
-
-
-print '<br>'.$langs->trans("PollOnChoice").'<br><br>'."\n";
-
-print '<div class=corps>'."\n";
-print '<table>'."\n";
-
-//affichage des cases texte de formulaire
-for ($i = 0; $i < $_SESSION["nbrecases"]; $i++) {
-       $j = $i + 1;
-       if (isset($_SESSION["choix$i"]) === false) {
-               $_SESSION["choix$i"] = '';
-       }
-       print '<tr><td>'.$langs->trans("TitleChoice").' '.$j.': </td><td><input type="text" name="choix[]" size="40" maxlength="40" value="'.dol_escape_htmltag($_SESSION["choix$i"]).'" id="choix'.$i.'">';
-       $tmparray = array('checkbox'=>$langs->trans("CheckBox"), 'yesno'=>$langs->trans("YesNoList"), 'foragainst'=>$langs->trans("PourContreList"));
-       print ' &nbsp; '.$langs->trans("Type").' '.$form->selectarray("typecolonne[]", $tmparray, $_SESSION["typecolonne$i"]);
-       print '</td></tr>'."\n";
-}
-
-print '</table>'."\n";
-
-//ajout de cases supplementaires
-print '<table><tr>'."\n";
-print '<td>'.$langs->trans("5MoreChoices").'</td><td><input type="image" name="ajoutcases" src="../img/add-16.png"></td>'."\n";
-print '</tr></table>'."\n";
-print'<br>'."\n";
-
-print '<table><tr>'."\n";
-print '<td></td><td><input type="submit" class="button" name="confirmecreation" value="'.dol_escape_htmltag($langs->trans("CreatePoll")).'"></td>'."\n";
-print '</tr></table>'."\n";
-
-//fin du formulaire et bandeau de pied
-print '</form>'."\n";
-
-
-print '<a name=bas></a>'."\n";
-print '<br><br><br>'."\n";
-print '</div>'."\n";
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/opensurvey/wizard/choix_date.php b/htdocs/opensurvey/wizard/choix_date.php
deleted file mode 100644 (file)
index d8f89b1..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-<?php
-/* Copyright (C) 2013       Laurent Destailleur     <eldy@users.sourceforge.net>
- * Copyright (C) 2014       Marcos García           <marcosgdf@gmail.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file       htdocs/opensurvey/wizard/choix_date.php
- *     \ingroup    opensurvey
- *     \brief      Page to create a new survey (date selection)
- */
-
-// Load Dolibarr environment
-require '../../main.inc.php';
-require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
-require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
-require_once DOL_DOCUMENT_ROOT."/opensurvey/lib/opensurvey.lib.php";
-
-// Security check
-if (!$user->rights->opensurvey->write) {
-       accessforbidden();
-}
-
-// Survey type is DATE
-$_SESSION["formatsondage"] = "D";
-
-$erreur = false;
-$erreurNbchoice = 0;
-
-/*
- * Actions
- */
-
-// Insert survey
-if (GETPOST('confirmation')) {
-       // We save hours entered
-       if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true && issetAndNoEmpty('nbrecaseshoraires', $_SESSION) === true) {
-               $nbofchoice = count($_SESSION["totalchoixjour"]);
-               $errheure = array();
-
-               if ($nbofchoice * $_SESSION["nbrecaseshoraires"] > 200) {
-                       setEventMessages($langs->trans("ErrorFieldTooLong"), null, 'errors');
-                       $erreurNb++;
-               } else {
-                       for ($i = 0; $i < $nbofchoice; $i++) {
-                               // Show hours choices
-                               for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) {
-                                       $horairesi = GETPOST("horaires".$i);
-                                       $_SESSION["horaires$i"][$j] = $horairesi[$j];
-
-                                       $tmphorairesi = GETPOST('horaires'.$i, 'array');
-
-                                       if (!is_array($tmphorairesi)) {
-                                               $errheure[$i][$j] = true;
-                                               $erreur = true;
-                                               continue;
-                                       }
-
-                                       // A range like 8:00-11:00
-                                       $creneaux = array();
-                                       $heures = array();
-                                       if (preg_match("/(\d{1,2}:\d{2})-(\d{1,2}:\d{2})/", $tmphorairesi[$j], $creneaux)) {
-                                               //on recupere les deux parties du preg_match qu'on redécoupe autour des ":"
-                                               $debutcreneau = explode(":", $creneaux[1]);
-                                               $fincreneau = explode(":", $creneaux[2]);
-
-                                               //comparaison des heures de fin et de debut
-                                               //si correctes, on entre les données dans la variables de session
-                                               if ($debutcreneau[0] < 24 && $fincreneau[0] < 24 && $debutcreneau[1] < 60 && $fincreneau[1] < 60 && ($debutcreneau[0] < $fincreneau[0] || ($debutcreneau[0] == $fincreneau[0] && $debutcreneau[1] < $fincreneau[1]))) {
-                                                       $_SESSION["horaires$i"][$j] = $creneaux[1].'-'.$creneaux[2];
-                                               } else { //sinon message d'erreur et nettoyage de la case
-                                                       $errheure[$i][$j] = true;
-                                                       $erreur = true;
-                                               }
-                                       } elseif (preg_match(";^(\d{1,2}h\d{0,2})-(\d{1,2}h\d{0,2})$;i", $tmphorairesi[$j], $creneaux)) { //si c'est un creneau type 8h00-11h00
-                                               //on recupere les deux parties du preg_match qu'on redécoupe autour des "H"
-                                               $debutcreneau = preg_split("/h/i", $creneaux[1]);
-                                               $fincreneau = preg_split("/h/i", $creneaux[2]);
-
-                                               //comparaison des heures de fin et de debut
-                                               //si correctes, on entre les données dans la variables de session
-                                               if ($debutcreneau[0] < 24 && $fincreneau[0] < 24 && $debutcreneau[1] < 60 && $fincreneau[1] < 60 && ($debutcreneau[0] < $fincreneau[0] || ($debutcreneau[0] == $fincreneau[0] && $debutcreneau[1] < $fincreneau[1]))) {
-                                                       $_SESSION["horaires$i"][$j] = $creneaux[1].'-'.$creneaux[2];
-                                               } else { //sinon message d'erreur et nettoyage de la case
-                                                       $errheure[$i][$j] = true;
-                                                       $erreur = true;
-                                               }
-                                       } elseif (preg_match(";^(\d{1,2}):(\d{2})$;", $tmphorairesi[$j], $heures)) { //si c'est une heure simple type 8:00
-                                               //si valeures correctes, on entre les données dans la variables de session
-                                               if ($heures[1] < 24 && $heures[2] < 60) {
-                                                       $_SESSION["horaires$i"][$j] = $heures[0];
-                                               } else { //sinon message d'erreur et nettoyage de la case
-                                                       $errheure[$i][$j] = true;
-                                                       $erreur = true;
-                                               }
-                                       } elseif (preg_match(";^(\d{1,2})h(\d{0,2})$;i", $tmphorairesi[$j], $heures)) { //si c'est une heure encore plus simple type 8h
-                                               //si valeures correctes, on entre les données dans la variables de session
-                                               if ($heures[1] < 24 && $heures[2] < 60) {
-                                                       $_SESSION["horaires$i"][$j] = $heures[0];
-                                               } else { //sinon message d'erreur et nettoyage de la case
-                                                       $errheure[$i][$j] = true;
-                                                       $erreur = true;
-                                               }
-                                       } elseif (preg_match(";^(\d{1,2})-(\d{1,2})$;", $tmphorairesi[$j], $heures)) { //si c'est un creneau simple type 8-11
-                                               //si valeures correctes, on entre les données dans la variables de session
-                                               if ($heures[1] < $heures[2] && $heures[1] < 24 && $heures[2] < 24) {
-                                                       $_SESSION["horaires$i"][$j] = $heures[0];
-                                               } else { //sinon message d'erreur et nettoyage de la case
-                                                       $errheure[$i][$j] = true;
-                                                       $erreur = true;
-                                               }
-                                       } elseif (preg_match(";^(\d{1,2})h-(\d{1,2})h$;", $tmphorairesi[$j], $heures)) { //si c'est un creneau H type 8h-11h
-                                               //si valeures correctes, on entre les données dans la variables de session
-                                               if ($heures[1] < $heures[2] && $heures[1] < 24 && $heures[2] < 24) {
-                                                       $_SESSION["horaires$i"][$j] = $heures[0];
-                                               } else { //sinon message d'erreur et nettoyage de la case
-                                                       $errheure[$i][$j] = true;
-                                                       $erreur = true;
-                                               }
-                                       } elseif ($tmphorairesi[$j] == "") { //Si la case est vide
-                                               unset($_SESSION["horaires$i"][$j]);
-                                       } else { //pour tout autre format, message d'erreur
-                                               $errheure[$i][$j] = true;
-                                               $erreur = true;
-                                       }
-
-                                       if (issetAndNoEmpty('horaires'.$i, $_SESSION) === false || issetAndNoEmpty($j, $_SESSION['horaires'.$i]) === false) {
-                                               if (issetAndNoEmpty('horaires'.$i, $_SESSION) === true) {
-                                                       $_SESSION["horaires$i"][$j] = '';
-                                               } else {
-                                                       $_SESSION["horaires$i"] = array();
-                                                       $_SESSION["horaires$i"][$j] = '';
-                                               }
-                                       }
-                               }
-
-                               if ($_SESSION["horaires$i"][0] == "" && $_SESSION["horaires$i"][1] == "" && $_SESSION["horaires$i"][2] == "" && $_SESSION["horaires$i"][3] == "" && $_SESSION["horaires$i"][4] == "") {
-                                       $choixdate .= ",";
-                                       $choixdate .= $_SESSION["totalchoixjour"][$i];
-                               } else {
-                                       for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) {
-                                               if ($_SESSION["horaires$i"][$j] != "") {
-                                                       $choixdate .= ",";
-                                                       $choixdate .= $_SESSION["totalchoixjour"][$i];
-                                                       $choixdate .= "@";
-                                                       // On remplace la virgule et l'arobase pour ne pas avoir de problème par la suite
-                                                       $choixdate .= str_replace(array(',', '@'), array('&#44;', '&#64;'), $_SESSION["horaires$i"][$j]);
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-
-               if (!empty($errheure)) {
-                       setEventMessages($langs->trans("ErrorBadFormat"), null, 'errors');
-               }
-       }
-
-       //If just one day and no other time options, error message
-       $tmphoraires0 = GETPOST('horaires0', 'array');
-       if (count($_SESSION["totalchoixjour"]) == "1" && $tmphoraires0[0] == "" && $tmphoraires0[1] == "" && $tmphoraires0[2] == "" && $tmphoraires0[3] == "" && $tmphoraires0[4] == "") {
-               setEventMessages($langs->trans("MoreChoices"), null, 'errors');
-               $erreur = true;
-       }
-
-       // Add survey into database
-       if (!$erreur && $erreurNb == 0) {
-               $_SESSION["toutchoix"] = substr("$choixdate", 1);
-
-               ajouter_sondage();
-       }
-}
-
-// Reset days
-if (GETPOST('reset')) {
-       $nbofchoice = count($_SESSION["totalchoixjour"]);
-       for ($i = 0; $i < $nbofchoice; $i++) {
-               for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) {
-                       unset($_SESSION["horaires$i"][$j]);
-               }
-       }
-
-       unset($_SESSION["totalchoixjour"]);
-       unset($_SESSION["nbrecaseshoraires"]);
-}
-
-
-
-/*
- * View
- */
-
-if (!isset($_SESSION['description']) && !isset($_SESSION['mail'])) {
-       dol_print_error('', $langs->trans('ErrorOpenSurveyFillFirstSection'));
-       exit;
-}
-
-$arrayofjs = array();
-$arrayofcss = array('/opensurvey/css/style.css');
-llxHeader('', $langs->trans("OpenSurvey"), "", '', 0, 0, $arrayofjs, $arrayofcss);
-
-//nombre de cases par défaut
-if (!isset($_SESSION["nbrecaseshoraires"])) {
-       $_SESSION["nbrecaseshoraires"] = 5;
-} elseif (GETPOST('ajoutcases') && $_SESSION["nbrecaseshoraires"] == 5) {
-       $_SESSION["nbrecaseshoraires"] = 10;
-}
-
-//valeurs de la date du jour actuel
-$jourAJ = date("j");
-$moisAJ = date("n");
-$anneeAJ = date("Y");
-
-// Initialisation des jour, mois et année
-if (!isset($_SESSION['jour'])) {
-       $_SESSION['jour'] = date('j');
-}
-if (!isset($_SESSION['mois'])) {
-       $_SESSION['mois'] = date('n');
-}
-if (!isset($_SESSION['annee'])) {
-       $_SESSION['annee'] = date('Y');
-}
-
-//mise a jour des valeurs de session si bouton retour a aujourd'hui
-if (!issetAndNoEmpty('choixjourajout') && !issetAndNoEmpty('choixjourretrait') && (issetAndNoEmpty('retourmois') || issetAndNoEmpty('retourmois_x'))) {
-       $_SESSION["jour"] = date("j");
-       $_SESSION["mois"] = date("n");
-       $_SESSION["annee"] = date("Y");
-}
-
-//mise a jour des valeurs de session si mois avant
-if (issetAndNoEmpty('moisavant_x') || issetAndNoEmpty('moisavant')) {
-       if ($_SESSION["mois"] == 1) {
-               $_SESSION["mois"]   = 12;
-               $_SESSION["annee"]  = $_SESSION["annee"] - 1;
-       } else {
-               $_SESSION["mois"] -= 1;
-       }
-
-       //On sauvegarde les heures deja entrées
-       if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true) {
-               $nbofchoice = count($_SESSION["totalchoixjour"]);
-               for ($i = 0; $i < $nbofchoice; $i++) {
-                       //affichage des 5 cases horaires
-                       for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) {
-                               $horairesi = GETPOST("horaires".$i);
-                               $_SESSION["horaires$i"][$j] = $horairesi[$j];
-                       }
-               }
-       }
-}
-
-//mise a jour des valeurs de session si mois apres
-if (issetAndNoEmpty('moisapres_x') || issetAndNoEmpty('moisapres')) {
-       if ($_SESSION["mois"] == 12) {
-               $_SESSION["mois"] = 1;
-               $_SESSION["annee"] += 1;
-       } else {
-               $_SESSION["mois"] += 1;
-       }
-
-       //On sauvegarde les heures deja entrées
-       if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true) {
-               $nbofchoice = count($_SESSION["totalchoixjour"]);
-               for ($i = 0; $i < $nbofchoice; $i++) {
-                       //affichage des 5 cases horaires
-                       for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) {
-                               $horairesi = GETPOST("horaires".$i);
-                               $_SESSION["horaires$i"][$j] = $horairesi[$j];
-                       }
-               }
-       }
-}
-
-//mise a jour des valeurs de session si annee avant
-if (issetAndNoEmpty('anneeavant_x') || issetAndNoEmpty('anneeavant')) {
-       $_SESSION["annee"] -= 1;
-
-       //On sauvegarde les heures deja entrées
-       if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true) {
-               $nbofchoice = count($_SESSION["totalchoixjour"]);
-               for ($i = 0; $i < $nbofchoice; $i++) {
-                       //affichage des 5 cases horaires
-                       for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) {
-                               $horairesi = GETPOST("horaires".$i);
-                               $_SESSION["horaires$i"][$j] = $horairesi[$j];
-                       }
-               }
-       }
-}
-
-//mise a jour des valeurs de session si annee apres
-if (issetAndNoEmpty('anneeapres_x') || issetAndNoEmpty('anneeapres')) {
-       $_SESSION["annee"] += 1;
-
-       //On sauvegarde les heures deja entrées
-       if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true) {
-               $nbofchoice = count($_SESSION["totalchoixjour"]);
-               for ($i = 0; $i < $nbofchoice; $i++) {
-                       //affichage des 5 cases horaires
-                       for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) {
-                               $horairesi = GETPOST("horaires".$i);
-                               $_SESSION["horaires$i"][$j] = $horairesi[$j];
-                       }
-               }
-       }
-}
-
-//valeurs du nombre de jour dans le mois et du premier jour du mois
-$nbrejourmois = date("t", mktime(0, 0, 0, $_SESSION["mois"], 1, $_SESSION["annee"]));
-$premierjourmois = date("N", mktime(0, 0, 0, $_SESSION["mois"], 1, $_SESSION["annee"])) - 1;
-
-//traduction de la valeur du mois
-if (is_integer($_SESSION["mois"]) && $_SESSION["mois"] > 0 && $_SESSION["mois"] < 13) {
-       $motmois = dol_print_date(mktime(0, 0, 0, $_SESSION["mois"], 10), '%B');
-} else {
-       $motmois = dol_print_date(dol_now(), '%B');
-}
-
-
-//Debut du formulaire et bandeaux de tete
-print '<form name="formulaire" action="" method="POST">'."\n";
-print '<input type="hidden" name="token" value="'.newToken().'">';
-
-print load_fiche_titre($langs->trans("CreatePoll").' (2 / 2)');
-
-//affichage de l'aide pour les jours
-print '<div class="bodydate">'."\n";
-print $langs->trans("OpenSurveyStep2")."\n";
-print '</div>'."\n";
-
-//debut du tableau qui affiche le calendrier
-print '<div class="corps">'."\n";
-print '<div class="center">'."\n";
-print '<table align="center">'."\n"; // The div class=center has no effect on table, so we must keep the align=center for table
-print '<tr><td><input type="image" name="anneeavant" value="<<" src="../img/rewind.png"></td><td><input type="image" name="moisavant" value="<" src="../img/previous.png"></td>';
-print '<td width="150px" align="center"> '.$motmois.' '.$_SESSION["annee"].'<br>';
-print '<input type="image" name="retourmois" alt="'.dol_escape_htmltag($langs->trans("BackToCurrentMonth")).'" title="'.dol_escape_htmltag($langs->trans("BackToCurrentMonth")).'" value="" src="'.img_picto('', 'refresh', '', 0, 1).'">';
-print '</td><td><input type="image" name="moisapres" value=">" src="../img/next.png"></td>';
-print '<td><input type="image" name="anneeapres" value=">>" src="../img/fforward.png"></td><td></td><td></td><td></td><td></td><td></td><td>';
-print '</td></tr>'."\n";
-print '</table>'."\n";
-print '</div>'."\n";
-
-print '<div class="center calendrier">'."\n";
-print '<table align="center">'."\n"; // The div class=center has no effect on table, so we must keep the align=center for table
-print '<tr>'."\n";
-
-//affichage des jours de la semaine en haut du tableau
-for ($i = 0; $i < 7; $i++) {
-       print '<td align="center" class="joursemaine">'.dol_print_date(mktime(0, 0, 0, 0, $i, 10), '%A').'</td>';
-}
-
-print '</tr>'."\n";
-
-//ajout d'une entrée dans la variable de session qui contient toutes les dates
-if (issetAndNoEmpty('choixjourajout')) {
-       if (!isset($_SESSION["totalchoixjour"])) {
-               $_SESSION["totalchoixjour"] = array();
-       }
-
-       // Test pour Ã©viter les doublons dans la variable qui contient toutes les dates
-       $journeuf = true;
-       if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true && issetAndNoEmpty('choixjourajout') === true) {
-               $nbofchoice = count($_SESSION["totalchoixjour"]);
-               for ($i = 0; $i < $nbofchoice; $i++) {
-                       $choixjourajout = GETPOST("choixjourajout");
-                       if ($_SESSION["totalchoixjour"][$i] == mktime(0, 0, 0, $_SESSION["mois"], $choixjourajout[0], $_SESSION["annee"])) {
-                               $journeuf = false;
-                       }
-               }
-       }
-
-       // Si le test est passé, alors on insere la valeur dans la variable de session qui contient les dates
-       if ($journeuf && issetAndNoEmpty('choixjourajout') === true) {
-               $choixjourajout = GETPOST("choixjourajout");
-               array_push($_SESSION["totalchoixjour"], dol_mktime(0, 0, 0, $_SESSION["mois"], $choixjourajout[0], $_SESSION["annee"]));
-               sort($_SESSION["totalchoixjour"]);
-               $cle = array_search(dol_mktime(0, 0, 0, $_SESSION["mois"], $choixjourajout[0], $_SESSION["annee"]), $_SESSION["totalchoixjour"]);
-
-               //On sauvegarde les heures deja entrées
-               for ($i = 0; $i < $cle; $i++) {
-                       $horairesi = GETPOST("horaires".$i);
-                       for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) {
-                               if (issetAndNoEmpty('horaires'.$i) === true && issetAndNoEmpty($i, $_POST['horaires'.$i]) === true) {
-                                       $_SESSION["horaires$i"][$j] = $horairesi[$j];
-                               }
-                       }
-               }
-
-               $nbofchoice = count($_SESSION["totalchoixjour"]);
-               for ($i = $cle; $i < $nbofchoice; $i++) {
-                       $k = $i + 1;
-                       if (issetAndNoEmpty('horaires'.$i) === true && issetAndNoEmpty($i, $_POST['horaires'.$i]) === true) {
-                               for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) {
-                                       $horairesi = GETPOST("horaires".$i);
-                                       $_SESSION["horaires$i"][$j] = $horairesi[$j];
-                               }
-                       }
-               }
-
-               unset($_SESSION["horaires$cle"]);
-       }
-}
-
-//retrait d'une entrée dans la variable de session qui contient toutes les dates
-if (issetAndNoEmpty('choixjourretrait')) {
-       //On sauvegarde les heures deja entrées
-       $nbofchoice = count($_SESSION["totalchoixjour"]);
-       for ($i = 0; $i < $nbofchoice; $i++) {
-               //affichage des 5 cases horaires
-               for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) {
-                       $horairesi = GETPOST("horaires".$i);
-                       $_SESSION["horaires$i"][$j] = $horairesi[$j];
-               }
-       }
-
-       for ($i = 0; $i < $nbofchoice; $i++) {
-               $choixjourretrait = GETPOST('choixjourretrait');
-               if ($_SESSION["totalchoixjour"][$i] == mktime(0, 0, 0, $_SESSION["mois"], $choixjourretrait[0], $_SESSION["annee"])) {
-                       for ($j = $i; $j < $nbofchoice; $j++) {
-                               $k = $j + 1;
-                               $_SESSION["horaires$j"] = $_SESSION["horaires$k"];
-                       }
-
-                       array_splice($_SESSION["totalchoixjour"], $i, 1);
-               }
-       }
-}
-
-//report des horaires dans toutes les cases
-if (issetAndNoEmpty('reporterhoraires')) {
-       $_SESSION["horaires0"] = GETPOST("horaires0");
-       $nbofchoice = count($_SESSION["totalchoixjour"]);
-       for ($i = 0; $i < $nbofchoice; $i++) {
-               $j = $i + 1;
-               $_SESSION["horaires$j"] = $_SESSION["horaires$i"];
-       }
-}
-
-//report des horaires dans toutes les cases
-if (issetAndNoEmpty('resethoraires')) {
-       $nbofchoice = count($_SESSION["totalchoixjour"]);
-       for ($i = 0; $i < $nbofchoice; $i++) {
-               unset($_SESSION["horaires$i"]);
-       }
-}
-
-// affichage du calendrier
-print '<tr>'."\n";
-
-for ($i = 0; $i < $nbrejourmois + $premierjourmois; $i++) {
-       $numerojour = $i - $premierjourmois + 1;
-
-       // On saute a la ligne tous les 7 jours
-       if (($i % 7) == 0 && $i != 0) {
-               print '</tr><tr>'."\n";
-       }
-
-       // On affiche les jours precedants en gris et incliquables
-       if ($i < $premierjourmois) {
-               print '<td class="avant"></td>'."\n";
-       } else {
-               if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true) {
-                       $nbofchoice = count($_SESSION["totalchoixjour"]);
-                       for ($j = 0; $j < $nbofchoice; $j++) {
-                               // show red buttons
-                               if (date("j", $_SESSION["totalchoixjour"][$j]) == $numerojour && date("n", $_SESSION["totalchoixjour"][$j]) == $_SESSION["mois"] && date("Y", $_SESSION["totalchoixjour"][$j]) == $_SESSION["annee"]) {
-                                       print '<td align="center" class="choisi"><input type="submit" class="bouton OFF" name="choixjourretrait[]" value="'.$numerojour.'"></td>'."\n";
-                                       $dejafait = $numerojour;
-                               }
-                       }
-               }
-
-               // If no red button, we show green or grey button with number of day
-               if (isset($dejafait) === false || $dejafait != $numerojour) {
-                       // green button
-                       if (($numerojour >= $jourAJ && $_SESSION["mois"] == $moisAJ && $_SESSION["annee"] == $anneeAJ) || ($_SESSION["mois"] > $moisAJ && $_SESSION["annee"] == $anneeAJ) || $_SESSION["annee"] > $anneeAJ) {
-                               print '<td align="center" class="libre"><input type="submit" class="bouton ON" name="choixjourajout[]" value="'.$numerojour.'"></td>'."\n";
-                       } else {
-                               // grey button
-                               print '<td align="center" class="avant">'.$numerojour.'</td>'."\n";
-                       }
-               }
-       }
-}
-
-//fin du tableau
-print '</tr>'."\n";
-print '</table>'."\n";
-print '</div></div>'."\n";
-
-print '<div class="bodydate"><div class="center">'."\n";
-
-// affichage de tous les jours choisis
-if (issetAndNoEmpty('totalchoixjour', $_SESSION) || $erreur) {
-       //affichage des jours
-       print '<br>'."\n";
-       print '<div align="left">';
-       print '<strong>'.$langs->trans("SelectedDays").':</strong>'."<br>\n";
-       print $langs->trans("SelectDayDesc")."<br>\n";
-       print '</div><br>';
-
-       print '<table>'."\n";
-       print '<tr>'."\n";
-       print '<td></td>'."\n";
-
-       for ($i = 0; $i < $_SESSION["nbrecaseshoraires"]; $i++) {
-               $j = $i + 1;
-               print '<td classe="somme"><div class="center">'.$langs->trans("Time").' '.$j.'</div></td>'."\n";
-       }
-
-       if ($_SESSION["nbrecaseshoraires"] < 10) {
-               print '<td classe="somme"><input type="image" name="ajoutcases" src="../img/add-16.png"></td>'."\n";
-       }
-
-       print '</tr>'."\n";
-
-       //affichage de la liste des jours choisis
-       $nbofchoice = count($_SESSION["totalchoixjour"]);
-
-       for ($i = 0; $i < $nbofchoice; $i++) {
-               print '<tr>'."\n";
-               print '<td>'.dol_print_date($_SESSION["totalchoixjour"][$i], 'daytext').' ('.dol_print_date($_SESSION["totalchoixjour"][$i], '%A').')</td>';
-
-               //affichage des cases d'horaires
-               for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) {
-                       //si on voit une erreur, le fond de la case est rouge
-                       if (isset($errheure[$i][$j]) && $errheure[$i][$j]) {
-                               print '<td><input type=text size="10" maxlength="11" name=horaires'.$i.'[] value="'.$_SESSION["horaires$i"][$j].'" style="background-color:#FF6666;"></td>'."\n";
-                       } else {
-                               //sinon la case est vide normalement
-                               print '<td><input type=text size="10" maxlength="11" name=horaires'.$i.'[] value="'.$_SESSION["horaires$i"][$j].'"></td>'."\n";
-                       }
-               }
-               print '</tr>'."\n";
-       }
-
-       print '</table>'."\n";
-
-       // show buttons to cancel, delete days or create survey
-       print '<table>'."\n";
-       print '<tr>'."\n";
-       print '<td><input type="submit" class="button" name="reset" value="'.dol_escape_htmltag($langs->trans("RemoveAllDays")).'"></td><td><input type="submit" class="button" name="reporterhoraires" value="'.dol_escape_htmltag($langs->trans("CopyHoursOfFirstDay")).'"></td><td><input type="submit" class="button" name="resethoraires" value="'.dol_escape_htmltag($langs->trans("RemoveAllHours")).'"></td></tr>'."\n";
-       print'<tr><td colspan="3"><br><br></td></tr>'."\n";
-       print '<tr><td colspan="3" align="center"><input type="submit" class="button" name="confirmation" value="'.$langs->trans("CreatePoll").'"></td></tr>'."\n";
-       print '</table>'."\n";
-}
-
-print '</tr>'."\n";
-print '</table>'."\n";
-print '<a name=bas></a>'."\n";
-//fin du formulaire et bandeau de pied
-print '</form>'."\n";
-//bandeau de pied
-print '<br><br><br><br>'."\n";
-print '</div></div>'."\n";
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/opensurvey/wizard/create_survey.php b/htdocs/opensurvey/wizard/create_survey.php
deleted file mode 100644 (file)
index 48e6b56..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-<?php
-/* Copyright (C) 2013-2014 Laurent Destailleur <eldy@users.sourceforge.net>
- * Copyright (C) 2014      Marcos García       <marcosgdf@gmail.com>
- * Copyright (C) 2015-2016 Alexandre Spangaro  <aspangaro@open-dsi.fr>
- * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file       htdocs/opensurvey/wizard/create_survey.php
- *     \ingroup    opensurvey
- *     \brief      Page to create a new survey
- */
-
-// Load Dolibarr environment
-require '../../main.inc.php';
-require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
-require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
-require_once DOL_DOCUMENT_ROOT."/core/class/doleditor.class.php";
-require_once DOL_DOCUMENT_ROOT."/opensurvey/lib/opensurvey.lib.php";
-
-// Security check
-if (!$user->rights->opensurvey->write) {
-       accessforbidden();
-}
-
-$langs->load("opensurvey");
-
-$title = GETPOST('title');
-$description = GETPOST('description', 'restricthtml');
-$mailsonde = GETPOST('mailsonde');
-$creation_sondage_date = GETPOST('creation_sondage_date');
-$creation_sondage_autre = GETPOST('creation_sondage_autre');
-
-// We init some session variable to avoir warning
-$session_var = array('title', 'description', 'mailsonde');
-foreach ($session_var as $var) {
-       if (isset($_SESSION[$var])) {
-               $_SESSION[$var] = null;
-       }
-}
-
-// On initialise Ã©galement les autres variables
-$cocheplus = '';
-$cochemail = '';
-
-// Jump to correct page
-if (!empty($creation_sondage_date) || !empty($creation_sondage_autre)) {
-       $_SESSION["title"] = $title;
-       $_SESSION["description"] = $description;
-
-       if (GETPOST('mailsonde') == 'on') {
-               $_SESSION["mailsonde"] = true;
-       } else {
-               $_SESSION["mailsonde"] = false;
-       }
-
-       if (GETPOST('allow_comments') == 'on') {
-               $_SESSION['allow_comments'] = true;
-       } else {
-               $_SESSION['allow_comments'] = false;
-       }
-
-       if (GETPOST('allow_spy') == 'on') {
-               $_SESSION['allow_spy'] = true;
-       } else {
-               $_SESSION['allow_spy'] = false;
-       }
-
-       $testdate = false;
-       $champdatefin = dol_mktime(0, 0, 0, GETPOST('champdatefinmonth'), GETPOST('champdatefinday'), GETPOST('champdatefinyear'));
-
-       if ($champdatefin && ($champdatefin > 0)) {     // A date was provided
-               // Expire date is not before today
-               if ($champdatefin >= dol_now()) {
-                       $testdate = true;
-                       $_SESSION['champdatefin'] = dol_print_date($champdatefin, 'dayrfc');
-               } else {
-                       $testdate = true;
-                       $_SESSION['champdatefin'] = dol_print_date($champdatefin, 'dayrfc');
-                       //$testdate = false;
-                       //$_SESSION['champdatefin'] = dol_print_date($champdatefin,'dayrfc');
-                       setEventMessages('ExpireDate', null, 'warnings');
-               }
-       }
-
-       if (!$testdate) {
-               setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("ExpireDate")), null, 'errors');
-       }
-
-       if ($title && $testdate) {
-               if (!empty($creation_sondage_date)) {
-                       header("Location: choix_date.php");
-                       exit();
-               }
-
-               if (!empty($creation_sondage_autre)) {
-                       header("Location: choix_autre.php");
-                       exit();
-               }
-       }
-}
-
-
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-$arrayofjs = array();
-$arrayofcss = array('/opensurvey/css/style.css');
-llxHeader('', $langs->trans("OpenSurvey"), '', "", 0, 0, $arrayofjs, $arrayofcss);
-
-print load_fiche_titre($langs->trans("CreatePoll").' (1 / 2)');
-
-// debut du formulaire
-print '<form name="formulaire" action="" method="POST">'."\n";
-print '<input type="hidden" name="token" value="'.newToken().'">';
-
-print dol_get_fiche_head();
-
-// Affichage des différents champs textes a remplir
-print '<table class="border centpercent">'."\n";
-
-print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("PollTitle").'</td><td><input type="text" name="title" class="minwidth300" maxlength="80" value="'.$_SESSION["title"].'"></td>'."\n";
-if (!$_SESSION["title"] && (GETPOST('creation_sondage_date') || GETPOST('creation_sondage_autre'))) {
-       setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PollTitle")), null, 'errors');
-}
-
-print '</tr>'."\n";
-print '<tr><td>'.$langs->trans("Description").'</td><td>';
-$doleditor = new DolEditor('description', $_SESSION["description"], '', 120, 'dolibarr_notes', 'In', 1, 1, 1, ROWS_7, '90%');
-$doleditor->Create(0, '');
-print '</td>'."\n";
-print '</tr>'."\n";
-
-print '<tr><td class="fieldrequired">'.$langs->trans("ExpireDate").'</td><td>';
-
-print $form->selectDate($champdatefin ? $champdatefin : -1, 'champdatefin', '', '', '', "add", 1, 0);
-
-print '</tr>'."\n";
-print '</table>'."\n";
-
-print dol_get_fiche_end();
-
-//focus javascript sur le premier champ
-print '<script type="text/javascript">'."\n";
-print 'document.formulaire.title.focus();'."\n";
-print '</script>'."\n";
-
-print '<br>'."\n";
-
-// Check or not
-
-if ($_SESSION["mailsonde"]) {
-       $cochemail = "checked";
-}
-
-print '<input type="checkbox" id="mailsonde" name="mailsonde" '.$cochemail.'> <label for="mailsonde">'.$langs->trans("ToReceiveEMailForEachVote").'</label><br>'."\n";
-
-if ($_SESSION['allow_comments']) {
-       $allow_comments = 'checked';
-}
-if (GETPOSTISSET('allow_comments')) {
-       $allow_comments = GETPOST('allow_comments') ? 'checked' : '';
-}
-print '<input type="checkbox" id="allow_comments" name="allow_comments" '.$allow_comments.'"> <label for="allow_comments">'.$langs->trans('CanComment').'</label><br>'."\n";
-
-if ($_SESSION['allow_spy']) {
-       $allow_spy = 'checked';
-}
-if (GETPOSTISSET('allow_spy')) {
-       $allow_spy = GETPOST('allow_spy') ? 'checked' : '';
-}
-print '<input type="checkbox" id="allow_spy" name="allow_spy" '.$allow_spy.'> <label for="allow_spy">'.$langs->trans('CanSeeOthersVote').'</label><br>'."\n";
-
-if (GETPOST('choix_sondage')) {
-       if (GETPOST('choix_sondage') == 'date') {
-               print '<input type="hidden" name="creation_sondage_date" value="date">';
-       } else {
-               print '<input type="hidden" name="creation_sondage_autre" value="autre">';
-       }
-       print '<input type="hidden" name="choix_sondage" value="'.GETPOST('choix_sondage').'">';
-       print '<br><input type="submit" class="button" name="submit" value="'.$langs->trans("CreatePoll").' ('.(GETPOST('choix_sondage') == 'date' ? $langs->trans("TypeDate") : $langs->trans("TypeClassic")).')">';
-} else {
-       // Show image to selecte between date survey or other survey
-       print '<br><table>'."\n";
-       print '<tr><td>'.$langs->trans("CreateSurveyDate").'</td><td></td> '."\n";
-       print '<td><input type="image" name="creation_sondage_date" value="'.$langs->trans('CreateSurveyDate').'" src="../img/calendar-32.png"></td></tr>'."\n";
-       print '<tr><td>'.$langs->trans("CreateSurveyStandard").'</td><td></td> '."\n";
-       print '<td><input type="image" name="creation_sondage_autre" value="'.$langs->trans('CreateSurveyStandard').'" src="../img/chart-32.png"></td></tr>'."\n";
-       print '</table>'."\n";
-}
-print '<br><br><br>'."\n";
-print '</form>'."\n";
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/opensurvey/wizard/index.php b/htdocs/opensurvey/wizard/index.php
deleted file mode 100644 (file)
index b8ccd0d..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-<?php
-/* Copyright (C) 2013  Laurent Destailleur     <eldy@users.sourceforge.net>
- * Copyright (C) 2014  Marcos García          <marcosgdf@gmail.com>
- * Copyright (C) 2016  Regis Houssin           <regis.houssin@inodbox.com>
- * Copyright (C) 2019       Frédéric France     <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-
-if (!defined('NOTOKENRENEWAL')) {
-       define('NOTOKENRENEWAL', '1');
-}
-
-// Load Dolibarr environment
-require '../../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/opensurvey/lib/opensurvey.lib.php';
-
-// Security check
-if (!$user->rights->opensurvey->write) {
-       accessforbidden();
-}
-
-$langs->load("opensurvey");
-
-
-/*
- * View
- */
-
-$arrayofjs = array();
-$arrayofcss = array('/opensurvey/css/style.css');
-llxHeader('', $langs->trans("Survey"), '', "", 0, 0, $arrayofjs, $arrayofcss);
-
-print load_fiche_titre($langs->trans("CreatePoll"), '', 'poll');
-
-print '<form name="formulaire" action="create_survey.php" method="POST">';
-print '<input type="hidden" name="token" value="'.newToken().'">';
-print '<div class="center">';
-print '<p>'.$langs->trans("OrganizeYourMeetingEasily").'</p>';
-print '<div class="corps">';
-print '<br>';
-print '<div class="index_date">';
-print '<div><img class="opacity imgopensurveywizard" src="../img/date.png" onclick="document.formulaire.date.click()"></div>';
-print '<button id="date" name="choix_sondage" value="date" type="submit" class="button orange bigrounded"><img src="../img/calendar-32.png" alt="'.dol_escape_htmltag($langs->trans("CreateSurveyDate")).'" style="padding-right: 4px">'.dol_escape_htmltag($langs->trans("CreateSurveyDate")).'</button>';
-print '</div>';
-print '<div class="index_sondage">';
-print '<div><img class="opacity imgopensurveywizard" src="../img/sondage2.png" onclick="document.formulaire.autre.click()"></div>';
-print '<button id="autre" name="choix_sondage" value="autre" type="submit" class="button blue bigrounded"><img src="../img/chart-32.png" alt="'.dol_escape_htmltag($langs->trans("CreateSurveyStandard")).'" style="padding-right: 4px">'.dol_escape_htmltag($langs->trans("CreateSurveyStandard")).'</button>';
-print '</div>';
-print '<div style="clear:both;"></div>';
-print '</div>';
-print '</div></form>';
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/paybox/admin/paybox.php b/htdocs/paybox/admin/paybox.php
deleted file mode 100644 (file)
index 9b3a2a7..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-<?php
-/* Copyright (C) 2004      Rodolphe Quiedeville <rodolphe@quiedeville.org>
- * Copyright (C) 2005-2010 Laurent Destailleur  <eldy@users.sourceforge.org>
- * Copyright (C) 2011-2012 Juanjo Menent               <jmenent@2byte.es>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file       htdocs/paybox/admin/paybox.php
- * \ingroup    paybox
- * \brief      Page to setup paybox module
- */
-
-// Load Dolibarr environment
-require '../../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-
-$servicename = 'PayBox';
-
-// Load translation files required by the page
-$langs->loadLangs(array('admin', 'other', 'paybox', 'paypal', 'stripe'));
-
-if (!$user->admin) {
-       accessforbidden();
-}
-
-$action = GETPOST('action', 'aZ09');
-
-
-if ($action == 'setvalue' && $user->admin) {
-       $db->begin();
-       //$result=dolibarr_set_const($db, "PAYBOX_IBS_DEVISE", GETPOST("PAYBOX_IBS_DEVISE"),'chaine',0,'',$conf->entity);
-       $result = dolibarr_set_const($db, "PAYBOX_CGI_URL_V1", GETPOST('PAYBOX_CGI_URL_V1', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "PAYBOX_CGI_URL_V2", GETPOST('PAYBOX_CGI_URL_V2', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "PAYBOX_IBS_SITE", GETPOST('PAYBOX_IBS_SITE', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "PAYBOX_IBS_RANG", GETPOST('PAYBOX_IBS_RANG', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "PAYBOX_PBX_IDENTIFIANT", GETPOST('PAYBOX_PBX_IDENTIFIANT', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_CREDITOR", GETPOST('ONLINE_PAYMENT_CREDITOR', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "PAYBOX_BANK_ACCOUNT_FOR_PAYMENTS", GETPOST('PAYBOX_BANK_ACCOUNT_FOR_PAYMENTS', 'int'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_CSS_URL", GETPOST('ONLINE_PAYMENT_CSS_URL', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_MESSAGE_FORM", GETPOST('ONLINE_PAYMENT_MESSAGE_FORM', 'restricthtml'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_MESSAGE_OK", GETPOST('ONLINE_PAYMENT_MESSAGE_OK', 'restricthtml'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_MESSAGE_KO", GETPOST('ONLINE_PAYMENT_MESSAGE_KO', 'restricthtml'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_SENDEMAIL", GETPOST('ONLINE_PAYMENT_SENDEMAIL', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       // Payment token for URL
-       $result = dolibarr_set_const($db, "PAYMENT_SECURITY_TOKEN", GETPOST('PAYMENT_SECURITY_TOKEN', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "PAYMENT_SECURITY_TOKEN_UNIQUE", GETPOST('PAYMENT_SECURITY_TOKEN_UNIQUE', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-               $result = dolibarr_set_const($db, "PAYBOX_HMAC_KEY", dol_encode(GETPOST('PAYBOX_HMAC_KEY', 'alpha')), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-
-
-       if (!$error) {
-               $db->commit();
-               setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
-       } else {
-               $db->rollback();
-               dol_print_error($db);
-       }
-}
-
-
-/*
- *     View
- */
-
-$IBS_SITE = "1999888"; // Site test
-if (empty($conf->global->PAYBOX_IBS_SITE)) {
-       $conf->global->PAYBOX_IBS_SITE = $IBS_SITE;
-}
-$IBS_RANG = "99"; // Rang test
-if (empty($conf->global->PAYBOX_IBS_RANG)) {
-       $conf->global->PAYBOX_IBS_RANG = $IBS_RANG;
-}
-$IBS_DEVISE = "978"; // Euro
-if (empty($conf->global->PAYBOX_IBS_DEVISE)) {
-       $conf->global->PAYBOX_IBS_DEVISE = $IBS_DEVISE;
-}
-
-llxHeader();
-
-$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
-print load_fiche_titre($langs->trans("PayBoxSetup"), $linkback, 'title_setup');
-
-$h = 0;
-$head = array();
-
-$head[$h][0] = DOL_URL_ROOT."/paybox/admin/paybox.php";
-$head[$h][1] = $langs->trans("PayBox");
-$head[$h][2] = 'payboxaccount';
-$h++;
-
-print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
-print '<input type="hidden" name="token" value="'.newToken().'">';
-print '<input type="hidden" name="action" value="setvalue">';
-
-print dol_get_fiche_head($head, 'payboxaccount', '', -1);
-
-print $langs->trans("PayBoxDesc")."<br>\n";
-print '<br>';
-
-print '<table class="noborder centpercent">';
-print '<tr class="liste_titre">';
-print '<td>'.$langs->trans("AccountParameter").'</td>';
-print '<td>'.$langs->trans("Value").'</td>';
-print "</tr>\n";
-
-
-print '<tr class="oddeven"><td>';
-print '<span class="fieldrequired">'.$langs->trans("PAYBOX_PBX_SITE").'</span></td><td>';
-print '<input size="32" type="text" name="PAYBOX_IBS_SITE" value="'.$conf->global->PAYBOX_IBS_SITE.'">';
-print '<span class="opacitymedium"><br>'.$langs->trans("Example").': 1999888 ('.$langs->trans("Test").')</span>';
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td>';
-print '<span class="fieldrequired">'.$langs->trans("PAYBOX_PBX_RANG").'</span></td><td>';
-print '<input size="32" type="text" name="PAYBOX_IBS_RANG" value="'.$conf->global->PAYBOX_IBS_RANG.'">';
-print '<span class="opacitymedium"><br>'.$langs->trans("Example").': 99 ('.$langs->trans("Test").')</span>';
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td>';
-print '<span class="fieldrequired">'.$langs->trans("PAYBOX_PBX_IDENTIFIANT").'</span></td><td>';
-print '<input size="32" type="text" name="PAYBOX_PBX_IDENTIFIANT" value="'.$conf->global->PAYBOX_PBX_IDENTIFIANT.'">';
-print '<span class="opacitymedium"><br>'.$langs->trans("Example").': 2 ('.$langs->trans("Test").')</span>';
-print '</td></tr>';
-
-print '<tr class="oddeven"><td>';
-print '<span class="fieldrequired">'.$langs->trans("PAYBOX_HMAC_KEY").'</span></td><td>';
-print '<input size="100" type="text" name="PAYBOX_HMAC_KEY" value="'.dol_decode($conf->global->PAYBOX_HMAC_KEY).'">';
-print '<span class="opacitymedium"><br>'.$langs->trans("Example").': 1A2B3C4D5E6F</span>';
-print '</td></tr>';
-
-print '<tr class="liste_titre">';
-print '<td>'.$langs->trans("UsageParameter").'</td>';
-print '<td>'.$langs->trans("Value").'</td>';
-print "</tr>\n";
-
-/*
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("PAYBOX_IBS_DEVISE").'</td><td>';
-print '<input size="32" type="text" name="PAYBOX_IBS_DEVISE" value="'.$conf->global->PAYBOX_IBS_DEVISE.'">';
-print '<br>'.$langs->trans("Example").': 978 (EUR)';
-print '</td></tr>';
-*/
-
-/*
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("PAYBOX_CGI_URL_V1").'</td><td>';
-print '<input size="64" type="text" name="PAYBOX_CGI_URL_V1" value="'.$conf->global->PAYBOX_CGI_URL_V1.'">';
-print '<br>'.$langs->trans("Example").': http://mysite/cgi-bin/module_linux.cgi';
-print '</td></tr>';
-*/
-
-
-print '<tr class="oddeven"><td>';
-print '<span class="fieldrequired">'.$langs->trans("PAYBOX_CGI_URL_V2").'</span></td><td>';
-print '<input size="64" type="text" name="PAYBOX_CGI_URL_V2" value="'.$conf->global->PAYBOX_CGI_URL_V2.'">';
-print '<span class="opacitymedium"><br>'.$langs->trans("Example").' (preprod): https://preprod-tpeweb.paybox.com/php/';
-print '<br>'.$langs->trans("Example").' (prod): https://tpeweb.paybox.com/php/</span>';
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("PublicVendorName").'</td><td>';
-print '<input type="text" class="minwidth300" name="ONLINE_PAYMENT_CREDITOR" value="'.$conf->global->ONLINE_PAYMENT_CREDITOR.'">';
-print '<br><span class="opacitymedium">'.$langs->trans("Example").': '.$mysoc->name.'</span>';
-print '</td></tr>';
-
-
-if (isModEnabled("banque")) {
-       print '<tr class="oddeven"><td>';
-       print $langs->trans("BankAccount").'</td><td>';
-       $form->select_comptes($conf->global->PAYBOX_BANK_ACCOUNT_FOR_PAYMENTS, 'PAYBOX_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1);
-       print '</td></tr>';
-}
-
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("CSSUrlForPaymentForm").'</td><td>';
-print '<input size="64" type="text" name="ONLINE_PAYMENT_CSS_URL" value="'.$conf->global->ONLINE_PAYMENT_CSS_URL.'">';
-print '<span class="opacitymedium"><br>'.$langs->trans("Example").': http://mysite/mycss.css</span>';
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("MessageForm").'</td><td>';
-$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_FORM', $conf->global->ONLINE_PAYMENT_MESSAGE_FORM, '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_2, '90%');
-$doleditor->Create();
-print '</td></tr>';
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("MessageOK").'</td><td>';
-$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_OK', $conf->global->ONLINE_PAYMENT_MESSAGE_OK, '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_2, '90%');
-$doleditor->Create();
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("MessageKO").'</td><td>';
-$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_KO', $conf->global->ONLINE_PAYMENT_MESSAGE_KO, '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_2, '90%');
-$doleditor->Create();
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td class="fieldrequired">';
-print $langs->trans("ONLINE_PAYMENT_SENDEMAIL").'</td><td>';
-print '<input size="32" type="text" name="ONLINE_PAYMENT_SENDEMAIL" value="'.$conf->global->ONLINE_PAYMENT_SENDEMAIL.'">';
-print ' &nbsp; <span class="opacitymedium">'.$langs->trans("Example").': myemail@myserver.com, Payment service &lt;myemail2@myserver2.com&gt;</span>';
-print '</td></tr>';
-
-// Payment token for URL
-print '<tr class="oddeven"><td>';
-print $langs->trans("SecurityToken").'</td><td>';
-print '<input size="48" type="text" id="PAYMENT_SECURITY_TOKEN" name="PAYMENT_SECURITY_TOKEN" value="'.$conf->global->PAYMENT_SECURITY_TOKEN.'">';
-if (!empty($conf->use_javascript_ajax)) {
-       print '&nbsp;'.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token" class="linkobject"');
-}
-print '</td></tr>';
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("SecurityTokenIsUnique").'</td><td>';
-print $form->selectyesno("PAYMENT_SECURITY_TOKEN_UNIQUE", (empty($conf->global->PAYMENT_SECURITY_TOKEN) ? 0 : $conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE), 1);
-print '</td></tr>';
-
-print '</table>';
-
-print dol_get_fiche_end();
-
-print $form->buttonsSaveCancel("Modify", '');
-
-print '</form>';
-
-print '<br><br>';
-
-include DOL_DOCUMENT_ROOT.'/core/tpl/onlinepaymentlinks.tpl.php';
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/paybox/img/object_paybox.png b/htdocs/paybox/img/object_paybox.png
deleted file mode 100644 (file)
index 4bd819f..0000000
Binary files a/htdocs/paybox/img/object_paybox.png and /dev/null differ
diff --git a/htdocs/paybox/lib/paybox.lib.php b/htdocs/paybox/lib/paybox.lib.php
deleted file mode 100644 (file)
index 7f41d45..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-<?php
-/* Copyright (C) 2008-2009 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2005-2007 Regis Houssin        <regis.houssin@inodbox.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file                   htdocs/paybox/lib/paybox.lib.php
- *     \ingroup                paybox
- *  \brief                     Library for common paybox functions
- */
-
-
-
-
-/**
- * Create a redirect form to paybox form
- *
- * @param      int     $PRICE          Price
- * @param   string     $CURRENCY       Currency
- * @param   string     $EMAIL          EMail
- * @param   string     $urlok          Url to go back if payment is OK
- * @param   string     $urlko          Url to go back if payment is KO
- * @param   string     $TAG            Full tag
- * @return  int                1 if OK, -1 if ERROR
- */
-function print_paybox_redirect($PRICE, $CURRENCY, $EMAIL, $urlok, $urlko, $TAG)
-{
-       global $conf, $langs, $db;
-
-       dol_syslog("Paybox.lib::print_paybox_redirect", LOG_DEBUG);
-
-       // Clean parameters
-       $PBX_IDENTIFIANT = "2"; // Identifiant pour v2 test
-       if (!empty($conf->global->PAYBOX_PBX_IDENTIFIANT)) {
-               $PBX_IDENTIFIANT = $conf->global->PAYBOX_PBX_IDENTIFIANT;
-       }
-       $IBS_SITE = "1999888"; // Site test
-       if (!empty($conf->global->PAYBOX_IBS_SITE)) {
-               $IBS_SITE = $conf->global->PAYBOX_IBS_SITE;
-       }
-       $IBS_RANG = "99"; // Rang test
-       if (!empty($conf->global->PAYBOX_IBS_RANG)) {
-               $IBS_RANG = $conf->global->PAYBOX_IBS_RANG;
-       }
-       $IBS_DEVISE = "840"; // Currency (Dollar US by default)
-       if ($CURRENCY == 'EUR') {
-               $IBS_DEVISE = "978";
-       }
-       if ($CURRENCY == 'USD') {
-               $IBS_DEVISE = "840";
-       }
-
-       $URLPAYBOX = "";
-       if ($conf->global->PAYBOX_CGI_URL_V1) {
-               $URLPAYBOX = $conf->global->PAYBOX_CGI_URL_V1;
-       }
-       if ($conf->global->PAYBOX_CGI_URL_V2) {
-               $URLPAYBOX = $conf->global->PAYBOX_CGI_URL_V2;
-       }
-
-       if (empty($IBS_DEVISE)) {
-               dol_print_error('', "Paybox setup param PAYBOX_IBS_DEVISE not defined");
-               return -1;
-       }
-       if (empty($URLPAYBOX)) {
-               dol_print_error('', "Paybox setup param PAYBOX_CGI_URL_V1 and PAYBOX_CGI_URL_V2 undefined");
-               return -1;
-       }
-       if (empty($IBS_SITE)) {
-               dol_print_error('', "Paybox setup param PAYBOX_IBS_SITE not defined");
-               return -1;
-       }
-       if (empty($IBS_RANG)) {
-               dol_print_error('', "Paybox setup param PAYBOX_IBS_RANG not defined");
-               return -1;
-       }
-
-       $conf->global->PAYBOX_HASH = 'sha512';
-
-       // Definition des parametres vente produit pour paybox
-       $IBS_CMD = $TAG;
-       $IBS_TOTAL = $PRICE * 100; // En centimes
-       $IBS_MODE = 1; // Mode formulaire
-       $IBS_PORTEUR = $EMAIL;
-       $IBS_RETOUR = "montant:M;ref:R;auto:A;trans:T"; // Format des parametres du get de validation en reponse (url a definir sous paybox)
-       $IBS_TXT = ' '; // Use a space
-       $IBS_EFFECTUE = $urlok;
-       $IBS_ANNULE = $urlko;
-       $IBS_REFUSE = $urlko;
-       $IBS_BKGD = "#FFFFFF";
-       $IBS_WAIT = "2000";
-       $IBS_LANG = "GBR"; // By default GBR=english (FRA, GBR, ESP, ITA et DEU...)
-       if (preg_match('/^FR/i', $langs->defaultlang)) {
-               $IBS_LANG = "FRA";
-       }
-       if (preg_match('/^ES/i', $langs->defaultlang)) {
-               $IBS_LANG = "ESP";
-       }
-       if (preg_match('/^IT/i', $langs->defaultlang)) {
-               $IBS_LANG = "ITA";
-       }
-       if (preg_match('/^DE/i', $langs->defaultlang)) {
-               $IBS_LANG = "DEU";
-       }
-       if (preg_match('/^NL/i', $langs->defaultlang)) {
-               $IBS_LANG = "NLD";
-       }
-       if (preg_match('/^SE/i', $langs->defaultlang)) {
-               $IBS_LANG = "SWE";
-       }
-       $IBS_OUTPUT = 'E';
-       $PBX_SOURCE = 'HTML';
-       $PBX_TYPEPAIEMENT = 'CARTE';
-       $PBX_HASH = $conf->global->PAYBOX_HASH;
-       $PBX_TIME = dol_print_date(dol_now(), 'dayhourrfc', 'gmt');
-
-       $msg = "PBX_IDENTIFIANT=".$PBX_IDENTIFIANT.
-                  "&PBX_MODE=".$IBS_MODE.
-                  "&PBX_SITE=".$IBS_SITE.
-                  "&PBX_RANG=".$IBS_RANG.
-                  "&PBX_TOTAL=".$IBS_TOTAL.
-                  "&PBX_DEVISE=".$IBS_DEVISE.
-                  "&PBX_CMD=".$IBS_CMD.
-                  "&PBX_PORTEUR=".$IBS_PORTEUR.
-                  "&PBX_RETOUR=".$IBS_RETOUR.
-                  "&PBX_EFFECTUE=".$IBS_EFFECTUE.
-                  "&PBX_ANNULE=".$IBS_ANNULE.
-                  "&PBX_REFUSE=".$IBS_REFUSE.
-                  "&PBX_TXT=".$IBS_TXT.
-                  "&PBX_BKGD=".$IBS_BKGD.
-                  "&PBX_WAIT=".$IBS_WAIT.
-                  "&PBX_LANGUE=".$IBS_LANG.
-                  "&PBX_OUTPUT=".$IBS_OUTPUT.
-                  "&PBX_SOURCE=".$PBX_SOURCE.
-                  "&PBX_TYPEPAIEMENT=".$PBX_TYPEPAIEMENT;
-                  "&PBX_HASH=".$PBX_HASH;
-                  "&PBX_TIME=".$PBX_TIME;
-
-       $binKey = pack("H*", dol_decode($conf->global->PAYBOX_HMAC_KEY));
-
-       $hmac = strtoupper(hash_hmac($PBX_HASH, $msg, $binKey));
-
-
-       dol_syslog("Soumission Paybox", LOG_DEBUG);
-       dol_syslog("IBS_MODE: $IBS_MODE", LOG_DEBUG);
-       dol_syslog("IBS_SITE: $IBS_SITE", LOG_DEBUG);
-       dol_syslog("IBS_RANG: $IBS_RANG", LOG_DEBUG);
-       dol_syslog("IBS_TOTAL: $IBS_TOTAL", LOG_DEBUG);
-       dol_syslog("IBS_DEVISE: $IBS_DEVISE", LOG_DEBUG);
-       dol_syslog("IBS_CMD: $IBS_CMD", LOG_DEBUG);
-       dol_syslog("IBS_PORTEUR: $IBS_PORTEUR", LOG_DEBUG);
-       dol_syslog("IBS_RETOUR: $IBS_RETOUR", LOG_DEBUG);
-       dol_syslog("IBS_EFFECTUE: $IBS_EFFECTUE", LOG_DEBUG);
-       dol_syslog("IBS_ANNULE: $IBS_ANNULE", LOG_DEBUG);
-       dol_syslog("IBS_REFUSE: $IBS_REFUSE", LOG_DEBUG);
-       dol_syslog("IBS_BKGD: $IBS_BKGD", LOG_DEBUG);
-       dol_syslog("IBS_WAIT: $IBS_WAIT", LOG_DEBUG);
-       dol_syslog("IBS_LANG: $IBS_LANG", LOG_DEBUG);
-       dol_syslog("IBS_OUTPUT: $IBS_OUTPUT", LOG_DEBUG);
-       dol_syslog("PBX_IDENTIFIANT: $PBX_IDENTIFIANT", LOG_DEBUG);
-       dol_syslog("PBX_SOURCE: $PBX_SOURCE", LOG_DEBUG);
-       dol_syslog("PBX_TYPEPAIEMENT: $PBX_TYPEPAIEMENT", LOG_DEBUG);
-       dol_syslog("PBX_HASH: $PBX_HASH", LOG_DEBUG);
-       dol_syslog("PBX_TIME: $PBX_TIME", LOG_DEBUG);
-
-       header("Content-type: text/html; charset=".$conf->file->character_set_client);
-       header("X-Content-Type-Options: nosniff");
-
-       print '<html>'."\n";
-       print '<head>'."\n";
-       print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=".$conf->file->character_set_client."\">\n";
-       print '</head>'."\n";
-       print '<body>'."\n";
-       print "\n";
-
-       // Formulaire pour module Paybox
-       print '<form action="'.$URLPAYBOX.'" NAME="Submit" method="POST">'."\n";
-
-       // For Paybox V2 (PBX_xxx)
-       print '<!-- Param for Paybox v2 -->'."\n";
-       print '<input type="hidden" name="PBX_IDENTIFIANT" value="'.$PBX_IDENTIFIANT.'">'."\n";
-       print '<input type="hidden" name="PBX_MODE" value="'.$IBS_MODE.'">'."\n";
-       print '<input type="hidden" name="PBX_SITE" value="'.$IBS_SITE.'">'."\n";
-       print '<input type="hidden" name="PBX_RANG" value="'.$IBS_RANG.'">'."\n";
-       print '<input type="hidden" name="PBX_TOTAL" value="'.$IBS_TOTAL.'">'."\n";
-       print '<input type="hidden" name="PBX_DEVISE" value="'.$IBS_DEVISE.'">'."\n";
-       print '<input type="hidden" name="PBX_CMD" value="'.$IBS_CMD.'">'."\n";
-       print '<input type="hidden" name="PBX_PORTEUR" value="'.$IBS_PORTEUR.'">'."\n";
-       print '<input type="hidden" name="PBX_RETOUR" value="'.$IBS_RETOUR.'">'."\n";
-       print '<input type="hidden" name="PBX_EFFECTUE" value="'.$IBS_EFFECTUE.'">'."\n";
-       print '<input type="hidden" name="PBX_ANNULE" value="'.$IBS_ANNULE.'">'."\n";
-       print '<input type="hidden" name="PBX_REFUSE" value="'.$IBS_REFUSE.'">'."\n";
-       print '<input type="hidden" name="PBX_TXT" value="'.$IBS_TXT.'">'."\n";
-       print '<input type="hidden" name="PBX_BKGD" value="'.$IBS_BKGD.'">'."\n";
-       print '<input type="hidden" name="PBX_WAIT" value="'.$IBS_WAIT.'">'."\n";
-       print '<input type="hidden" name="PBX_LANGUE" value="'.$IBS_LANG.'">'."\n";
-       print '<input type="hidden" name="PBX_OUTPUT" value="'.$IBS_OUTPUT.'">'."\n";
-       print '<input type="hidden" name="PBX_SOURCE" value="'.$PBX_SOURCE.'">'."\n";
-       print '<input type="hidden" name="PBX_TYPEPAIEMENT" value="'.$PBX_TYPEPAIEMENT.'">'."\n";
-       print '<input type="hidden" name="PBX_HASH" value="'.$PBX_HASH.'">'."\n";
-       print '<input type="hidden" name="PBX_TIME" value="'.$PBX_TIME.'">'."\n";
-       // Footprint of parameters
-       print '<input type="hidden" name="PBX_HMAC" value="'.$hmac.'">'."\n";
-       print '</form>'."\n";
-
-
-       print "\n";
-       print '<script type="text/javascript">'."\n";
-       print ' document.Submit.submit();'."\n";
-       print '</script>'."\n";
-       print "\n";
-       print '</body></html>'."\n";
-       print "\n";
-
-       return;
-}
diff --git a/htdocs/paypal/admin/paypal.php b/htdocs/paypal/admin/paypal.php
deleted file mode 100644 (file)
index 68759ee..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
-<?php
-/* Copyright (C) 2004          Rodolphe Quiedeville    <rodolphe@quiedeville.org>
- * Copyright (C) 2005-2013     Laurent Destailleur             <eldy@users.sourceforge.org>
- * Copyright (C) 2011-2012     Regis Houssin                   <regis.houssin@inodbox.com>
- * Copyright (C) 2011-2012  Juanjo Menent                      <jmenent@2byte.es>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file       htdocs/paypal/admin/paypal.php
- * \ingroup    paypal
- * \brief      Page to setup paypal module
- */
-
-// Load Dolibarr environment
-require '../../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-
-$servicename = 'PayPal';
-
-// Load translation files required by the page
-$langs->loadLangs(array('admin', 'other', 'paypal', 'paybox', 'stripe'));
-
-if (!$user->admin) {
-       accessforbidden();
-}
-
-$action = GETPOST('action', 'aZ09');
-
-if ($action == 'setvalue' && $user->admin) {
-       $db->begin();
-
-       $result = dolibarr_set_const($db, "PAYPAL_API_USER", GETPOST('PAYPAL_API_USER', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "PAYPAL_API_PASSWORD", GETPOST('PAYPAL_API_PASSWORD', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "PAYPAL_API_SIGNATURE", GETPOST('PAYPAL_API_SIGNATURE', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "PAYPAL_SSLVERSION", GETPOST('PAYPAL_SSLVERSION', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_CREDITOR", GETPOST('ONLINE_PAYMENT_CREDITOR', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS", GETPOST('PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS', 'int'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "PAYPAL_API_INTEGRAL_OR_PAYPALONLY", GETPOST('PAYPAL_API_INTEGRAL_OR_PAYPALONLY', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_CSS_URL", GETPOST('ONLINE_PAYMENT_CSS_URL', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "PAYPAL_ADD_PAYMENT_URL", GETPOST('PAYPAL_ADD_PAYMENT_URL', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_MESSAGE_FORM", GETPOST('ONLINE_PAYMENT_MESSAGE_FORM', 'restricthtml'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_MESSAGE_OK", GETPOST('ONLINE_PAYMENT_MESSAGE_OK', 'restricthtml'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_MESSAGE_KO", GETPOST('ONLINE_PAYMENT_MESSAGE_KO', 'restricthtml'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_SENDEMAIL", GETPOST('ONLINE_PAYMENT_SENDEMAIL', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       // Payment token for URL
-       $result = dolibarr_set_const($db, "PAYMENT_SECURITY_TOKEN", GETPOST('PAYMENT_SECURITY_TOKEN', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       if (empty($conf->use_javascript_ajax)) {
-               $result = dolibarr_set_const($db, "PAYMENT_SECURITY_TOKEN_UNIQUE", GETPOST('PAYMENT_SECURITY_TOKEN_UNIQUE', 'alpha'), 'chaine', 0, '', $conf->entity);
-               if (!($result > 0)) {
-                       $error++;
-               }
-       }
-
-       if (!$error) {
-               $db->commit();
-               setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
-       } else {
-               $db->rollback();
-               dol_print_error($db);
-       }
-}
-
-if ($action == "setlive") {
-       $liveenable = GETPOST('value', 'int') ? 0 : 1;
-       $res = dolibarr_set_const($db, "PAYPAL_API_SANDBOX", $liveenable, 'yesno', 0, '', $conf->entity);
-       if (!($res > 0)) {
-               $error++;
-       }
-       if (!$error) {
-               setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
-       } else {
-               setEventMessages($langs->trans("Error"), null, 'errors');
-       }
-}
-
-
-/*
- *     View
- */
-
-$form = new Form($db);
-
-llxHeader('', $langs->trans("PaypalSetup"));
-
-
-$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
-print load_fiche_titre($langs->trans("ModuleSetup").' PayPal', $linkback);
-
-$head = paypaladmin_prepare_head();
-
-print '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
-print '<input type="hidden" name="token" value="'.newToken().'">';
-print '<input type="hidden" name="action" value="setvalue">';
-
-
-print dol_get_fiche_head($head, 'paypalaccount', '', -1);
-
-print '<span class="opacitymedium">'.$langs->trans("PaypalDesc")."</span><br>\n";
-
-// Test if php curl exist
-if (!function_exists('curl_version')) {
-       $langs->load("errors");
-       setEventMessages($langs->trans("ErrorPhpCurlNotInstalled"), null, 'errors');
-}
-
-
-print '<br>';
-
-print '<div class="div-table-responsive-no-min">';
-print '<table class="noborder centpercent">';
-
-// Account Parameters
-print '<tr class="liste_titre">';
-print '<td>'.$langs->trans("AccountParameter").'</td>';
-print '<td>'.$langs->trans("Value").'</td>';
-print "</tr>\n";
-
-print '<tr class="oddeven">';
-print '<td>';
-print $langs->trans("PaypalLiveEnabled").'</td><td>';
-if (empty($conf->global->PAYPAL_API_SANDBOX)) {
-       print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=setlive&token='.newToken().'&value=0">';
-       print img_picto($langs->trans("Activated"), 'switch_on');
-} else {
-       print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=setlive&token='.newToken().'&value=1">';
-       print img_picto($langs->trans("Disabled"), 'switch_off');
-}
-print '</td></tr>';
-
-print '<tr class="oddeven"><td class="fieldrequired">';
-print $langs->trans("PAYPAL_API_USER").'</td><td>';
-print '<input size="32" type="text" name="PAYPAL_API_USER" value="'.$conf->global->PAYPAL_API_USER.'">';
-print ' &nbsp; <span class="opacitymedium">'.$langs->trans("Example").': admin-facilitator_api1.example.com, paypal_api1.mywebsite.com</span>';
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td class="fieldrequired">';
-print $langs->trans("PAYPAL_API_PASSWORD").'</td><td>';
-print '<input size="32" type="text" name="PAYPAL_API_PASSWORD" value="'.$conf->global->PAYPAL_API_PASSWORD.'">';
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td class="fieldrequired">';
-print $langs->trans("PAYPAL_API_SIGNATURE").'</td><td>';
-print '<input size="64" type="text" name="PAYPAL_API_SIGNATURE" value="'.$conf->global->PAYPAL_API_SIGNATURE.'">';
-print '<br><span class="opacitymedium">'.$langs->trans("Example").': ASsqXEmw4KzmX-CPChWSVDNCNfd.A3YNR7uz-VncXXAERFDFDFDF</span>';
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("PAYPAL_SSLVERSION").'</td><td>';
-print $form->selectarray("PAYPAL_SSLVERSION", array('1'=> $langs->trans('TLSv1'), '6'=> $langs->trans('TLSv1.2')), $conf->global->PAYPAL_SSLVERSION);
-print '</td></tr>';
-
-print '</table>';
-print '</div>';
-
-print '<br>';
-
-
-print '<div class="div-table-responsive-no-min">';
-print '<table class="noborder centpercent">';
-
-// Usage Parameters
-print '<tr class="liste_titre">';
-print '<td>'.$langs->trans("UsageParameter").'</td>';
-print '<td>'.$langs->trans("Value").'</td>';
-print "</tr>\n";
-
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("PAYPAL_API_INTEGRAL_OR_PAYPALONLY").'</td><td>';
-print $form->selectarray("PAYPAL_API_INTEGRAL_OR_PAYPALONLY", array('integral'=> $langs->trans('PaypalModeIntegral'), 'paypalonly'=> $langs->trans('PaypalModeOnlyPaypal')), $conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY);
-print '</td></tr>';
-
-/*
-print '<tr class="oddeven"><td>';
-print '<span class="fieldrequired">'.$langs->trans("PAYPAL_API_EXPRESS").'</span></td><td>';
-print $form->selectyesno("PAYPAL_API_EXPRESS",$conf->global->PAYPAL_API_EXPRESS);
-print '</td></tr>';
-*/
-
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("PublicVendorName").'</td><td>';
-print '<input size="64" type="text" name="ONLINE_PAYMENT_CREDITOR" value="'.$conf->global->ONLINE_PAYMENT_CREDITOR.'">';
-print ' &nbsp; <span class="opacitymedium">'.$langs->trans("Example").': '.$mysoc->name.'</span>';
-print '</td></tr>';
-
-if (isModEnabled("banque")) {
-       print '<tr class="oddeven"><td>';
-       print $langs->trans("BankAccount").'</td><td>';
-       print img_picto('', 'bank_account').' ';
-       $form->select_comptes($conf->global->PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS, 'PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1);
-       print '</td></tr>';
-}
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("CSSUrlForPaymentForm").'</td><td>';
-print '<input size="64" type="text" name="ONLINE_PAYMENT_CSS_URL" value="'.$conf->global->ONLINE_PAYMENT_CSS_URL.'">';
-print ' &nbsp; <span class="opacitymedium">'.$langs->trans("Example").': http://mysite/mycss.css</span>';
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("PAYPAL_ADD_PAYMENT_URL").'</td><td>';
-print $form->selectyesno("PAYPAL_ADD_PAYMENT_URL", $conf->global->PAYPAL_ADD_PAYMENT_URL, 1);
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("MessageForm").'</td><td>';
-$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_FORM', $conf->global->ONLINE_PAYMENT_MESSAGE_FORM, '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_4, '90%');
-$doleditor->Create();
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("MessageOK").'</td><td>';
-$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_OK', $conf->global->ONLINE_PAYMENT_MESSAGE_OK, '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_4, '90%');
-$doleditor->Create();
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("MessageKO").'</td><td>';
-$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_KO', $conf->global->ONLINE_PAYMENT_MESSAGE_KO, '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_4, '90%');
-$doleditor->Create();
-print '</td></tr>';
-
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("ONLINE_PAYMENT_SENDEMAIL").'</td><td>';
-print '<input class="minwidth200" type="text" name="ONLINE_PAYMENT_SENDEMAIL" value="'.$conf->global->ONLINE_PAYMENT_SENDEMAIL.'">';
-print ' &nbsp;  <span class="opacitymedium">'.$langs->trans("Example").': myemail@myserver.com, Payment service &lt;myemail2@myserver2.com&gt;</span>';
-print '</td></tr>';
-
-print '</table>';
-print '</div>';
-
-print '<br>';
-
-print '<div class="div-table-responsive-no-min">';
-print '<table class="noborder centpercent">';
-
-print '<tr class="liste_titre">';
-print '<td>'.$langs->trans("UrlGenerationParameters").'</td>';
-print '<td>'.$langs->trans("Value").'</td>';
-print "</tr>\n";
-
-// Payment token for URL
-print '<tr class="oddeven"><td>';
-print $langs->trans("SecurityToken").'</td><td>';
-print '<input class="minwidth300" type="text" id="PAYMENT_SECURITY_TOKEN" name="PAYMENT_SECURITY_TOKEN" value="'.$conf->global->PAYMENT_SECURITY_TOKEN.'">';
-if (!empty($conf->use_javascript_ajax)) {
-       print '&nbsp;'.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token" class="linkobject"');
-}
-if (!empty($conf->global->PAYMENT_SECURITY_ACCEPT_ANY_TOKEN)) {
-       $langs->load("errors");
-       print img_warning($langs->trans("WarningTheHiddenOptionIsOn", 'PAYMENT_SECURITY_ACCEPT_ANY_TOKEN'), '', 'pictowarning marginleftonly');
-}
-print '</td></tr>';
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("SecurityTokenIsUnique").'</td><td>';
-if ($conf->use_javascript_ajax) {
-       print ajax_constantonoff('PAYMENT_SECURITY_TOKEN_UNIQUE');
-} else {
-       $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
-       print $form->selectarray("PAYMENT_SECURITY_TOKEN_UNIQUE", $arrval, $conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE);
-}
-print '</td></tr>';
-
-print '</table>';
-print '</div>';
-
-print dol_get_fiche_end();
-
-print $form->buttonsSaveCancel("Modify", '');
-
-print '</form>';
-
-print '<br><br>';
-
-// Help doc
-print '<u>'.$langs->trans("InformationToFindParameters", "Paypal").'</u>:<br>';
-if (!empty($conf->use_javascript_ajax)) {
-       print '<a class="reposition" id="apidoca">'.$langs->trans("ClickHere").'...</a>';
-}
-
-$realpaypalurl = 'www.paypal.com';
-$sandboxpaypalurl = 'developer.paypal.com';
-
-print '<div id="apidoc">';
-print 'Your API authentication information can be found with following steps. We recommend that you open a separate Web browser session when carrying out this procedure.<br>
-1. Log in to your PayPal account (on real paypal <a href="https://'.$realpaypalurl.'" target="_blank" rel="noopener noreferrer external">'.$realpaypalurl.'</a> (or sandbox <a href="https://'.$sandboxpaypalurl.'" target="_blank" rel="noopener noreferrer external">'.$sandboxpaypalurl.'</a>).<br>
-2. Click the "Profile" or "Preferencies" subtab located under the My Account heading.<br>
-3. Click the link "API Access".<br>
-4. Click the View API Certificate link in the right column.<br>
-5. Click the Request API signature radio button on the Request API Credentials page.<br>
-6. Complete the Request API Credential Request form by clicking the agreement checkbox and clicking Submit.<br>
-7. Save the values for API Username, Password and Signature (make sure this long character signature is copied).<br>
-8. Click the "Modify" button after copying your API Username, Password, and Signature.
-';
-print '</div>';
-
-if (!empty($conf->use_javascript_ajax)) {
-       print "\n".'<script type="text/javascript">';
-       print '$(document).ready(function () {
-                   $("#apidoc").hide();
-                   $("#apidoca").click(function() {
-                                       console.log("We click on apidoca show/hide");
-                       $("#apidoc").show();
-                       $("#apidoca").hide();
-                                       return false;
-                   })
-                       });';
-       print '</script>';
-}
-
-print '<br><br>';
-
-$token = '';
-
-include DOL_DOCUMENT_ROOT.'/core/tpl/onlinepaymentlinks.tpl.php';
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/paypal/img/object_paypal.png b/htdocs/paypal/img/object_paypal.png
deleted file mode 100644 (file)
index 872a035..0000000
Binary files a/htdocs/paypal/img/object_paypal.png and /dev/null differ
diff --git a/htdocs/paypal/lib/paypal.lib.php b/htdocs/paypal/lib/paypal.lib.php
deleted file mode 100644 (file)
index 7900395..0000000
+++ /dev/null
@@ -1,617 +0,0 @@
-<?php
-/* Copyright (C) 2008-2012     Laurent Destailleur     <eldy@users.sourceforge.net>
- * Copyright (C) 2011-2012     Regis Houssin           <regis.houssin@inodbox.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file                   htdocs/paypal/lib/paypal.lib.php
- *  \ingroup           paypal
- *  \brief                     Library for common paypal functions
- */
-
-require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
-
-
-/**
- *  Define head array for tabs of paypal tools setup pages
- *
- *  @return                    Array of head
- */
-function paypaladmin_prepare_head()
-{
-       global $langs, $conf;
-
-       $h = 0;
-       $head = array();
-
-       $head[$h][0] = DOL_URL_ROOT."/paypal/admin/paypal.php";
-       $head[$h][1] = $langs->trans("PayPal");
-       $head[$h][2] = 'paypalaccount';
-       $h++;
-
-       $object = new stdClass();
-
-       // Show more tabs from modules
-       // Entries must be declared in modules descriptor with line
-       // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab
-       // $this->tabs = array('entity:-tabname);                                                                                               to remove a tab
-       complete_head_from_modules($conf, $langs, $object, $head, $h, 'paypaladmin');
-
-       complete_head_from_modules($conf, $langs, $object, $head, $h, 'paypaladmin', 'remove');
-
-       return $head;
-}
-
-
-/**
- * Send redirect to paypal to browser
- *
- * @param      float   $paymentAmount          Amount
- * @param   string     $currencyCodeType       Currency code
- * @param      string  $paymentType            Payment type
- * @param      string  $returnURL                      Url to use if payment is OK
- * @param   string     $cancelURL                      Url to use if payment is KO
- * @param   string     $tag                            Full tag
- * @return     string                                          No return (a redirect is done) if OK, or Error message if KO
- */
-function print_paypal_redirect($paymentAmount, $currencyCodeType, $paymentType, $returnURL, $cancelURL, $tag)
-{
-       //declaring of global variables
-       global $conf, $langs;
-       global $API_Endpoint, $API_Url, $API_version, $USE_PROXY, $PROXY_HOST, $PROXY_PORT;
-       global $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE;
-
-       global $shipToName, $shipToStreet, $shipToCity, $shipToState, $shipToCountryCode, $shipToZip, $shipToStreet2, $phoneNum;
-       global $email, $desc;
-
-       //'------------------------------------
-       //' Calls the SetExpressCheckout API call
-       //'
-       //'-------------------------------------------------
-
-       if (empty($conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY)) {
-               $conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY = 'integral';
-       }
-
-       $solutionType = 'Sole';
-       $landingPage = 'Billing';
-       // For payment with Paypal only
-       if ($conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY == 'paypalonly') {
-               $solutionType = 'Mark';
-               $landingPage = 'Login';
-       }
-       // For payment with Credit card or Paypal
-       if ($conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY == 'integral') {
-               $solutionType = 'Sole';
-               $landingPage = 'Billing';
-       }
-       // For payment with Credit card
-       if ($conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY == 'cconly') {
-               $solutionType = 'Sole';
-               $landingPage = 'Billing';
-       }
-
-       dol_syslog("print_paypal_redirect expresscheckout redirect with callSetExpressCheckout $paymentAmount, $currencyCodeType, $paymentType, $returnURL, $cancelURL, $tag, $solutionType, $landingPage, $shipToName, $shipToStreet, $shipToCity, $shipToState, $shipToCountryCode, $shipToZip, $shipToStreet2, $phoneNum");
-       $resArray = callSetExpressCheckout(
-               $paymentAmount,
-               $currencyCodeType,
-               $paymentType,
-               $returnURL,
-               $cancelURL,
-               $tag,
-               $solutionType,
-               $landingPage,
-               $shipToName,
-               $shipToStreet,
-               $shipToCity,
-               $shipToState,
-               $shipToCountryCode,
-               $shipToZip,
-               $shipToStreet2,
-               $phoneNum,
-               $email,
-               $desc
-       );
-
-       dol_syslog("print_paypal_redirect resArray=".var_export($resArray, true), LOG_DEBUG);
-
-       $ack = strtoupper($resArray["ACK"]);
-       if ($ack == "SUCCESS" || $ack == "SUCCESSWITHWARNING") {
-               $token = $resArray["TOKEN"];
-
-               // Redirect to paypal.com here
-               $payPalURL = $API_Url.$token;
-               dol_syslog("Redirect to ".$payPalURL, LOG_INFO);
-               header("Location: ".$payPalURL);
-               exit;
-       } else {
-               //Display a user friendly Error on the page using any of the following error information returned by PayPal
-               $ErrorCode = urldecode($resArray["L_ERRORCODE0"]);
-               $ErrorShortMsg = urldecode($resArray["L_SHORTMESSAGE0"]);
-               $ErrorLongMsg = urldecode($resArray["L_LONGMESSAGE0"]);
-               $ErrorSeverityCode = urldecode($resArray["L_SEVERITYCODE0"]);
-
-               if ($ErrorCode == 10729) {
-                       $mesg .= "PayPal can't accept payments for this thirdparty. An address is defined but is not complete (missing State).<br>Ask system administrator to fix address or to setup Paypal module to accept payments even on not complete addresses (remove option PAYPAL_REQUIRE_VALID_SHIPPING_ADDRESS).<br>\n";
-               } else {
-                       $mesg = $langs->trans('SetExpressCheckoutAPICallFailed')."<br>\n";
-                       $mesg .= $langs->trans('DetailedErrorMessage').": ".$ErrorLongMsg."<br>\n";
-                       $mesg .= $langs->trans('ShortErrorMessage').": ".$ErrorShortMsg."<br>\n";
-                       $mesg .= $langs->trans('ErrorCode').": ".$ErrorCode."<br>\n";
-                       $mesg .= $langs->trans('ErrorSeverityCode').": ".$ErrorSeverityCode."<br>\n";
-               }
-
-               return $mesg;
-       }
-}
-
-/**
- *-------------------------------------------------------------------------------------------------------------------------------------------
- * Purpose:     Prepares the parameters for the SetExpressCheckout API Call.
- * Inputs:
- *      paymentAmount:      Total value of the shopping cart
- *      currencyCodeType:   Currency code value the PayPal API
- *      paymentType:        paymentType has to be one of the following values: Sale or Order or Authorization
- *      returnURL:          the page where buyers return to after they are done with the payment review on PayPal
- *      cancelURL:          the page where buyers return to when they cancel the payment review on PayPal
- *      shipToName:     the Ship to name entered on the merchant's site
- *      shipToStreet:       the Ship to Street entered on the merchant's site
- *      shipToCity:         the Ship to City entered on the merchant's site
- *      shipToState:        the Ship to State entered on the merchant's site
- *      shipToCountryCode:  the Code for Ship to Country entered on the merchant's site
- *      shipToZip:          the Ship to ZipCode entered on the merchant's site
- *      shipToStreet2:      the Ship to Street2 entered on the merchant's site
- *      phoneNum:           the phoneNum  entered on the merchant's site
- *      email:              the buyer email
- *      desc:               Product description
- * See https://developer.paypal.com/docs/classic/api/merchant/SetExpressCheckout_API_Operation_NVP/
- *
- * @param      double                  $paymentAmount          Payment amount
- * @param      string                  $currencyCodeType       Currency
- * @param      string                  $paymentType            Payment type
- * @param      string                  $returnURL                      Return Url
- * @param      string                  $cancelURL                      Cancel Url
- * @param      string                  $tag                            Full tag
- * @param      string                  $solutionType           Type ('Mark' or 'Sole')
- * @param      string                  $landingPage            Landing page ('Login' or 'Billing')
- * @param      string                  $shipToName                     Ship to name
- * @param      string                  $shipToStreet           Ship to street
- * @param      string                  $shipToCity                     Ship to city
- * @param      string                  $shipToState            Ship to state
- * @param      string                  $shipToCountryCode      Ship to country code
- * @param      string                  $shipToZip                      Ship to zip
- * @param      string                  $shipToStreet2          Ship to street2
- * @param      string                  $phoneNum                       Phone
- * @param      string                  $email                          Email
- * @param      string                  $desc                           Description
- * @return     array                                                           Array
- */
-function callSetExpressCheckout($paymentAmount, $currencyCodeType, $paymentType, $returnURL, $cancelURL, $tag, $solutionType, $landingPage, $shipToName, $shipToStreet, $shipToCity, $shipToState, $shipToCountryCode, $shipToZip, $shipToStreet2, $phoneNum, $email = '', $desc = '')
-{
-       //------------------------------------------------------------------------------------------------------------------------------------
-       // Construct the parameter string that describes the SetExpressCheckout API call in the shortcut implementation
-
-       //declaring of global variables
-       global $conf, $langs, $mysoc;
-       global $API_Endpoint, $API_Url, $API_version, $USE_PROXY, $PROXY_HOST, $PROXY_PORT;
-       global $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE;
-
-       $nvpstr = '';
-       //$nvpstr = $nvpstr . "&VERSION=".$API_version;                         // Already added by hash_call
-       $nvpstr = $nvpstr."&RETURNURL=".urlencode($returnURL);
-       $nvpstr = $nvpstr."&CANCELURL=".urlencode($cancelURL);
-       if (!empty($conf->global->PAYPAL_ALLOW_NOTES)) {
-               $nvpstr = $nvpstr."&ALLOWNOTE=0";
-       }
-       if (empty($conf->global->PAYPAL_REQUIRE_VALID_SHIPPING_ADDRESS)) {
-               $nvpstr = $nvpstr."&NOSHIPPING=1"; // An empty or not complete shipping address will be accepted
-       } else {
-               $nvpstr = $nvpstr."&NOSHIPPING=0"; // A valid shipping address is required (full required fields mandatory)
-       }
-       $nvpstr = $nvpstr."&SOLUTIONTYPE=".urlencode($solutionType);
-       $nvpstr = $nvpstr."&LANDINGPAGE=".urlencode($landingPage);
-       if (!empty($conf->global->PAYPAL_CUSTOMER_SERVICE_NUMBER)) {
-               $nvpstr = $nvpstr."&CUSTOMERSERVICENUMBER=".urlencode($conf->global->PAYPAL_CUSTOMER_SERVICE_NUMBER); // Hotline phone number
-       }
-
-       $paypalprefix = 'PAYMENTREQUEST_0_';
-       //$paypalprefix = '';
-       if (!empty($paypalprefix) && $paymentType == 'Sole') {
-               $paymentType = 'Sale';
-       }
-
-       $nvpstr = $nvpstr."&AMT=".urlencode($paymentAmount); // Total for all elements
-
-       $nvpstr = $nvpstr."&".$paypalprefix."INVNUM=".urlencode($tag);
-       $nvpstr = $nvpstr."&".$paypalprefix."AMT=".urlencode($paymentAmount); // AMT deprecated by paypal -> PAYMENTREQUEST_n_AMT
-       $nvpstr = $nvpstr."&".$paypalprefix."ITEMAMT=".urlencode($paymentAmount); // AMT deprecated by paypal -> PAYMENTREQUEST_n_AMT
-       $nvpstr = $nvpstr."&".$paypalprefix."PAYMENTACTION=".urlencode($paymentType); // PAYMENTACTION deprecated by paypal -> PAYMENTREQUEST_n_PAYMENTACTION
-       $nvpstr = $nvpstr."&".$paypalprefix."CURRENCYCODE=".urlencode($currencyCodeType); // CURRENCYCODE deprecated by paypal -> PAYMENTREQUEST_n_CURRENCYCODE
-
-       $nvpstr = $nvpstr."&".$paypalprefix."L_PAYMENTREQUEST_0_QTY0=1";
-       $nvpstr = $nvpstr."&".$paypalprefix."L_PAYMENTREQUEST_0_AMT0=".urlencode($paymentAmount);
-       $nvpstr = $nvpstr."&".$paypalprefix."L_PAYMENTREQUEST_0_NAME0=".urlencode($desc);
-       $nvpstr = $nvpstr."&".$paypalprefix."L_PAYMENTREQUEST_0_NUMBER0=0";
-
-       $nvpstr = $nvpstr."&".$paypalprefix."SHIPTONAME=".urlencode($shipToName); // SHIPTONAME deprecated by paypal -> PAYMENTREQUEST_n_SHIPTONAME
-       $nvpstr = $nvpstr."&".$paypalprefix."SHIPTOSTREET=".urlencode($shipToStreet); //
-       $nvpstr = $nvpstr."&".$paypalprefix."SHIPTOSTREET2=".urlencode($shipToStreet2);
-       $nvpstr = $nvpstr."&".$paypalprefix."SHIPTOCITY=".urlencode($shipToCity);
-       $nvpstr = $nvpstr."&".$paypalprefix."SHIPTOSTATE=".urlencode($shipToState);
-       $nvpstr = $nvpstr."&".$paypalprefix."SHIPTOCOUNTRYCODE=".urlencode($shipToCountryCode);
-       $nvpstr = $nvpstr."&".$paypalprefix."SHIPTOZIP=".urlencode($shipToZip);
-       $nvpstr = $nvpstr."&".$paypalprefix."PHONENUM=".urlencode($phoneNum);
-       if (!empty($email)) {
-               $nvpstr = $nvpstr."&".$paypalprefix."EMAIL=".urlencode($email); // EMAIL deprecated by paypal -> PAYMENTREQUEST_n_EMAIL
-       }
-       if (!empty($desc)) {
-               $nvpstr = $nvpstr."&".$paypalprefix."DESC=".urlencode($desc); // DESC deprecated by paypal -> PAYMENTREQUEST_n_DESC
-       }
-
-       if (!empty($conf->global->PAYPAL_LOGOIMG) && $mysoc->logo) {
-               global $dolibarr_main_url_root;
-
-               // Define $urlwithroot
-               $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
-               $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
-               //$urlwithroot=DOL_MAIN_URL_ROOT;                                       // This is to use same domain name than current
-
-               $urllogo = $urlwithroot."/viewimage.php?modulepart=mycompany&file=".urlencode('logos/'.$mysoc->logo);
-               $nvpstr = $nvpstr."&LOGOIMG=".urlencode($urllogo);
-       }
-       if (!empty($conf->global->PAYPAL_BRANDNAME)) {
-               $nvpstr = $nvpstr."&BRANDNAME=".urlencode($conf->global->PAYPAL_BRANDNAME); // BRANDNAME
-       }
-       if (!empty($conf->global->PAYPAL_NOTETOBUYER)) {
-               $nvpstr = $nvpstr."&NOTETOBUYER=".urlencode($conf->global->PAYPAL_NOTETOBUYER); // PAYPAL_NOTETOBUYER
-       }
-
-       $_SESSION["FinalPaymentAmt"] = $paymentAmount;
-       $_SESSION["currencyCodeType"] = $currencyCodeType;
-       $_SESSION["PaymentType"] = $paymentType; // 'Mark', 'Sole'
-       $_SESSION['ipaddress'] = getUserRemoteIP(); // Payer ip
-
-       //'---------------------------------------------------------------------------------------------------------------
-       //' Make the API call to PayPal
-       //' If the API call succeded, then redirect the buyer to PayPal to begin to authorize payment.
-       //' If an error occured, show the resulting errors
-       //'---------------------------------------------------------------------------------------------------------------
-       $resArray = hash_call("SetExpressCheckout", $nvpstr);
-       $ack = strtoupper($resArray["ACK"]);
-       if ($ack == "SUCCESS" || $ack == "SUCCESSWITHWARNING") {
-               $token = urldecode($resArray["TOKEN"]);
-               $_SESSION['TOKEN'] = $token;
-       }
-
-       return $resArray;
-}
-
-/**
- *     Prepares the parameters for the GetExpressCheckoutDetails API Call.
- *
- *     @param  string  $token          Token
- *     @return array                           The NVP Collection object of the GetExpressCheckoutDetails Call Response.
- */
-function getDetails($token)
-{
-       //'--------------------------------------------------------------
-       //' At this point, the buyer has completed authorizing the payment
-       //' at PayPal.  The function will call PayPal to obtain the details
-       //' of the authorization, incuding any shipping information of the
-       //' buyer.  Remember, the authorization is not a completed transaction
-       //' at this state - the buyer still needs an additional step to finalize
-       //' the transaction
-       //'--------------------------------------------------------------
-
-       //declaring of global variables
-       global $conf, $langs;
-       global $API_Endpoint, $API_Url, $API_version, $USE_PROXY, $PROXY_HOST, $PROXY_PORT;
-       global $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE;
-
-       //'---------------------------------------------------------------------------
-       //' Build a second API request to PayPal, using the token as the
-       //'  ID to get the details on the payment authorization
-       //'---------------------------------------------------------------------------
-       $nvpstr = "&TOKEN=".$token;
-
-       //'---------------------------------------------------------------------------
-       //' Make the API call and store the results in an array.
-       //' If the call was a success, show the authorization details, and provide
-       //'     an action to complete the payment.
-       //' If failed, show the error
-       //'---------------------------------------------------------------------------
-       $resArray = hash_call("GetExpressCheckoutDetails", $nvpstr);
-       $ack = strtoupper($resArray["ACK"]);
-       if ($ack == "SUCCESS" || $ack == "SUCCESSWITHWARNING") {
-               $_SESSION['payer_id'] = $resArray['PAYERID'];
-       }
-       return $resArray;
-}
-
-
-/**
- *     Validate payment
- *
- *     @param  string  $token                          Token
- *     @param  string  $paymentType            Type
- *     @param  string  $currencyCodeType       Currency
- *     @param  string  $payerID                        Payer ID
- *     @param  string  $ipaddress                      IP Address
- *     @param  string  $FinalPaymentAmt        Amount
- *     @param  string  $tag                            Full tag
- *     @return array
- */
-function confirmPayment($token, $paymentType, $currencyCodeType, $payerID, $ipaddress, $FinalPaymentAmt, $tag)
-{
-       /* Gather the information to make the final call to
-        finalize the PayPal payment.  The variable nvpstr
-        holds the name value pairs
-        */
-
-       //declaring of global variables
-       global $conf, $langs;
-       global $API_Endpoint, $API_Url, $API_version, $USE_PROXY, $PROXY_HOST, $PROXY_PORT;
-       global $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE;
-
-       $nvpstr = '';
-       $nvpstr .= '&TOKEN='.urlencode($token);
-       $nvpstr .= '&PAYERID='.urlencode($payerID);
-       $nvpstr .= '&PAYMENTACTION='.urlencode($paymentType);
-       $nvpstr .= '&AMT='.urlencode($FinalPaymentAmt);
-       $nvpstr .= '&CURRENCYCODE='.urlencode($currencyCodeType);
-       $nvpstr .= '&IPADDRESS='.urlencode($ipaddress);
-       $nvpstr .= '&INVNUM='.urlencode($tag);
-
-       /* Make the call to PayPal to finalize payment
-        If an error occured, show the resulting errors
-        */
-       $resArray = hash_call("DoExpressCheckoutPayment", $nvpstr);
-
-       /* Display the API response back to the browser.
-        If the response from PayPal was a success, display the response parameters'
-        If the response was an error, display the errors received using APIError.php.
-        */
-       $ack = strtoupper($resArray["ACK"]);
-
-       return $resArray;
-}
-
-/**
- *     This function makes a DoDirectPayment API call
- *
- *  paymentType:        paymentType has to be one of the following values: Sale or Order or Authorization
- *  paymentAmount:      total value of the shopping cart
- *  currencyCode:       currency code value the PayPal API
- *  firstName:          first name as it appears on credit card
- *  lastName:           last name as it appears on credit card
- *  street:             buyer's street address line as it appears on credit card
- *  city:               buyer's city
- *  state:              buyer's state
- *  countryCode:        buyer's country code
- *  zip:                buyer's zip
- *  creditCardType:     buyer's credit card type (i.e. Visa, MasterCard ... )
- *  creditCardNumber:   buyers credit card number without any spaces, dashes or any other characters
- *  expDate:            credit card expiration date
- *  cvv2:               Card Verification Value
- *     @return         array   The NVP Collection object of the DoDirectPayment Call Response.
- */
-/*
-function DirectPayment($paymentType, $paymentAmount, $creditCardType, $creditCardNumber, $expDate, $cvv2, $firstName, $lastName, $street, $city, $state, $zip, $countryCode, $currencyCode, $tag)
-{
-       //declaring of global variables
-       global $conf, $langs;
-       global $API_Endpoint, $API_Url, $API_version, $USE_PROXY, $PROXY_HOST, $PROXY_PORT;
-       global $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE;
-
-       //Construct the parameter string that describes DoDirectPayment
-       $nvpstr = '';
-       $nvpstr = $nvpstr . "&AMT=" . urlencode($paymentAmount);              // deprecated by paypal
-       $nvpstr = $nvpstr . "&CURRENCYCODE=" . urlencode($currencyCode);
-       $nvpstr = $nvpstr . "&PAYMENTACTION=" . urlencode($paymentType);      // deprecated by paypal
-       $nvpstr = $nvpstr . "&CREDITCARDTYPE=" . urlencode($creditCardType);
-       $nvpstr = $nvpstr . "&ACCT=" . urlencode($creditCardNumber);
-       $nvpstr = $nvpstr . "&EXPDATE=" . urlencode($expDate);
-       $nvpstr = $nvpstr . "&CVV2=" . urlencode($cvv2);
-       $nvpstr = $nvpstr . "&FIRSTNAME=" . urlencode($firstName);
-       $nvpstr = $nvpstr . "&LASTNAME=" . urlencode($lastName);
-       $nvpstr = $nvpstr . "&STREET=" . urlencode($street);
-       $nvpstr = $nvpstr . "&CITY=" . urlencode($city);
-       $nvpstr = $nvpstr . "&STATE=" . urlencode($state);
-       $nvpstr = $nvpstr . "&COUNTRYCODE=" . urlencode($countryCode);
-       $nvpstr = $nvpstr . "&IPADDRESS=" . getUserRemotIP();
-       $nvpstr = $nvpstr . "&INVNUM=" . urlencode($tag);
-
-       $resArray=hash_call("DoDirectPayment", $nvpstr);
-
-       return $resArray;
-}
-*/
-
-
-/**
- * hash_call: Function to perform the API call to PayPal using API signature
- *
- * @param      string  $methodName     is name of API  method.
- * @param      string  $nvpStr                 is nvp string.
- * @return     array                                   returns an associtive array containing the response from the server.
- */
-function hash_call($methodName, $nvpStr)
-{
-       //declaring of global variables
-       global $conf, $langs;
-       global $API_Endpoint, $API_Url, $API_version, $USE_PROXY, $PROXY_HOST, $PROXY_PORT, $PROXY_USER, $PROXY_PASS;
-       global $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE;
-
-       // TODO problem with triggers
-       $API_version = "98.0";
-       if (!empty($conf->global->PAYPAL_API_SANDBOX) || GETPOST('forcesandbox', 'alpha')) {            // We can force sand box with param 'forcesandbox'
-               $API_Endpoint = "https://api-3t.sandbox.paypal.com/nvp";
-               $API_Url = "https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=";
-       } else {
-               $API_Endpoint = "https://api-3t.paypal.com/nvp";
-               $API_Url = "https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=";
-       }
-
-       // Clean parameters
-       $PAYPAL_API_USER = "";
-       if (!empty($conf->global->PAYPAL_API_USER)) {
-               $PAYPAL_API_USER = $conf->global->PAYPAL_API_USER;
-       }
-       $PAYPAL_API_PASSWORD = "";
-       if (!empty($conf->global->PAYPAL_API_PASSWORD)) {
-               $PAYPAL_API_PASSWORD = $conf->global->PAYPAL_API_PASSWORD;
-       }
-       $PAYPAL_API_SIGNATURE = "";
-       if (!empty($conf->global->PAYPAL_API_SIGNATURE)) {
-               $PAYPAL_API_SIGNATURE = $conf->global->PAYPAL_API_SIGNATURE;
-       }
-       $PAYPAL_API_SANDBOX = "";
-       if (!empty($conf->global->PAYPAL_API_SANDBOX)) {
-               $PAYPAL_API_SANDBOX = $conf->global->PAYPAL_API_SANDBOX;
-       }
-       // TODO END problem with triggers
-
-       dol_syslog("Paypal API endpoint ".$API_Endpoint);
-
-       //setting the curl parameters.
-       $ch = curl_init();
-
-       /*print $API_Endpoint."-".$API_version."-".$PAYPAL_API_USER."-".$PAYPAL_API_PASSWORD."-".$PAYPAL_API_SIGNATURE."<br>";
-        print $USE_PROXY."-".$gv_ApiErrorURL."<br>";
-        print $nvpStr;
-        exit;*/
-       curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
-       curl_setopt($ch, CURLOPT_VERBOSE, 1);
-       // TLSv1 by default or change to TLSv1.2 in module configuration
-       curl_setopt($ch, CURLOPT_SSLVERSION, (empty($conf->global->PAYPAL_SSLVERSION) ? 1 : $conf->global->PAYPAL_SSLVERSION));
-
-       $ssl_verifypeer = -1;
-
-       // Turning on or off the ssl target certificate
-       if ($ssl_verifypeer < 0) {
-               global $dolibarr_main_prod;
-               $ssl_verifypeer =  ($dolibarr_main_prod ? true : false);
-       }
-       if (!empty($conf->global->MAIN_CURL_DISABLE_VERIFYPEER)) {
-               $ssl_verifypeer = 0;
-       }
-
-       //turning off the server and peer verification(TrustManager Concept).
-       curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, ($ssl_verifypeer ? true : false));
-       curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, ($ssl_verifypeer ? true : false));
-
-       curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, empty($conf->global->MAIN_USE_CONNECT_TIMEOUT) ? 5 : $conf->global->MAIN_USE_CONNECT_TIMEOUT);
-       curl_setopt($ch, CURLOPT_TIMEOUT, empty($conf->global->MAIN_USE_RESPONSE_TIMEOUT) ? 30 : $conf->global->MAIN_USE_RESPONSE_TIMEOUT);
-
-       curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
-       curl_setopt($ch, CURLOPT_POST, 1);
-
-       //if USE_PROXY constant set to true in Constants.php, then only proxy will be enabled.
-       if ($USE_PROXY) {
-               dol_syslog("Paypal API hash_call set proxy to ".$PROXY_HOST.":".$PROXY_PORT." - ".$PROXY_USER.":".$PROXY_PASS);
-               //curl_setopt ($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); // Curl 7.10
-               curl_setopt($ch, CURLOPT_PROXY, $PROXY_HOST.":".$PROXY_PORT);
-               if ($PROXY_USER) {
-                       curl_setopt($ch, CURLOPT_PROXYUSERPWD, $PROXY_USER.":".$PROXY_PASS);
-               }
-       }
-
-       //NVPRequest for submitting to server
-       $nvpreq = "METHOD=".urlencode($methodName)."&VERSION=".urlencode($API_version)."&PWD=".urlencode($PAYPAL_API_PASSWORD)."&USER=".urlencode($PAYPAL_API_USER)."&SIGNATURE=".urlencode($PAYPAL_API_SIGNATURE).$nvpStr;
-       $nvpreq .= "&LOCALECODE=".strtoupper($langs->getDefaultLang(1));
-       //$nvpreq.="&BRANDNAME=".urlencode();       // Override merchant name
-       //$nvpreq.="&NOTIFYURL=".urlencode();       // For Instant Payment Notification url
-
-
-       dol_syslog("Paypal API hash_call nvpreq=".$nvpreq);
-
-       //setting the nvpreq as POST FIELD to curl
-       curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
-
-       //getting response from server
-       $response = curl_exec($ch);
-
-       $nvpReqArray = deformatNVP($nvpreq);
-       $_SESSION['nvpReqArray'] = $nvpReqArray;
-
-       //convrting NVPResponse to an Associative Array
-       dol_syslog("Paypal API hash_call Response nvpresp=".$response);
-       $nvpResArray = deformatNVP($response);
-
-       if (curl_errno($ch)) {
-               // moving to display page to display curl errors
-               $_SESSION['curl_error_no'] = curl_errno($ch);
-               $_SESSION['curl_error_msg'] = curl_error($ch);
-
-               //Execute the Error handling module to display errors.
-       } else {
-               //closing the curl
-               curl_close($ch);
-       }
-
-       return $nvpResArray;
-}
-
-
-/**
- * This function will take NVPString and convert it to an Associative Array and it will decode the response.
- * It is usefull to search for a particular key and displaying arrays.
- *
- * @param      string  $nvpstr                 NVPString
- * @return     array                                   nvpArray = Associative Array
- */
-function deformatNVP($nvpstr)
-{
-       $intial = 0;
-       $nvpArray = array();
-
-       while (strlen($nvpstr)) {
-               //postion of Key
-               $keypos = strpos($nvpstr, '=');
-               //position of value
-               $valuepos = strpos($nvpstr, '&') ? strpos($nvpstr, '&') : strlen($nvpstr);
-
-               /*getting the Key and Value values and storing in a Associative Array*/
-               $keyval = substr($nvpstr, $intial, $keypos);
-               $valval = substr($nvpstr, $keypos + 1, $valuepos - $keypos - 1);
-               //decoding the respose
-               $nvpArray[urldecode($keyval)] = urldecode($valval);
-               $nvpstr = substr($nvpstr, $valuepos + 1, strlen($nvpstr));
-       }
-       return $nvpArray;
-}
-
-/**
- *     Get API errors
- *
- *     @return array           Array of errors
- */
-function getApiError()
-{
-       $errors = array();
-
-       $resArray = $_SESSION['reshash'];
-
-       if (isset($_SESSION['curl_error_no'])) {
-               $errors[] = $_SESSION['curl_error_no'].'-'.$_SESSION['curl_error_msg'];
-       }
-
-       foreach ($resArray as $key => $value) {
-               $errors[] = $key.'-'.$value;
-       }
-
-       return $errors;
-}
diff --git a/htdocs/paypal/lib/paypalfunctions.lib.php b/htdocs/paypal/lib/paypalfunctions.lib.php
deleted file mode 100644 (file)
index 713c304..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-<?php
-/* Copyright (C) 2010-2011 Laurent Destailleur  <eldy@users.sourceforge.org>
- * Copyright (C) 2011      Regis Houssin               <regis.houssin@inodbox.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file       htdocs/paypal/lib/paypalfunctions.lib.php
- * \ingroup    paypal
- * \brief      Page with Paypal init var.
- */
-
-if (session_id() == "") {
-       session_start();
-       if (ini_get('register_globals')) {    // To solve bug in using $_SESSION
-               foreach ($_SESSION as $key => $value) {
-                       if (isset($GLOBALS[$key])) {
-                               unset($GLOBALS[$key]);
-                       }
-               }
-       }
-}
-
-// ==================================
-// PayPal Express Checkout Module
-// ==================================
-
-$API_version = "56";
-
-/*
- ' Define the PayPal Redirect URLs.
- '  This is the URL that the buyer is first sent to do authorize payment with their paypal account
- '  change the URL depending if you are testing on the sandbox or the live PayPal site
- '
- ' For the sandbox, the URL is       https://www.sandbox.paypal.com/webscr&cmd=_express-checkout&token=
- ' For the live site, the URL is        https://www.paypal.com/webscr&cmd=_express-checkout&token=
- */
-if (!empty($conf->global->PAYPAL_API_SANDBOX) || GETPOST('forcesandbox', 'alpha')) {           // We can force sand box with param 'forcesandbox'
-       $API_Endpoint = "https://api-3t.sandbox.paypal.com/nvp";
-       $API_Url = "https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=";
-} else {
-       $API_Endpoint = "https://api-3t.paypal.com/nvp";
-       $API_Url = "https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=";
-}
-
-// Clean parameters
-$PAYPAL_API_USER = "";
-if (!empty($conf->global->PAYPAL_API_USER)) {
-       $PAYPAL_API_USER = $conf->global->PAYPAL_API_USER;
-}
-$PAYPAL_API_PASSWORD = "";
-if (!empty($conf->global->PAYPAL_API_PASSWORD)) {
-       $PAYPAL_API_PASSWORD = $conf->global->PAYPAL_API_PASSWORD;
-}
-$PAYPAL_API_SIGNATURE = "";
-if (!empty($conf->global->PAYPAL_API_SIGNATURE)) {
-       $PAYPAL_API_SIGNATURE = $conf->global->PAYPAL_API_SIGNATURE;
-}
-$PAYPAL_API_SANDBOX = "";
-if (!empty($conf->global->PAYPAL_API_SANDBOX)) {
-       $PAYPAL_API_SANDBOX = $conf->global->PAYPAL_API_SANDBOX;
-}
-
-// Proxy
-$PROXY_HOST = $conf->global->MAIN_PROXY_HOST;
-$PROXY_PORT = $conf->global->MAIN_PROXY_PORT;
-$PROXY_USER = $conf->global->MAIN_PROXY_USER;
-$PROXY_PASS = $conf->global->MAIN_PROXY_PASS;
-$USE_PROXY = empty($conf->global->MAIN_PROXY_USE) ?false:true;
diff --git a/htdocs/stripe/admin/stripe.php b/htdocs/stripe/admin/stripe.php
deleted file mode 100644 (file)
index 1c5a507..0000000
+++ /dev/null
@@ -1,627 +0,0 @@
-<?php
-/* Copyright (C) 2017          Alexandre Spangaro              <aspangaro@open-dsi.fr>
- * Copyright (C) 2017          Olivier Geffroy                 <jeff@jeffinfo.com>
- * Copyright (C) 2017          Saasprov                                <saasprov@gmail.com>
- * Copyright (C) 2018-2022  Thibault FOUCART           <support@ptibogxiv.net>
- * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file       htdocs/stripe/admin/stripe.php
- * \ingroup    stripe
- * \brief      Page to setup stripe module
- */
-
-// Load Dolibarr environment
-require '../../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/stripe/lib/stripe.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
-require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
-
-$servicename = 'Stripe';
-
-// Load translation files required by the page
-$langs->loadLangs(array('admin', 'other', 'paypal', 'paybox', 'stripe'));
-
-if (empty($user->admin)) {
-       accessforbidden();
-}
-if (empty($conf->stripe->enabled)) {
-       accessforbidden();
-}
-
-$action = GETPOST('action', 'aZ09');
-
-
-/*
- * Actions
- */
-
-if ($action == 'setvalue' && $user->admin) {
-       $db->begin();
-
-       if (empty($conf->stripeconnect->enabled)) {
-               $result = dolibarr_set_const($db, "STRIPE_TEST_PUBLISHABLE_KEY", GETPOST('STRIPE_TEST_PUBLISHABLE_KEY', 'alpha'), 'chaine', 0, '', $conf->entity);
-               if (!($result > 0)) {
-                       $error++;
-               }
-               $result = dolibarr_set_const($db, "STRIPE_TEST_SECRET_KEY", GETPOST('STRIPE_TEST_SECRET_KEY', 'alpha'), 'chaine', 0, '', $conf->entity);
-               if (!($result > 0)) {
-                       $error++;
-               }
-               $result = dolibarr_set_const($db, "STRIPE_TEST_WEBHOOK_ID", GETPOST('STRIPE_TEST_WEBHOOK_ID', 'alpha'), 'chaine', 0, '', $conf->entity);
-               if (!($result > 0)) {
-                       $error++;
-               }
-               $result = dolibarr_set_const($db, "STRIPE_TEST_WEBHOOK_KEY", GETPOST('STRIPE_TEST_WEBHOOK_KEY', 'alpha'), 'chaine', 0, '', $conf->entity);
-               if (!($result > 0)) {
-                       $error++;
-               }
-               $result = dolibarr_set_const($db, "STRIPE_LIVE_PUBLISHABLE_KEY", GETPOST('STRIPE_LIVE_PUBLISHABLE_KEY', 'alpha'), 'chaine', 0, '', $conf->entity);
-               if (!($result > 0)) {
-                       $error++;
-               }
-               $result = dolibarr_set_const($db, "STRIPE_LIVE_SECRET_KEY", GETPOST('STRIPE_LIVE_SECRET_KEY', 'alpha'), 'chaine', 0, '', $conf->entity);
-               if (!($result > 0)) {
-                       $error++;
-               }
-               $result = dolibarr_set_const($db, "STRIPE_LIVE_WEBHOOK_ID", GETPOST('STRIPE_LIVE_WEBHOOK_ID', 'alpha'), 'chaine', 0, '', $conf->entity);
-               if (!($result > 0)) {
-                       $error++;
-               }
-               $result = dolibarr_set_const($db, "STRIPE_LIVE_WEBHOOK_KEY", GETPOST('STRIPE_LIVE_WEBHOOK_KEY', 'alpha'), 'chaine', 0, '', $conf->entity);
-               if (!($result > 0)) {
-                       $error++;
-               }
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_CREDITOR", GETPOST('ONLINE_PAYMENT_CREDITOR', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "STRIPE_BANK_ACCOUNT_FOR_PAYMENTS", GETPOST('STRIPE_BANK_ACCOUNT_FOR_PAYMENTS', 'int'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "STRIPE_USER_ACCOUNT_FOR_ACTIONS", GETPOST('STRIPE_USER_ACCOUNT_FOR_ACTIONS', 'int'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS", GETPOST('STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS', 'int'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       if (GETPOSTISSET('STRIPE_LOCATION')) {
-               $result = dolibarr_set_const($db, "STRIPE_LOCATION", GETPOST('STRIPE_LOCATION', 'alpha'), 'chaine', 0, '', $conf->entity);
-               if (!$result > 0) {
-                       $error++;
-               }
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_CSS_URL", GETPOST('ONLINE_PAYMENT_CSS_URL', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_MESSAGE_FORM", GETPOST('ONLINE_PAYMENT_MESSAGE_FORM', 'restricthtml'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_MESSAGE_OK", GETPOST('ONLINE_PAYMENT_MESSAGE_OK', 'restricthtml'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_MESSAGE_KO", GETPOST('ONLINE_PAYMENT_MESSAGE_KO', 'restricthtml'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       $result = dolibarr_set_const($db, "ONLINE_PAYMENT_SENDEMAIL", GETPOST('ONLINE_PAYMENT_SENDEMAIL'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       // Stock decrement
-       //$result = dolibarr_set_const($db, "ONLINE_PAYMENT_WAREHOUSE", (GETPOST('ONLINE_PAYMENT_WAREHOUSE', 'alpha') > 0 ? GETPOST('ONLINE_PAYMENT_WAREHOUSE', 'alpha') : ''), 'chaine', 0, '', $conf->entity);
-       //if (! $result > 0)
-       //      $error ++;
-
-       // Payment token for URL
-       $result = dolibarr_set_const($db, "PAYMENT_SECURITY_TOKEN", GETPOST('PAYMENT_SECURITY_TOKEN', 'alpha'), 'chaine', 0, '', $conf->entity);
-       if (!($result > 0)) {
-               $error++;
-       }
-       if (empty($conf->use_javascript_ajax)) {
-               $result = dolibarr_set_const($db, "PAYMENT_SECURITY_TOKEN_UNIQUE", GETPOST('PAYMENT_SECURITY_TOKEN_UNIQUE', 'alpha'), 'chaine', 0, '', $conf->entity);
-               if (!($result > 0)) {
-                       $error++;
-               }
-       }
-
-       if (!$error) {
-               $db->commit();
-               setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
-       } else {
-               $db->rollback();
-               dol_print_error($db);
-       }
-}
-
-if ($action == "setlive") {
-       $liveenable = GETPOST('value', 'int');
-       $res = dolibarr_set_const($db, "STRIPE_LIVE", $liveenable, 'yesno', 0, '', $conf->entity);
-       if ($res > 0) {
-               setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
-       } else {
-               setEventMessages($langs->trans("Error"), null, 'errors');
-       }
-}
-//TODO: import script for stripe account saving in alone or connect mode for stripe.class.php
-
-
-/*
- *     View
- */
-
-$form = new Form($db);
-$formproduct = new FormProduct($db);
-
-llxHeader('', $langs->trans("StripeSetup"));
-
-$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
-print load_fiche_titre($langs->trans("ModuleSetup").' Stripe', $linkback);
-
-$head = stripeadmin_prepare_head();
-
-print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
-print '<input type="hidden" name="token" value="'.newToken().'">';
-print '<input type="hidden" name="action" value="setvalue">';
-
-print dol_get_fiche_head($head, 'stripeaccount', '', -1);
-
-$stripearrayofwebhookevents = array('account.updated', 'payout.created', 'payout.paid', 'charge.pending', 'charge.refunded', 'charge.succeeded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed', 'payment_method.attached', 'payment_method.updated', 'payment_method.card_automatically_updated', 'payment_method.detached', 'source.chargeable', 'customer.deleted');
-
-print '<span class="opacitymedium">'.$langs->trans("StripeDesc")."</span><br>\n";
-
-print '<br>';
-
-print '<div class="div-table-responsive-no-min">';
-print '<table class="noborder centpercent">';
-print '<tr class="liste_titre">';
-print '<td>'.$langs->trans("AccountParameter").'</td>';
-print '<td>'.$langs->trans("Value").'</td>';
-print '<td></td>';
-print "</tr>\n";
-
-print '<tr class="oddeven">';
-print '<td>';
-print $langs->trans("StripeLiveEnabled").'</td><td>';
-if ($conf->use_javascript_ajax) {
-       print ajax_constantonoff('STRIPE_LIVE');
-} else {
-       $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
-       print $form->selectarray("STRIPE_LIVE", $arrval, $conf->global->STRIPE_LIVE);
-}
-print '</td><td></td></tr>';
-
-if (empty($conf->stripeconnect->enabled)) {
-       print '<tr class="oddeven"><td>';
-       print '<span class="fieldrequired">'.$langs->trans("STRIPE_TEST_PUBLISHABLE_KEY").'</span></td><td>';
-       print '<input class="minwidth300" type="text" name="STRIPE_TEST_PUBLISHABLE_KEY" value="'.$conf->global->STRIPE_TEST_PUBLISHABLE_KEY.'" placeholder="'.$langs->trans("Example").': pk_test_xxxxxxxxxxxxxxxxxxxxxxxx">';
-       print '</td><td></td></tr>';
-
-       print '<tr class="oddeven"><td>';
-       print '<span class="titlefield fieldrequired">'.$langs->trans("STRIPE_TEST_SECRET_KEY").'</span></td><td>';
-       print '<input class="minwidth300" type="text" name="STRIPE_TEST_SECRET_KEY" value="'.$conf->global->STRIPE_TEST_SECRET_KEY.'" placeholder="'.$langs->trans("Example").': sk_test_xxxxxxxxxxxxxxxxxxxxxxxx">';
-       print '</td><td></td></tr>';
-
-       print '<tr class="oddeven"><td>';
-       print '<span class="titlefield">'.$langs->trans("STRIPE_TEST_WEBHOOK_KEY").'</span></td><td>';
-       if ($conf->global->MAIN_FEATURES_LEVEL >= 2) {
-               print '<input class="minwidth300" type="text" name="STRIPE_TEST_WEBHOOK_ID" value="'.getDolGlobalString('STRIPE_TEST_WEBHOOK_ID').'" placeholder="'.$langs->trans("Example").': we_xxxxxxxxxxxxxxxxxxxxxxxx">';
-               print '<br>';
-       }
-       print '<input class="minwidth300" type="text" name="STRIPE_TEST_WEBHOOK_KEY" value="'.getDolGlobalString('STRIPE_TEST_WEBHOOK_KEY').'" placeholder="'.$langs->trans("Example").': whsec_xxxxxxxxxxxxxxxxxxxxxxxx">';
-         $out = img_picto('', 'globe').' <span class="opacitymedium">'.$langs->trans("ToOfferALinkForTestWebhook").'</span> ';
-       $url = dol_buildpath('/public/stripe/ipn.php?test', 3);
-       $out .= '<input type="text" id="onlinetestwebhookurl" class="minwidth500" value="'.$url.'" disabled>';
-       $out .= ajax_autoselect("onlinetestwebhookurl", 0);
-       print '<br>'.$out;
-       print '</td><td>';
-       if ($conf->global->MAIN_FEATURES_LEVEL >= 2) {
-               if (!empty($conf->global->STRIPE_TEST_WEBHOOK_KEY) && !empty($conf->global->STRIPE_TEST_SECRET_KEY) && !empty($conf->global->STRIPE_TEST_WEBHOOK_ID)) {
-                       \Stripe\Stripe::setApiKey($conf->global->STRIPE_TEST_SECRET_KEY);
-                       $endpoint = \Stripe\WebhookEndpoint::retrieve($conf->global->STRIPE_TEST_WEBHOOK_ID);
-                       $endpoint->enabled_events = $stripearrayofwebhookevents;
-                       if (GETPOST('webhook', 'alpha') == $conf->global->STRIPE_TEST_WEBHOOK_ID) {
-                               if (!GETPOST('status', 'alpha')) {
-                                       $endpoint->disabled = true;
-                               } else {
-                                       $endpoint->disabled = false;
-                               }
-                       }
-                       $endpoint->url = dol_buildpath('/public/stripe/ipn.php?test', 3);
-                       $endpoint->save();
-                       if ($endpoint->status == 'enabled') {
-                               print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=ipn&webhook='.$endpoint->id.'&status=0">';
-                               print img_picto($langs->trans("Activated"), 'switch_on');
-                       } else {
-                               print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=ipn&webhook='.$endpoint->id.'&status=1">';
-                               print img_picto($langs->trans("Disabled"), 'switch_off');
-                       }
-                       //print $endpoint;
-               } else {
-                       print img_picto($langs->trans("Inactive"), 'statut5');
-               }
-       }
-       print'</td></tr>';
-} else {
-       print '<tr class="oddeven"><td>'.$langs->trans("StripeConnect").'</td>';
-       print '<td><b>'.$langs->trans("StripeConnect_Mode").'</b><br>';
-       print $langs->trans("STRIPE_APPLICATION_FEE_PLATFORM").' ';
-       print price($conf->global->STRIPE_APPLICATION_FEE_PERCENT);
-       print '% + ';
-       print price($conf->global->STRIPE_APPLICATION_FEE);
-       print ' '.$langs->getCurrencySymbol($conf->currency).' '.$langs->trans("minimum").' '.price($conf->global->STRIPE_APPLICATION_FEE_MINIMAL).' '.$langs->getCurrencySymbol($conf->currency);
-       print '</td><td></td></tr>';
-}
-
-if (empty($conf->stripeconnect->enabled)) {
-       print '<tr class="oddeven"><td>';
-       print '<span class="fieldrequired">'.$langs->trans("STRIPE_LIVE_PUBLISHABLE_KEY").'</span></td><td>';
-       print '<input class="minwidth300" type="text" name="STRIPE_LIVE_PUBLISHABLE_KEY" value="'.getDolGlobalString('STRIPE_LIVE_PUBLISHABLE_KEY').'" placeholder="'.$langs->trans("Example").': pk_live_xxxxxxxxxxxxxxxxxxxxxxxx">';
-       print '</td><td></td></tr>';
-
-       print '<tr class="oddeven"><td>';
-       print '<span class="fieldrequired">'.$langs->trans("STRIPE_LIVE_SECRET_KEY").'</span></td><td>';
-       print '<input class="minwidth300" type="text" name="STRIPE_LIVE_SECRET_KEY" value="'.getDolGlobalString('STRIPE_LIVE_SECRET_KEY').'" placeholder="'.$langs->trans("Example").': sk_live_xxxxxxxxxxxxxxxxxxxxxxxx">';
-       print '</td><td></td></tr>';
-
-       print '<tr class="oddeven"><td>';
-       print '<span class="titlefield">'.$langs->trans("STRIPE_LIVE_WEBHOOK_KEY").'</span></td><td>';
-       if ($conf->global->MAIN_FEATURES_LEVEL >= 2) {
-               print '<input class="minwidth300" type="text" name="STRIPE_LIVE_WEBHOOK_ID" value="'.getDolGlobalString('STRIPE_LIVE_WEBHOOK_ID').'" placeholder="'.$langs->trans("Example").': we_xxxxxxxxxxxxxxxxxxxxxxxx">';
-               print '<br>';
-       }
-       print '<input class="minwidth300" type="text" name="STRIPE_LIVE_WEBHOOK_KEY" value="'.getDolGlobalString('STRIPE_LIVE_WEBHOOK_KEY').'" placeholder="'.$langs->trans("Example").': whsec_xxxxxxxxxxxxxxxxxxxxxxxx">';
-       $out = img_picto('', 'globe', 'class="pictofixedwidth"').' <span class="opacitymedium">'.$langs->trans("ToOfferALinkForLiveWebhook").'</span> ';
-       $url = dol_buildpath('/public/stripe/ipn.php', 3);
-       $out .= '<input type="text" id="onlinelivewebhookurl" class="minwidth500" value="'.$url.'" disabled>';
-       $out .= ajax_autoselect("onlinelivewebhookurl", 0);
-       print '<br>'.$out;
-       print '</td><td>';
-       if ($conf->global->MAIN_FEATURES_LEVEL >= 2) {
-               if (!empty($conf->global->STRIPE_LIVE_WEBHOOK_KEY) && !empty($conf->global->STRIPE_LIVE_SECRET_KEY) && !empty($conf->global->STRIPE_LIVE_WEBHOOK_ID)) {
-                       \Stripe\Stripe::setApiKey($conf->global->STRIPE_LIVE_SECRET_KEY);
-                       $endpoint = \Stripe\WebhookEndpoint::retrieve($conf->global->STRIPE_LIVE_WEBHOOK_ID);
-                       $endpoint->enabled_events = $stripearrayofwebhookevents;
-                       if (GETPOST('webhook', 'alpha') == $conf->global->STRIPE_LIVE_WEBHOOK_ID) {
-                               if (empty(GETPOST('status', 'alpha'))) {
-                                       $endpoint->disabled = true;
-                               } else {
-                                       $endpoint->disabled = false;
-                               }
-                       }
-                       $endpoint->url = dol_buildpath('/public/stripe/ipn.php', 3);
-                       $endpoint->save();
-                       if ($endpoint->status == 'enabled') {
-                               print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=ipn&webhook='.$endpoint->id.'&status=0">';
-                               print img_picto($langs->trans("Activated"), 'switch_on');
-                       } else {
-                               print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=ipn&webhook='.$endpoint->id.'&status=1">';
-                               print img_picto($langs->trans("Disabled"), 'switch_off');
-                       }
-                       //print $endpoint;
-               } else {
-                       print img_picto($langs->trans("Inactive"), 'statut5');
-               }
-       }
-       print '</td></tr>';
-} else {
-       print '<tr class="oddeven"><td>'.$langs->trans("StripeConnect").'</td>';
-       print '<td>'.$langs->trans("StripeConnect_Mode").'</td><td></td></tr>';
-}
-
-
-print '</table>';
-print '</div>';
-
-print '<br>';
-
-
-print '<div class="div-table-responsive-no-min">';
-print '<table class="noborder centpercent">';
-print '<tr class="liste_titre">';
-print '<td>'.$langs->trans("UsageParameter").'</td>';
-print '<td>'.$langs->trans("Value").'</td>';
-print "</tr>\n";
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("PublicVendorName").'</td><td>';
-print '<input class="minwidth300" type="text" name="ONLINE_PAYMENT_CREDITOR" value="'.getDolGlobalString('ONLINE_PAYMENT_CREDITOR').'">';
-print ' &nbsp; <span class="opacitymedium">'.$langs->trans("Example").': '.$mysoc->name.'</span>';
-print '</td></tr>';
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("StripeUserAccountForActions").'</td><td>';
-print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers(getDolGlobalString('STRIPE_USER_ACCOUNT_FOR_ACTIONS'), 'STRIPE_USER_ACCOUNT_FOR_ACTIONS', 0);
-print '</td></tr>';
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("BankAccount").'</td><td>';
-print img_picto('', 'bank_account', 'class="pictofixedwidth"');
-$form->select_comptes(getDolGlobalString('STRIPE_BANK_ACCOUNT_FOR_PAYMENTS'), 'STRIPE_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1);
-print '</td></tr>';
-
-if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {     // What is this for ?
-       print '<tr class="oddeven"><td>';
-       print $langs->trans("BankAccountForBankTransfer").'</td><td>';
-       print img_picto('', 'bank_account', 'class="pictofixedwidth"');
-       $form->select_comptes(getDolGlobalString('STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS'), 'STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS', 0, '', 1);
-       print '</td></tr>';
-}
-
-// Card Present for Stripe Terminal
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code
-       print '<tr class="oddeven"><td>';
-       print $langs->trans("STRIPE_CARD_PRESENT").'</td><td>';
-       if ($conf->use_javascript_ajax) {
-               print ajax_constantonoff('STRIPE_CARD_PRESENT');
-       } else {
-               $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
-               print $form->selectarray("STRIPE_CARD_PRESENT", $arrval, $conf->global->STRIPE_CARD_PRESENT);
-       }
-       print '</td></tr>';
-}
-
-// Locations for Stripe Terminal
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code
-       print '<tr class="oddeven"><td>';
-       print $langs->trans("TERMINAL_LOCATION").'</td><td>';
-       $service = 'StripeTest';
-       $servicestatus = 0;
-       if (!empty($conf->global->STRIPE_LIVE) && !GETPOST('forcesandbox', 'alpha')) {
-               $service = 'StripeLive';
-               $servicestatus = 1;
-       }
-       global $stripearrayofkeysbyenv;
-       $site_account = $stripearrayofkeysbyenv[$servicestatus]['secret_key'];
-       if (!empty($site_account)) {
-               \Stripe\Stripe::setApiKey($site_account);
-       }
-       if (isModEnabled('stripe') && (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha'))) {
-               $service = 'StripeTest';
-               $servicestatus = '0';
-               dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning');
-       } else {
-               $service = 'StripeLive';
-               $servicestatus = '1';
-       }
-       $stripe = new Stripe($db);
-       if (!empty($site_account)) {
-               // If $site_account not defined, then key not set and no way to call API Location
-               $stripeacc = $stripe->getStripeAccount($service);
-               if ($stripeacc) {
-                       $locations = \Stripe\Terminal\Location::all('', array("stripe_account" => $stripeacc));
-               } else {
-                       $locations = \Stripe\Terminal\Location::all();
-               }
-       }
-
-       $location = array();
-       $location[""] = $langs->trans("NotDefined");
-       foreach ($locations as $tmplocation) {
-               $location[$tmplocation->id] = $tmplocation->display_name;
-       }
-       print $form->selectarray("STRIPE_LOCATION", $location, getDolGlobalString('STRIPE_LOCATION'));
-       print '</td></tr>';
-}
-
-// Activate Payment Request API
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code
-       print '<tr class="oddeven"><td>';
-       print $langs->trans("STRIPE_PAYMENT_REQUEST_API").' ?? Not used, what is it for ??</td><td>';
-       if ($conf->use_javascript_ajax) {
-               print ajax_constantonoff('STRIPE_PAYMENT_REQUEST_API');
-       } else {
-               $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
-               print $form->selectarray("STRIPE_PAYMENT_REQUEST_API", $arrval, getDolGlobalString('STRIPE_PAYMENT_REQUEST_API'));
-       }
-       print '</td></tr>';
-}
-
-// Activate SEPA DIRECT_DEBIT
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code
-       print '<tr class="oddeven"><td>';
-       print $langs->trans("STRIPE_SEPA_DIRECT_DEBIT").'</td><td>';
-       if ($conf->use_javascript_ajax) {
-               print ajax_constantonoff('STRIPE_SEPA_DIRECT_DEBIT');
-       } else {
-               $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
-               print $form->selectarray("STRIPE_SEPA_DIRECT_DEBIT", $arrval, getDolGlobalString('STRIPE_SEPA_DIRECT_DEBIT'));
-       }
-       print '</td></tr>';
-}
-
-// Activate Klarna
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code
-       print '<tr class="oddeven"><td>';
-       print $langs->trans("STRIPE_KLARNA").'</td><td>';
-       if ($conf->use_javascript_ajax) {
-               print ajax_constantonoff('STRIPE_KLARNA');
-       } else {
-               $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
-               print $form->selectarray("STRIPE_KLARNA", $arrval, $conf->global->STRIPE_KLARNA);
-       }
-       print ' &nbsp; <span class="opacitymedium">'.$langs->trans("ExampleOnlyForKlarnaCustomers").'</span>';
-       print '</td></tr>';
-}
-
-// Activate Bancontact
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code
-       print '<tr class="oddeven"><td>';
-       print $langs->trans("STRIPE_BANCONTACT").'</td><td>';
-       if ($conf->use_javascript_ajax) {
-               print ajax_constantonoff('STRIPE_BANCONTACT');
-       } else {
-               $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
-               print $form->selectarray("STRIPE_BANCONTACT", $arrval, $conf->global->STRIPE_BANCONTACT);
-       }
-       print ' &nbsp; <span class="opacitymedium">'.$langs->trans("ExampleOnlyForBECustomers").'</span>';
-       print '</td></tr>';
-}
-
-// Activate iDEAL
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code
-       print '<tr class="oddeven"><td>';
-       print $langs->trans("STRIPE_IDEAL").'</td><td>';
-       if ($conf->use_javascript_ajax) {
-               print ajax_constantonoff('STRIPE_IDEAL');
-       } else {
-               $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
-               print $form->selectarray("STRIPE_IDEAL", $arrval, $conf->global->STRIPE_SEPA_DIRECT_DEBIT);
-       }
-       print ' &nbsp; <span class="opacitymedium">'.$langs->trans("ExampleOnlyForNLCustomers").'</span>';
-       print '</td></tr>';
-}
-
-// Activate Giropay
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code
-       print '<tr class="oddeven"><td>';
-       print $langs->trans("STRIPE_GIROPAY").'</td><td>';
-       if ($conf->use_javascript_ajax) {
-               print ajax_constantonoff('STRIPE_GIROPAY');
-       } else {
-               $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
-               print $form->selectarray("STRIPE_GIROPAY", $arrval, $conf->global->STRIPE_GIROPAY);
-       }
-       print ' &nbsp; <span class="opacitymedium">'.$langs->trans("ExampleOnlyForDECustomers").'</span>';
-       print '</td></tr>';
-}
-
-// Activate Sofort
-if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code
-       print '<tr class="oddeven"><td>';
-       print $langs->trans("STRIPE_SOFORT").'</td><td>';
-       if ($conf->use_javascript_ajax) {
-               print ajax_constantonoff('STRIPE_SOFORT');
-       } else {
-               $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
-               print $form->selectarray("STRIPE_SOFORT", $arrval, $conf->global->STRIPE_SOFORT);
-       }
-       print ' &nbsp; <span class="opacitymedium">'.$langs->trans("ExampleOnlyForATBEDEITNLESCustomers").'</span>';
-       print '</td></tr>';
-}
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("CSSUrlForPaymentForm").'</td><td>';
-print '<input size="64" type="text" name="ONLINE_PAYMENT_CSS_URL" value="'.$conf->global->ONLINE_PAYMENT_CSS_URL.'">';
-print ' &nbsp; <span class="opacitymedium">'.$langs->trans("Example").': http://mysite/mycss.css</span>';
-print '</td></tr>';
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("MessageForm").'</td><td>';
-$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_FORM', $conf->global->ONLINE_PAYMENT_MESSAGE_FORM, '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_2, '90%');
-$doleditor->Create();
-print '</td></tr>';
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("MessageOK").'</td><td>';
-$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_OK', $conf->global->ONLINE_PAYMENT_MESSAGE_OK, '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_2, '90%');
-$doleditor->Create();
-print '</td></tr>';
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("MessageKO").'</td><td>';
-$doleditor = new DolEditor('ONLINE_PAYMENT_MESSAGE_KO', $conf->global->ONLINE_PAYMENT_MESSAGE_KO, '', 100, 'dolibarr_details', 'In', false, true, true, ROWS_2, '90%');
-$doleditor->Create();
-print '</td></tr>';
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("ONLINE_PAYMENT_SENDEMAIL").'</td><td>';
-print img_picto('', 'email', 'class="pictofixedwidth"');
-print '<input class="minwidth200" type="text" name="ONLINE_PAYMENT_SENDEMAIL" value="'.$conf->global->ONLINE_PAYMENT_SENDEMAIL.'">';
-print ' &nbsp; <span class="opacitymedium">'.$langs->trans("Example").': myemail@myserver.com, Payment service &lt;myemail2@myserver2.com&gt;</span>';
-print '</td></tr>';
-
-print '</table>';
-print '</div>';
-
-print '<br>';
-
-print '<div class="div-table-responsive-no-min">';
-print '<table class="noborder centpercent">';
-
-print '<tr class="liste_titre">';
-print '<td>'.$langs->trans("UrlGenerationParameters").'</td>';
-print '<td>'.$langs->trans("Value").'</td>';
-print "</tr>\n";
-
-// Payment token for URL
-print '<tr class="oddeven"><td>';
-print $langs->trans("SecurityToken").'</td><td>';
-print '<input class="minwidth300"  type="text" id="PAYMENT_SECURITY_TOKEN" name="PAYMENT_SECURITY_TOKEN" value="'.$conf->global->PAYMENT_SECURITY_TOKEN.'">';
-if (!empty($conf->use_javascript_ajax)) {
-       print '&nbsp;'.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token" class="linkobject"');
-}
-if (!empty($conf->global->PAYMENT_SECURITY_ACCEPT_ANY_TOKEN)) {
-       $langs->load("errors");
-       print img_warning($langs->trans("WarningTheHiddenOptionIsOn", 'PAYMENT_SECURITY_ACCEPT_ANY_TOKEN'), '', 'pictowarning marginleftonly');
-}
-print '</td></tr>';
-
-print '<tr class="oddeven"><td>';
-print $langs->trans("SecurityTokenIsUnique").'</td><td>';
-if ($conf->use_javascript_ajax) {
-       print ajax_constantonoff('PAYMENT_SECURITY_TOKEN_UNIQUE', null, null, 0, 0, 1);
-} else {
-       $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
-       print $form->selectarray("PAYMENT_SECURITY_TOKEN_UNIQUE", $arrval, $conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE);
-}
-print '</td></tr>';
-
-print '</table>';
-print '</div>';
-
-print dol_get_fiche_end();
-
-print $form->buttonsSaveCancel("Save", '');
-
-print '</form>';
-
-print '<br><br>';
-
-
-$token = '';
-
-include DOL_DOCUMENT_ROOT.'/core/tpl/onlinepaymentlinks.tpl.php';
-
-print info_admin($langs->trans("ExampleOfTestCreditCard", '4242424242424242 (no 3DSecure) or 4000000000003063 (3DSecure required) or 4000002760003184 (3DSecure2 required on all transaction) or 4000003800000446 (3DSecure2 required, the off-session allowed)', '4000000000000101', '4000000000000069', '4000000000000341'));
-
-if (!empty($conf->use_javascript_ajax)) {
-       print "\n".'<script type="text/javascript">';
-       print '$(document).ready(function () {
-                   $("#apidoc").hide();
-                   $("#apidoca").click(function() {
-                                       console.log("We click on apidoca show/hide");
-                       $("#apidoc").show();
-                       $("#apidoca").hide();
-                                       return false;
-                   });
-                  });';
-       print '</script>';
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/stripe/ajax/ajax.php b/htdocs/stripe/ajax/ajax.php
deleted file mode 100644 (file)
index 5fa4da8..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
- /*  Copyright (C) 2021                Thibault FOUCART        <support@ptibogxiv.net>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file       htdocs/stripe/ajax/ajax.php
- *     \brief      Ajax action for Stipe ie: Terminal
- */
-
-if (!defined('NOTOKENRENEWAL')) {
-       define('NOTOKENRENEWAL', '1');
-}
-if (!defined('NOREQUIREMENU')) {
-       define('NOREQUIREMENU', '1');
-}
-if (!defined('NOREQUIREHTML')) {
-       define('NOREQUIREHTML', '1');
-}
-if (!defined('NOREQUIREAJAX')) {
-       define('NOREQUIREAJAX', '1');
-}
-if (!defined('NOBROWSERNOTIF')) {
-       define('NOBROWSERNOTIF', '1');
-}
-
-// Load Dolibarr environment
-require '../../main.inc.php'; // Load $user and permissions
-require_once DOL_DOCUMENT_ROOT.'/includes/stripe/stripe-php/init.php';
-require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
-require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
-
-$action = GETPOST('action', 'aZ09');
-$location = GETPOST('location', 'alphanohtml');
-$stripeacc = GETPOST('stripeacc', 'alphanohtml');
-$servicestatus = GETPOST('servicestatus', 'int');
-$amount = GETPOST('amount', 'int');
-
-if (empty($user->rights->takepos->run)) {
-       accessforbidden();
-}
-
-
-/*
- * View
- */
-
-top_httphead('application/json');
-
-if ($action == 'getConnexionToken') {
-       try {
-               // Be sure to authenticate the endpoint for creating connection tokens.
-               // Force to use the correct API key
-               global $stripearrayofkeysbyenv;
-               \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$servicestatus]['secret_key']);
-               // The ConnectionToken's secret lets you connect to any Stripe Terminal reader
-               // and take payments with your Stripe account.
-               $array = array();
-               if (isset($location) && !empty($location))  $array['location'] = $location;
-               if (empty($stripeacc)) {                                // If the Stripe connect account not set, we use common API usage
-                       $connectionToken = \Stripe\Terminal\ConnectionToken::create($array);
-               } else {
-                       $connectionToken = \Stripe\Terminal\ConnectionToken::create($array, array("stripe_account" => $stripeacc));
-               }
-               echo json_encode(array('secret' => $connectionToken->secret));
-       } catch (Error $e) {
-               http_response_code(500);
-               echo json_encode(['error' => $e->getMessage()]);
-       }
-} elseif ($action == 'createPaymentIntent') {
-       try {
-               $json_str = file_get_contents('php://input');
-               $json_obj = json_decode($json_str);
-
-               // For Terminal payments, the 'payment_method_types' parameter must include
-               // 'card_present' and the 'capture_method' must be set to 'manual'
-               $object = new Facture($db);
-               $object->fetch($json_obj->invoiceid);
-               $object->fetch_thirdparty();
-
-               $fulltag='INV='.$object->id.'.CUS='.$object->thirdparty->id;
-               $tag=null;
-               $fulltag=dol_string_unaccent($fulltag);
-
-               $stripe = new Stripe($db);
-               $customer = $stripe->customerStripe($object->thirdparty, $stripeacc, $servicestatus, 1);
-
-               $intent = $stripe->getPaymentIntent($json_obj->amount, $object->multicurrency_code, null, 'Stripe payment: '.$fulltag.(is_object($object)?' ref='.$object->ref:''), $object, $customer, $stripeacc, $servicestatus, 1, 'terminal', false, null, 0, 1);
-
-               echo json_encode(array('client_secret' => $intent->client_secret));
-       } catch (Error $e) {
-               http_response_code(500);
-               echo json_encode(['error' => $e->getMessage()]);
-       }
-} elseif ($action == 'capturePaymentIntent') {
-       try {
-               // retrieve JSON from POST body
-               $json_str = file_get_contents('php://input');
-               $json_obj = json_decode($json_str);
-               if (empty($stripeacc)) {                                // If the Stripe connect account not set, we use common API usage
-                       $intent = \Stripe\PaymentIntent::retrieve($json_obj->id);
-               } else {
-                       $intent = \Stripe\PaymentIntent::retrieve($json_obj->id, array("stripe_account" => $stripeacc));
-               }
-               $intent = $intent->capture();
-
-               echo json_encode($intent);
-       } catch (Error $e) {
-               http_response_code(500);
-               echo json_encode(['error' => $e->getMessage()]);
-       }
-}
diff --git a/htdocs/stripe/charge.php b/htdocs/stripe/charge.php
deleted file mode 100644 (file)
index 0aee0c1..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-<?php
-/* Copyright (C) 2018-2022  Thibault FOUCART        <support@ptibogxiv.net>
- * Copyright (C) 2019       Frédéric France         <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-// Put here all includes required by your class file
-
-// Load Dolibarr environment
-require '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
-require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
-require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
-//require_once DOL_DOCUMENT_ROOT.'/core/lib/stripe.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
-require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
-require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
-if (isModEnabled('accounting')) {
-       require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
-}
-
-// Load translation files required by the page
-$langs->loadLangs(array('compta', 'salaries', 'bills', 'hrm', 'stripe'));
-
-// Security check
-$socid = GETPOST("socid", "int");
-if ($user->socid) {
-       $socid = $user->socid;
-}
-//$result = restrictedArea($user, 'salaries', '', '', '');
-
-$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
-$rowid = GETPOST("rowid", 'alpha');
-$sortfield = GETPOST('sortfield', 'aZ09comma');
-$sortorder = GETPOST('sortorder', 'aZ09comma');
-$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
-if (empty($page) || $page == -1) {
-       $page = 0;
-}     // If $page is not defined, or '' or -1
-$offset = $limit * $page;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-
-$result = restrictedArea($user, 'banque');
-$optioncss = GETPOST('optioncss', 'alpha');
-
-/*
- * View
- */
-
-$form = new Form($db);
-$societestatic = new Societe($db);
-$memberstatic = new Adherent($db);
-$acc = new Account($db);
-$stripe = new Stripe($db);
-
-llxHeader('', $langs->trans("StripeChargeList"));
-
-if (isModEnabled('stripe') && (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha'))) {
-       $service = 'StripeTest';
-       $servicestatus = '0';
-       dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning');
-} else {
-       $service = 'StripeLive';
-       $servicestatus = '1';
-}
-
-$stripeacc = $stripe->getStripeAccount($service);
-/*if (empty($stripeaccount))
-{
-       print $langs->trans('ErrorStripeAccountNotDefined');
-}*/
-
-if (!$rowid) {
-       $option = array('limit' => $limit + 1);
-       $num = 0;
-
-       $param = '';
-       $totalnboflines = '';
-       $moreforfilter = '';
-       $list = null;
-       if (GETPOSTISSET('starting_after_'.$page)) {
-               $option['starting_after'] = GETPOST('starting_after_'.$page, 'alphanohtml');
-       }
-       print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
-       if ($optioncss != '') {
-               print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
-       }
-
-       print '<input type="hidden" name="token" value="'.newToken().'">';
-       print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
-       print '<input type="hidden" name="action" value="list">';
-       print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
-       print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
-       print '<input type="hidden" name="page" value="'.$page.'">';
-
-       $title = $langs->trans("StripeChargeList");
-       $title .= ($stripeacc ? ' (Stripe connection with Stripe OAuth Connect account '.$stripeacc.')' : ' (Stripe connection with keys from Stripe module setup)');
-
-       print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $totalnboflines, 'title_accountancy.png', 0, '', 'hidepaginationprevious', $limit);
-
-       print '<div class="div-table-responsive">';
-       print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
-
-       print '<tr class="liste_titre">';
-       print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
-       print_liste_field_titre("StripeCustomerId", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
-       print_liste_field_titre("Customer", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
-       print_liste_field_titre("Origin", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
-       print_liste_field_titre("DatePayment", $_SERVER["PHP_SELF"], "", "", "", '', $sortfield, $sortorder, 'center ');
-       print_liste_field_titre("Type", $_SERVER["PHP_SELF"], "", "", "", '', $sortfield, $sortorder, 'left ');
-       print_liste_field_titre("Paid", $_SERVER["PHP_SELF"], "", "", "", '', $sortfield, $sortorder, 'right ');
-       print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "", "", "", '', '', '', 'right ');
-       print "</tr>\n";
-
-       try {
-               if ($stripeacc) {
-                       $list = \Stripe\Charge::all($option, array("stripe_account" => $stripeacc));
-               } else {
-                       $list = \Stripe\Charge::all($option);
-               }
-
-               $num = count($list->data);
-
-
-               //if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage);
-               if ($limit > 0 && $limit != $conf->liste_limit) {
-                       $param .= '&limit='.urlencode($limit);
-               }
-               $param .= '&starting_after_'.($page + 1).'='.$list->data[($limit - 1)]->id;
-               //$param.='&ending_before_'.($page+1).'='.$list->data[($limit-1)]->id;
-       } catch (Exception $e) {
-               print '<tr><td colspan="6">'.$e->getMessage().'</td></td>';
-       }
-
-       //print $list;
-       $i = 0;
-       if (!empty($list)) {
-               foreach ($list->data as $charge) {
-                       if ($i >= $limit) {
-                               break;
-                       }
-
-                       if ($charge->refunded == '1') {
-                               $status = img_picto($langs->trans("refunded"), 'statut6');
-                       } elseif ($charge->paid == '1') {
-                               $status = img_picto($langs->trans((string) $charge->status), 'statut4');
-                       } else {
-                               $label = $langs->trans("Message").": ".$charge->failure_message."<br>";
-                               $label .= $langs->trans("Network").": ".$charge->outcome->network_status."<br>";
-                               $label .= $langs->trans("Status").": ".$langs->trans((string) $charge->outcome->seller_message);
-                               $status = $form->textwithpicto(img_picto($langs->trans((string) $charge->status), 'statut8'), $label, -1);
-                       }
-
-                       if (isset($charge->payment_method_details->type) && $charge->payment_method_details->type == 'card') {
-                               $type = $langs->trans("card");
-                       } elseif (isset($charge->source->type) && $charge->source->type == 'card') {
-                               $type = $langs->trans("card");
-                       } elseif (isset($charge->payment_method_details->type) && $charge->payment_method_details->type == 'three_d_secure') {
-                               $type = $langs->trans("card3DS");
-                       } elseif (isset($charge->payment_method_details->type) && $charge->payment_method_details->type == 'sepa_debit') {
-                               $type = $langs->trans("sepadebit");
-                       } elseif (isset($charge->payment_method_details->type) && $charge->payment_method_details->type == 'ideal') {
-                               $type = $langs->trans("iDEAL");
-                       }
-
-                       // Why this ?
-                       /*if (!empty($charge->payment_intent)) {
-                        if (empty($stripeacc)) {                               // If the Stripe connect account not set, we use common API usage
-                        $charge = \Stripe\PaymentIntent::retrieve($charge->payment_intent);
-                        } else {
-                        $charge = \Stripe\PaymentIntent::retrieve($charge->payment_intent, array("stripe_account" => $stripeacc));
-                        }
-                        }*/
-
-                       // The metadata FULLTAG is defined by the online payment page
-                       $FULLTAG = $charge->metadata->FULLTAG;
-
-                       // Save into $tmparray all metadata
-                       $tmparray = dolExplodeIntoArray($FULLTAG, '.', '=');
-                       // Load origin object according to metadata
-                       if (!empty($tmparray['CUS']) && $tmparray['CUS'] > 0) {
-                               $societestatic->fetch($tmparray['CUS']);
-                       } elseif (!empty($charge->metadata->dol_thirdparty_id) && $charge->metadata->dol_thirdparty_id > 0) {
-                               $societestatic->fetch($charge->metadata->dol_thirdparty_id);
-                       } else {
-                               $societestatic->id = 0;
-                       }
-                       if (!empty($tmparray['MEM']) && $tmparray['MEM'] > 0) {
-                               $memberstatic->fetch($tmparray['MEM']);
-                       } else {
-                               $memberstatic->id = 0;
-                       }
-
-                       print '<tr class="oddeven">';
-
-                       if (!empty($stripeacc)) {
-                               $connect = $stripeacc.'/';
-                       } else {
-                               $connect = '';
-                       }
-
-                       // Ref
-                       $url = 'https://dashboard.stripe.com/'.$connect.'test/payments/'.$charge->id;
-                       if ($servicestatus) {
-                               $url = 'https://dashboard.stripe.com/'.$connect.'payments/'.$charge->id;
-                       }
-                       print "<td>";
-                       print "<a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'globe')." ".$charge->id."</a>";
-                       if ($charge->payment_intent) {
-                               print '<br><span class="opacitymedium">'.$charge->payment_intent.'</span>';
-                       }
-                       print "</td>\n";
-
-                       // Stripe customer
-                       print "<td>";
-                       if (isModEnabled('stripe') && !empty($stripeacc)) {
-                               $connect = $stripeacc.'/';
-                       }
-                       $url = 'https://dashboard.stripe.com/'.$connect.'test/customers/'.$charge->customer;
-                       if ($servicestatus) {
-                               $url = 'https://dashboard.stripe.com/'.$connect.'customers/'.$charge->customer;
-                       }
-                       if (!empty($charge->customer)) {
-                               print '<a href="'.$url.'" target="_stripe">'.img_picto($langs->trans('ShowInStripe'), 'globe').' '.$charge->customer.'</a>';
-                       }
-                       print "</td>\n";
-
-                       // Link
-                       print "<td>";
-                       if ($societestatic->id > 0) {
-                               print $societestatic->getNomUrl(1);
-                       } elseif ($memberstatic->id > 0) {
-                               print $memberstatic->getNomUrl(1);
-                       }
-                       print "</td>\n";
-
-                       // Origin
-                       print "<td>";
-                       if ($charge->metadata->dol_type == "order" || $charge->metadata->dol_type == "commande") {
-                               $object = new Commande($db);
-                               $object->fetch($charge->metadata->dol_id);
-                               if ($object->id > 0) {
-                                       print "<a href='".DOL_URL_ROOT."/commande/card.php?id=".$object->id."'>".img_picto('', 'order')." ".$object->ref."</a>";
-                               } else {
-                                       print $FULLTAG;
-                               }
-                       } elseif ($charge->metadata->dol_type == "invoice" || $charge->metadata->dol_type == "facture") {
-                               $object = new Facture($db);
-                               $object->fetch($charge->metadata->dol_id);
-                               if ($object->id > 0) {
-                                       print "<a href='".DOL_URL_ROOT."/compta/facture/card.php?facid=".$charge->metadata->dol_id."'>".img_picto('', 'bill')." ".$object->ref."</a>";
-                               } else {
-                                       print $FULLTAG;
-                               }
-                       } else {
-                               print $FULLTAG;
-                       }
-                       print "</td>\n";
-
-                       // Date payment
-                       print '<td class="center">'.dol_print_date($charge->created, 'dayhour')."</td>\n";
-                       // Type
-                       print '<td>';
-                       print $type;
-                       print '</td>';
-                       // Amount
-                       print '<td class="right"><span class="amount">'.price(($charge->amount - $charge->amount_refunded) / 100, 0, '', 1, - 1, - 1, strtoupper($charge->currency))."</span></td>";
-                       // Status
-                       print '<td class="right">';
-                       print $status;
-                       print "</td>\n";
-
-                       print "</tr>\n";
-
-                       $i++;
-               }
-       }
-
-       print '</table>';
-       print '</div>';
-       print '</form>';
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/stripe/class/actions_stripe.class.php b/htdocs/stripe/class/actions_stripe.class.php
deleted file mode 100644 (file)
index 8e5cd83..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-<?php
-/* Copyright (C) 2009-2016 Regis Houssin  <regis.houssin@inodbox.com>
- * Copyright (C) 2011      Herve Prot     <herve.prot@symeos.com>
- * Copyright (C) 2014      Philippe Grand <philippe.grand@atoo-net.com>
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-// TODO File not used. To remove.
-
-/**
- *     \file       htdocs/stripe/class/actions_stripe.class.php
- *     \ingroup    stripe
- *     \brief      File Class actionsstripeconnect
- */
-require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
-
-
-$langs->load("stripe@stripe");
-
-
-/**
- *     Class Actions Stripe Connect
- */
-class ActionsStripeconnect
-{
-       /**
-        * @var DoliDB Database handler.
-        */
-       public $db;
-
-       private $config = array();
-
-       // For Hookmanager return
-       public $resprints;
-       public $results = array();
-
-
-       /**
-        *      Constructor
-        *
-        *      @param  DoliDB  $db             Database handler
-        */
-       public function __construct($db)
-       {
-               $this->db = $db;
-       }
-
-
-       /**
-        * formObjectOptions
-        *
-        * @param       array   $parameters             Parameters
-        * @param       Object  $object                 Object
-        * @param       string  $action                 Action
-        * @return bool
-        */
-       public function formObjectOptions($parameters, &$object, &$action)
-       {
-               global $db, $conf, $user, $langs, $form;
-
-               if (isModEnabled('stripe') && (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha'))) {
-                       $service = 'StripeTest';
-                       dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning');
-               } else {
-                       $service = 'StripeLive';
-               }
-
-               if (is_array($parameters) && !empty($parameters)) {
-                       foreach ($parameters as $key => $value) {
-                               $key = $value;
-                       }
-               }
-
-
-               if (is_object($object) && $object->element == 'societe') {
-                       $this->resprints .= '<tr><td>';
-                       $this->resprints .= '<table width="100%" class="nobordernopadding"><tr><td>';
-                       $this->resprints .= $langs->trans('StripeCustomer');
-                       $this->resprints .= '<td><td class="right">';
-                       //                              $this->resprints.= '<a class="editfielda" href="'.$dolibarr_main_url_root.dol_buildpath('/dolipress/card.php?socid='.$object->id, 1).'">'.img_edit().'</a>';
-                       $this->resprints .= '</td></tr></table>';
-                       $this->resprints .= '</td>';
-                       $this->resprints .= '<td colspan="3">';
-                       $stripe = new Stripe($this->db);
-                       if ($stripe->getStripeAccount($service) && $object->client != 0) {
-                               $customer = $stripe->customerStripe($object, $stripe->getStripeAccount($service));
-                               $this->resprints .= $customer->id;
-                       } else {
-                               $this->resprints .= $langs->trans("NoStripe");
-                       }
-                       $this->resprints .= '</td></tr>';
-               } elseif (is_object($object) && $object->element == 'member') {
-                       $this->resprints .= '<tr><td>';
-                       $this->resprints .= '<table width="100%" class="nobordernopadding"><tr><td>';
-                       $this->resprints .= $langs->trans('StripeCustomer');
-                       $this->resprints .= '<td><td class="right">';
-                       $this->resprints .= '</td></tr></table>';
-                       $this->resprints .= '</td>';
-                       $this->resprints .= '<td colspan="3">';
-                       $stripe = new Stripe($this->db);
-                       if ($stripe->getStripeAccount($service) && $object->fk_soc > 0) {
-                               $object->fetch_thirdparty();
-                               $customer = $stripe->customerStripe($object->thirdparty, $stripe->getStripeAccount($service));
-                               $this->resprints .= $customer->id;
-                       } else {
-                               $this->resprints .= $langs->trans("NoStripe");
-                       }
-                       $this->resprints .= '</td></tr>';
-
-                       $this->resprints .= '<tr><td>';
-                       $this->resprints .= '<table width="100%" class="nobordernopadding"><tr><td>';
-                       $this->resprints .= $langs->trans('SubscriptionStripe');
-                       $this->resprints .= '<td><td class="right">';
-                       $this->resprints .= '</td></tr></table>';
-                       $this->resprints .= '</td>';
-                       $this->resprints .= '<td colspan="3">';
-                       $stripe = new Stripe($this->db);
-                       if (7 == 4) {
-                               $object->fetch_thirdparty();
-                               $customer = $stripe->customerStripe($object, $stripe->getStripeAccount($service));
-                               $this->resprints .= $customer->id;
-                       } else {
-                               $this->resprints .= $langs->trans("NoStripe");
-                       }
-                       $this->resprints .= '</td></tr>';
-               } elseif (is_object($object) && $object->element == 'adherent_type') {
-                       $this->resprints .= '<tr><td>';
-                       $this->resprints .= '<table width="100%" class="nobordernopadding"><tr><td>';
-                       $this->resprints .= $langs->trans('PlanStripe');
-                       $this->resprints .= '<td><td class="right">';
-                       //                              $this->resprints.= '<a class="editfielda" href="'.$dolibarr_main_url_root.dol_buildpath('/dolipress/card.php?socid='.$object->id, 1).'">'.img_edit().'</a>';
-                       $this->resprints .= '</td></tr></table>';
-                       $this->resprints .= '</td>';
-                       $this->resprints .= '<td colspan="3">';
-                       $stripe = new Stripe($this->db);
-                       if (7 == 4) {
-                               $object->fetch_thirdparty();
-                               $customer = $stripe->customerStripe($object, $stripe->getStripeAccount($service));
-                               $this->resprints .= $customer->id;
-                       } else {
-                               $this->resprints .= $langs->trans("NoStripe");
-                       }
-                       $this->resprints .= '</td></tr>';
-               }
-               return 0;
-       }
-
-       /**
-        * addMoreActionsButtons
-        *
-        * @param array         $parameters     Parameters
-        * @param Object        $object         Object
-        * @param string        $action         action
-        * @return int                                  0
-        */
-       public function addMoreActionsButtons($parameters, &$object, &$action)
-       {
-               global $db, $conf, $user, $langs, $form;
-               if (is_object($object) && $object->element == 'facture') {
-                       // On verifie si la facture a des paiements
-                       $sql = 'SELECT pf.amount';
-                       $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf';
-                       $sql .= ' WHERE pf.fk_facture = '.((int) $object->id);
-
-                       $totalpaid = 0;
-
-                       $result = $this->db->query($sql);
-                       if ($result) {
-                               $i = 0;
-                               $num = $this->db->num_rows($result);
-
-                               while ($i < $num) {
-                                       $objp = $this->db->fetch_object($result);
-                                       $totalpaid += $objp->amount;
-                                       $i++;
-                               }
-                       } else {
-                               dol_print_error($this->db, '');
-                       }
-
-                       $resteapayer = $object->total_ttc - $totalpaid;
-                       // Request a direct debit order
-                       if ($object->statut > Facture::STATUS_DRAFT && $object->statut < Facture::STATUS_ABANDONED && $object->paye == 0) {
-                               $stripe = new Stripe($this->db);
-                               if ($resteapayer > 0) {
-                                       if ($stripe->getStripeAccount($conf->entity)) {  // a modifier avec droit stripe
-                                               $langs->load("withdrawals");
-                                               print '<a class="butActionDelete" href="'.dol_buildpath('/stripeconnect/payment.php?facid='.$object->id.'&action=create', 1).'" title="'.dol_escape_htmltag($langs->trans("StripeConnectPay")).'">'.$langs->trans("StripeConnectPay").'</a>';
-                                       } else {
-                                               print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans("StripeConnectPay").'</a>';
-                                       }
-                               } elseif ($resteapayer == 0) {
-                                       print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans("StripeConnectPay").'</a>';
-                               }
-                       } else {
-                               print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans("StripeConnectPay").'</a>';
-                       }
-               } elseif (is_object($object) && $object->element == 'invoice_supplier') {
-                       print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("StripeConnectPay")).'">'.$langs->trans("StripeConnectPay").'</a>';
-               } elseif (is_object($object) && $object->element == 'member') {
-                       print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("StripeAutoSubscription")).'">'.$langs->trans("StripeAutoSubscription").'</a>';
-               }
-               return 0;
-       }
-}
diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php
deleted file mode 100644 (file)
index 7fc1156..0000000
+++ /dev/null
@@ -1,1293 +0,0 @@
-<?php
-/* Copyright (C) 2018-2021     Thibault FOUCART       <support@ptibogxiv.net>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-// Put here all includes required by your class file
-require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
-require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
-require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
-require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
-require_once DOL_DOCUMENT_ROOT.'/stripe/config.php'; // This set stripe global env
-
-
-/**
- *     Stripe class
- */
-class Stripe extends CommonObject
-{
-       /**
-        * @var int ID
-        */
-       public $rowid;
-
-       /**
-        * @var int Thirdparty ID
-        */
-       public $fk_soc;
-
-       /**
-        * @var int ID
-        */
-       public $fk_key;
-
-       /**
-        * @var int ID
-        */
-       public $id;
-
-       public $mode;
-
-       /**
-        * @var int Entity
-        */
-       public $entity;
-
-       public $statut;
-
-       public $type;
-
-       public $code;
-       public $declinecode;
-
-       /**
-        * @var string Message
-        */
-       public $message;
-
-       /**
-        *      Constructor
-        *
-        *      @param  DoliDB          $db                     Database handler
-        */
-       public function __construct($db)
-       {
-               $this->db = $db;
-       }
-
-
-       /**
-        * Return main company OAuth Connect stripe account
-        *
-        * @param       string  $mode           'StripeTest' or 'StripeLive'
-        * @param       int             $fk_soc         Id of thirdparty
-        * @param       int             $entity         Id of entity (-1 = current environment)
-        * @return      string                          Stripe account 'acc_....' or '' if no OAuth token found
-        */
-       public function getStripeAccount($mode = 'StripeTest', $fk_soc = 0, $entity = -1)
-       {
-               global $conf;
-
-               $key = '';
-               if ($entity < 0) {
-                       $entity = $conf->entity;
-               }
-
-               $sql = "SELECT tokenstring";
-               $sql .= " FROM ".MAIN_DB_PREFIX."oauth_token";
-               $sql .= " WHERE service = '".$this->db->escape($mode)."'";
-               $sql .= " AND entity = ".((int) $entity);
-               if ($fk_soc > 0) {
-                       $sql .= " AND fk_soc = ".((int) $fk_soc);
-               } else {
-                       $sql .= " AND fk_soc IS NULL";
-               }
-               $sql .= " AND fk_user IS NULL AND fk_adherent IS NULL";
-
-               dol_syslog(get_class($this)."::getStripeAccount", LOG_DEBUG);
-
-               $result = $this->db->query($sql);
-               if ($result) {
-                       if ($this->db->num_rows($result)) {
-                               $obj = $this->db->fetch_object($result);
-                               $tokenstring = $obj->tokenstring;
-
-                               $tmparray = json_decode($tokenstring);
-                               $key = empty($tmparray->stripe_user_id) ? '' : $tmparray->stripe_user_id;
-                       } else {
-                               $tokenstring = '';
-                       }
-               } else {
-                       dol_print_error($this->db);
-               }
-
-               dol_syslog("No dedicated Stripe Connect account available for entity ".$conf->entity);
-               return $key;
-       }
-
-       /**
-        * getStripeCustomerAccount
-        *
-        * @param       int             $id                             Id of third party
-        * @param       int             $status                 Status
-        * @param       string  $site_account   Value to use to identify with account to use on site when site can offer several accounts. For example: 'pk_live_123456' when using Stripe service.
-        * @return      string                                  Stripe customer ref 'cu_xxxxxxxxxxxxx' or ''
-        */
-       public function getStripeCustomerAccount($id, $status = 0, $site_account = '')
-       {
-               include_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
-               $societeaccount = new SocieteAccount($this->db);
-               return $societeaccount->getCustomerAccount($id, 'stripe', $status, $site_account); // Get thirdparty cus_...
-       }
-
-
-       /**
-        * Get the Stripe customer of a thirdparty (with option to create it in Stripe if not linked yet).
-        * Search on site_account = 0 or = $stripearrayofkeysbyenv[$status]['publishable_key']
-        *
-        * @param       Societe $object                                                 Object thirdparty to check, or create on stripe (create on stripe also update the stripe_account table for current entity)
-        * @param       string  $key                                                    ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect
-        * @param       int             $status                                                 Status (0=test, 1=live)
-        * @param       int             $createifnotlinkedtostripe              1=Create the stripe customer and the link if the thirdparty is not yet linked to a stripe customer
-        * @return      \Stripe\StripeCustomer|null                     Stripe Customer or null if not found
-        */
-       public function customerStripe(Societe $object, $key = '', $status = 0, $createifnotlinkedtostripe = 0)
-       {
-               global $conf, $user;
-
-               if (empty($object->id)) {
-                       dol_syslog("customerStripe is called with the parameter object that is not loaded");
-                       return null;
-               }
-
-               $customer = null;
-
-               // Force to use the correct API key
-               global $stripearrayofkeysbyenv;
-               \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
-
-               $sql = "SELECT sa.key_account as key_account, sa.entity"; // key_account is cus_....
-               $sql .= " FROM ".MAIN_DB_PREFIX."societe_account as sa";
-               $sql .= " WHERE sa.fk_soc = ".((int) $object->id);
-               $sql .= " AND sa.entity IN (".getEntity('societe').")";
-               $sql .= " AND sa.site = 'stripe' AND sa.status = ".((int) $status);
-               $sql .= " AND (sa.site_account IS NULL OR sa.site_account = '' OR sa.site_account = '".$this->db->escape($stripearrayofkeysbyenv[$status]['publishable_key'])."')";
-               $sql .= " AND sa.key_account IS NOT NULL AND sa.key_account <> ''";
-
-               dol_syslog(get_class($this)."::customerStripe search stripe customer id for thirdparty id=".$object->id, LOG_DEBUG);
-               $resql = $this->db->query($sql);
-               if ($resql) {
-                       $num = $this->db->num_rows($resql);
-                       if ($num) {
-                               $obj = $this->db->fetch_object($resql);
-                               $tiers = $obj->key_account;
-
-                               dol_syslog(get_class($this)."::customerStripe found stripe customer key_account = ".$tiers.". We will try to read it on Stripe with publishable_key = ".$stripearrayofkeysbyenv[$status]['publishable_key']);
-
-                               try {
-                                       if (empty($key)) {                              // If the Stripe connect account not set, we use common API usage
-                                               //$customer = \Stripe\Customer::retrieve("$tiers");
-                                               $customer = \Stripe\Customer::retrieve(array('id'=>"$tiers", 'expand[]'=>'sources'));
-                                       } else {
-                                               //$customer = \Stripe\Customer::retrieve("$tiers", array("stripe_account" => $key));
-                                               $customer = \Stripe\Customer::retrieve(array('id'=>"$tiers", 'expand[]'=>'sources'), array("stripe_account" => $key));
-                                       }
-                               } catch (Exception $e) {
-                                       // For exemple, we may have error: 'No such customer: cus_XXXXX; a similar object exists in live mode, but a test mode key was used to make this request.'
-                                       $this->error = $e->getMessage();
-                               }
-                       } elseif ($createifnotlinkedtostripe) {
-                               $ipaddress = getUserRemoteIP();
-
-                               $dataforcustomer = array(
-                                       "email" => $object->email,
-                                       "description" => $object->name,
-                                       "metadata" => array('dol_id'=>$object->id, 'dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress)
-                               );
-
-                               $vatcleaned = $object->tva_intra ? $object->tva_intra : null;
-
-                               /*
-                               $taxinfo = array('type'=>'vat');
-                               if ($vatcleaned)
-                               {
-                                       $taxinfo["tax_id"] = $vatcleaned;
-                               }
-                               // We force data to "null" if not defined as expected by Stripe
-                               if (empty($vatcleaned)) $taxinfo=null;
-                               $dataforcustomer["tax_info"] = $taxinfo;
-                               */
-
-                               //$a = \Stripe\Stripe::getApiKey();
-                               //var_dump($a);var_dump($key);exit;
-                               try {
-                                       // Force to use the correct API key
-                                       global $stripearrayofkeysbyenv;
-                                       \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
-
-                                       if (empty($key)) {                              // If the Stripe connect account not set, we use common API usage
-                                               $customer = \Stripe\Customer::create($dataforcustomer);
-                                       } else {
-                                               $customer = \Stripe\Customer::create($dataforcustomer, array("stripe_account" => $key));
-                                       }
-
-                                       // Create the VAT record in Stripe
-                                       if (!empty($conf->global->STRIPE_SAVE_TAX_IDS)) {       // We setup to save Tax info on Stripe side. Warning: This may result in error when saving customer
-                                               if (!empty($vatcleaned)) {
-                                                       $isineec = isInEEC($object);
-                                                       if ($object->country_code && $isineec) {
-                                                               //$taxids = $customer->allTaxIds($customer->id);
-                                                               $customer->createTaxId($customer->id, array('type'=>'eu_vat', 'value'=>$vatcleaned));
-                                                       }
-                                               }
-                                       }
-
-                                       // Create customer in Dolibarr
-                                       $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_account (fk_soc, login, key_account, site, site_account, status, entity, date_creation, fk_user_creat)";
-                                       $sql .= " VALUES (".((int) $object->id).", '', '".$this->db->escape($customer->id)."', 'stripe', '".$this->db->escape($stripearrayofkeysbyenv[$status]['publishable_key'])."', ".((int) $status).", ".((int) $conf->entity).", '".$this->db->idate(dol_now())."', ".((int) $user->id).")";
-                                       $resql = $this->db->query($sql);
-                                       if (!$resql) {
-                                               $this->error = $this->db->lasterror();
-                                       }
-                               } catch (Exception $e) {
-                                       $this->error = $e->getMessage();
-                               }
-                       }
-               } else {
-                       dol_print_error($this->db);
-               }
-
-               return $customer;
-       }
-
-       /**
-        * Get the Stripe payment method Object from its ID
-        *
-        * @param       string  $paymentmethod                          Payment Method ID
-        * @param       string  $key                                            ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect
-        * @param       int             $status                                         Status (0=test, 1=live)
-        * @return      \Stripe\PaymentMethod|null                      Stripe PaymentMethod or null if not found
-        */
-       public function getPaymentMethodStripe($paymentmethod, $key = '', $status = 0)
-       {
-               $stripepaymentmethod = null;
-
-               try {
-                       // Force to use the correct API key
-                       global $stripearrayofkeysbyenv;
-                       \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
-                       if (empty($key)) {                              // If the Stripe connect account not set, we use common API usage
-                               $stripepaymentmethod = \Stripe\PaymentMethod::retrieve(''.$paymentmethod->id.'');
-                       } else {
-                               $stripepaymentmethod = \Stripe\PaymentMethod::retrieve(''.$paymentmethod->id.'', array("stripe_account" => $key));
-                       }
-               } catch (Exception $e) {
-                       $this->error = $e->getMessage();
-               }
-
-               return $stripepaymentmethod;
-       }
-
-       /**
-        * Get the Stripe reader Object from its ID
-        *
-        * @param       string  $reader                         Reader ID
-        * @param       string  $key                            ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect
-        * @param       int     $status                         Status (0=test, 1=live)
-        * @return      \Stripe\Terminal\Reader|null            Stripe Reader or null if not found
-        */
-       public function getSelectedReader($reader, $key = '', $status = 0)
-       {
-               $selectedreader = null;
-
-               try {
-                       // Force to use the correct API key
-                       global $stripearrayofkeysbyenv;
-                       \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
-                       if (empty($key)) {                              // If the Stripe connect account not set, we use common API usage
-                               $selectedreader = \Stripe\Terminal\Reader::retrieve(''.$reader.'');
-                       } else {
-                               $stripepaymentmethod = \Stripe\Terminal\Reader::retrieve(''.$reader.'', array("stripe_account" => $key));
-                       }
-               } catch (Exception $e) {
-                       $this->error = $e->getMessage();
-               }
-
-               return $selectedreader;
-       }
-
-       /**
-        * Get the Stripe payment intent. Create it with confirmnow=false
-        * Warning. If a payment was tried and failed, a payment intent was created.
-        * But if we change something on object to pay (amount or other), reusing same payment intent is not allowed by Stripe.
-        * Recommended solution is to recreate a new payment intent each time we need one (old one will be automatically closed after a delay),
-        * that's why i comment the part of code to retrieve a payment intent with object id (never mind if we cumulate payment intent with old ones that will not be used)
-        * Note: This is used when option STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION is on when making a payment from the public/payment/newpayment.php page
-        * but not when using the STRIPE_USE_NEW_CHECKOUT.
-        *
-        * @param   double  $amount                             Amount
-        * @param   string  $currency_code                      Currency code
-        * @param   string  $tag                                Tag
-        * @param   string  $description                        Description
-        * @param       mixed   $object                                                     Object to pay with Stripe
-        * @param       string  $customer                                                       Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe()
-        * @param       string  $key                                                        ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect
-        * @param       int             $status                                                     Status (0=test, 1=live)
-        * @param       int             $usethirdpartyemailforreceiptemail      1=use thirdparty email for receipt
-        * @param       int             $mode                                   automatic=automatic confirmation/payment when conditions are ok, manual=need to call confirm() on intent
-        * @param   boolean $confirmnow                         false=default, true=try to confirm immediatly after create (if conditions are ok)
-        * @param   string  $payment_method                     'pm_....' (if known)
-        * @param   string  $off_session                        If we use an already known payment method to pay when customer is not available during the checkout flow.
-        * @param       string  $noidempotency_key                                      Do not use the idempotency_key when creating the PaymentIntent
-        * @return      \Stripe\PaymentIntent|null                              Stripe PaymentIntent or null if not found and failed to create
-        */
-       public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false, $payment_method = null, $off_session = 0, $noidempotency_key = 1)
-       {
-               global $conf, $user;
-
-               dol_syslog(get_class($this)."::getPaymentIntent", LOG_INFO, 1);
-
-               $error = 0;
-
-               if (empty($status)) {
-                       $service = 'StripeTest';
-               } else {
-                       $service = 'StripeLive';
-               }
-
-               $arrayzerounitcurrency = array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
-               if (!in_array($currency_code, $arrayzerounitcurrency)) {
-                       $stripeamount = $amount * 100;
-               } else {
-                       $stripeamount = $amount;
-               }
-
-               $fee = $amount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE;
-               if ($fee >= $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL > $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
-                       $fee = $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL;
-               } elseif ($fee < $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
-                       $fee = $conf->global->STRIPE_APPLICATION_FEE_MINIMAL;
-               }
-               if (!in_array($currency_code, $arrayzerounitcurrency)) {
-                       $stripefee = round($fee * 100);
-               } else {
-                       $stripefee = round($fee);
-               }
-
-               $paymentintent = null;
-
-               if (is_object($object) && getDolGlobalInt('STRIPE_REUSE_EXISTING_INTENT_IF_FOUND') && !getDolGlobalInt('STRIPE_CARD_PRESENT')) {
-                       // Warning. If a payment was tried and failed, a payment intent was created.
-                       // But if we change something on object to pay (amount or other that does not change the idempotency key), reusing same payment intent is not allowed by Stripe.
-                       // Recommended solution is to recreate a new payment intent each time we need one (old one will be automatically closed by Stripe after a delay), Stripe will
-                       // automatically return the existing payment intent if idempotency is provided when we try to create the new one.
-                       // That's why we can comment the part of code to retrieve a payment intent with object id (never mind if we cumulate payment intent with old ones that will not be used)
-
-                       $sql = "SELECT pi.ext_payment_id, pi.entity, pi.fk_facture, pi.sourcetype, pi.ext_payment_site";
-                       $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pi";
-                       $sql .= " WHERE pi.fk_facture = ".((int) $object->id);
-                       $sql .= " AND pi.sourcetype = '".$this->db->escape($object->element)."'";
-                       $sql .= " AND pi.entity IN (".getEntity('societe').")";
-                       $sql .= " AND pi.ext_payment_site = '".$this->db->escape($service)."'";
-
-                       dol_syslog(get_class($this)."::getPaymentIntent search stripe payment intent for object id = ".$object->id, LOG_DEBUG);
-                       $resql = $this->db->query($sql);
-                       if ($resql) {
-                               $num = $this->db->num_rows($resql);
-                               if ($num) {
-                                       $obj = $this->db->fetch_object($resql);
-                                       $intent = $obj->ext_payment_id;
-
-                                       dol_syslog(get_class($this)."::getPaymentIntent found existing payment intent record");
-
-                                       // Force to use the correct API key
-                                       global $stripearrayofkeysbyenv;
-                                       \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
-
-                                       try {
-                                               if (empty($key)) {                              // If the Stripe connect account not set, we use common API usage
-                                                       $paymentintent = \Stripe\PaymentIntent::retrieve($intent);
-                                               } else {
-                                                       $paymentintent = \Stripe\PaymentIntent::retrieve($intent, array("stripe_account" => $key));
-                                               }
-                                       } catch (Exception $e) {
-                                               $error++;
-                                               $this->error = $e->getMessage();
-                                       }
-                               }
-                       }
-               }
-
-               if (empty($paymentintent)) {
-                       // Try to create intent. See https://stripe.com/docs/api/payment_intents/create
-                       $ipaddress = getUserRemoteIP();
-                       $metadata = array('dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress);
-                       if (is_object($object)) {
-                               $metadata['dol_type'] = $object->element;
-                               $metadata['dol_id'] = $object->id;
-                               if (is_object($object->thirdparty) && $object->thirdparty->id > 0) {
-                                       $metadata['dol_thirdparty_id'] = $object->thirdparty->id;
-                               }
-                       }
-
-                       // list of payment method types
-                       $paymentmethodtypes = array("card");
-                       $descriptor = dol_trunc($tag, 10, 'right', 'UTF-8', 1);
-                       if (getDolGlobalInt('STRIPE_SEPA_DIRECT_DEBIT')) {
-                               $paymentmethodtypes[] = "sepa_debit"; //&& ($object->thirdparty->isInEEC())
-                               //$descriptor = preg_replace('/ref=[^:=]+/', '', $descriptor);  // Clean ref
-                       }
-                       if (getDolGlobalInt('STRIPE_KLARNA')) {
-                               $paymentmethodtypes[] = "klarna";
-                       }
-                       if (getDolGlobalInt('STRIPE_BANCONTACT')) {
-                               $paymentmethodtypes[] = "bancontact";
-                       }
-                       if (getDolGlobalInt('STRIPE_IDEAL')) {
-                               $paymentmethodtypes[] = "ideal";
-                       }
-                       if (getDolGlobalInt('STRIPE_GIROPAY')) {
-                               $paymentmethodtypes[] = "giropay";
-                       }
-                       if (getDolGlobalInt('STRIPE_SOFORT')) {
-                               $paymentmethodtypes[] = "sofort";
-                       }
-                       if (getDolGlobalInt('STRIPE_CARD_PRESENT') && $mode == 'terminal') {
-                               $paymentmethodtypes = array("card_present");
-                       }
-
-                       $dataforintent = array(
-                               "confirm" => $confirmnow, // Do not confirm immediatly during creation of intent
-                               "confirmation_method" => $mode,
-                               "amount" => $stripeamount,
-                               "currency" => $currency_code,
-                               "payment_method_types" => $paymentmethodtypes,
-                               "description" => $description,
-                               //"save_payment_method" => true,
-                               "setup_future_usage" => "on_session",
-                               "metadata" => $metadata
-                       );
-                       if ($descriptor) {
-                               $dataforintent["statement_descriptor_suffix"] = $descriptor; // For card payment, 22 chars that appears on bank receipt (prefix into stripe setup + this suffix)
-                               $dataforintent["statement_descriptor"] = $descriptor;   // For SEPA, it will take only statement_descriptor, not statement_descriptor_suffix
-                       }
-                       if (!is_null($customer)) {
-                               $dataforintent["customer"] = $customer;
-                       }
-                       // payment_method =
-                       // payment_method_types = array('card')
-                       //var_dump($dataforintent);
-                       if ($off_session) {
-                               unset($dataforintent['setup_future_usage']);
-                               // We can't use both "setup_future_usage" = "off_session" and "off_session" = true.
-                               // Because $off_session parameter is dedicated to create paymentintent off_line (and not future payment), we need to use "off_session" = true.
-                               //$dataforintent["setup_future_usage"] = "off_session";
-                               $dataforintent["off_session"] = true;
-                       }
-                       if (getDolGlobalInt('STRIPE_GIROPAY')) {
-                               unset($dataforintent['setup_future_usage']);
-                       }
-                       if (getDolGlobalInt('STRIPE_KLARNA')) {
-                               unset($dataforintent['setup_future_usage']);
-                       }
-                       if (getDolGlobalInt('STRIPE_CARD_PRESENT') && $mode == 'terminal') {
-                               unset($dataforintent['setup_future_usage']);
-                               $dataforintent["capture_method"] = "manual";
-                               $dataforintent["confirmation_method"] = "manual";
-                       }
-                       if (!is_null($payment_method)) {
-                               $dataforintent["payment_method"] = $payment_method;
-                               $description .= ' - '.$payment_method;
-                       }
-
-                       if ($conf->entity != getDolGlobalInt('STRIPECONNECT_PRINCIPAL') && $stripefee > 0) {
-                               $dataforintent["application_fee_amount"] = $stripefee;
-                       }
-                       if ($usethirdpartyemailforreceiptemail && is_object($object) && $object->thirdparty->email) {
-                               $dataforintent["receipt_email"] = $object->thirdparty->email;
-                       }
-
-                       try {
-                               // Force to use the correct API key
-                               global $stripearrayofkeysbyenv;
-                               \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
-
-                               $arrayofoptions = array();
-                               if (empty($noidempotency_key)) {
-                                       $arrayofoptions["idempotency_key"] = $description;
-                               }
-                               // Note: If all data for payment intent are same than a previous on, even if we use 'create', Stripe will return ID of the old existing payment intent.
-                               if (!empty($key)) {                             // If the Stripe connect account not set, we use common API usage
-                                       $arrayofoptions["stripe_account"] = $key;
-                               }
-
-                               dol_syslog("dataforintent to create paymentintent = ".var_export($dataforintent, true));
-
-                               $paymentintent = \Stripe\PaymentIntent::create($dataforintent, $arrayofoptions);
-
-                               // Store the payment intent
-                               if (is_object($object)) {
-                                       $paymentintentalreadyexists = 0;
-                                       // Check that payment intent $paymentintent->id is not already recorded.
-                                       $sql = "SELECT pi.rowid";
-                                       $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pi";
-                                       $sql .= " WHERE pi.entity IN (".getEntity('societe').")";
-                                       $sql .= " AND pi.ext_payment_site = '".$this->db->escape($service)."'";
-                                       $sql .= " AND pi.ext_payment_id = '".$this->db->escape($paymentintent->id)."'";
-
-                                       dol_syslog(get_class($this)."::getPaymentIntent search if payment intent already in prelevement_demande", LOG_DEBUG);
-                                       $resql = $this->db->query($sql);
-                                       if ($resql) {
-                                               $num = $this->db->num_rows($resql);
-                                               if ($num) {
-                                                       $obj = $this->db->fetch_object($resql);
-                                                       if ($obj) {
-                                                               $paymentintentalreadyexists++;
-                                                       }
-                                               }
-                                       } else {
-                                               dol_print_error($this->db);
-                                       }
-
-                                       // If not, we create it.
-                                       if (!$paymentintentalreadyexists) {
-                                               $now = dol_now();
-                                               $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_demande (date_demande, fk_user_demande, ext_payment_id, fk_facture, sourcetype, entity, ext_payment_site, amount)";
-                                               $sql .= " VALUES ('".$this->db->idate($now)."', ".((int) $user->id).", '".$this->db->escape($paymentintent->id)."', ".((int) $object->id).", '".$this->db->escape($object->element)."', ".((int) $conf->entity).", '".$this->db->escape($service)."', ".((float) $amount).")";
-                                               $resql = $this->db->query($sql);
-                                               if (!$resql) {
-                                                       $error++;
-                                                       $this->error = $this->db->lasterror();
-                                                       dol_syslog(get_class($this)."::PaymentIntent failed to insert paymentintent with id=".$paymentintent->id." into database.", LOG_ERR);
-                                               }
-                                       }
-                               } else {
-                                       $_SESSION["stripe_payment_intent"] = $paymentintent;
-                               }
-                       } catch (Stripe\Error\Card $e) {
-                               $error++;
-                               $this->error = $e->getMessage();
-                               $this->code = $e->getStripeCode();
-                               $this->declinecode = $e->getDeclineCode();
-                       } catch (Exception $e) {
-                               //var_dump($dataforintent);
-                               //var_dump($description);
-                               //var_dump($key);
-                               //var_dump($paymentintent);
-                               //var_dump($e->getMessage());
-                               //var_dump($e);
-                               $error++;
-                               $this->error = $e->getMessage();
-                               $this->code = '';
-                               $this->declinecode = '';
-                       }
-               }
-
-               dol_syslog(get_class($this)."::getPaymentIntent return error=".$error." this->error=".$this->error, LOG_INFO, -1);
-
-               if (!$error) {
-                       return $paymentintent;
-               } else {
-                       return null;
-               }
-       }
-
-       /**
-        * Get the Stripe payment intent. Create it with confirmnow=false
-        * Warning. If a payment was tried and failed, a payment intent was created.
-        * But if we change something on object to pay (amount or other), reusing same payment intent is not allowed.
-        * Recommanded solution is to recreate a new payment intent each time we need one (old one will be automatically closed after a delay),
-        * that's why i comment the part of code to retrieve a payment intent with object id (never mind if we cumulate payment intent with old ones that will not be used)
-        * Note: This is used when option STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION is on when making a payment from the public/payment/newpayment.php page
-        * but not when using the STRIPE_USE_NEW_CHECKOUT.
-        *
-        * @param   string  $description                        Description
-        * @param       Societe $object                                                     Object to pay with Stripe
-        * @param       string  $customer                                                       Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe()
-        * @param       string  $key                                                        ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect
-        * @param       int             $status                                                     Status (0=test, 1=live)
-        * @param       int             $usethirdpartyemailforreceiptemail      1=use thirdparty email for receipt
-        * @param   boolean $confirmnow                         false=default, true=try to confirm immediatly after create (if conditions are ok)
-        * @return      \Stripe\SetupIntent|null                                Stripe SetupIntent or null if not found and failed to create
-        */
-       public function getSetupIntent($description, $object, $customer, $key, $status, $usethirdpartyemailforreceiptemail = 0, $confirmnow = false)
-       {
-               global $conf;
-
-               dol_syslog("getSetupIntent description=".$description.' confirmnow='.$confirmnow, LOG_INFO, 1);
-
-               $error = 0;
-
-               if (empty($status)) {
-                       $service = 'StripeTest';
-               } else {
-                       $service = 'StripeLive';
-               }
-
-               $setupintent = null;
-
-               if (empty($setupintent)) {
-                       $ipaddress = getUserRemoteIP();
-                       $metadata = array('dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress);
-                       if (is_object($object)) {
-                               $metadata['dol_type'] = $object->element;
-                               $metadata['dol_id'] = $object->id;
-                               if (is_object($object->thirdparty) && $object->thirdparty->id > 0) {
-                                       $metadata['dol_thirdparty_id'] = $object->thirdparty->id;
-                               }
-                       }
-
-                       // list of payment method types
-                       $paymentmethodtypes = array("card");
-                       if (!empty($conf->global->STRIPE_SEPA_DIRECT_DEBIT)) {
-                               $paymentmethodtypes[] = "sepa_debit"; //&& ($object->thirdparty->isInEEC())
-                       }
-                       if (!empty($conf->global->STRIPE_BANCONTACT)) {
-                               $paymentmethodtypes[] = "bancontact";
-                       }
-                       if (!empty($conf->global->STRIPE_IDEAL)) {
-                               $paymentmethodtypes[] = "ideal";
-                       }
-                       // Giropay not possible for setup intent
-                       if (!empty($conf->global->STRIPE_SOFORT)) {
-                               $paymentmethodtypes[] = "sofort";
-                       }
-
-                       $dataforintent = array(
-                               "confirm" => $confirmnow, // Do not confirm immediatly during creation of intent
-                               "payment_method_types" => $paymentmethodtypes,
-                               "usage" => "off_session",
-                               "metadata" => $metadata
-                       );
-                       if (!is_null($customer)) {
-                               $dataforintent["customer"] = $customer;
-                       }
-                       if (!is_null($description)) {
-                               $dataforintent["description"] = $description;
-                       }
-                       // payment_method =
-                       // payment_method_types = array('card')
-                       //var_dump($dataforintent);
-
-                       if ($usethirdpartyemailforreceiptemail && is_object($object) && $object->thirdparty->email) {
-                               $dataforintent["receipt_email"] = $object->thirdparty->email;
-                       }
-
-                       try {
-                               // Force to use the correct API key
-                               global $stripearrayofkeysbyenv;
-                               \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
-
-                               dol_syslog("getSetupIntent ".$stripearrayofkeysbyenv[$status]['publishable_key'], LOG_DEBUG);
-
-                               // Note: If all data for payment intent are same than a previous on, even if we use 'create', Stripe will return ID of the old existing payment intent.
-                               if (empty($key)) {                              // If the Stripe connect account not set, we use common API usage
-                                       //$setupintent = \Stripe\SetupIntent::create($dataforintent, array("idempotency_key" => "$description"));
-                                       $setupintent = \Stripe\SetupIntent::create($dataforintent, array());
-                               } else {
-                                       //$setupintent = \Stripe\SetupIntent::create($dataforintent, array("idempotency_key" => "$description", "stripe_account" => $key));
-                                       $setupintent = \Stripe\SetupIntent::create($dataforintent, array("stripe_account" => $key));
-                               }
-                               //var_dump($setupintent->id);
-
-                               // Store the setup intent
-                               /*if (is_object($object))
-                               {
-                                       $setupintentalreadyexists = 0;
-                                       // Check that payment intent $setupintent->id is not already recorded.
-                                       $sql = "SELECT pi.rowid";
-                                       $sql.= " FROM " . MAIN_DB_PREFIX . "prelevement_demande as pi";
-                                       $sql.= " WHERE pi.entity IN (".getEntity('societe').")";
-                                       $sql.= " AND pi.ext_payment_site = '" . $this->db->escape($service) . "'";
-                                       $sql.= " AND pi.ext_payment_id = '".$this->db->escape($setupintent->id)."'";
-
-                                       dol_syslog(get_class($this) . "::getPaymentIntent search if payment intent already in prelevement_demande", LOG_DEBUG);
-                                       $resql = $this->db->query($sql);
-                                       if ($resql) {
-                                               $num = $this->db->num_rows($resql);
-                                               if ($num)
-                                               {
-                                                       $obj = $this->db->fetch_object($resql);
-                                                       if ($obj) $setupintentalreadyexists++;
-                                               }
-                                       }
-                                       else dol_print_error($this->db);
-
-                                       // If not, we create it.
-                                       if (! $setupintentalreadyexists)
-                                       {
-                                               $now=dol_now();
-                                               $sql = "INSERT INTO " . MAIN_DB_PREFIX . "prelevement_demande (date_demande, fk_user_demande, ext_payment_id, fk_facture, sourcetype, entity, ext_payment_site)";
-                                               $sql .= " VALUES ('".$this->db->idate($now)."', ".((int) $user->id).", '".$this->db->escape($setupintent->id)."', ".((int) $object->id).", '".$this->db->escape($object->element)."', " . ((int) $conf->entity) . ", '" . $this->db->escape($service) . "', ".((float) $amount).")";
-                                               $resql = $this->db->query($sql);
-                                               if (! $resql)
-                                               {
-                                                       $error++;
-                                                       $this->error = $this->db->lasterror();
-                                                       dol_syslog(get_class($this) . "::PaymentIntent failed to insert paymentintent with id=".$setupintent->id." into database.");
-                                               }
-                                       }
-                               }
-                               else
-                               {
-                                       $_SESSION["stripe_setup_intent"] = $setupintent;
-                               }*/
-                       } catch (Exception $e) {
-                               //var_dump($dataforintent);
-                               //var_dump($description);
-                               //var_dump($key);
-                               //var_dump($setupintent);
-                               //var_dump($e->getMessage());
-                               $error++;
-                               $this->error = $e->getMessage();
-                       }
-               }
-
-               if (!$error) {
-                       dol_syslog("getSetupIntent ".(is_object($setupintent) ? $setupintent->id : ''), LOG_INFO, -1);
-                       return $setupintent;
-               } else {
-                       dol_syslog("getSetupIntent return error=".$error, LOG_INFO, -1);
-                       return null;
-               }
-       }
-
-
-       /**
-        * Get the Stripe card of a company payment mode (option to create it on Stripe if not linked yet is no more available on new Stripe API)
-        *
-        * @param       \Stripe\StripeCustomer  $cu                                                             Object stripe customer.
-        * @param       CompanyPaymentMode              $object                                                 Object companypaymentmode to check, or create on stripe (create on stripe also update the societe_rib table for current entity)
-        * @param       string                                  $stripeacc                                              ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect
-        * @param       int                                             $status                                                 Status (0=test, 1=live)
-        * @param       int                                             $createifnotlinkedtostripe              1=Create the stripe card and the link if the card is not yet linked to a stripe card. Deprecated with new Stripe API and SCA.
-        * @return      \Stripe\StripeCard|\Stripe\PaymentMethod|null                   Stripe Card or null if not found
-        */
-       public function cardStripe($cu, CompanyPaymentMode $object, $stripeacc = '', $status = 0, $createifnotlinkedtostripe = 0)
-       {
-               global $conf, $user, $langs;
-
-               $card = null;
-
-               $sql = "SELECT sa.stripe_card_ref, sa.proprio, sa.exp_date_month, sa.exp_date_year, sa.number, sa.cvn"; // stripe_card_ref is card_....
-               $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib as sa";
-               $sql .= " WHERE sa.rowid = ".((int) $object->id); // We get record from ID, no need for filter on entity
-               $sql .= " AND sa.type = 'card'";
-
-               dol_syslog(get_class($this)."::cardStripe search stripe card id for paymentmode id=".$object->id.", stripeacc=".$stripeacc.", status=".$status.", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG);
-               $resql = $this->db->query($sql);
-               if ($resql) {
-                       $num = $this->db->num_rows($resql);
-                       if ($num) {
-                               $obj = $this->db->fetch_object($resql);
-                               $cardref = $obj->stripe_card_ref;
-                               dol_syslog(get_class($this)."::cardStripe cardref=".$cardref);
-                               if ($cardref) {
-                                       try {
-                                               if (empty($stripeacc)) {                                // If the Stripe connect account not set, we use common API usage
-                                                       if (!preg_match('/^pm_/', $cardref) && !empty($cu->sources)) {
-                                                               $card = $cu->sources->retrieve($cardref);
-                                                       } else {
-                                                               $card = \Stripe\PaymentMethod::retrieve($cardref);
-                                                       }
-                                               } else {
-                                                       if (!preg_match('/^pm_/', $cardref) && !empty($cu->sources)) {
-                                                               //$card = $cu->sources->retrieve($cardref, array("stripe_account" => $stripeacc));              // this API fails when array stripe_account is provided
-                                                               $card = $cu->sources->retrieve($cardref);
-                                                       } else {
-                                                               //$card = \Stripe\PaymentMethod::retrieve($cardref, array("stripe_account" => $stripeacc));             // Don't know if this works
-                                                               $card = \Stripe\PaymentMethod::retrieve($cardref);
-                                                       }
-                                               }
-                                       } catch (Exception $e) {
-                                               $this->error = $e->getMessage();
-                                               dol_syslog($this->error, LOG_WARNING);
-                                       }
-                               } elseif ($createifnotlinkedtostripe) {
-                                       $exp_date_month = $obj->exp_date_month;
-                                       $exp_date_year = $obj->exp_date_year;
-                                       $number = $obj->number;
-                                       $cvc = $obj->cvn; // cvn in database, cvc for stripe
-                                       $cardholdername = $obj->proprio;
-
-                                       $ipaddress = getUserRemoteIP();
-
-                                       $dataforcard = array(
-                                               "source" => array('object'=>'card', 'exp_month'=>$exp_date_month, 'exp_year'=>$exp_date_year, 'number'=>$number, 'cvc'=>$cvc, 'name'=>$cardholdername),
-                                               "metadata" => array('dol_id'=>$object->id, 'dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress)
-                                       );
-
-                                       //$a = \Stripe\Stripe::getApiKey();
-                                       //var_dump($a);
-                                       //var_dump($stripeacc);exit;
-                                       try {
-                                               if (empty($stripeacc)) {                                // If the Stripe connect account not set, we use common API usage
-                                                       if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) {
-                                                               dol_syslog("Try to create card with dataforcard = ".json_encode($dataforcard));
-                                                               $card = $cu->sources->create($dataforcard);
-                                                               if (!$card) {
-                                                                       $this->error = 'Creation of card on Stripe has failed';
-                                                               }
-                                                       } else {
-                                                               $connect = '';
-                                                               if (!empty($stripeacc)) {
-                                                                       $connect = $stripeacc.'/';
-                                                               }
-                                                               $url = 'https://dashboard.stripe.com/'.$connect.'test/customers/'.$cu->id;
-                                                               if ($status) {
-                                                                       $url = 'https://dashboard.stripe.com/'.$connect.'customers/'.$cu->id;
-                                                               }
-                                                               $urtoswitchonstripe = ' <a href="'.$url.'" target="_stripe">'.img_picto($langs->trans('ShowInStripe'), 'globe').'</a>';
-
-                                                               //dol_syslog("Error: This case is not supported", LOG_ERR);
-                                                               $this->error = $langs->trans('CreationOfPaymentModeMustBeDoneFromStripeInterface', $urtoswitchonstripe);
-                                                       }
-                                               } else {
-                                                       if (empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) {
-                                                               dol_syslog("Try to create card with dataforcard = ".json_encode($dataforcard));
-                                                               $card = $cu->sources->create($dataforcard, array("stripe_account" => $stripeacc));
-                                                               if (!$card) {
-                                                                       $this->error = 'Creation of card on Stripe has failed';
-                                                               }
-                                                       } else {
-                                                               $connect = '';
-                                                               if (!empty($stripeacc)) {
-                                                                       $connect = $stripeacc.'/';
-                                                               }
-                                                               $url = 'https://dashboard.stripe.com/'.$connect.'test/customers/'.$cu->id;
-                                                               if ($status) {
-                                                                       $url = 'https://dashboard.stripe.com/'.$connect.'customers/'.$cu->id;
-                                                               }
-                                                               $urtoswitchonstripe = ' <a href="'.$url.'" target="_stripe">'.img_picto($langs->trans('ShowInStripe'), 'globe').'</a>';
-
-                                                               //dol_syslog("Error: This case is not supported", LOG_ERR);
-                                                               $this->error = $langs->trans('CreationOfPaymentModeMustBeDoneFromStripeInterface', $urtoswitchonstripe);
-                                                       }
-                                               }
-
-                                               if ($card) {
-                                                       $sql = "UPDATE ".MAIN_DB_PREFIX."societe_rib";
-                                                       $sql .= " SET stripe_card_ref = '".$this->db->escape($card->id)."', card_type = '".$this->db->escape($card->brand)."',";
-                                                       $sql .= " country_code = '".$this->db->escape($card->country)."',";
-                                                       $sql .= " approved = ".($card->cvc_check == 'pass' ? 1 : 0);
-                                                       $sql .= " WHERE rowid = ".((int) $object->id);
-                                                       $sql .= " AND type = 'card'";
-                                                       $resql = $this->db->query($sql);
-                                                       if (!$resql) {
-                                                               $this->error = $this->db->lasterror();
-                                                       }
-                                               }
-                                       } catch (Exception $e) {
-                                               $this->error = $e->getMessage();
-                                               dol_syslog($this->error, LOG_WARNING);
-                                       }
-                               }
-                       }
-               } else {
-                       dol_print_error($this->db);
-               }
-
-               return $card;
-       }
-
-
-       /**
-        * Get the Stripe SEPA of a company payment mode
-        *
-        * @param       \Stripe\StripeCustomer  $cu                                                             Object stripe customer.
-        * @param       CompanyPaymentMode              $object                                                 Object companypaymentmode to check, or create on stripe (create on stripe also update the societe_rib table for current entity)
-        * @param       string                                  $stripeacc                                              ''=Use common API. If not '', it is the Stripe connect account 'acc_....' to use Stripe connect
-        * @param       int                                             $status                                                 Status (0=test, 1=live)
-        * @param       int                                             $createifnotlinkedtostripe              1=Create the stripe sepa and the link if the sepa is not yet linked to a stripe sepa. Deprecated with new Stripe API and SCA.
-        * @return      \Stripe\PaymentMethod|null                      Stripe SEPA or null if not found
-        */
-       public function sepaStripe($cu, CompanyPaymentMode $object, $stripeacc = '', $status = 0, $createifnotlinkedtostripe = 0)
-       {
-               global $conf, $user, $langs;
-               $sepa = null;
-
-               $sql = "SELECT sa.stripe_card_ref, sa.proprio, sa.iban_prefix"; // stripe_card_ref is src_ for sepa
-               $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib as sa";
-               $sql .= " WHERE sa.rowid = ".((int) $object->id); // We get record from ID, no need for filter on entity
-               $sql .= " AND sa.type = 'ban'"; //type ban to get normal bank account of customer (prelevement)
-
-               $soc = new Societe($this->db);
-               $soc->fetch($object->fk_soc);
-
-               dol_syslog(get_class($this)."::sepaStripe search stripe ban id for paymentmode id=".$object->id.", stripeacc=".$stripeacc.", status=".$status.", createifnotlinkedtostripe=".$createifnotlinkedtostripe, LOG_DEBUG);
-               $resql = $this->db->query($sql);
-               if ($resql) {
-                       $num = $this->db->num_rows($resql);
-                       if ($num) {
-                               $obj = $this->db->fetch_object($resql);
-                               $cardref = $obj->stripe_card_ref;
-                               dol_syslog(get_class($this)."::sepaStripe cardref=".$cardref);
-                               if ($cardref) {
-                                       try {
-                                               if (empty($stripeacc)) {                                // If the Stripe connect account not set, we use common API usage
-                                                       if (!preg_match('/^pm_/', $cardref) && !empty($cu->sources)) {
-                                                               $sepa = $cu->sources->retrieve($cardref);
-                                                       } else {
-                                                               $sepa = \Stripe\PaymentMethod::retrieve($cardref);
-                                                       }
-                                               } else {
-                                                       if (!preg_match('/^pm_/', $cardref) && !empty($cu->sources)) {
-                                                               //$sepa = $cu->sources->retrieve($cardref, array("stripe_account" => $stripeacc));              // this API fails when array stripe_account is provided
-                                                               $sepa = $cu->sources->retrieve($cardref);
-                                                       } else {
-                                                               //$sepa = \Stripe\PaymentMethod::retrieve($cardref, array("stripe_account" => $stripeacc));             // Don't know if this works
-                                                               $sepa = \Stripe\PaymentMethod::retrieve($cardref);
-                                                       }
-                                               }
-                                       } catch (Exception $e) {
-                                               $this->error = $e->getMessage();
-                                               dol_syslog($this->error, LOG_WARNING);
-                                       }
-                               } elseif ($createifnotlinkedtostripe) {
-                                       $iban = $obj->iban_prefix; //prefix ?
-                                       $ipaddress = getUserRemoteIP();
-
-                                       $dataforcard = array(
-                                               'type'=>'sepa_debit',
-                                               "sepa_debit" => array('iban' => $iban),
-                                               'currency' => 'eur',
-                                               'usage' => 'reusable',
-                                               'owner' => array(
-                                                       'name' => $soc->name,
-                                               ),
-                                               "metadata" => array('dol_id'=>$object->id, 'dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>$ipaddress)
-                                       );
-
-                                       //$a = \Stripe\Stripe::getApiKey();
-                                       //var_dump($a);var_dump($stripeacc);exit;
-                                       try {
-                                               dol_syslog("Try to create sepa_debit 0");
-
-                                               $service = 'StripeTest';
-                                               $servicestatus = 0;
-                                               if (!empty($conf->global->STRIPE_LIVE) && !GETPOST('forcesandbox', 'alpha')) {
-                                                       $service = 'StripeLive';
-                                                       $servicestatus = 1;
-                                               }
-                                               // Force to use the correct API key
-                                               global $stripearrayofkeysbyenv;
-                                               $stripeacc = $stripearrayofkeysbyenv[$servicestatus]['secret_key'];
-
-                                               dol_syslog("Try to create sepa_debit with data = ".json_encode($dataforcard));
-                                               $s = new \Stripe\StripeClient($stripeacc);
-                                               $sepa = $s->sources->create($dataforcard);
-                                               if (!$sepa) {
-                                                       $this->error = 'Creation of sepa_debit on Stripe has failed';
-                                               } else {
-                                                       // association du client avec cette source de paimeent
-                                                       $cs = $cu->createSource($cu->id, array('source' => $sepa->id));
-                                                       if (!$cs) {
-                                                               $this->error = 'Link SEPA <-> Customer failed';
-                                                       } else {
-                                                               dol_syslog("Try to create sepa_debit 3");
-                                                               // print json_encode($sepa);
-
-                                                               $sql = "UPDATE ".MAIN_DB_PREFIX."societe_rib";
-                                                               $sql .= " SET stripe_card_ref = '".$this->db->escape($sepa->id)."', card_type = 'sepa_debit',";
-                                                               $sql .= " stripe_account= '" . $this->db->escape($cu->id . "@" . $stripeacc) . "'";
-                                                               $sql .= " WHERE rowid = ".((int) $object->id);
-                                                               $sql .= " AND type = 'ban'";
-                                                               $resql = $this->db->query($sql);
-                                                               if (!$resql) {
-                                                                       $this->error = $this->db->lasterror();
-                                                               }
-                                                       }
-                                               }
-                                       } catch (Exception $e) {
-                                               $this->error = $e->getMessage();
-                                               dol_syslog($this->error, LOG_WARNING);
-                                       }
-                               }
-                       }
-               } else {
-                       dol_print_error($this->db);
-               }
-
-               return $sepa;
-       }
-
-       /**
-        * Create charge.
-        * This is called by page htdocs/stripe/payment.php and may be deprecated.
-        *
-        * @param       int     $amount                                                                 Amount to pay
-        * @param       string  $currency                                                               EUR, GPB...
-        * @param       string  $origin                                                                 Object type to pay (order, invoice, contract...)
-        * @param       int     $item                                                                   Object id to pay
-        * @param       string  $source                                                                 src_xxxxx or card_xxxxx or pm_xxxxx
-        * @param       string  $customer                                                               Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe()
-        * @param       string  $account                                                                Stripe account ref 'acc_xxxxxxxxxxxxx' via  getStripeAccount()
-        * @param       int             $status                                                                 Status (0=test, 1=live)
-        * @param       int             $usethirdpartyemailforreceiptemail              Use thirdparty email as receipt email
-        * @param       boolean $capture                                                                Set capture flag to true (take payment) or false (wait)
-        * @return Stripe
-        */
-       public function createPaymentStripe($amount, $currency, $origin, $item, $source, $customer, $account, $status = 0, $usethirdpartyemailforreceiptemail = 0, $capture = true)
-       {
-               global $conf;
-
-               $error = 0;
-
-               if (empty($status)) {
-                       $service = 'StripeTest';
-               } else {
-                       $service = 'StripeLive';
-               }
-
-               $sql = "SELECT sa.key_account as key_account, sa.fk_soc, sa.entity";
-               $sql .= " FROM ".MAIN_DB_PREFIX."societe_account as sa";
-               $sql .= " WHERE sa.key_account = '".$this->db->escape($customer)."'";
-               //$sql.= " AND sa.entity IN (".getEntity('societe').")";
-               $sql .= " AND sa.site = 'stripe' AND sa.status = ".((int) $status);
-
-               dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
-               $result = $this->db->query($sql);
-               if ($result) {
-                       if ($this->db->num_rows($result)) {
-                               $obj = $this->db->fetch_object($result);
-                               $key = $obj->fk_soc;
-                       } else {
-                               $key = null;
-                       }
-               } else {
-                       $key = null;
-               }
-
-               $arrayzerounitcurrency = array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
-               if (!in_array($currency, $arrayzerounitcurrency)) {
-                       $stripeamount = $amount * 100;
-               } else {
-                       $stripeamount = $amount;
-               }
-
-               $societe = new Societe($this->db);
-               if ($key > 0) {
-                       $societe->fetch($key);
-               }
-
-               $description = "";
-               $ref = "";
-               if ($origin == 'order') {
-                       $order = new Commande($this->db);
-                       $order->fetch($item);
-                       $ref = $order->ref;
-                       $description = "ORD=".$ref.".CUS=".$societe->id.".PM=stripe";
-               } elseif ($origin == 'invoice') {
-                       $invoice = new Facture($this->db);
-                       $invoice->fetch($item);
-                       $ref = $invoice->ref;
-                       $description = "INV=".$ref.".CUS=".$societe->id.".PM=stripe";
-               }
-
-               $ipaddress = getUserRemoteIP();
-
-               $metadata = array(
-                       "dol_id" => "".$item."",
-                       "dol_type" => "".$origin."",
-                       "dol_thirdparty_id" => "".$societe->id."",
-                       'dol_thirdparty_name' => $societe->name,
-                       'dol_version'=>DOL_VERSION,
-                       'dol_entity'=>$conf->entity,
-                       'ipaddress'=>$ipaddress
-               );
-               $return = new Stripe($this->db);
-               try {
-                       // Force to use the correct API key
-                       global $stripearrayofkeysbyenv;
-                       \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$status]['secret_key']);
-
-                       if (empty($conf->stripeconnect->enabled)) {     // With a common Stripe account
-                               if (preg_match('/pm_/i', $source)) {
-                                       $stripecard = $source;
-                                       $amountstripe = $stripeamount;
-                                       $FULLTAG = 'PFBO'; // Payment From Back Office
-                                       $stripe = $return;
-                                       $amounttopay = $amount;
-                                       $servicestatus = $status;
-
-                                       dol_syslog("* createPaymentStripe get stripeacc", LOG_DEBUG);
-                                       $stripeacc = $stripe->getStripeAccount($service); // Get Stripe OAuth connect account if it exists (no network access here)
-
-                                       dol_syslog("* createPaymentStripe Create payment for customer ".$customer->id." on source card ".$stripecard->id.", amounttopay=".$amounttopay.", amountstripe=".$amountstripe.", FULLTAG=".$FULLTAG, LOG_DEBUG);
-
-                                       // Create payment intent and charge payment (confirmnow = true)
-                                       $paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $invoice, $customer->id, $stripeacc, $servicestatus, 0, 'automatic', true, $stripecard->id, 1);
-
-                                       $charge = new stdClass();
-                                       if ($paymentintent->status == 'succeeded') {
-                                               $charge->status = 'ok';
-                                       } else {
-                                               $charge->status = 'failed';
-                                               $charge->failure_code = $stripe->code;
-                                               $charge->failure_message = $stripe->error;
-                                               $charge->failure_declinecode = $stripe->declinecode;
-                                               $stripefailurecode = $stripe->code;
-                                               $stripefailuremessage = $stripe->error;
-                                               $stripefailuredeclinecode = $stripe->declinecode;
-                                       }
-                               } elseif (preg_match('/acct_/i', $source)) {
-                                       $charge = \Stripe\Charge::create(array(
-                                               "amount" => "$stripeamount",
-                                               "currency" => "$currency",
-                                               "statement_descriptor_suffix" => dol_trunc($description, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description)
-                                               "description" => "Stripe payment: ".$description,
-                                               "capture"  => $capture,
-                                               "metadata" => $metadata,
-                                               "source" => "$source"
-                                       ));
-                               } else {
-                                       $paymentarray = array(
-                                               "amount" => "$stripeamount",
-                                               "currency" => "$currency",
-                                               "statement_descriptor_suffix" => dol_trunc($description, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description)
-                                               "description" => "Stripe payment: ".$description,
-                                               "capture"  => $capture,
-                                               "metadata" => $metadata,
-                                               "source" => "$source",
-                                               "customer" => "$customer"
-                                       );
-
-                                       if ($societe->email && $usethirdpartyemailforreceiptemail) {
-                                               $paymentarray["receipt_email"] = $societe->email;
-                                       }
-
-                                       $charge = \Stripe\Charge::create($paymentarray, array("idempotency_key" => "$description"));
-                               }
-                       } else {
-                               // With Stripe Connect
-                               $fee = $amount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE;
-                               if ($fee >= $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL && $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL > $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
-                                       $fee = $conf->global->STRIPE_APPLICATION_FEE_MAXIMAL;
-                               } elseif ($fee < $conf->global->STRIPE_APPLICATION_FEE_MINIMAL) {
-                                       $fee = $conf->global->STRIPE_APPLICATION_FEE_MINIMAL;
-                               }
-
-                               if (!in_array($currency, $arrayzerounitcurrency)) {
-                                       $stripefee = round($fee * 100);
-                               } else {
-                                       $stripefee = round($fee);
-                               }
-
-                               $paymentarray = array(
-                                       "amount" => "$stripeamount",
-                                       "currency" => "$currency",
-                               "statement_descriptor_suffix" => dol_trunc($description, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description)
-                                       "description" => "Stripe payment: ".$description,
-                                       "capture"  => $capture,
-                                       "metadata" => $metadata,
-                                       "source" => "$source",
-                                       "customer" => "$customer"
-                               );
-                               if ($conf->entity != $conf->global->STRIPECONNECT_PRINCIPAL && $stripefee > 0) {
-                                       $paymentarray["application_fee_amount"] = $stripefee;
-                               }
-                               if ($societe->email && $usethirdpartyemailforreceiptemail) {
-                                       $paymentarray["receipt_email"] = $societe->email;
-                               }
-
-                               if (preg_match('/pm_/i', $source)) {
-                                       $stripecard = $source;
-                                       $amountstripe = $stripeamount;
-                                       $FULLTAG = 'PFBO'; // Payment From Back Office
-                                       $stripe = $return;
-                                       $amounttopay = $amount;
-                                       $servicestatus = $status;
-
-                                       dol_syslog("* createPaymentStripe get stripeacc", LOG_DEBUG);
-                                       $stripeacc = $stripe->getStripeAccount($service); // Get Stripe OAuth connect account if it exists (no network access here)
-
-                                       dol_syslog("* createPaymentStripe Create payment on card ".$stripecard->id.", amounttopay=".$amounttopay.", amountstripe=".$amountstripe.", FULLTAG=".$FULLTAG, LOG_DEBUG);
-
-                                       // Create payment intent and charge payment (confirmnow = true)
-                                       $paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $invoice, $customer->id, $stripeacc, $servicestatus, 0, 'automatic', true, $stripecard->id, 1);
-
-                                       $charge = new stdClass();
-                                       if ($paymentintent->status == 'succeeded') {
-                                               $charge->status = 'ok';
-                                               $charge->id = $paymentintent->id;
-                                       } else {
-                                               $charge->status = 'failed';
-                                               $charge->failure_code = $stripe->code;
-                                               $charge->failure_message = $stripe->error;
-                                               $charge->failure_declinecode = $stripe->declinecode;
-                                       }
-                               } else {
-                                       $charge = \Stripe\Charge::create($paymentarray, array("idempotency_key" => "$description", "stripe_account" => "$account"));
-                               }
-                       }
-                       if (isset($charge->id)) {
-                       }
-
-                       $return->statut = 'success';
-                       $return->id = $charge->id;
-
-                       if (preg_match('/pm_/i', $source)) {
-                               $return->message = 'Payment retrieved by card status = '.$charge->status;
-                       } else {
-                               if ($charge->source->type == 'card') {
-                                       $return->message = $charge->source->card->brand." ....".$charge->source->card->last4;
-                               } elseif ($charge->source->type == 'three_d_secure') {
-                                       $stripe = new Stripe($this->db);
-                                       $src = \Stripe\Source::retrieve("".$charge->source->three_d_secure->card."", array(
-                                       "stripe_account" => $stripe->getStripeAccount($service)
-                                       ));
-                                       $return->message = $src->card->brand." ....".$src->card->last4;
-                               } else {
-                                       $return->message = $charge->id;
-                               }
-                       }
-               } catch (\Stripe\Error\Card $e) {
-                       include DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
-                       // Since it's a decline, \Stripe\Error\Card will be caught
-                       $body = $e->getJsonBody();
-                       $err = $body['error'];
-
-                       $return->statut = 'error';
-                       $return->id = $err['charge'];
-                       $return->type = $err['type'];
-                       $return->code = $err['code'];
-                       $return->message = $err['message'];
-                       $body = "Error: <br>".$return->id." ".$return->message." ";
-                       $subject = '[Alert] Payment error using Stripe';
-                       $cmailfile = new CMailFile($subject, $conf->global->ONLINE_PAYMENT_SENDEMAIL, $conf->global->MAIN_INFO_SOCIETE_MAIL, $body);
-                       $cmailfile->sendfile();
-
-                       $error++;
-                       dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
-               } catch (\Stripe\Error\RateLimit $e) {
-                       // Too many requests made to the API too quickly
-                       $error++;
-                       dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
-               } catch (\Stripe\Error\InvalidRequest $e) {
-                       // Invalid parameters were supplied to Stripe's API
-                       $error++;
-                       dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
-               } catch (\Stripe\Error\Authentication $e) {
-                       // Authentication with Stripe's API failed
-                       // (maybe you changed API keys recently)
-                       $error++;
-                       dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
-               } catch (\Stripe\Error\ApiConnection $e) {
-                       // Network communication with Stripe failed
-                       $error++;
-                       dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
-               } catch (\Stripe\Error\Base $e) {
-                       // Display a very generic error to the user, and maybe send
-                       // yourself an email
-                       $error++;
-                       dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
-               } catch (Exception $e) {
-                       // Something else happened, completely unrelated to Stripe
-                       $error++;
-                       dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
-               }
-               return $return;
-       }
-}
diff --git a/htdocs/stripe/config.php b/htdocs/stripe/config.php
deleted file mode 100644 (file)
index 453eeb2..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-/* Copyright (C) 2017          Alexandre Spangaro              <aspangaro@open-dsi.fr>
- * Copyright (C) 2017          Saasprov                                <saasprov@gmail.com>
- * Copyright (C) 2017          Ferran Marcet                   <fmarcet@2byte.es.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- *
- * Set Stripe environment: set the ApiKey and AppInfo
- */
-
-/**
-*  \file       htdocs/stripe/config.php
-*  \ingroup    Stripe
-*  \brief      Page to move config in api
-*/
-
-require_once DOL_DOCUMENT_ROOT.'/includes/stripe/stripe-php/init.php';
-require_once DOL_DOCUMENT_ROOT.'/includes/stripe/stripe-php/lib/Stripe.php';
-
-//global $stripe;
-global $conf;
-global $stripearrayofkeysbyenv;
-
-$stripearrayofkeysbyenv = array(
-       0=>array(
-               "secret_key"      => empty($conf->global->STRIPE_TEST_SECRET_KEY) ? '' : $conf->global->STRIPE_TEST_SECRET_KEY,
-               "publishable_key" => empty($conf->global->STRIPE_TEST_PUBLISHABLE_KEY) ? '' : $conf->global->STRIPE_TEST_PUBLISHABLE_KEY
-       ),
-       1=>array(
-               "secret_key"      => empty($conf->global->STRIPE_LIVE_SECRET_KEY) ? '' : $conf->global->STRIPE_LIVE_SECRET_KEY,
-               "publishable_key" => empty($conf->global->STRIPE_LIVE_PUBLISHABLE_KEY) ? '' : $conf->global->STRIPE_LIVE_PUBLISHABLE_KEY
-       )
-);
-
-$stripearrayofkeys = array();
-if (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha')) {
-       $stripearrayofkeys = $stripearrayofkeysbyenv[0]; // Test
-} else {
-       $stripearrayofkeys = $stripearrayofkeysbyenv[1]; // Live
-}
-
-\Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']);
-\Stripe\Stripe::setAppInfo("Dolibarr Stripe", DOL_VERSION, "https://www.dolibarr.org"); // add dolibarr version
-\Stripe\Stripe::setApiVersion(empty($conf->global->STRIPE_FORCE_VERSION) ? "2020-08-27" : $conf->global->STRIPE_FORCE_VERSION); // force version API
diff --git a/htdocs/stripe/lib/stripe.lib.php b/htdocs/stripe/lib/stripe.lib.php
deleted file mode 100644 (file)
index b0503a7..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-<?php
-/* Copyright (C) 2017      Alexandre Spangaro   <aspangaro@open-dsi.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- *     \file                   htdocs/stripe/lib/stripe.lib.php
- *     \ingroup                stripe
- *  \brief                     Library for common stripe functions
- */
-
-require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
-
-/**
- *  Define head array for tabs of stripe tools setup pages
- *
- *  @return                    Array of head
- */
-function stripeadmin_prepare_head()
-{
-       global $langs, $conf;
-
-       $h = 0;
-       $head = array();
-
-       $head[$h][0] = DOL_URL_ROOT."/stripe/admin/stripe.php";
-       $head[$h][1] = $langs->trans("Stripe");
-       $head[$h][2] = 'stripeaccount';
-       $h++;
-
-       $object = new stdClass();
-
-       // Show more tabs from modules
-       // Entries must be declared in modules descriptor with line
-       // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab
-       // $this->tabs = array('entity:-tabname);                                                                                               to remove a tab
-       complete_head_from_modules($conf, $langs, $object, $head, $h, 'stripeadmin');
-
-       complete_head_from_modules($conf, $langs, $object, $head, $h, 'stripeadmin', 'remove');
-
-       return $head;
-}
-
-
-/**
- * Show footer of company in HTML pages
- *
- * @param   Societe            $fromcompany    Third party
- * @param   Translate  $langs                  Output language
- * @return     void
- */
-function html_print_stripe_footer($fromcompany, $langs)
-{
-       global $conf;
-
-       // Juridical status
-       $line1 = "";
-       if ($fromcompany->forme_juridique_code) {
-               $line1 .= ($line1 ? " - " : "").getFormeJuridiqueLabel($fromcompany->forme_juridique_code);
-       }
-       // Capital
-       if ($fromcompany->capital) {
-               $line1 .= ($line1 ? " - " : "").$langs->transnoentities("CapitalOf", $fromcompany->capital)." ".$langs->transnoentities("Currency".$conf->currency);
-       }
-
-       $reg = array();
-
-       // Prof Id 1
-       if ($fromcompany->idprof1 && ($fromcompany->country_code != 'FR' || !$fromcompany->idprof2)) {
-               $field = $langs->transcountrynoentities("ProfId1", $fromcompany->country_code);
-               if (preg_match('/\((.*)\)/i', $field, $reg)) {
-                       $field = $reg[1];
-               }
-               $line1 .= ($line1 ? " - " : "").$field.": ".$fromcompany->idprof1;
-       }
-       // Prof Id 2
-       if ($fromcompany->idprof2) {
-               $field = $langs->transcountrynoentities("ProfId2", $fromcompany->country_code);
-               if (preg_match('/\((.*)\)/i', $field, $reg)) {
-                       $field = $reg[1];
-               }
-               $line1 .= ($line1 ? " - " : "").$field.": ".$fromcompany->idprof2;
-       }
-
-       // Second line of company infos
-       $line2 = "";
-       // Prof Id 3
-       if ($fromcompany->idprof3) {
-               $field = $langs->transcountrynoentities("ProfId3", $fromcompany->country_code);
-               if (preg_match('/\((.*)\)/i', $field, $reg)) {
-                       $field = $reg[1];
-               }
-               $line2 .= ($line2 ? " - " : "").$field.": ".$fromcompany->idprof3;
-       }
-       // Prof Id 4
-       if ($fromcompany->idprof4) {
-               $field = $langs->transcountrynoentities("ProfId4", $fromcompany->country_code);
-               if (preg_match('/\((.*)\)/i', $field, $reg)) {
-                       $field = $reg[1];
-               }
-               $line2 .= ($line2 ? " - " : "").$field.": ".$fromcompany->idprof4;
-       }
-       // IntraCommunautary VAT
-       if ($fromcompany->tva_intra != '') {
-               $line2 .= ($line2 ? " - " : "").$langs->transnoentities("VATIntraShort").": ".$fromcompany->tva_intra;
-       }
-
-       print '<br><br><hr>'."\n";
-       print '<div class="center"><span style="font-size: 10px;">'."\n";
-       print $fromcompany->name.'<br>';
-       print $line1.'<br>';
-       print $line2;
-       print '</span></div>'."\n";
-}
diff --git a/htdocs/stripe/payout.php b/htdocs/stripe/payout.php
deleted file mode 100644 (file)
index 36c798c..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-<?php
-/* Copyright (C) 2018-2023  Thibault FOUCART        <support@ptibogxiv.net>
- * Copyright (C) 2019       Frédéric France         <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-// Put here all includes required by your class file
-
-// Load Dolibarr environment
-require '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
-require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
-require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
-//require_once DOL_DOCUMENT_ROOT.'/core/lib/stripe.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
-require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
-require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
-if (isModEnabled('accounting')) {
-       require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
-}
-
-// Load translation files required by the page
-$langs->loadLangs(array('compta', 'salaries', 'bills', 'hrm', 'stripe'));
-
-// Security check
-$socid = GETPOST("socid", "int");
-if ($user->socid) {
-       $socid = $user->socid;
-}
-//$result = restrictedArea($user, 'salaries', '', '', '');
-
-$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
-$rowid = GETPOST("rowid", 'alpha');
-$sortfield = GETPOST('sortfield', 'aZ09comma');
-$sortorder = GETPOST('sortorder', 'aZ09comma');
-$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
-if (empty($page) || $page == -1) {
-       $page = 0;
-}     // If $page is not defined, or '' or -1
-$offset = $limit * $page;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-$optioncss = GETPOST('optioncss', 'alpha');
-$param = "";
-$num = 0;
-$totalnboflines = 0;
-
-$result = restrictedArea($user, 'banque');
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-$acc = new Account($db);
-$stripe = new Stripe($db);
-
-llxHeader('', $langs->trans("StripePayoutList"));
-
-if (isModEnabled('stripe') && (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha'))) {
-       $service = 'StripeTest';
-       $servicestatus = '0';
-       dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning');
-} else {
-       $service = 'StripeLive';
-       $servicestatus = '1';
-}
-
-$stripeacc = $stripe->getStripeAccount($service);
-/*if (empty($stripeaccount))
-{
-       print $langs->trans('ErrorStripeAccountNotDefined');
-}*/
-
-if (!$rowid) {
-       print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
-       if ($optioncss != '') {
-               print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
-       }
-       print '<input type="hidden" name="token" value="'.newToken().'">';
-       print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
-       print '<input type="hidden" name="action" value="list">';
-       print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
-       print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
-       print '<input type="hidden" name="page" value="'.$page.'">';
-
-       $title = $langs->trans("StripePayoutList");
-       $title .= ($stripeacc ? ' (Stripe connection with Stripe OAuth Connect account '.$stripeacc.')' : ' (Stripe connection with keys from Stripe module setup)');
-
-       print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $totalnboflines, 'title_accountancy.png', 0, '', '', $limit);
-
-       print '<div class="div-table-responsive">';
-       print '<table class="tagtable liste'.(!empty($moreforfilter) ? " listwithfilterbefore" : "").'">'."\n";
-
-       print '<tr class="liste_titre">';
-       print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
-       //print_liste_field_titre("StripeCustomerId",$_SERVER["PHP_SELF"],"","","","",$sortfield,$sortorder);
-       //print_liste_field_titre("CustomerId", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
-       //print_liste_field_titre("Origin", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
-       print_liste_field_titre("DatePayment", $_SERVER["PHP_SELF"], "", "", "", '', $sortfield, $sortorder, 'center ');
-       print_liste_field_titre("DateOperation", $_SERVER["PHP_SELF"], "", "", "", '', $sortfield, $sortorder, 'center ');
-       print_liste_field_titre("Description", $_SERVER["PHP_SELF"], "", "", "", '', $sortfield, $sortorder, 'left ');
-       print_liste_field_titre("Paid", $_SERVER["PHP_SELF"], "", "", "", '', $sortfield, $sortorder, 'right ');
-       print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "", "", "", '', '', '', 'right ');
-       print "</tr>\n";
-
-       print "</tr>\n";
-
-       try {
-               if ($stripeacc) {
-                       $payout = \Stripe\Payout::all(array("limit" => $limit), array("stripe_account" => $stripeacc));
-               } else {
-                       $payout = \Stripe\Payout::all(array("limit" => $limit));
-               }
-
-               foreach ($payout->data as $payout) {
-                       print '<tr class="oddeven">';
-
-                       // Ref
-                       if (!empty($stripeacc)) {
-                               $connect = $stripeacc.'/';
-                       } else $connect = null;
-
-                       $url = 'https://dashboard.stripe.com/'.$connect.'test/payouts/'.$payout->id;
-                       if ($servicestatus) {
-                               $url = 'https://dashboard.stripe.com/'.$connect.'payouts/'.$payout->id;
-                       }
-
-                       print "<td><a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'globe')." ".$payout->id."</a></td>\n";
-
-                       // Date payment
-                       print '<td class="center">'.dol_print_date($payout->created, 'dayhour')."</td>\n";
-                       // Date payment
-                       print '<td class="center">'.dol_print_date($payout->arrival_date, 'dayhour')."</td>\n";
-                       // Type
-                       print '<td>'.$payout->description.'</td>';
-                       // Amount
-                       print '<td class="right"><span class="amount">'.price(($payout->amount) / 100, 0, '', 1, -1, -1, strtoupper($payout->currency))."</span></td>";
-                       // Status
-                       print "<td class='right'>";
-                       if ($payout->status == 'paid') {
-                               print img_picto($langs->trans($payout->status), 'statut4');
-                       } elseif ($payout->status == 'pending') {
-                               print img_picto($langs->trans($payout->status), 'statut7');
-                       } elseif ($payout->status == 'in_transit') {
-                               print img_picto($langs->trans($payout->status), 'statut7');
-                       } elseif ($payout->status == 'failed') {
-                               print img_picto($langs->trans($payout->status), 'statut7');
-                       } elseif ($payout->status == 'canceled') {
-                               print img_picto($langs->trans($payout->status), 'statut8');
-                       }
-                       print '</td>';
-                       print "</tr>\n";
-               }
-       } catch (Exception $e) {
-               print '<tr><td colspan="6">'.$e->getMessage().'</td></td>';
-       }
-       print "</table>";
-       print '</div>';
-       print '</form>';
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/stripe/transaction.php b/htdocs/stripe/transaction.php
deleted file mode 100644 (file)
index 29eec24..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-<?php
-/* Copyright (C) 2018-2019  Thibault FOUCART        <support@ptibogxiv.net>
- * Copyright (C) 2018-2021  Frédéric France         <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-// Put here all includes required by your class file
-
-// Load Dolibarr environment
-require '../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
-require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
-require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
-//require_once DOL_DOCUMENT_ROOT.'/core/lib/stripe.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
-require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
-require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
-if (isModEnabled('accounting')) {
-       require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
-}
-
-// Load translation files required by the page
-$langs->loadLangs(array('compta', 'salaries', 'bills', 'hrm', 'stripe'));
-
-// Security check
-$socid = GETPOST("socid", "int");
-if ($user->socid) {
-       $socid = $user->socid;
-}
-//$result = restrictedArea($user, 'salaries', '', '', '');
-
-$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
-$rowid = GETPOST("rowid", 'alpha');
-$sortfield = GETPOST('sortfield', 'aZ09comma');
-$sortorder = GETPOST('sortorder', 'aZ09comma');
-$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
-if (empty($page) || $page == -1) {
-       $page = 0;
-}     // If $page is not defined, or '' or -1
-$offset = $limit * $page;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-$optioncss = GETPOST('optioncss', 'alpha');
-$param = "";
-$num = 0;
-$totalnboflines = 0;
-$result = restrictedArea($user, 'banque');
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-$societestatic = new Societe($db);
-$memberstatic = new Adherent($db);
-$acc = new Account($db);
-$stripe = new Stripe($db);
-
-llxHeader('', $langs->trans("StripeTransactionList"));
-
-if (isModEnabled('stripe') && (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha'))) {
-       $service = 'StripeTest';
-       $servicestatus = '0';
-       dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning');
-} else {
-       $service = 'StripeLive';
-       $servicestatus = '1';
-}
-$stripeacc = $stripe->getStripeAccount($service);
-/*if (empty($stripeaccount))
-{
-       print $langs->trans('ErrorStripeAccountNotDefined');
-}*/
-
-if (!$rowid) {
-       print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
-       if ($optioncss != '') {
-               print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
-       }
-       print '<input type="hidden" name="token" value="'.newToken().'">';
-       print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
-       print '<input type="hidden" name="action" value="list">';
-       print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
-       print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
-       print '<input type="hidden" name="page" value="'.$page.'">';
-
-       $title = $langs->trans("StripeTransactionList");
-       $title .= (!empty($stripeacc) ? ' (Stripe connection with Stripe OAuth Connect account '.$stripeacc.')' : ' (Stripe connection with keys from Stripe module setup)');
-
-       print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $totalnboflines, 'title_accountancy.png', 0, '', '', $limit);
-
-       print '<div class="div-table-responsive">';
-       print '<table class="tagtable liste'.(!empty($moreforfilter) ? " listwithfilterbefore" : "").'">'."\n";
-
-       print '<tr class="liste_titre">';
-       print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
-       //print_liste_field_titre("StripeCustomerId",$_SERVER["PHP_SELF"],"","","","",$sortfield,$sortorder);
-       //print_liste_field_titre("CustomerId", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
-       //print_liste_field_titre("Origin", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
-       print_liste_field_titre("DatePayment", $_SERVER["PHP_SELF"], "", "", "", '', $sortfield, $sortorder, 'center ');
-       print_liste_field_titre("Type", $_SERVER["PHP_SELF"], "", "", "", '', $sortfield, $sortorder, 'left ');
-       print_liste_field_titre("Paid", $_SERVER["PHP_SELF"], "", "", "", '', $sortfield, $sortorder, 'right ');
-       print_liste_field_titre("Fee", $_SERVER["PHP_SELF"], "", "", "", '', $sortfield, $sortorder, 'right ');
-       print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "", "", "", '', '', '', 'right ');
-       print "</tr>\n";
-       $connect = "";
-
-       try {
-               if ($stripeacc) {
-                       $txn = \Stripe\BalanceTransaction::all(array("limit" => $limit), array("stripe_account" => $stripeacc));
-               } else {
-                       $txn = \Stripe\BalanceTransaction::all(array("limit" => $limit));
-               }
-
-               foreach ($txn->data as $txn) {
-                       //$charge = $txn;
-                       //var_dump($txn);
-
-                       // The metadata FULLTAG is defined by the online payment page
-                       /*$FULLTAG=$charge->metadata->FULLTAG;
-
-                       // Save into $tmparray all metadata
-                       $tmparray = dolExplodeIntoArray($FULLTAG,'.','=');
-                       // Load origin object according to metadata
-                       if (!empty($tmparray['CUS']))
-                       {
-                               $societestatic->fetch($tmparray['CUS']);
-                       }
-                       else
-                       {
-                               $societestatic->id = 0;
-                       }
-                       if (!empty($tmparray['MEM']))
-                       {
-                               $memberstatic->fetch($tmparray['MEM']);
-                       }
-                       else
-                       {
-                               $memberstatic->id = 0;
-                       }
-
-                       $societestatic->fetch($charge->metadata->idcustomer);
-                       $societestatic->id = $charge->metadata->idcustomer;
-                       $societestatic->lastname = $obj->lastname;
-                       $societestatic->firstname = $obj->firstname;
-                       $societestatic->admin = $obj->admin;
-                       $societestatic->login = $obj->login;
-                       $societestatic->email = $obj->email;
-                       $societestatic->societe_id = $obj->fk_soc;*/
-
-                       print '<tr class="oddeven">';
-
-                       // Ref
-                       if (!empty($stripeacc)) {
-                               $connect = $stripeacc.'/';
-                       }
-
-                       // Ref
-                       if (preg_match('/po_/i', $txn->source)) {
-                               $origin = "payouts";
-                       } elseif (preg_match('/fee_/i', $txn->source)) {
-                               $origin = "connect/application_fees";
-                       } else {
-                               $origin = "payments";
-                       }
-
-                       $url = 'https://dashboard.stripe.com/'.$connect.'test/'.$origin.'/'.$txn->source;
-                       if ($servicestatus) {
-                               $url = 'https://dashboard.stripe.com/'.$connect.$origin.'/'.$txn->source;
-                       }
-                       if ($txn->type == 'stripe_fee' || $txn->type == 'reserve_transaction') {
-                               print "<td>".$txn->type."</td>";
-                       } else {
-                               print "<td><a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'globe')." ".$txn->source."</a></td>\n";
-                       }
-
-                       // Stripe customer
-                       //print "<td>".$charge->customer."</td>\n";
-                       // Link
-                       /*print "<td>";
-                       if ($societestatic->id > 0) {
-                               print $societestatic->getNomUrl(1);
-                       }
-                       if ($memberstatic->id > 0) {
-                               print $memberstatic->getNomUrl(1);
-                       }
-                       print "</td>\n";*/
-                       // Origine
-                       //print "<td>";
-                       ////if ($charge->metadata->dol_type=="order"){
-                       //      $object = new Commande($db);
-                       //      $object->fetch($charge->metadata->dol_id);
-                       //      print "<a href='".DOL_URL_ROOT."/commande/card.php?id=".$charge->metadata->dol_id."'>".img_picto('', 'object_order')." ".$object->ref."</a>";
-                       //} elseif ($charge->metadata->dol_type=="invoice"){
-                       //      $object = new Facture($db);
-                       //      $object->fetch($charge->metadata->dol_id);
-                       //      print "<a href='".DOL_URL_ROOT."/compta/facture/card.php?facid=".$charge->metadata->dol_id."'>".img_picto('', 'object_invoice')." ".$object->ref."</a>";
-                       //}
-                       //print "</td>\n";
-                       // Date payment
-                       print '<td class="center">'.dol_print_date($txn->created, 'dayhour')."</td>\n";
-                       // Type
-                       print '<td>'.$txn->type.'</td>';
-                       // Amount
-                       print '<td class="right"><span class="amount">'.price(($txn->amount) / 100, 0, '', 1, - 1, - 1, strtoupper($txn->currency))."</span></td>";
-                       print '<td class="right"><span class="amount">'.price(($txn->fee) / 100, 0, '', 1, - 1, - 1, strtoupper($txn->currency))."</span></td>";
-                       // Status
-                       print "<td class='right'>";
-                       if ($txn->status == 'available') {
-                               print img_picto($langs->trans("".$txn->status.""), 'statut4');
-                       } elseif ($txn->status == 'pending') {
-                               print img_picto($langs->trans("".$txn->status.""), 'statut7');
-                       } elseif ($txn->status == 'failed') {
-                               print img_picto($langs->trans("".$txn->status.""), 'statut8');
-                       }
-                       print '</td>';
-                       print "</tr>\n";
-               }
-       } catch (Exception $e) {
-               print '<tr><td colspan="6">'.$e->getMessage().'</td></td>';
-       }
-       print "</table>";
-       print '</div>';
-       print '</form>';
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/htdocs/zapier/README.md b/htdocs/zapier/README.md
deleted file mode 100644 (file)
index 66c4385..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-Module Zapier
-==============
-
-This is a module to add interface between Zapier and Dolibarr ERP CRM.
-
-
-Documentation
--------------
-
-[Module documentation](https://wiki.dolibarr.org/index.php/Module_Zapier)
diff --git a/htdocs/zapier/admin/about.php b/htdocs/zapier/admin/about.php
deleted file mode 100644 (file)
index 71120a3..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-/* Copyright (C) 2004-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2019 Frédéric FRANCE <frederic.france@free.fr>
- *
- *
- * LICENSE =================================================================
- *
- * 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 <https://www.gnu.org/licenses/>.
- *
- */
-
-/**
- *    \file       htdocs/zapier/admin/about.php
- *    \ingroup    zapier
- *    \brief      About page of module Zapier.
- */
-
-// Load Dolibarr environment
-require '../../main.inc.php';
-
-// Libraries
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-require_once '../lib/zapier.lib.php';
-
-// Translations
-$langs->loadLangs(array('admin', 'errors', 'zapier'));
-
-// Access control
-if (!$user->admin) {
-       accessforbidden();
-}
-
-if (empty($conf->zapier->enabled)) accessforbidden();
-if (empty($user->admin)) accessforbidden();
-
-
-// Parameters
-$action = GETPOST('action', 'aZ09');
-$backtopage = GETPOST('backtopage', 'alpha');
-
-
-
-/*
- * Actions
- */
-
-// None
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-$page_name = "ZapierAbout";
-$help_url = 'EN:Module_Zapier';
-llxHeader('', $langs->trans($page_name), $help_url);
-
-// Subheader
-$linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1').'">'.$langs->trans("BackToModuleList").'</a>';
-
-print load_fiche_titre($langs->trans($page_name), $linkback, 'object_zapier');
-
-// Configuration header
-$head = zapierAdminPrepareHead();
-print dol_get_fiche_head($head, 'about', '', 0, 'zapier');
-
-dol_include_once('/core/modules/modZapier.class.php');
-$tmpmodule = new modZapier($db);
-print $tmpmodule->getDescLong();
-
-// Page end
-print dol_get_fiche_end();
-llxFooter();
-$db->close();
diff --git a/htdocs/zapier/admin/setup.php b/htdocs/zapier/admin/setup.php
deleted file mode 100644 (file)
index 6737d23..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-/* Copyright (C) 2004-2017  Laurent Destailleur     <eldy@users.sourceforge.net>
- * Copyright (C) 2019       Frédéric FRANCE         <frederic.france@free.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    zapier/admin/setup.php
- * \ingroup zapier
- * \brief   Zapier setup page.
- */
-
-// Load Dolibarr environment
-require '../../main.inc.php';
-
-// Libraries
-require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/zapier/lib/zapier.lib.php';
-
-// Translations
-$langs->loadLangs(array('admin', 'zapier'));
-
-// Access control
-if (!$user->admin) {
-       accessforbidden();
-}
-
-// Parameters
-$action = GETPOST('action', 'aZ09');
-$backtopage = GETPOST('backtopage', 'alpha');
-
-$arrayofparameters = array(
-//     'ZAPIERFORDOLIBARR_MYPARAM1'=>array('css'=>'minwidth200', 'enabled'=>1),
-//     'ZAPIERFORDOLIBARR_MYPARAM2'=>array('css'=>'minwidth500', 'enabled'=>1)
-);
-
-if (empty($conf->zapier->enabled)) accessforbidden();
-if (empty($user->admin)) accessforbidden();
-
-
-/*
- * Actions
- */
-
-if ((float) DOL_VERSION >= 6) {
-       include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
-}
-
-
-/*
- * View
- */
-
-$page_name = 'ZapierForDolibarrSetup';
-$help_url = 'EN:Module_Zapier';
-llxHeader('', $langs->trans($page_name), $help_url);
-
-// Subheader
-$linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1').'">'.$langs->trans("BackToModuleList").'</a>';
-
-print load_fiche_titre($langs->trans($page_name), $linkback, 'object_zapier');
-
-// Configuration header
-$head = zapierAdminPrepareHead();
-print dol_get_fiche_head($head, 'settings', '', -1, "zapier");
-
-
-if ($action == 'edit') {
-       print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
-       print '<input type="hidden" name="token" value="'.newToken().'">';
-       print '<input type="hidden" name="action" value="update">';
-
-       print '<table class="noborder centpercent">';
-       print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
-
-       foreach ($arrayofparameters as $key => $val) {
-               print '<tr class="oddeven"><td>';
-               print $form->textwithpicto($langs->trans($key), $langs->trans($key.'Tooltip'));
-               print '</td><td><input name="'.$key.'"  class="flat '.(empty($val['css']) ? 'minwidth200' : $val['css']).'" value="'.getDolGlobalString($key).'"></td></tr>';
-       }
-       print '</table>';
-
-       print '<br><div class="center">';
-       print '<input class="button button-save" type="submit" value="'.$langs->trans("Save").'">';
-       print '</div>';
-
-       print '</form>';
-       print '<br>';
-} else {
-       if (!empty($arrayofparameters)) {
-               print '<table class="noborder centpercent">';
-               print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
-
-               foreach ($arrayofparameters as $key => $val) {
-                       print '<tr class="oddeven"><td>';
-                       print $form->textwithpicto($langs->trans($key), $langs->trans($key.'Tooltip'));
-                       print '</td><td>'.getDolGlobalString($key).'</td></tr>';
-               }
-
-               print '</table>';
-
-               print '<div class="tabsAction">';
-               print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'">'.$langs->trans("Modify").'</a>';
-               print '</div>';
-       } else {
-               // Setup page goes here
-               echo '<br><br><span class="opacitymediumdisabled">'.$langs->trans("ZapierSetupPage").'</span><br><br>';
-               //print '<br>'.$langs->trans("NothingToSetup");
-       }
-}
-
-
-// Page end
-print dol_get_fiche_end();
-
-llxFooter();
-$db->close();
diff --git a/htdocs/zapier/class/api_zapier.class.php b/htdocs/zapier/class/api_zapier.class.php
deleted file mode 100644 (file)
index 3db4006..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
-<?php
-/* Copyright (C) 2015       Jean-François Ferry     <jfefe@aternatik.fr>
- * Copyright (C) 2019-2020  Frédéric France         <frederic.france@netlogic.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    htdocs/zapier/class/api_zapier.class.php
- * \ingroup zapier
- * \brief   File for API management of hook.
- */
-
-use Luracast\Restler\RestException;
-
-require_once DOL_DOCUMENT_ROOT.'/zapier/class/hook.class.php';
-
-
-/**
- * API class for zapier hook
- *
- * @access protected
- * @class  DolibarrApiAccess {@requires user,external}
- */
-class Zapier extends DolibarrApi
-{
-       /**
-        * @var array   $FIELDS     Mandatory fields, checked when create and update object
-        */
-       public static $FIELDS = array(
-               'url',
-       );
-
-
-       /**
-        * @var Hook $hook {@type Hook}
-        */
-       public $hook;
-
-       /**
-        * Constructor
-        *
-        * @url     GET /
-        *
-        */
-       public function __construct()
-       {
-               global $db, $conf;
-               $this->db = $db;
-               $this->hook = new Hook($this->db);
-       }
-
-       /**
-        * Get properties of a hook object
-        *
-        * Return an array with hook informations
-        *
-        * @param   int             $id ID of hook
-        * @return  array|mixed     data without useless information
-        *
-        * @url GET /hooks/{id}
-        * @throws  RestException
-        */
-       public function get($id)
-       {
-               if (!DolibarrApiAccess::$user->rights->zapier->read) {
-                       throw new RestException(401);
-               }
-
-               $result = $this->hook->fetch($id);
-               if (!$result) {
-                       throw new RestException(404, 'Hook not found');
-               }
-
-               if (!DolibarrApi::_checkAccessToResource('hook', $this->hook->id)) {
-                       throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
-               }
-
-               return $this->_cleanObjectDatas($this->hook);
-       }
-
-       /**
-        * Get list of possibles choices for module
-        *
-        * Return an array with hook informations
-        *
-        * @return  array     data
-        *
-        * @url GET /getmoduleschoices/
-        * @throws  RestException
-        */
-       public function getModulesChoices()
-       {
-               if (!DolibarrApiAccess::$user->rights->zapier->read) {
-                       throw new RestException(401);
-               }
-
-               $arraychoices = array(
-                       'invoices' => 'Invoices',
-                       'orders' => 'Orders',
-                       'thirdparties' => 'Thirparties',
-                       'contacts' => 'Contacts',
-                       'users' => 'Users',
-               );
-               // $result = $this->hook->fetch($id);
-               // if (! $result ) {
-               //     throw new RestException(404, 'Hook not found');
-               // }
-
-               // if (! DolibarrApi::_checkAccessToResource('hook', $this->hook->id)) {
-               //     throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
-               // }
-
-               return $arraychoices;
-       }
-
-       /**
-        * List hooks
-        *
-        * Get a list of hooks
-        *
-        * @param string           $sortfield           Sort field
-        * @param string           $sortorder           Sort order
-        * @param int              $limit               Limit for list
-        * @param int              $page                Page number
-        * @param string           $sqlfilters          Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
-        * @return  array                               Array of order objects
-        *
-        * @throws RestException
-        *
-        * @url GET /hooks/
-        */
-       public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
-       {
-               global $db, $conf;
-
-               if (!DolibarrApiAccess::$user->rights->zapier->read) {
-                       throw new RestException(401);
-               }
-
-               $obj_ret = array();
-
-               $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : '';
-
-               // Set to 1 if there is a field socid in table of object
-               $restrictonsocid = 0;
-
-               // If the internal user must only see his customers, force searching by him
-               $search_sale = 0;
-               if ($restrictonsocid && !DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) {
-                       $search_sale = DolibarrApiAccess::$user->id;
-               }
-
-               $sql = "SELECT t.rowid";
-               if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
-                       // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
-                       $sql .= ", sc.fk_soc, sc.fk_user";
-               }
-               $sql .= " FROM ".MAIN_DB_PREFIX."hook_mytable as t";
-
-               if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
-                       $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
-               }
-               $sql .= " WHERE 1 = 1";
-
-               // Example of use $mode
-               //if ($mode == 1) $sql.= " AND s.client IN (1, 3)";
-               //if ($mode == 2) $sql.= " AND s.client IN (2, 3)";
-
-               $tmpobject = new Hook($this->db);
-               if ($tmpobject->ismultientitymanaged) {
-                       $sql .= ' AND t.entity IN ('.getEntity('hook').')';
-               }
-               if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
-                       $sql .= " AND t.fk_soc = sc.fk_soc";
-               }
-               if ($restrictonsocid && $socid) {
-                       $sql .= " AND t.fk_soc = ".((int) $socid);
-               }
-               if ($restrictonsocid && $search_sale > 0) {
-                       // Join for the needed table to filter by sale
-                       $sql .= " AND t.rowid = sc.fk_soc";
-               }
-               // Insert sale filter
-               if ($restrictonsocid && $search_sale > 0) {
-                       $sql .= " AND sc.fk_user = ".((int) $search_sale);
-               }
-               if ($sqlfilters) {
-                       $errormessage = '';
-                       $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
-                       if ($errormessage) {
-                               throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
-                       }
-               }
-
-               $sql .= $this->db->order($sortfield, $sortorder);
-               if ($limit) {
-                       if ($page < 0) {
-                               $page = 0;
-                       }
-                       $offset = $limit * $page;
-
-                       $sql .= $this->db->plimit($limit + 1, $offset);
-               }
-
-               $result = $this->db->query($sql);
-               $i = 0;
-               if ($result) {
-                       $num = $this->db->num_rows($result);
-                       while ($i < $num) {
-                               $obj = $this->db->fetch_object($result);
-                               $hook_static = new Hook($this->db);
-                               if ($hook_static->fetch($obj->rowid)) {
-                                       $obj_ret[] = $this->_cleanObjectDatas($hook_static);
-                               }
-                               $i++;
-                       }
-               } else {
-                       throw new RestException(503, 'Error when retrieve hook list');
-               }
-               if (!count($obj_ret)) {
-                       throw new RestException(404, 'No hook found');
-               }
-               return $obj_ret;
-       }
-
-       /**
-        * Create hook object
-        *
-        * @param array $request_data   Request datas
-        * @return int  ID of hook
-        *
-        * @url POST /hook/
-        */
-       public function post($request_data = null)
-       {
-               if (!DolibarrApiAccess::$user->rights->zapier->write) {
-                       throw new RestException(401);
-               }
-
-               // Check mandatory fields
-               $fields = array(
-                       'url',
-               );
-               dol_syslog("API Zapier create hook receive : ".print_r($request_data, true), LOG_DEBUG);
-               $result = $this->validate($request_data, $fields);
-
-               foreach ($request_data as $field => $value) {
-                       $this->hook->$field = $value;
-               }
-               $this->hook->fk_user = DolibarrApiAccess::$user->id;
-               // on crée le hook dans la base
-               if (!$this->hook->create(DolibarrApiAccess::$user)) {
-                       throw new RestException(500, "Error creating Hook", array_merge(array($this->hook->error), $this->hook->errors));
-               }
-               return array(
-                       'id' => $this->hook->id,
-               );
-       }
-
-       // /**
-       //  * Update hook
-       //  *
-       //  * @param int   $id             Id of hook to update
-       //  * @param array $request_data   Datas
-       //  * @return int
-       //  *
-       //  * @url      PUT /hooks/{id}
-       //  */
-       /*public function put($id, $request_data = null)
-       {
-               if (! DolibarrApiAccess::$user->rights->zapier->write) {
-                       throw new RestException(401);
-               }
-
-               $result = $this->hook->fetch($id);
-               if( ! $result ) {
-                       throw new RestException(404, 'Hook not found');
-               }
-
-               if( ! DolibarrApi::_checkAccessToResource('hook', $this->hook->id)) {
-                       throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
-               }
-
-               foreach($request_data as $field => $value) {
-                       if ($field == 'id') {
-                               continue;
-                       }
-                       $this->hook->$field = $value;
-               }
-
-               if ($this->hook->update($id, DolibarrApiAccess::$user) > 0) {
-                       return $this->get($id);
-               } else {
-                       throw new RestException(500, $this->hook->error);
-               }
-       }*/
-
-       /**
-        * Delete hook
-        *
-        * @param   int     $id   Hook ID
-        * @return  array
-        *
-        * @url DELETE /hook/{id}
-        */
-       public function delete($id)
-       {
-               if (!DolibarrApiAccess::$user->rights->zapier->delete) {
-                       throw new RestException(401);
-               }
-
-               $result = $this->hook->fetch($id);
-               if (!$result) {
-                       throw new RestException(404, 'Hook not found');
-               }
-
-               if (!DolibarrApi::_checkAccessToResource('hook', $this->hook->id)) {
-                       throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
-               }
-
-               if (!$this->hook->delete(DolibarrApiAccess::$user)) {
-                       throw new RestException(500, 'Error when deleting Hook : '.$this->hook->error);
-               }
-
-               return array(
-                       'success' => array(
-                               'code' => 200,
-                               'message' => 'Hook deleted'
-                       )
-               );
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
-       /**
-        * Clean sensible object datas
-        *
-        * @param   Object  $object     Object to clean
-        * @return  Object              Object with cleaned properties
-        */
-       public function _cleanObjectDatas($object)
-       {
-               // phpcs:disable
-               $object = parent::_cleanObjectDatas($object);
-
-               /*unset($object->note);
-        unset($object->address);
-        unset($object->barcode_type);
-        unset($object->barcode_type_code);
-        unset($object->barcode_type_label);
-        unset($object->barcode_type_coder);*/
-
-               return $object;
-       }
-
-       /**
-        * Validate fields before create or update object
-        *
-        * @param   array       $data       Array of data to validate
-        * @param   array       $fields     Array of fields needed
-        * @return  array
-        *
-        * @throws  RestException
-        */
-       private function validate($data, $fields)
-       {
-               $hook = array();
-               foreach ($fields as $field) {
-                       if (!isset($data[$field])) {
-                               throw new RestException(400, $field." field missing");
-                       }
-                       $hook[$field] = $data[$field];
-               }
-               return $hook;
-       }
-}
diff --git a/htdocs/zapier/class/hook.class.php b/htdocs/zapier/class/hook.class.php
deleted file mode 100644 (file)
index 9b5b733..0000000
+++ /dev/null
@@ -1,707 +0,0 @@
-<?php
-/* Copyright (C) 2017  Laurent Destailleur <eldy@users.sourceforge.net>
- * Copyright (C) 2019       Frédéric France     <frederic.france@netlogic.fr>
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file        htdocs/zapier/class/hook.class.php
- * \ingroup     zapier
- * \brief       This file is a CRUD class file for Hook (Create/Read/Update/Delete)
- */
-
-require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
-
-/**
- * Class for Hook
- */
-class Hook extends CommonObject
-{
-       /**
-        * @var string ID to identify managed object
-        */
-       public $element = 'hook';
-
-       /**
-        * @var string Name of table without prefix where object is stored
-        */
-       public $table_element = 'zapier_hook';
-
-       /**
-        * @var int  Does hook support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
-        */
-       public $ismultientitymanaged = 0;
-
-       /**
-        * @var int  Does hook support extrafields ? 0=No, 1=Yes
-        */
-       public $isextrafieldmanaged = 1;
-
-       /**
-        * @var string String with name of icon for hook. Must be the part after the 'object_' into object_hook.png
-        */
-       public $picto = 'hook@zapier';
-
-
-       const STATUS_DRAFT = 0;
-       const STATUS_VALIDATED = 1;
-       const STATUS_DISABLED = -1;
-
-
-       /**
-        *  'type' if the field format ('integer', 'integer:Class:pathtoclass', 'varchar(x)', 'double(24,8)', 'text', 'html', 'datetime', 'timestamp', 'float')
-        *  'label' the translation key.
-        *  'enabled' is a condition when the field must be managed.
-        *  'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). Using a negative value means field is not shown by default on list but can be selected for viewing)
-        *  'noteditable' says if field is not editable (1 or 0)
-        *  'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
-        *  'default' is a default value for creation (can still be replaced by the global setup of default values)
-        *  'index' if we want an index in database.
-        *  'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...).
-        *  'position' is the sort order of field.
-        *  'searchall' is 1 if we want to search in this field when making a search from the quick search button.
-        *  'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8).
-        *  'css' is the CSS style to use on field. For example: 'maxwidth200'
-        *  'help' is a string visible as a tooltip on field
-        *  'comment' is not used. You can store here any text of your choice. It is not used by application.
-        *  'showoncombobox' if value of the field must be visible into the label of the combobox that list record
-        *  'arrayofkeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel")
-        */
-
-       /**
-        * @var array  Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
-        */
-       public $fields = array(
-               'rowid' => array(
-                       'type' => 'integer',
-                       'label' => 'TechnicalID',
-                       'enabled' => 1,
-                       'visible' => -2,
-                       'noteditable' => 1,
-                       'notnull' => 1,
-                       'index' => 1,
-                       'position' => 1,
-                       'comment' => 'Id',
-               ),
-               'entity' => array(
-                       'type' => 'integer',
-                       'label' => 'Entity',
-                       'enabled' => 1,
-                       'visible' => 0,
-                       'notnull' => 1,
-                       'default' => 1,
-                       'index' => 1,
-                       'position' => 20,
-               ),
-               'fk_user' => array(
-                       'type' => 'integer',
-                       'label' => 'UserOwner',
-                       'enabled' => 1,
-                       'visible' => -2,
-                       'notnull' => 1,
-                       'position' => 510,
-                       'foreignkey' => 'llx_user.rowid',
-               ),
-               'url' => array(
-                       'type' => 'varchar(255)',
-                       'label' => 'Url',
-                       'enabled' => 1,
-                       'visible' => 1,
-                       'position' => 30,
-                       'searchall' => 1,
-                       'css' => 'minwidth200',
-                       'help' => 'Hook url'
-               ),
-               'module' => array(
-                       'type' => 'varchar(128)',
-                       'label' => 'Module',
-                       'enabled' => 1,
-                       'visible' => 1,
-                       'position' => 30,
-                       'searchall' => 1,
-                       'css' => 'minwidth200',
-                       'help' => 'Hook module'
-               ),
-               'action' => array(
-                       'type' => 'varchar(128)',
-                       'label' => 'Action',
-                       'enabled' => 1,
-                       'visible' => 1,
-                       'position' => 30,
-                       'searchall' => 1,
-                       'css' => 'minwidth200',
-                       'help' => 'Hook action trigger'
-               ),
-               'event' => array(
-                       'type' => 'varchar(255)',
-                       'label' => 'Event',
-                       'enabled' => 1,
-                       'visible' => 1,
-                       'position' => 30,
-                       'searchall' => 1,
-                       'css' => 'minwidth200',
-                       'help' => 'Event',
-                       'showoncombobox' => 1,
-               ),
-               'date_creation' => array(
-                       'type' => 'datetime',
-                       'label' => 'DateCreation',
-                       'enabled' => 1,
-                       'visible' => -2,
-                       'notnull' => 1,
-                       'position' => 500,
-               ),
-               'import_key' => array(
-                       'type' => 'varchar(14)',
-                       'label' => 'ImportId',
-                       'enabled' => 1,
-                       'visible' => -2,
-                       'notnull' => -1,
-                       'index' => 0,
-                       'position' => 1000,
-               ),
-               'status' => array(
-                       'type' => 'integer',
-                       'label' => 'Status',
-                       'enabled' => 1,
-                       'visible' => 1,
-                       'notnull' => 1,
-                       'default' => 0,
-                       'index' => 1,
-                       'position' => 1000,
-                       'arrayofkeyval' => array(
-                               0 => 'Draft',
-                               1 => 'Active',
-                               -1 => 'Canceled',
-                       ),
-               ),
-       );
-
-       /**
-        * @var int ID
-        */
-       public $rowid;
-
-       /**
-        * @var string Ref
-        */
-       public $ref;
-
-       /**
-        * @var int Entity
-        */
-       public $entity;
-
-       /**
-        * @var string label
-        */
-       public $label;
-
-       /**
-        * @var string url of webhook
-        */
-       public $url;
-
-       /**
-        * @var int ID of user owner webhook
-        */
-       public $fk_user;
-
-       /**
-        * @var int Status
-        */
-       public $status;
-
-       /**
-        * @var integer|string date_creation
-        */
-       public $date_creation;
-
-       /**
-        * @var integer tms
-        */
-       public $tms;
-
-       /**
-        * @var int ID
-        */
-       public $fk_user_creat;
-
-       /**
-        * @var int ID
-        */
-       public $fk_user_modif;
-
-       /**
-        * @var string import_key
-        */
-       public $import_key;
-
-
-       /**
-        * Constructor
-        *
-        * @param DoliDb $db Database handler
-        */
-       public function __construct(DoliDB $db)
-       {
-               global $conf, $langs, $user;
-
-               $this->db = $db;
-
-               if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) {
-                       $this->fields['rowid']['visible'] = 0;
-               }
-               if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
-                       $this->fields['entity']['enabled'] = 0;
-               }
-
-               // Unset fields that are disabled
-               foreach ($this->fields as $key => $val) {
-                       if (isset($val['enabled']) && empty($val['enabled'])) {
-                               unset($this->fields[$key]);
-                       }
-               }
-
-               // Translate some data of arrayofkeyval
-               foreach ($this->fields as $key => $val) {
-                       if (is_array($this->fields['status']['arrayofkeyval'])) {
-                               foreach ($this->fields['status']['arrayofkeyval'] as $key2 => $val2) {
-                                       $this->fields['status']['arrayofkeyval'][$key2] = $langs->trans($val2);
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Create object into database
-        *
-        * @param  User $user      User that creates
-        * @param  bool $notrigger false=launch triggers after, true=disable triggers
-        * @return int             <0 if KO, Id of created object if OK
-        */
-       public function create(User $user, $notrigger = false)
-       {
-               return $this->createCommon($user, $notrigger);
-       }
-
-       /**
-        * Clone an object into another one
-        *
-        * @param   User    $user       User that creates
-        * @param   int     $fromid     Id of object to clone
-        * @return  mixed               New object created, <0 if KO
-        */
-       public function createFromClone(User $user, $fromid)
-       {
-               global $langs, $hookmanager, $extrafields;
-               $error = 0;
-
-               dol_syslog(__METHOD__, LOG_DEBUG);
-
-               $object = new self($this->db);
-
-               $this->db->begin();
-
-               // Load source object
-               $object->fetchCommon($fromid);
-               // Reset some properties
-               unset($object->id);
-               unset($object->fk_user_creat);
-               unset($object->import_key);
-
-               // Clear fields
-               $object->ref = "copy_of_".$object->ref;
-               $object->title = $langs->trans("CopyOf")." ".$object->title;
-               // ...
-               // Clear extrafields that are unique
-               if (is_array($object->array_options) && count($object->array_options) > 0) {
-                       $extrafields->fetch_name_optionals_label($this->table_element);
-                       foreach ($object->array_options as $key => $option) {
-                               $shortkey = preg_replace('/options_/', '', $key);
-                               if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
-                                       // var_dump($key);
-                                       // var_dump($clonedObj->array_options[$key]);
-                                       // exit;
-                                       unset($object->array_options[$key]);
-                               }
-                       }
-               }
-
-               // Create clone
-               $object->context['createfromclone'] = 'createfromclone';
-               $result = $object->createCommon($user);
-               if ($result < 0) {
-                       $error++;
-                       $this->error = $object->error;
-                       $this->errors = $object->errors;
-               }
-
-               unset($object->context['createfromclone']);
-
-               // End
-               if (!$error) {
-                       $this->db->commit();
-                       return $object;
-               } else {
-                       $this->db->rollback();
-                       return -1;
-               }
-       }
-
-       /**
-        * Load object in memory from the database
-        *
-        * @param int    $id   Id object
-        * @param string $ref  Ref
-        * @return int         <0 if KO, 0 if not found, >0 if OK
-        */
-       public function fetch($id, $ref = null)
-       {
-               $result = $this->fetchCommon($id, $ref);
-               if ($result > 0 && !empty($this->table_element_line)) {
-                       //$this->fetchLines();
-               }
-               return $result;
-       }
-
-       /**
-        * Load object lines in memory from the database
-        *
-        * @return int         <0 if KO, 0 if not found, >0 if OK
-        */
-       /*public function fetchLines()
-       {
-               $this->lines=array();
-
-               // Load lines with object MyObjectLine
-
-               return count($this->lines)?1:0;
-       }*/
-
-       /**
-        * Load list of objects in memory from the database.
-        *
-        * @param  string      $sortorder    Sort Order
-        * @param  string      $sortfield    Sort field
-        * @param  int         $limit        limit
-        * @param  int         $offset       Offset
-        * @param  array       $filter       Filter array. Example array('field'=>'valueforlike', 'customurl'=>...)
-        * @param  string      $filtermode   Filter mode (AND or OR)
-        * @return array|int                 int <0 if KO, array of pages if OK
-        */
-       public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
-       {
-               global $conf;
-
-               dol_syslog(__METHOD__, LOG_DEBUG);
-
-               $records = array();
-
-               $sql = 'SELECT';
-               $sql .= ' t.rowid';
-               // TODO Get all fields
-               $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
-               $sql .= ' WHERE t.entity = '.((int) $conf->entity);
-               // Manage filter
-               $sqlwhere = array();
-               if (count($filter) > 0) {
-                       foreach ($filter as $key => $value) {
-                               if ($key == 't.rowid') {
-                                       $sqlwhere[] = $key." = ".((int) $value);
-                               } elseif (strpos($key, 'date') !== false) {
-                                       $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
-                               } elseif ($key == 'customsql') {
-                                       $sqlwhere[] = $value;
-                               } else {
-                                       $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
-                               }
-                       }
-               }
-               if (count($sqlwhere) > 0) {
-                       $sql .= ' AND ('.implode(' '.$this->db->escape($filtermode).' ', $sqlwhere).')';
-               }
-
-               if (!empty($sortfield)) {
-                       $sql .= $this->db->order($sortfield, $sortorder);
-               }
-               if (!empty($limit)) {
-                       $sql .= $this->db->plimit($limit, $offset);
-               }
-
-               $resql = $this->db->query($sql);
-               if ($resql) {
-                       $num = $this->db->num_rows($resql);
-
-                       while ($obj = $this->db->fetch_object($resql)) {
-                               $record = new self($this->db);
-
-                               $record->id = $obj->rowid;
-                               // TODO Get other fields
-
-                               //var_dump($record->id);
-                               $records[$record->id] = $record;
-                       }
-                       $this->db->free($resql);
-
-                       return $records;
-               } else {
-                       $this->errors[] = 'Error '.$this->db->lasterror();
-                       dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
-
-                       return -1;
-               }
-       }
-
-       /**
-        * Update object into database
-        *
-        * @param  User $user      User that modifies
-        * @param  bool $notrigger false=launch triggers after, true=disable triggers
-        * @return int             <0 if KO, >0 if OK
-        */
-       public function update(User $user, $notrigger = false)
-       {
-               return $this->updateCommon($user, $notrigger);
-       }
-
-       /**
-        *  Delete object in database
-        *
-        * @param User $user       User that deletes
-        * @param bool $notrigger  false=launch triggers after, true=disable triggers
-        * @return int             <0 if KO, >0 if OK
-        */
-       public function delete(User $user, $notrigger = false)
-       {
-               return $this->deleteCommon($user, $notrigger);
-               //return $this->deleteCommon($user, $notrigger, 1);
-       }
-
-       /**
-        *  Return a link to the object card (with optionaly the picto)
-        *
-        *  @param  int     $withpicto                  Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
-        *  @param  string  $option                     On what the link point to ('nolink', ...)
-        *  @param  int     $notooltip                  1=Disable tooltip
-        *  @param  string  $morecss                    Add more css on link
-        *  @param  int     $save_lastsearch_value      -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
-        *  @return     string                              String with URL
-        */
-       public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
-       {
-               global $db, $conf, $langs, $hookmanager, $action;
-               global $dolibarr_main_authentication, $dolibarr_main_demo;
-               global $menumanager;
-
-               if (!empty($conf->dol_no_mouse_hover)) {
-                       // Force disable tooltips
-                       $notooltip = 1;
-               }
-
-               $result = '';
-
-               $label = '<u>'.$langs->trans("Hook").'</u>';
-               $label .= '<br>';
-               $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
-
-               $url = DOL_URL_ROOT.'/zapier/hook_card.php?id='.$this->id;
-
-               if ($option != 'nolink') {
-                       // Add param to save lastsearch_values or not
-                       $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
-                       if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
-                               $add_save_lastsearch_values = 1;
-                       }
-                       if ($add_save_lastsearch_values) {
-                               $url .= '&save_lastsearch_values=1';
-                       }
-               }
-
-               $linkclose = '';
-               if (empty($notooltip)) {
-                       if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
-                               $label = $langs->trans("ShowMyObject");
-                               $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
-                       }
-                       $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
-                       $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
-               } else {
-                       $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
-               }
-
-               $linkstart = '<a href="'.$url.'"';
-               $linkstart .= $linkclose.'>';
-               $linkend = '</a>';
-
-               $result .= $linkstart;
-               if ($withpicto) {
-                       $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
-               }
-               if ($withpicto != 2) {
-                       $result .= $this->ref;
-               }
-               $result .= $linkend;
-               //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
-
-               $hookmanager->initHooks(array('hookdao'));
-               $parameters = array(
-                       'id' => $this->id,
-                       'getnomurl' => &$result,
-               );
-               // Note that $action and $object may have been modified by some hooks
-               $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action);
-               if ($reshook > 0) {
-                       $result = $hookmanager->resPrint;
-               } else {
-                       $result .= $hookmanager->resPrint;
-               }
-
-               return $result;
-       }
-
-       /**
-        *  Return label of the status
-        *
-        *  @param  int     $mode       0 = long label
-        *                              1 = short label
-        *                              2 = Picto + short label
-        *                              3 = Picto, 4=Picto + long label
-        *                              5 = Short label + Picto
-        *                              6 = Long label + Picto
-        *  @return     string              Label of status
-        */
-       public function getLibStatut($mode = 0)
-       {
-               return $this->LibStatut($this->status, $mode);
-       }
-
-       // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
-       /**
-        *  Return the status
-        *
-        *  @param  int     $status     Id status
-        *  @param  int     $mode       0 = long label,
-        *                              1 = short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
-        *  @return string              Label of status
-        */
-       public function LibStatut($status, $mode = 0)
-       {
-               // phpcs:enable
-               global $langs;
-
-               if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
-                       global $langs;
-                       //$langs->load("mymodule");
-                       $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Disabled');
-                       $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
-                       $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Disabled');
-                       $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
-               }
-
-               $statusType = 'status5';
-               if ($status == self::STATUS_VALIDATED) {
-                       $statusType = 'status4';
-               }
-
-               return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
-       }
-
-       /**
-        *  Load the info information in the object
-        *
-        *  @param  int     $id       Id of object
-        *  @return     void
-        */
-       public function info($id)
-       {
-               $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
-               $sql .= ' fk_user_creat, fk_user_modif';
-               $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
-               $sql .= ' WHERE t.rowid = '.((int) $id);
-               $result = $this->db->query($sql);
-               if ($result) {
-                       if ($this->db->num_rows($result)) {
-                               $obj = $this->db->fetch_object($result);
-                               $this->id = $obj->rowid;
-
-
-                               $this->user_creation_id = $obj->fk_user_creat;
-                               $this->user_modification_id = $obj->fk_user_modif;
-                               $this->date_creation     = $this->db->jdate($obj->datec);
-                               $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
-                       }
-
-                       $this->db->free($result);
-               } else {
-                       dol_print_error($this->db);
-               }
-       }
-
-       /**
-        * Initialise object with example values
-        * Id must be 0 if object instance is a specimen
-        *
-        * @return void
-        */
-       public function initAsSpecimen()
-       {
-               $this->initAsSpecimenCommon();
-       }
-
-
-       /**
-        * Action executed by scheduler
-        * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters'
-        *
-        * @return  int         0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK)
-        */
-       public function doScheduledJob()
-       {
-               global $conf, $langs;
-
-               //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
-
-               $error = 0;
-               $this->output = '';
-               $this->error = '';
-
-               dol_syslog(__METHOD__, LOG_DEBUG);
-
-               $now = dol_now();
-
-               $this->db->begin();
-
-               // ...
-
-               $this->db->commit();
-
-               return $error;
-       }
-}
-
-/**
- * Class MyObjectLine. You can also remove this and generate a CRUD class for lines objects.
- */
-/*
-class MyObjectLine
-{
-       // @var int ID
-       public $id;
-       // @var mixed Sample line property 1
-       public $prop1;
-       // @var mixed Sample line property 2
-       public $prop2;
-}
-*/
diff --git a/htdocs/zapier/lib/zapier.lib.php b/htdocs/zapier/lib/zapier.lib.php
deleted file mode 100644 (file)
index 5b6a3bd..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-/* Copyright (C) 2019 Frédéric FRANCE <frederic.france@free.fr>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-
-/**
- * \file    zapier/lib/zapier.lib.php
- * \ingroup zapier
- * \brief   Library files with common functions for ZapierForDolibarr
- */
-
-/**
- * Prepare admin pages header
- *
- * @return array
- */
-function zapierAdminPrepareHead()
-{
-       global $langs, $conf;
-
-       $langs->load("zapier");
-
-       $h = 0;
-       $head = array();
-
-       $head[$h][0] = dol_buildpath("/zapier/admin/setup.php", 1);
-       $head[$h][1] = $langs->trans("Settings");
-       $head[$h][2] = 'settings';
-       $h++;
-       $head[$h][0] = dol_buildpath("/zapier/admin/about.php", 1);
-       $head[$h][1] = $langs->trans("About");
-       $head[$h][2] = 'about';
-       $h++;
-
-       // Show more tabs from modules
-       // Entries must be declared in modules descriptor with line
-       //$this->tabs = array(
-       //      'entity:+tabname:Title:@zapier:/zapier/mypage.php?id=__ID__'
-       //); // to add new tab
-       //$this->tabs = array(
-       //      'entity:-tabname:Title:@zapier:/zapier/mypage.php?id=__ID__'
-       //); // to remove a tab
-       complete_head_from_modules($conf, $langs, null, $head, $h, 'zapier');
-
-       complete_head_from_modules($conf, $langs, null, $head, $h, 'zapier', 'remove');
-
-       return $head;
-}
diff --git a/installer/install_creorga.ps1 b/installer/install_creorga.ps1
new file mode 100644 (file)
index 0000000..6ab8488
--- /dev/null
@@ -0,0 +1,46 @@
+$conffile=$PSScriptRoot + "/installlist.json" 
+
+$cfg = Get-Content -Raw -Path $conffile | ConvertFrom-Json
+
+if (!(Test-Path $cfg.installpath -PathType Container)) {
+  New-Item -ItemType Directory -Force -Path $pp
+}
+
+$ProgressPreference = 'SilentlyContinue'
+#Download
+foreach ($item in $cfg.baseapps){
+  Write-Host "Download $($item.name) ($($item.file))"
+  $outfile=$PSScriptRoot+"/"+$item.file
+  Invoke-WebRequest -Uri $item.url -OutFile $outfile
+}
+$ProgressPreference = 'Continue'
+#Extract
+foreach ($item in $cfg.baseapps){
+  $outfile=$PSScriptRoot+"/"+$item.file
+  $ext = (Get-ChildItem $outfile).Extension
+  if ($ext -is ".zip"){
+    Write-Host "Extract $($item.name) ($($item.file))"
+    $installpath=$cfg.installpath+"/"+$item.installpath
+    Expand-Archive -Path $outfile -DestinationPath $installpath
+  }
+  
+}
+#Install / Configure
+foreach ($item in $cfg.baseapps){
+  if ($item.name -is "apache"){
+    $appexe = $cfg.installpath+"/Apache24/bin/httpd.exe"
+    & $appexe -k install -n creorgaserver
+  }
+  if ($item.name -is "php"){
+
+  }
+  
+  if ($item.name -is "postgresql"){
+    # pg_ctl.exe register -N "dkspgsql" -U "NT AUTHORITY\NetworkService" -D "C:/Program Files/postgresql/pgsql/bin/pgsql/data" -w
+# #"D:\dksapps\bin\pgsql\bin\pg_ctl" -D "D:\dksapps\data\pgsql" -l logdatei start
+# D:\dksapps\bin\pgsql\bin\initdb.exe  D:\dksapps\data\pgsql
+  }
+  if ($item.name -is "libreoffice"){
+
+  }
+}
\ No newline at end of file
diff --git a/installer/installlist.json b/installer/installlist.json
new file mode 100644 (file)
index 0000000..b2b3f4e
--- /dev/null
@@ -0,0 +1,35 @@
+{
+"installpath":"C:/Creorga",
+"baseapps":[{
+  "name":"apache",
+  "url":"https://de.apachehaus.com/downloads/httpd-2.4.55-o111s-x64-vs17.zip",
+  "file":"httpd-2.4.55-o111s-x64-vs17.zip",
+  "version":"2.4.55 (o111s;vs17)",
+  "installpath":""
+},{
+  "name":"mod_fcgid",
+  "url":"https://de.apachehaus.com/downloads/mod_fcgid-2.3.9a-2.4.x-x64-vs17.zip",
+  "file":"mod_fcgid-2.3.9a-2.4.x-x64-vs17.zip",
+  "version":"2.3.9a-2.4.x-x64-vs17",
+  "installpath":""
+},{
+  "name":"mod_log_rotate",
+  "url":"https://de.apachehaus.com/downloads/mod_log_rotate-1.0.2-2.4.x-x64-vc17.zip",
+  "file":"mod_log_rotate-1.0.2-2.4.x-x64-vc17.zip",
+  "version":"1.0.2-2.4.x-x64-vc17",
+  "installpath":""
+},{
+  "name":"php",
+  "url":"https://windows.php.net/downloads/releases/latest/php-8.1-Win32-vs16-x64-latest.zip",
+  "file":"php-8.1-Win32-vs16-x64-latest.zip",
+  "version":"8.1 (vs16)",
+  "installpath":"php81"
+},{
+  "name":"postgresql",
+  "url":"https://sbp.enterprisedb.com/getfile.jsp?fileid=1258789",
+  "file":"postgresql-15.5-1-windows-x64-binaries.zip",
+  "version":"15.5-1",
+  "installpath":""
+}
+]
+}
\ No newline at end of file
diff --git a/tmp.php b/tmp.php
new file mode 100644 (file)
index 0000000..b82cfc8
--- /dev/null
+++ b/tmp.php
@@ -0,0 +1,6 @@
+// convert TTF font to TCPDF format and store it on the fonts folder
+$fontname = TCPDF_FONTS::addTTFfont('pathto/arial.ttf', 'TrueTypeUnicode', '', 96);
+
+// use the font
+$pdf->SetFont($fontname, '', 14, '', false);
+
diff --git a/tools/doap/README b/tools/doap/README
deleted file mode 100644 (file)
index e25307c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-README (English)
-##################################################
-Building DOAP files
-##################################################
-
-This directory contains files and docs used to build
-a DOAP descriptor file for Dolibarr.
-DOAP files are files to describe a software to submit
-easily its description, in one way, to several software
-directories.
-
-Note: a DOAP descriptor file can be generated by sourceforge:
-http://sourceforge.net/api/project/name/dolibarr/doap
diff --git a/tools/doxygen/dolibarr-doxygen-build.pl b/tools/doxygen/dolibarr-doxygen-build.pl
deleted file mode 100644 (file)
index 75a5cce..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/perl
-#--------------------------------------------------------------------
-# Lance la generation de la doc dev doxygen
-#--------------------------------------------------------------------
-
-# Detecte repertoire du script
-($DIR=$0) =~ s/([^\/\\]+)$//;
-$DIR||='.';
-$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
-
-$OPTIONS="";
-#$OPTIONS="-d Preprocessor";
-
-$CONFFILE="dolibarr-doxygen.doxyfile";
-
-use Cwd;
-my $dir = getcwd;
-
-print "Current dir is: $dir\n";
-print "Running dir for doxygen must be: $DIR\n";
-
-if (! -s $CONFFILE)
-{
-    print "Error: current directory for building Dolibarr doxygen documentation is not correct.\n";
-    print "\n";
-       print "Change your current directory then, to launch the script, run:\n";
-       print '> perl .\dolibarr-doxygen-build.pl  (on Windows)'."\n";
-       print '> perl ../dolibarr-doxygen-build.pl  (on Linux or BSD)'."\n";
-    sleep 4;
-    exit 1;   
-}
-
-$SOURCE="../..";
-
-# Get version $MAJOR, $MINOR and $BUILD
-$result = open( IN, "< " . $SOURCE . "/htdocs/filefunc.inc.php" );
-if ( !$result ) { die "Error: Can't open descriptor file " . $SOURCE . "/htdocs/filefunc.inc.php\n"; }
-while (<IN>) {
-       if ( $_ =~ /define\('DOL_VERSION', '([\d\.a-z\-]+)'\)/ ) { $PROJVERSION = $1; break; }
-}
-close IN;
-($MAJOR,$MINOR,$BUILD)=split(/\./,$PROJVERSION,3);
-if ($MINOR eq '') { die "Error can't detect version into ".$SOURCE . "/htdocs/filefunc.inc.php"; }
-
-
-$version=$MAJOR.".".$MINOR.".".$BUILD;
-
-
-print "Running doxygen for version ".$version.", please wait...\n";
-print "cat $CONFFILE | sed -e 's/x\.y\.z/".$version."/' | doxygen $OPTIONS - 2>&1\n";
-$result=`cat $CONFFILE | sed -e 's/x\.y\.z/$version/' | doxygen $OPTIONS - 2>&1`;
-
-print $result;
-
-0;
diff --git a/tools/doxygen/dolibarr-doxygen-filter.pl b/tools/doxygen/dolibarr-doxygen-filter.pl
deleted file mode 100644 (file)
index 9233bd9..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/perl
-#--------------------------------------------------------------------
-# \brief       This script is a preprocessor for PHP files to be used
-#                      on PHP source files before running Doxygen.
-# \author      Laurent Destailleur
-#--------------------------------------------------------------------
-
-# Usage: dolibarr-doxygen-filter.pl pathtofilefromdolibarrroot
-
-$file=$ARGV[0];
-if (! $file)
-{
-       print "Usage: dolibarr-doxygen-filter.pl pathtofilefromdolibarrroot\n";
-       exit;
-}
-
-open(FILE,$file) || die "Failed to open file $file";
-while (<FILE>)
-{
-       if ($_ =~ /\\version\s/i)
-       {
-               $_ =~ s/\$Id://i;
-               $_ =~ s/(Exp|)\s\$$//i;
-               $_ =~ s/(\\version\s+)[^\s]+\s/$1/i;
-               $_ =~ s/(\w)\s(\w)/$1_$2/g;
-       }
-       $_ =~ s/exit\s*;/exit(0);/i;
-       $i=0;
-       $len=length($_);
-       $s="";
-       $insidequote=0;
-       $insidedquote=0;
-       $ignore="";
-       while ($i < $len)
-       {
-               $c=substr($_,$i,1);
-               if ($c eq "\\")
-               {
-                       if ($insidequote)  { $ignore="'";  };
-                       if ($insidedquote) { $ignore="\""; };
-               }
-               else
-               {
-                       if ($c eq "'")
-                       {
-                               if (! $insidedquote)
-                               {
-                                       $c="\"";
-                                       #print "X".$ignore;
-                                       if ($ignore ne "'")
-                                       {
-                                               #print "Z".$ignore;
-                                               $insidequote++;
-                                               if ($insidequote == 2)
-                                               {
-                                                       $insidequote=0;
-                                               }
-                                       }
-                               }
-                               #print "X".$insidequote;
-                       }
-                       elsif ($c eq "\"")
-                       {
-                               #print "Y".$insidequote;
-                               if ($insidequote)
-                               {
-                                       $c="'";
-                               }
-                               else
-                               {
-                                       if ($ignore ne "\"")
-                                       {
-                                               $insidedquote++;
-                                               if ($insidedquote == 2)
-                                               {
-                                                       $insidedquote=0;
-                                               }
-                                       }
-                               }
-                       }
-                       $ignore="";
-               }
-               $s.=$c;
-               $i++;
-       }
-       print $s;
-}
-close(FILE);
diff --git a/tools/doxygen/dolibarr-doxygen-getversion.pl b/tools/doxygen/dolibarr-doxygen-getversion.pl
deleted file mode 100644 (file)
index 6d05037..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/perl
-#--------------------------------------------------------------------
-# Script to get version of a source file
-# Does not work with cygwin cvs command on Windows.
-#
-#--------------------------------------------------------------------
-
-# Usage: dolibarr-doxygen-getversion.pl pathtofilefromdolibarrroot
-
-$file=$ARGV[0];
-if (! $file) 
-{
-       print "Usage: dolibarr-doxygen-getversion.pl pathtofilefromdolibarrroot\n";
-       exit;
-}
-
-$commande='cvs status "'.$file.'" | sed -n \'s/^[ \]*Working revision:[ \t]*\([0-9][0-9\.]*\).*/\1/p\'';
-#print $commande;
-$result=`$commande 2>&1`;
-
-print $result;
diff --git a/tools/doxygen/dolibarr-doxygen.doxyfile b/tools/doxygen/dolibarr-doxygen.doxyfile
deleted file mode 100644 (file)
index 3140066..0000000
+++ /dev/null
@@ -1,1636 +0,0 @@
-# Doxyfile 1.7.3
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the
-# iconv built into libc) for the transcoding. See
-# https://www.gnu.org/software/libiconv for the list of possible encodings.
-
-DOXYFILE_ENCODING = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME = dolibarr
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER = x.y.z
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = ../../build
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS = YES
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
-# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
-# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
-
-OUTPUT_LANGUAGE = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF = 
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
-
-STRIP_FROM_PATH = "../.."
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH = 
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like regular Qt-style comments
-# (thus requiring an explicit @brief command for a brief description.)
-
-JAVADOC_AUTOBRIEF = YES
-
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
-# interpret the first line (until the first dot) of a Qt-style
-# comment as the brief description. If set to NO, the comments
-# will behave just like regular Qt-style comments (thus requiring
-# an explicit \brief command for a brief description.)
-
-QT_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
-
-INHERIT_DOCS = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 2
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES = 
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
-# sources only. Doxygen will then generate output that is more tailored for
-# Java. For instance, namespaces will be presented as packages, qualified
-# scopes will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources only. Doxygen will then generate output that is more tailored for
-# Fortran.
-
-OPTIMIZE_FOR_FORTRAN = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for
-# VHDL.
-
-OPTIMIZE_OUTPUT_VHDL = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given extension.
-# Doxygen has a built-in mapping, but you can override or extend it using this
-# tag. The format is ext=language, where ext is a file extension, and language
-# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
-# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
-# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
-# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
-
-EXTENSION_MAPPING = 
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should
-# set this tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
-# func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-
-CPP_CLI_SUPPORT = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
-# Doxygen will parse them like normal C++ but will assume all classes use public
-# instead of private inheritance when no explicit protection keyword is present.
-
-SIP_SUPPORT = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate getter
-# and setter methods for a property. Setting this option to YES (the default)
-# will make doxygen to replace the get and set methods by a property in the
-# documentation. This will only work if the methods are indeed getting or
-# setting a simple type. If this is not the case, or you want to show the
-# methods anyway, you should set this option to NO.
-
-IDL_PROPERTY_SUPPORT = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
-# is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically
-# be useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-
-TYPEDEF_HIDES_STRUCT = NO
-
-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
-# determine which symbols to keep in memory and which to flush to disk.
-# When the cache is full, less often used symbols will be written to disk.
-# For small to medium size projects (<1000 input files) the default value is
-# probably good enough. For larger projects a too small cache size can cause
-# doxygen to be busy swapping symbols to and from disk most of the time
-# causing a significant performance penality.
-# If the system has enough physical memory increasing the cache will improve the
-# performance by keeping more symbols in memory. Note that the value works on
-# a logarithmic scale so increasing the size by one will rougly double the
-# memory usage. The cache size is given by this formula:
-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
-# corresponding to a cache size of 2^16 = 65536 symbols
-
-SYMBOL_CACHE_SIZE = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = YES
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base
-# name of the file that contains the anonymous namespace. By default
-# anonymous namespace are hidden.
-
-EXTRACT_ANON_NSPACES = YES
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = YES
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
-# will list include files with double quotes in the documentation
-# rather than with sharp brackets.
-
-FORCE_LOCAL_INCLUDES = NO
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
-# will sort the (brief and detailed) documentation of class members so that
-# constructors and destructors are listed first. If set to NO (the default)
-# the constructors will appear in the respective orders defined by
-# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
-# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
-# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
-# hierarchy of group names into alphabetical order. If set to NO (the default)
-# the group names will appear in their defined order.
-
-SORT_GROUP_NAMES = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = NO
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST = YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS = 
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES = YES
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
-# This will remove the Files entry from the Quick Index and from the
-# Folder Tree View (if specified). The default is YES.
-
-SHOW_FILES = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
-# Namespaces page.
-# This will remove the Namespaces entry from the Quick Index
-# and from the Folder Tree View (if specified). The default is YES.
-
-SHOW_NAMESPACES = NO
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the program writes to standard output
-# is used as the file version. See the manual for examples.
-
-#FILE_VERSION_FILTER = dolibarr-doxygen-getversion.pl
-FILE_VERSION_FILTER = 
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. The create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option.
-# You can optionally specify a file name after the option, if omitted
-# DoxygenLayout.xml will be used as the name of the layout file.
-
-LAYOUT_FILE = 
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = NO
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
-# documentation.
-
-WARN_NO_PARAMDOC = YES
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE = doxygen_warnings.log
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT = ../../htdocs ../../scripts
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
-# also the default input encoding. Doxygen uses libiconv (or the iconv built
-# into libc) for the transcoding. See https://www.gnu.org/software/libiconv for
-# the list of possible encodings.
-
-INPUT_ENCODING = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
-
-FILE_PATTERNS = *.php *.pl
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE = ../../build ../../dev ../../doc ../../document ../../documents ../../htdocs/conf/conf.php ../../htdocs/custom ../../htdocs/document ../../htdocs/documents ../../htdocs/includes
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem feature) are excluded
-# from the input.
-
-EXCLUDE_SYMLINKS = YES
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS = */CVS/* *google* *pibarcode*
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-
-EXCLUDE_SYMBOLS = 
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH = ../../htdocs/modulebuilder/template 
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS = *.php
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH = ../../doc/images
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output.
-# If FILTER_PATTERNS is specified, this tag will be
-# ignored.
-
-# Works on Linux only
-#INPUT_FILTER           = ../dolibarr-doxygen-filter.pl
-#INPUT_FILTER           = "perl ../dolibarr-doxygen-filter.pl"
-INPUT_FILTER = 
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis.
-# Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match.
-# The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
-# is applied to all files.
-
-FILTER_PATTERNS = 
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = YES
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.
-# Otherwise they will link to the documentation.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see https://www.gnu.org/software/global/global.html). You
-# will need version 4.8.6 or higher.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = YES
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-# Does not work with 1.7.3
-#HTML_HEADER = doxygen_header.html
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-# Does not work with 1.7.3
-HTML_FOOTER = doxygen_footer.html
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET = 
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
-# Doxygen will adjust the colors in the stylesheet and background images
-# according to this color. Hue is specified as an angle on a colorwheel,
-# see http://en.wikipedia.org/wiki/Hue for more information.
-# For instance the value 0 represents red, 60 is yellow, 120 is green,
-# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
-# The allowed range is 0 to 359.
-
-HTML_COLORSTYLE_HUE = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
-# the colors in the HTML output. For a value of 0 the output will use
-# grayscales only. A value of 255 will produce the most vivid colors.
-
-HTML_COLORSTYLE_SAT = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
-# the luminance component of the colors in the HTML output. Values below
-# 100 gradually make the output lighter, whereas values above 100 make
-# the output darker. The value divided by 100 is the actual gamma applied,
-# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
-# and 100 does not change the gamma.
-
-HTML_COLORSTYLE_GAMMA = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting
-# this to NO can help when comparing the output of multiple runs.
-
-HTML_TIMESTAMP = YES
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded. For this to work a browser that supports
-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
-
-HTML_DYNAMIC_SECTIONS = YES
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files
-# will be generated that can be used as input for Apple's Xcode 3
-# integrated development environment, introduced with OSX 10.5 (Leopard).
-# To create a documentation set, doxygen will generate a Makefile in the
-# HTML output directory. Running make will produce the docset in that
-# directory and running "make install" will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
-# it at startup.
-# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-
-GENERATE_DOCSET = NO
-
-# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
-# feed. A documentation feed provides an umbrella under which multiple
-# documentation sets from a single provider (such as a company or product suite)
-# can be grouped.
-
-DOCSET_FEEDNAME = "Doxygen generated docs"
-
-# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
-# should uniquely identify the documentation set bundle. This should be a
-# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
-# will append .docset to the name.
-
-DOCSET_BUNDLE_ID = org.doxygen.Project
-
-# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-
-DOCSET_PUBLISHER_ID = org.dolibarr.doc
-
-# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
-
-DOCSET_PUBLISHER_NAME = Dolibarr team
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output directory.
-
-CHM_FILE = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
-# is used to encode HtmlHelp index (hhk), content (hhc) and project file
-# content.
-
-CHM_INDEX_ENCODING = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
-# that can be used as input for Qt's qhelpgenerator to generate a
-# Qt Compressed Help (.qch) of the generated HTML documentation.
-
-GENERATE_QHP = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
-# be used to specify the file name of the resulting .qch file.
-# The path specified is relative to the HTML output folder.
-
-QCH_FILE = 
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#namespace
-
-QHP_NAMESPACE = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#virtual-folders
-
-QHP_VIRTUAL_FOLDER = doc
-
-# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
-# add. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#custom-filters
-
-QHP_CUST_FILTER_NAME = 
-
-# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see
-# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
-# Qt Help Project / Custom Filters</a>.
-
-QHP_CUST_FILTER_ATTRS = 
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's
-# filter section matches.
-# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
-# Qt Help Project / Filter Attributes</a>.
-
-QHP_SECT_FILTER_ATTRS = 
-
-# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
-# be used to specify the location of Qt's qhelpgenerator.
-# If non-empty doxygen will try to run qhelpgenerator on the generated
-# .qhp file.
-
-QHG_LOCATION = 
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
-#  will be generated, which together with the HTML files, form an Eclipse help
-# plugin. To install this plugin and make it available under the help contents
-# menu in Eclipse, the contents of the directory containing the HTML and XML
-# files needs to be copied into the plugins directory of eclipse. The name of
-# the directory within the plugins directory should be the same as
-# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
-# the help appears.
-
-GENERATE_ECLIPSEHELP = YES
-
-# A unique identifier for the eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have
-# this name.
-
-ECLIPSE_DOC_ID = org.doxygen.Project
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information.
-# If the tag value is set to YES, a side panel will be generated
-# containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
-# Windows users are probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = NO
-
-# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
-# and Class Hierarchy pages using a tree view instead of an ordered list.
-
-USE_INLINE_TREES = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
-# links to external symbols imported via tag files in a separate window.
-
-EXT_LINKS_IN_WINDOW = NO
-
-# Use this tag to change the font size of Latex formulas included
-# as images in the HTML documentation. The default is 10. Note that
-# when you change the font size after a successful doxygen run you need
-# to manually remove any form_*.png images from the HTML output directory
-# to force them to be regenerated.
-
-FORMULA_FONTSIZE = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are
-# not supported properly for IE 6.0, but are supported on all modern browsers.
-# Note that when changing this option you need to delete any form_*.png files
-# in the HTML output before the changes have effect.
-
-FORMULA_TRANSPARENT = YES
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box
-# for the HTML output. The underlying search engine uses javascript
-# and DHTML and should work on any modern browser. Note that when using
-# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
-# (GENERATE_DOCSET) there is already a search function so this one should
-# typically be disabled. For large projects the javascript based search engine
-# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
-
-SEARCHENGINE = NO
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a PHP enabled web server instead of at the web client
-# using Javascript. Doxygen will generate the search PHP script and index
-# file to put on the web server. The advantage of the server
-# based approach is that it scales better to large projects and allows
-# full text search. The disadvances is that it is more difficult to setup
-# and does not have live searching capabilities.
-
-SERVER_BASED_SEARCH = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-# Note that when enabling USE_PDFLATEX this option is only used for
-# generating bitmaps for formulas in the HTML output, but not in the
-# Makefile that is written to the output directory.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = a4
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER = 
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = YES
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-# If LATEX_SOURCE_CODE is set to YES then doxygen will include
-# source code with syntax highlighting in the LaTeX output.
-# Note that which sources are shown also depends on other settings
-# such as SOURCE_BROWSER.
-
-LATEX_SOURCE_CODE = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE = 
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA = 
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD = 
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader.
-# This is useful
-# if you want to understand what is going on.
-# On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = NO
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
-EXPAND_ONLY_PREDEF = YES
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH = 
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
-
-PREDEFINED = 
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED = 
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-#
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-#
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE = 
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option is superseded by the HAVE_DOT option below. This is only a
-# fallback. It is recommended to install and use dot, since it yields more
-# powerful graphs.
-
-CLASS_DIAGRAMS = NO
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see
-# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH = 
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = NO
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = YES
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
-# allowed to run in parallel. When set to 0 (the default) doxygen will
-# base this on the number of processors available in the system. You can set it
-# explicitly to a value larger than 0 to get control over the balance
-# between CPU load and processing speed.
-
-DOT_NUM_THREADS = 0
-
-# By default doxygen will write a font called FreeSans.ttf to the output
-# directory and reference it in all dot files that doxygen generates. This
-# font does not include all possible unicode characters however, so when you need
-# these (or just want a differently looking font) you can specify the font name
-# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
-# which can be done by putting it in a standard location or by setting the
-# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
-# containing the font.
-
-DOT_FONTNAME = FreeSans.ttf
-
-# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
-# The default size is 10pt.
-
-DOT_FONTSIZE = 10
-
-# By default doxygen will tell dot to use the output directory to look for the
-# FreeSans.ttf font (which doxygen will put there itself). If you specify a
-# different font using DOT_FONTNAME you can set the path where dot
-# can find it using this tag.
-
-DOT_FONTPATH = 
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS = NO
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT options are set to YES then
-# doxygen will generate a call dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable call graphs
-# for selected functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
-# doxygen will generate a caller dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable caller
-# graphs for selected functions only using the \callergraph command.
-
-CALLER_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH = 
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS = 
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
-# nodes that will be shown in the graph. If the number of nodes in a graph
-# becomes larger than this value, doxygen will truncate the graph, which is
-# visualized by representing a node as a red box. Note that doxygen if the
-# number of direct children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
-# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-
-DOT_GRAPH_MAX_NODES = 1024
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes
-# that lay further from the root node will be omitted. Note that setting this
-# option to 1 or 2 may greatly reduce the computation time needed for large
-# code bases. Also note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not
-# seem to support this out of the box. Warning: Depending on the platform used,
-# enabling this option may lead to badly anti-aliased labels on the edges of
-# a graph (i.e. they become hard to read).
-
-DOT_TRANSPARENT = YES
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
diff --git a/tools/doxygen/doxygen_footer.html b/tools/doxygen/doxygen_footer.html
deleted file mode 100644 (file)
index 2615af0..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<!-- 
-File added into doxygen generated documentation
--->
-
-
-
-<hr class="footer" />
-<address class="footer"><small>Generated on $datetime for <a href="https://www.dolibarr.org" title="ERP and CRM open source software">$projectname</a> by Doxygen $doxygenversion </small></address>
-
-
-<br>
-
-
-
-<!-- Global site tag (gtag.js) - Google Analytics -->
-<script async src="https://www.googletagmanager.com/gtag/js?id=UA-9049390-16"></script>
-<script>
-  window.dataLayer = window.dataLayer || [];
-  function gtag(){dataLayer.push(arguments);}
-  gtag('js', new Date());
-
-  gtag('config', 'UA-9049390-16');
-</script>
-
-</body>
-</html>
\ No newline at end of file
diff --git a/tools/doxygen/doxygen_header.html b/tools/doxygen/doxygen_header.html
deleted file mode 100644 (file)
index f60f482..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<!-- File added into doxygen generated documentation -->
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title>Dolibarr source code documentation</title>
-<!--  from dolibarr.org -->
-<meta http-equiv="Content-Type" content="text/html" charset=utf-8 />
-<meta name="verify-v1"
-       content="5uTEtcSaRHlZVnb3L4x4QrpRzdw3zMZ51+mJxf/4Cd8=" />
-<meta name="verify-v1"
-       content="ygCOli7T1nnmmIz2ikasGV2Y+1DLmLcsblrDp+tSo/Q=" />
-<link href="tabs.css" rel="stylesheet" type="text/css" />
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-<!-- End from dolibarr.org -->
-</head>
-
-<body>
-
-<div class="topmaincol">
-<div class="divpath">
-</div>
-</div>
-
-<div id="logodol">
-<div class="center">
-<table width="100%">
-       <tr>
-               <td><div id="projectname">$projectname</div> - <span id="projectnumber">$projectnumber</span></td>
-               <td class="right"><!-- banner start -->
-               <table cellpadding="0" cellspacing="0" class="moduletablemybanner">
-                       <tr>
-                               <td>
-                               <div class="bannergroupmybanner">
-
-                               <div class="banneritemmybanner">
-                               <div class="clr"></div>
-                               </div>
-
-                               </div>
-                               </td>
-                       </tr>
-               </table>
-               <!-- banner end --></td>
-       </tr>
-</table>
-</div>
-
-</div>
-
-<!-- End doxygen_header.html -->
-
-
diff --git a/tools/examples/zapier/.editorconfig b/tools/examples/zapier/.editorconfig
deleted file mode 100644 (file)
index 9228bbb..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# EditorConfig is awesome: https://editorconfig.org
-
-# top-most EditorConfig file
-root = true
-
-# Unix-style newlines with a newline ending every file
-[*]
-charset = utf-8
-end_of_line = lf
-
-[*.js]
-indent_style = space
-indent_size = 4
-insert_final_newline = true
-trim_trailing_whitespace = true
-
-[*.md]
-indent_style = space
-indent_size = 2
-insert_final_newline = true
-trim_trailing_whitespace = false
diff --git a/tools/examples/zapier/.gitignore b/tools/examples/zapier/.gitignore
deleted file mode 100644 (file)
index 3e9263e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-build
-docs
-node_modules
-*.log
-.environment
-.env
-.zapierapprc
-package-lock.json
diff --git a/tools/examples/zapier/.travis.yml b/tools/examples/zapier/.travis.yml
deleted file mode 100644 (file)
index 5b8db59..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-language: node_js
-node_js:
-  - 8.10.0
-before_script: 'npm install -g zapier-platform-cli'
-script: 'zapier test'
-notifications:
-  email: false
diff --git a/tools/examples/zapier/README.md b/tools/examples/zapier/README.md
deleted file mode 100644 (file)
index e452cc2..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# HOW TO BUILD
-
-Take a look at the dolibarr wiki page of Zapier module:
-
-https://wiki.dolibarr.org/index.php?title=Module_Zapier
-
diff --git a/tools/examples/zapier/action.json b/tools/examples/zapier/action.json
deleted file mode 100644 (file)
index e3aa4e6..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-{
-    "table_rowid": "id",
-    "id": 6764,
-    "ref": null,
-    "type_id": "5",
-    "type_code": "AC_RDV",
-    "type": null,
-    "type_color": null,
-    "code": null,
-    "label": "azerty",
-    "datec": null,
-    "datem": null,
-    "authorid": null,
-    "usermodid": null,
-    "datep": 1555365600,
-    "datef": 1555538399,
-    "durationp": 172799,
-    "fulldayevent": 1,
-    "punctual": 1,
-    "percentage": "-1",
-    "location": "",
-    "transparency": 1,
-    "priority": 0,
-    "userassigned": {
-        "1": {
-            "id": "1",
-            "transparency": 1
-        }
-    },
-    "userownerid": "1",
-    "userdoneid": null,
-    "usertodo": null,
-    "userdone": null,
-    "socid": null,
-    "contactid": null,
-    "elementtype": "",
-    "icalname": null,
-    "icalcolor": null,
-    "actions": [],
-    "email_msgid": null,
-    "email_from": null,
-    "email_sender": null,
-    "email_to": null,
-    "email_tocc": null,
-    "email_tobcc": null,
-    "email_subject": null,
-    "errors_to": null,
-    "import_key": null,
-    "linkedObjectsIds": null,
-    "fk_project": 0,
-    "modelpdf": null,
-    "note_public": null,
-    "note_private": null,
-    "note": "wxcvbn",
-    "duree": 0
-}
\ No newline at end of file
diff --git a/tools/examples/zapier/authentication.js b/tools/examples/zapier/authentication.js
deleted file mode 100644 (file)
index fceedd4..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*jshint esversion: 6 */
-const test = (z , bundle) => {
-    const url = bundle.authData.url+'/api/index.php/status';
-    // Normally you want to make a request to an endpoint that is either specifically designed to test auth, or one that
-    // every user will have access to, such as an account or profile endpoint like /me.
-    // In this example, we'll hit httpbin, which validates the Authorization Header against the arguments passed in the URL path
-    const promise = z.request({
-        url: url,
-    });
-
-    // This method can return any truthy value to indicate the credentials are valid.
-    // Raise an error to show
-    return promise.then((response) => {
-        if (response.status === 400) {
-            throw new Error('400 -The Session Key you supplied is invalid');
-        }
-        if (response.status === 403) {
-            throw new Error('403 -The Session Key you supplied is invalid');
-        }
-        return response;
-    });
-};
-
-// To include the session key header on all outbound requests, simply define a function here.
-// It runs runs before each request is sent out, allowing you to make tweaks to the request in a centralized spot
-const includeSessionKeyHeader = (request, z, bundle) => {
-    if (bundle.authData.sessionKey) {
-        request.headers = request.headers || {};
-        request.headers['DOLAPIKEY'] = bundle.authData.sessionKey;
-    }
-    return request;
-};
-
-// If we get a response and it is a 401, we can raise a special error telling Zapier to retry this after another exchange.
-const sessionRefreshIf401 = (response, z, bundle) => {
-    if (bundle.authData.sessionKey) {
-        if (response.status === 401) {
-            throw new z.errors.RefreshAuthError('Session apikey needs refreshing.');
-        }
-    }
-    return response;
-};
-
-const getSessionKey = async (z, bundle) => {
-    const url = bundle.authData.url + '/api/index.php/login';
-
-    const response = await z.request({
-        url: url,
-        method: 'POST',
-        body: {
-            login: bundle.authData.login,
-            password: bundle.authData.password,
-        },
-    });
-
-    // if (response.status === 401) {
-    //     throw new Error('The login/password you supplied is invalid');
-    // }
-    const json = JSON.parse(response.content);
-    return {
-        sessionKey: json.success.token || '',
-    };
-};
-
-module.exports = {
-    config: {
-        type: 'session',
-        sessionConfig: {
-            perform: getSessionKey
-        },
-        // Define any auth fields your app requires here. The user will be prompted to enter this info when
-        // they connect their account.
-        fields: [
-            {
-                key: 'url',
-                label: 'Url of service without trailing-slash',
-                required: true,
-                type: 'string'
-            },
-            {
-                key: 'login',
-                label: 'Login',
-                required: true,
-                type: 'string'
-            },
-            {
-                key: 'password',
-                label: 'Password',
-                required: true,
-                type: 'password'
-            }
-        ],
-        // The test method allows Zapier to verify that the credentials a user provides are valid. We'll execute this
-        // method whenever a user connects their account for the first time.
-        test,
-        // The method that will exchange the fields provided by the user for session credentials.
-        // assuming "login" is a key returned from the test
-        connectionLabel: '{{login}}'
-    },
-    befores: [includeSessionKeyHeader],
-    afters: [sessionRefreshIf401],
-};
diff --git a/tools/examples/zapier/creates/contact.js b/tools/examples/zapier/creates/contact.js
deleted file mode 100644 (file)
index bcb849a..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*jshint esversion: 6 */
-// create a particular contact by name
-const createContact = async (z, bundle) => {
-    const apiurl = bundle.authData.url  + '/api/index.php/contacts';
-
-    const response = await z.request({
-        method: 'POST',
-        url: apiurl,
-        body: {
-            name: bundle.inputData.name,
-            name_alias: bundle.inputData.name_alias,
-            ref_ext: bundle.inputData.ref_ext,
-            ref_int: bundle.inputData.ref_int,
-            address: bundle.inputData.address,
-            zip: bundle.inputData.zip,
-            town: bundle.inputData.town,
-            country_code: bundle.inputData.country_code,
-            country_id: bundle.inputData.country_id,
-            country: bundle.inputData.country,
-            phone: bundle.inputData.phone,
-            email: bundle.inputData.email,
-            sens: 'fromzapier'
-        }
-    });
-    const result = z.JSON.parse(response.content);
-    // api returns an integer when ok, a json when ko
-    return result.response || {id: response};
-};
-
-module.exports = {
-    key: 'contact',
-    noun: 'Contact',
-
-    display: {
-        label: 'Create Contact',
-        description: 'Creates a contact.'
-    },
-
-    operation: {
-        inputFields: [
-            {key: 'name', required: true},
-            {key: 'name_alias', required: false},
-            {key: 'address', required: false},
-            {key: 'zip', required: false},
-            {key: 'town', required: false},
-            {key: 'email', required: false}
-        ],
-        perform: createContact,
-
-        sample: {
-            id: 1,
-            name: 'DUPOND',
-            name_alias: 'DUPOND Ltd',
-            address: 'Rue des Canaries',
-            zip: '34090',
-            town: 'MONTPELLIER',
-            phone: '0123456789',
-            fax: '2345678901',
-            email: 'robot@domain.com'
-        },
-
-        outputFields: [
-            {key: 'id', type: "integer", label: 'ID'},
-            {key: 'name', label: 'Name'},
-            {key: 'name_alias', label: 'Name alias'},
-            {key: 'address', label: 'Address'},
-            {key: 'zip', label: 'Zip'},
-            {key: 'town', label: 'Town'},
-            {key: 'phone', label: 'Phone'},
-            {key: 'fax', label: 'Fax'},
-            {key: 'email', label: 'Email'}
-        ]
-    }
-};
diff --git a/tools/examples/zapier/creates/member.js b/tools/examples/zapier/creates/member.js
deleted file mode 100644 (file)
index 152f112..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*jshint esversion: 6 */
-// create a particular member by name
-const createMember = async (z, bundle) => {
-    const apiurl = bundle.authData.url  + '/api/index.php/members';
-
-    const response = await z.request({
-        method: 'POST',
-        url: apiurl,
-        body: {
-            name: bundle.inputData.name,
-            name_alias: bundle.inputData.name_alias,
-            ref_ext: bundle.inputData.ref_ext,
-            ref_int: bundle.inputData.ref_int,
-            address: bundle.inputData.address,
-            zip: bundle.inputData.zip,
-            town: bundle.inputData.town,
-            country_code: bundle.inputData.country_code,
-            country_id: bundle.inputData.country_id,
-            country: bundle.inputData.country,
-            phone: bundle.inputData.phone,
-            email: bundle.inputData.email,
-            sens: 'fromzapier'
-        }
-    });
-    const result = z.JSON.parse(response.content);
-    // api returns an integer when ok, a json when ko
-    return result.response || {id: response};
-};
-
-module.exports = {
-    key: 'member',
-    noun: 'Member',
-
-    display: {
-        label: 'Create Member',
-        description: 'Creates a member.'
-    },
-
-    operation: {
-        inputFields: [
-            {key: 'name', required: true},
-            {key: 'name_alias', required: false},
-            {key: 'address', required: false},
-            {key: 'zip', required: false},
-            {key: 'town', required: false},
-            {key: 'email', required: false}
-        ],
-        perform: createMember,
-
-        sample: {
-            id: 1,
-            name: 'DUPOND',
-            name_alias: 'DUPOND Ltd',
-            address: 'Rue des Canaries',
-            zip: '34090',
-            town: 'MONTPELLIER',
-            phone: '0123456789',
-            fax: '2345678901',
-            email: 'robot@domain.com'
-        },
-
-        outputFields: [
-            {key: 'id', type: "integer", label: 'ID'},
-            {key: 'name', label: 'Name'},
-            {key: 'name_alias', label: 'Name alias'},
-            {key: 'address', label: 'Address'},
-            {key: 'zip', label: 'Zip'},
-            {key: 'town', label: 'Town'},
-            {key: 'phone', label: 'Phone'},
-            {key: 'fax', label: 'Fax'},
-            {key: 'email', label: 'Email'}
-        ]
-    }
-};
diff --git a/tools/examples/zapier/creates/thirdparty.js b/tools/examples/zapier/creates/thirdparty.js
deleted file mode 100644 (file)
index 2abeef6..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*jshint esversion: 6 */
-// create a particular thirdparty by name
-const createThirdparty = async (z, bundle) => {
-    const apiurl = bundle.authData.url  + '/api/index.php/thirdparties';
-
-    const response = await z.request({
-        method: 'POST',
-        url: apiurl,
-        body: {
-            name: bundle.inputData.name,
-            name_alias: bundle.inputData.name_alias,
-            ref_ext: bundle.inputData.ref_ext,
-            ref_int: bundle.inputData.ref_int,
-            address: bundle.inputData.address,
-            zip: bundle.inputData.zip,
-            town: bundle.inputData.town,
-            country_code: bundle.inputData.country_code,
-            country_id: bundle.inputData.country_id,
-            country: bundle.inputData.country,
-            phone: bundle.inputData.phone,
-            email: bundle.inputData.email,
-            client: bundle.inputData.client,
-            fournisseur: bundle.inputData.fournisseur,
-            code_client: bundle.inputData.code_client,
-            code_fournisseur: bundle.inputData.code_fournisseur,
-            sens: 'fromzapier'
-        }
-    });
-    const result = z.JSON.parse(response.content);
-    // api returns an integer when ok, a json when ko
-    return result.response || {id: response};
-};
-
-module.exports = {
-    key: 'thirdparty',
-    noun: 'Thirdparty',
-
-    display: {
-        label: 'Create Thirdparty',
-        description: 'Creates a thirdparty.'
-    },
-
-    operation: {
-        inputFields: [
-            {key: 'name', required: true},
-            {key: 'name_alias', required: false},
-            {key: 'address', required: false},
-            {key: 'zip', required: false},
-            {key: 'town', required: false},
-            {key: 'email', required: false},
-            {key: 'client', type: 'integer', required: false},
-            {key: 'fournisseur', type: 'integer', required: false},
-            {key: 'code_client', required: false},
-            {key: 'code_fournisseur', required: false}
-        ],
-        perform: createThirdparty,
-
-        sample: {
-            id: 1,
-            name: 'DUPOND',
-            name_alias: 'DUPOND Ltd',
-            address: 'Rue des Canaries',
-            zip: '34090',
-            town: 'MONTPELLIER',
-            phone: '0123456789',
-            fax: '2345678901',
-            email: 'robot@domain.com',
-            client: 1,
-            fournisseur: 0,
-            code_client: 'CU1903-1234',
-            code_fournisseur: 'SU1903-2345'
-        },
-
-        outputFields: [
-            {key: 'id', type: "integer", label: 'ID'},
-            {key: 'name', label: 'Name'},
-            {key: 'name_alias', label: 'Name alias'},
-            {key: 'address', label: 'Address'},
-            {key: 'zip', label: 'Zip'},
-            {key: 'town', label: 'Town'},
-            {key: 'phone', label: 'Phone'},
-            {key: 'fax', label: 'Fax'},
-            {key: 'email', label: 'Email'},
-            {key: 'client', type: "integer", label: 'Customer/Prospect 0/1/2/3'},
-            {key: 'fournisseur', type: "integer", label: 'Supplier 0/1'},
-            {key: 'code_client', label: 'Customer code'},
-            {key: 'code_fournisseur', label: 'Supplier code'}
-        ]
-    }
-};
diff --git a/tools/examples/zapier/index.js b/tools/examples/zapier/index.js
deleted file mode 100644 (file)
index fdd1ed2..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*jshint esversion: 6 */
-const triggerAction = require('./triggers/action');
-const triggerOrder = require('./triggers/order');
-const triggerThirdparty = require('./triggers/thirdparty');
-const triggerContact = require('./triggers/contact');
-const triggerTicket = require('./triggers/ticket');
-const triggerUser = require('./triggers/user');
-const triggerMember = require('./triggers/member');
-
-const searchThirdparty = require('./searches/thirdparty');
-const searchContact = require('./searches/contact');
-const searchMember = require('./searches/member');
-
-const createThirdparty = require('./creates/thirdparty');
-const createContact = require('./creates/contact');
-const createMember = require('./creates/member');
-
-const {
-    config: authentication,
-    befores = [],
-    afters = [],
-} = require('./authentication');
-
-// To include the session key header on all outbound requests, simply define a function here.
-// It runs runs before each request is sent out, allowing you to make tweaks to the request in a centralized spot
-// const includeSessionKeyHeader = (request, z, bundle) => {
-//     if (bundle.authData.sessionKey) {
-//         request.headers = request.headers || {};
-//         request.headers['DOLAPIKEY'] = bundle.authData.sessionKey;
-//     }
-//     return request;
-// };
-
-// If we get a response and it is a 401, we can raise a special error telling Zapier to retry this after another exchange.
-// const sessionRefreshIf401 = (response, z, bundle) => {
-//     if (bundle.authData.sessionKey) {
-//         if (response.status === 401) {
-//             throw new z.errors.RefreshAuthError('Session apikey needs refreshing.');
-//         }
-//     }
-//     return response;
-// };
-
-// We can roll up all our behaviors in an App.
-const App = {
-    // This is just shorthand to reference the installed dependencies you have. Zapier will
-    // need to know these before we can upload
-    version: require('./package.json').version,
-    platformVersion: require('zapier-platform-core').version,
-
-    authentication: authentication,
-
-    // beforeRequest & afterResponse are optional hooks into the provided HTTP client
-    beforeRequest: [
-        ...befores
-    ],
-
-    afterResponse: [
-        ...afters
-    ],
-
-    // If you want to define optional resources to simplify creation of triggers, searches, creates - do that here!
-    resources: {
-    },
-
-    // If you want your trigger to show up, you better include it here!
-    triggers: {
-        [triggerAction.key]: triggerAction,
-        [triggerOrder.key]: triggerOrder,
-        [triggerThirdparty.key]: triggerThirdparty,
-        [triggerContact.key]: triggerContact,
-        [triggerTicket.key]: triggerTicket,
-        [triggerUser.key]: triggerUser,
-        [triggerMember.key]: triggerMember,
-    },
-
-    // If you want your searches to show up, you better include it here!
-    searches: {
-        [searchThirdparty.key]: searchThirdparty,
-        [searchContact.key]: searchContact,
-        [searchMember.key]: searchMember,
-    },
-
-    // If you want your creates to show up, you better include it here!
-    creates: {
-        [createThirdparty.key]: createThirdparty,
-        [createContact.key]: createContact,
-        [createMember.key]: createMember,
-    }
-};
-
-// Finally, export the app.
-module.exports = App;
diff --git a/tools/examples/zapier/package.json b/tools/examples/zapier/package.json
deleted file mode 100644 (file)
index 8852928..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-  "name": "dolibarr",
-  "version": "1.14.0",
-  "description": "An app for connecting Dolibarr to the Zapier platform.",
-  "repository": "Dolibarr/dolibarr",
-  "homepage": "https://www.dolibarr.org/",
-  "author": "Frédéric France <frederic.france@netlogic.fr>",
-  "license": "BSD-3-Clause",
-  "main": "index.js",
-  "scripts": {
-    "test": "mocha --recursive"
-  },
-  "engines": {
-    "node": "14.0.0",
-    "npm": ">=5.6.0"
-  },
-  "dependencies": {
-    "zapier-platform-core": "11.3.1"
-  },
-  "devDependencies": {
-    "mocha": "^5.2.0",
-    "should": "^13.2.0"
-  }
-}
diff --git a/tools/examples/zapier/resources/resources.js b/tools/examples/zapier/resources/resources.js
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/tools/examples/zapier/searches/contact.js b/tools/examples/zapier/searches/contact.js
deleted file mode 100644 (file)
index b52b8d3..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-module.exports = {
-    key: 'contact',
-
-    // You'll want to provide some helpful display labels and descriptions
-    // for users. Zapier will put them into the UX.
-    noun: 'Contact',
-    display: {
-        label: 'Find a Contact',
-        description: 'Search for contact.'
-    },
-
-    // `operation` is where we make the call to your API to do the search
-    operation: {
-        // This search only has one search field. Your searches might have just one, or many
-        // search fields.
-        inputFields: [
-            {
-                key: 'lastname',
-                type: 'string',
-                label: 'Lastname',
-                helpText: 'Lastname to limit to the search to (i.e. The company or %company%).'
-            },
-            {
-                key: 'email',
-                type: 'string',
-                label: 'Email',
-                helpText: 'Email to limit to the search to.'
-            }
-        ],
-
-        perform: async (z, bundle) => {
-            const url = bundle.authData.url  + '/api/index.php/contacts/';
-
-            // Put the search value in a query param. The details of how to build
-            // a search URL will depend on how your API works.
-            let filter = '';
-            if (bundle.inputData.lastname) {
-                filter = "t.lastname like \'%"+bundle.inputData.name+"%\'";
-            }
-            if (bundle.inputData.email) {
-                if (bundle.inputData.lastname) {
-                    filter += " and ";
-                }
-                filter += "t.email like \'"+bundle.inputData.email+"\'";
-            }
-            const response = await z.request({
-                url: url,
-                // this parameter avoid throwing errors and let us manage them
-                skipThrowForStatus: true,
-                params: {
-                    sqlfilters: filter
-                }
-            });
-            //z.console.log(response);
-            if (response.status != 200) {
-                return [];
-            }
-            return response.json;
-        },
-
-        // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
-        // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
-        // returned records, and have obviously dummy values that we can show to any user.
-        sample: {
-            id: 1,
-            createdAt: 1472069465,
-            name: 'DOE',
-            firstname: 'John',
-            authorId: 1,
-            directions: '1. Boil Noodles\n2.Serve with sauce',
-            style: 'italian'
-        },
-
-        // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
-        // field definitions. The result will be used to augment the sample.
-        // outputFields: () => { return []; }
-        // Alternatively, a static field definition should be provided, to specify labels for the fields
-        outputFields: [
-            {
-                key: 'id',
-                type: "integer",
-                label: 'ID'
-            },
-            {key: 'createdAt', type: "integer", label: 'Created At'},
-            {key: 'name', label: 'Name'},
-            {key: 'firstname', label: 'Firstname'},
-            {key: 'directions', label: 'Directions'},
-            {key: 'authorId', type: "integer", label: 'Author ID'},
-            {
-                key: 'style',
-                label: 'Style'
-            }
-        ]
-    }
-};
diff --git a/tools/examples/zapier/searches/member.js b/tools/examples/zapier/searches/member.js
deleted file mode 100644 (file)
index f1a8406..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-module.exports = {
-    key: 'member',
-
-    // You'll want to provide some helpful display labels and descriptions
-    // for users. Zapier will put them into the UX.
-    noun: 'Member',
-    display: {
-        label: 'Find a Member',
-        description: 'Search for member.'
-    },
-
-    // `operation` is where we make the call to your API to do the search
-    operation: {
-        // This search only has one search field. Your searches might have just one, or many
-        // search fields.
-        inputFields: [
-            {
-                key: 'lastname',
-                type: 'string',
-                label: 'Lastname',
-                helpText: 'Lastname to limit to the search to (i.e. The company or %company%).'
-            },
-            {
-                key: 'email',
-                type: 'string',
-                label: 'Email',
-                helpText: 'Email to limit to the search to.'
-            }
-        ],
-
-        perform: async (z, bundle) => {
-            const url = bundle.authData.url + '/api/index.php/members/';
-
-            // Put the search value in a query param. The details of how to build
-            // a search URL will depend on how your API works.
-            let filter = '';
-            if (bundle.inputData.lastname) {
-                filter = "t.lastname like \'%" + bundle.inputData.name + "%\'";
-            }
-            if (bundle.inputData.email) {
-                if (bundle.inputData.lastname) {
-                    filter += " and ";
-                }
-                filter += "t.email like \'" + bundle.inputData.email + "\'";
-            }
-            const response = await z.request({
-                url: url,
-                // this parameter avoid throwing errors and let us manage them
-                skipThrowForStatus: true,
-                params: {
-                    sqlfilters: filter
-                }
-            });
-            //z.console.log(response);
-            if (response.status != 200) {
-                return [];
-            }
-            return response.json;
-        },
-
-        // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
-        // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
-        // returned records, and have obviously dummy values that we can show to any user.
-        sample: {
-            id: 1,
-            createdAt: 1472069465,
-            name: 'DOE',
-            firstname: 'John',
-            authorId: 1,
-        },
-
-        // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
-        // field definitions. The result will be used to augment the sample.
-        // outputFields: () => { return []; }
-        // Alternatively, a static field definition should be provided, to specify labels for the fields
-        outputFields: [
-            {
-                key: 'id',
-                type: "integer",
-                label: 'ID'
-            },
-            { key: 'createdAt', type: "integer", label: 'Created At' },
-            { key: 'name', label: 'Name' },
-            { key: 'firstname', label: 'Firstname' },
-            { key: 'authorId', type: "integer", label: 'Author ID' },
-        ]
-    }
-};
diff --git a/tools/examples/zapier/searches/thirdparty.js b/tools/examples/zapier/searches/thirdparty.js
deleted file mode 100644 (file)
index e1e6878..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-module.exports = {
-    key: 'thirdparty',
-
-    // You'll want to provide some helpful display labels and descriptions
-    // for users. Zapier will put them into the UX.
-    noun: 'Thirdparty',
-    display: {
-        label: 'Find a Thirdparty',
-        description: 'Search for thirdparty.'
-    },
-
-    // `operation` is where we make the call to your API to do the search
-    operation: {
-        // This search only has one search field. Your searches might have just one, or many
-        // search fields.
-        inputFields: [
-            {
-                key: 'name',
-                type: 'string',
-                label: 'Name',
-                helpText: 'Name to limit to the search to (i.e. The company or %company%).'
-            },
-            {
-                key: 'email',
-                type: 'string',
-                label: 'Email',
-                helpText: 'Email to limit to the search to.'
-            }
-        ],
-
-        perform: async (z, bundle) => {
-            const url = bundle.authData.url  + '/api/index.php/thirdparties/';
-
-            // Put the search value in a query param. The details of how to build
-            // a search URL will depend on how your API works.
-            let filter = '';
-            if (bundle.inputData.name) {
-                filter = "t.nom like \'%"+bundle.inputData.name+"%\'";
-            }
-            if (bundle.inputData.email) {
-                if (bundle.inputData.name) {
-                    filter += " and ";
-                }
-                filter += "t.email like \'"+bundle.inputData.email+"\'";
-            }
-            const response = await z.request({
-                url: url,
-                // this parameter avoid throwing errors and let us manage them
-                skipThrowForStatus: true,
-                params: {
-                    sqlfilters: filter
-                }
-            });
-            //z.console.log(response);
-            if (response.status != 200) {
-                return [];
-            }
-            return response.json;
-        },
-
-        // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
-        // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
-        // returned records, and have obviously dummy values that we can show to any user.
-        sample: {
-            id: 1,
-            createdAt: 1472069465,
-            name: 'DOE',
-            firstname: 'John',
-            authorId: 1,
-            directions: '1. Boil Noodles\n2.Serve with sauce',
-            style: 'italian'
-        },
-
-        // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
-        // field definitions. The result will be used to augment the sample.
-        // outputFields: () => { return []; }
-        // Alternatively, a static field definition should be provided, to specify labels for the fields
-        outputFields: [
-            {
-                key: 'id',
-                type: "integer",
-                label: 'ID'
-            },
-            {key: 'createdAt', type: "integer", label: 'Created At'},
-            {key: 'name', label: 'Name'},
-            {key: 'firstname', label: 'Firstname'},
-            {key: 'directions', label: 'Directions'},
-            {key: 'authorId', type: "integer", label: 'Author ID'},
-            {
-                key: 'style',
-                label: 'Style'
-            }
-        ]
-    }
-};
diff --git a/tools/examples/zapier/test/index.js b/tools/examples/zapier/test/index.js
deleted file mode 100644 (file)
index 220e48f..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-require('should');
-
-const zapier = require('zapier-platform-core');
-
-// Use this to make test calls into your app:
-const App = require('../index');
-const appTester = zapier.createAppTester(App);
-
-describe('My App', () => {
-
-  it('should test something', (done) => {
-    const x = 1;
-    x.should.eql(1);
-    done();
-  });
-
-});
diff --git a/tools/examples/zapier/triggers/action.js b/tools/examples/zapier/triggers/action.js
deleted file mode 100644 (file)
index 0e15247..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-const subscribeHook = (z, bundle) => {
-    // `z.console.log()` is similar to `console.log()`.
-    z.console.log('suscribing hook!');
-
-    // bundle.targetUrl has the Hook URL this app should call when an action is created.
-    const data = {
-        url: bundle.targetUrl,
-        event: bundle.event,
-        module: 'action',
-        action: bundle.inputData.action
-    };
-
-    const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: url,
-        method: 'POST',
-        body: data,
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const unsubscribeHook = (z, bundle) => {
-    // bundle.subscribeData contains the parsed response JSON from the subscribe
-    // request made initially.
-    z.console.log('unsuscribing hook!');
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
-        method: 'DELETE',
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const getAction = (z, bundle) => {
-    // bundle.cleanedRequest will include the parsed JSON object (if it's not a
-    // test poll) and also a .querystring property with the URL's query string.
-    const action = {
-        id: bundle.cleanedRequest.id,
-        ref: bundle.cleanedRequest.ref,
-        ref_client: bundle.cleanedRequest.ref_client,
-        name: bundle.cleanedRequest.name,
-        firstname: bundle.cleanedRequest.firstname,
-        usertodo__name: bundle.cleanedRequest.usertodo__name,
-        location: bundle.cleanedRequest.location,
-        label: bundle.cleanedRequest.label,
-        authorId: bundle.cleanedRequest.authorId,
-        createdAt: bundle.cleanedRequest.createdAt,
-        module: bundle.cleanedRequest.module,
-        datep: bundle.cleanedRequest.datep,
-        datef: bundle.cleanedRequest.datef,
-        fulldayevent: bundle.cleanedRequest.fulldayevent,
-        transparency: bundle.cleanedRequest.transparency,
-        icalname: bundle.cleanedRequest.icalname,
-        icalcolor: bundle.cleanedRequest.icalcolor,
-        note: bundle.cleanedRequest.note,
-        note_public: bundle.cleanedRequest.note_public,
-        note_private: bundle.cleanedRequest.note_private,
-        action: bundle.cleanedRequest.action
-    };
-
-    return [action];
-};
-
-const getFallbackRealAction = (z, bundle) => {
-    // For the test poll, you should get some real data, to aid the setup process.
-    const module = bundle.inputData.module;
-    const options = {
-        url: bundle.authData.url + '/api/index.php/agendaevents/0',
-    };
-
-    return z.request(options).then((response) => [JSON.parse(response.content)]);
-};
-
-// const getActionsChoices = (z, bundle) => {
-//     // For the test poll, you should get some real data, to aid the setup process.
-//     const module = bundle.inputData.module;
-//     const options = {
-//         url: bundle.authData.url  + '/api/index.php/zapierapi/getactionschoices/actions',
-//     };
-
-//     return z.request(options).then((response) => JSON.parse(response.content));
-// };
-
-// We recommend writing your actions separate like this and rolling them
-// into the App definition at the end.
-module.exports = {
-    key: 'action',
-
-    // You'll want to provide some helpful display labels and descriptions
-    // for users. Zapier will put them into the UX.
-    noun: 'Action',
-    display: {
-        label: 'New Agenda',
-        description: 'Triggers when a new agenda with action is done in Dolibarr.'
-    },
-
-    // `operation` is where the business logic goes.
-    operation: {
-
-        // `inputFields` can define the fields a user could provide,
-        // we'll pass them in as `bundle.inputData` later.
-        inputFields: [
-            {
-                key: 'action',
-                required: true,
-                type: 'string',
-                helpText: 'Which action of agenda this should trigger on.',
-                choices: {
-                    create: "Create",
-                    modify: "Modify",
-                    delete: "Delete",
-                }
-            }
-        ],
-
-        type: 'hook',
-
-        performSubscribe: subscribeHook,
-        performUnsubscribe: unsubscribeHook,
-
-        perform: getAction,
-        performList: getFallbackRealAction,
-
-        // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
-        // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
-        // returned records, and have obviously dummy values that we can show to any user.
-        sample: {
-            id: 1,
-            createdAt: 1472069465,
-            name: 'Best Spagetti Ever',
-            authorId: 1,
-            action: 'create'
-        },
-
-        // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
-        // field definitions. The result will be used to augment the sample.
-        // outputFields: () => { return []; }
-        // Alternatively, a static field definition should be provided, to specify labels for the fields
-        outputFields: [
-            {
-                key: 'id',
-                type: "integer",
-                label: 'ID'
-            },
-            {
-                key: 'createdAt',
-                type: "integer",
-                label: 'Created At'
-            },
-            {
-                key: 'name',
-                label: 'Name'
-            },
-            {
-                key: 'usertodo__name',
-                label: 'UserToDo Name'
-            },
-            {
-                key: 'authorId',
-                type: "integer",
-                label: 'Author ID'
-            },
-            {
-                key: 'action',
-                label: 'Action'
-            }
-        ]
-    }
-};
diff --git a/tools/examples/zapier/triggers/contact.js b/tools/examples/zapier/triggers/contact.js
deleted file mode 100644 (file)
index 2ba3bd2..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-const subscribeHook = (z, bundle) => {
-    // `z.console.log()` is similar to `console.log()`.
-    z.console.log('suscribing hook!');
-
-    // bundle.targetUrl has the Hook URL this app should call when an action is created.
-    const data = {
-        url: bundle.targetUrl,
-        event: bundle.event,
-        module: 'contact',
-        action: bundle.inputData.action
-    };
-
-    const url = bundle.authData.url  + '/api/index.php/zapierapi/hook';
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: url,
-        method: 'POST',
-        body: data,
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const unsubscribeHook = (z, bundle) => {
-    // bundle.subscribeData contains the parsed response JSON from the subscribe
-    // request made initially.
-    z.console.log('unsuscribing hook!');
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
-        method: 'DELETE',
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const getContact = (z, bundle) => {
-    // bundle.cleanedRequest will include the parsed JSON object (if it's not a
-    // test poll) and also a .querystring property with the URL's query string.
-    const contact = {
-        id: bundle.cleanedRequest.id,
-        name: bundle.cleanedRequest.name,
-        name_alias: bundle.cleanedRequest.name_alias,
-        firstname: bundle.cleanedRequest.firstname,
-        address: bundle.cleanedRequest.address,
-        zip: bundle.cleanedRequest.zip,
-        town: bundle.cleanedRequest.town,
-        email: bundle.cleanedRequest.email,
-        phone_pro: bundle.cleanedRequest.phone_pro,
-        phone_perso: bundle.cleanedRequest.phone_perso,
-        phone_mobile: bundle.cleanedRequest.phone_mobile,
-        authorId: bundle.cleanedRequest.authorId,
-        createdAt: bundle.cleanedRequest.createdAt,
-        action: bundle.cleanedRequest.action
-    };
-
-    return [contact];
-};
-
-const getFallbackRealContact = (z, bundle) => {
-    // For the test poll, you should get some real data, to aid the setup process.
-    const module = bundle.inputData.module;
-    const options = {
-        url: bundle.authData.url + '/api/index.php/contacts/0',
-    };
-
-    return z.request(options).then((response) => [JSON.parse(response.content)]);
-};
-
-// const getModulesChoices = (z/*, bundle*/) => {
-//     // For the test poll, you should get some real data, to aid the setup process.
-//     const options = {
-//         url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
-//     };
-
-//     return z.request(options).then((response) => JSON.parse(response.content));
-// };
-// const getModulesChoices = () => {
-//     return {
-//         orders: "Order",
-//         invoices: "Invoice",
-//         contacts: "Contact",
-//         contacts: "Contacts"
-//     };
-// };
-
-// const getActionsChoices = (z, bundle) => {
-//     // For the test poll, you should get some real data, to aid the setup process.
-//     const module = bundle.inputData.module;
-//     const options = {
-//         url:  url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
-//     };
-
-//     return z.request(options).then((response) => JSON.parse(response.content));
-// };
-
-// We recommend writing your triggers separate like this and rolling them
-// into the App definition at the end.
-module.exports = {
-    key: 'contact',
-
-    // You'll want to provide some helpful display labels and descriptions
-    // for users. Zapier will put them into the UX.
-    noun: 'Contact',
-    display: {
-        label: 'New Contact',
-        description: 'Triggers when a new contact action is done in Dolibarr.'
-    },
-
-    // `operation` is where the business logic goes.
-    operation: {
-
-        // `inputFields` can define the fields a user could provide,
-        // we'll pass them in as `bundle.inputData` later.
-        inputFields: [
-            {
-                key: 'action',
-                required: true,
-                type: 'string',
-                helpText: 'Which action of contact this should trigger on.',
-                choices: {
-                    create: "Create",
-                    modify: "Modify",
-                    validate: "Validate",
-                }
-            }
-        ],
-
-        type: 'hook',
-
-        performSubscribe: subscribeHook,
-        performUnsubscribe: unsubscribeHook,
-
-        perform: getContact,
-        performList: getFallbackRealContact,
-
-        // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
-        // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
-        // returned records, and have obviously dummy values that we can show to any user.
-        sample: {
-            id: 1,
-            createdAt: 1472069465,
-            lastname: 'DOE',
-            firstname: 'John',
-            authorId: 1,
-            action: 'create'
-        },
-
-        // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
-        // field definitions. The result will be used to augment the sample.
-        // outputFields: () => { return []; }
-        // Alternatively, a static field definition should be provided, to specify labels for the fields
-        outputFields: [
-            {key: 'id', type: "integer", label: 'ID'},
-            {key: 'createdAt', label: 'Created At'},
-            {key: 'lastname', label: 'Lastname'},
-            {key: 'firstname', label: 'Firstname'},
-            {key: 'phone', label: 'Phone pro'},
-            {key: 'phone_perso', label: 'Phone perso'},
-            {key: 'phone_mobile', label: 'Phone mobile'},
-            {key: 'authorId', type: "integer", label: 'Author ID'},
-            {key: 'action', label: 'Action'}
-        ]
-    }
-};
diff --git a/tools/examples/zapier/triggers/member.js b/tools/examples/zapier/triggers/member.js
deleted file mode 100644 (file)
index 3385cdc..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-const subscribeHook = (z, bundle) => {
-    // `z.console.log()` is similar to `console.log()`.
-    z.console.log('suscribing hook!');
-
-    // bundle.targetUrl has the Hook URL this app should call when an action is created.
-    const data = {
-        url: bundle.targetUrl,
-        event: bundle.event,
-        module: 'member',
-        action: bundle.inputData.action
-    };
-
-    const url = bundle.authData.url  + '/api/index.php/zapierapi/hook';
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: url,
-        method: 'POST',
-        body: data,
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const unsubscribeHook = (z, bundle) => {
-    // bundle.subscribeData contains the parsed response JSON from the subscribe
-    // request made initially.
-    z.console.log('unsuscribing hook!');
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
-        method: 'DELETE',
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const getMember = (z, bundle) => {
-    // bundle.cleanedRequest will include the parsed JSON object (if it's not a
-    // test poll) and also a .querystring property with the URL's query string.
-    const member = {
-        id: bundle.cleanedRequest.id,
-        name: bundle.cleanedRequest.name,
-        name_alias: bundle.cleanedRequest.name_alias,
-        firstname: bundle.cleanedRequest.firstname,
-        address: bundle.cleanedRequest.address,
-        zip: bundle.cleanedRequest.zip,
-        town: bundle.cleanedRequest.town,
-        email: bundle.cleanedRequest.email,
-        phone_pro: bundle.cleanedRequest.phone_pro,
-        phone_perso: bundle.cleanedRequest.phone_perso,
-        phone_mobile: bundle.cleanedRequest.phone_mobile,
-        authorId: bundle.cleanedRequest.authorId,
-        createdAt: bundle.cleanedRequest.createdAt,
-        action: bundle.cleanedRequest.action
-    };
-
-    return [member];
-};
-
-const getFallbackRealMember = (z, bundle) => {
-    // For the test poll, you should get some real data, to aid the setup process.
-    const module = bundle.inputData.module;
-    const options = {
-        url: bundle.authData.url + '/api/index.php/members/0',
-    };
-
-    return z.request(options).then((response) => [JSON.parse(response.content)]);
-};
-
-// const getModulesChoices = (z/*, bundle*/) => {
-//     // For the test poll, you should get some real data, to aid the setup process.
-//     const options = {
-//         url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
-//     };
-
-//     return z.request(options).then((response) => JSON.parse(response.content));
-// };
-// const getModulesChoices = () => {
-//     return {
-//         orders: "Order",
-//         invoices: "Invoice",
-//         members: "Member",
-//         members: "Members"
-//     };
-// };
-
-// const getActionsChoices = (z, bundle) => {
-//     // For the test poll, you should get some real data, to aid the setup process.
-//     const module = bundle.inputData.module;
-//     const options = {
-//         url:  url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
-//     };
-
-//     return z.request(options).then((response) => JSON.parse(response.content));
-// };
-
-// We recommend writing your triggers separate like this and rolling them
-// into the App definition at the end.
-module.exports = {
-    key: 'member',
-
-    // You'll want to provide some helpful display labels and descriptions
-    // for users. Zapier will put them into the UX.
-    noun: 'Member',
-    display: {
-        label: 'New Member',
-        description: 'Triggers when a new member action is done in Dolibarr.'
-    },
-
-    // `operation` is where the business logic goes.
-    operation: {
-
-        // `inputFields` can define the fields a user could provide,
-        // we'll pass them in as `bundle.inputData` later.
-        inputFields: [
-            {
-                key: 'action',
-                required: true,
-                type: 'string',
-                helpText: 'Which action of member this should trigger on.',
-                choices: {
-                    create: "Create",
-                    modify: "Modify",
-                    validate: "Validate",
-                }
-            }
-        ],
-
-        type: 'hook',
-
-        performSubscribe: subscribeHook,
-        performUnsubscribe: unsubscribeHook,
-
-        perform: getMember,
-        performList: getFallbackRealMember,
-
-        // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
-        // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
-        // returned records, and have obviously dummy values that we can show to any user.
-        sample: {
-            id: 1,
-            createdAt: 1472069465,
-            lastname: 'DOE',
-            firstname: 'John',
-            authorId: 1,
-            action: 'create'
-        },
-
-        // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
-        // field definitions. The result will be used to augment the sample.
-        // outputFields: () => { return []; }
-        // Alternatively, a static field definition should be provided, to specify labels for the fields
-        outputFields: [
-            {key: 'id', type: "integer", label: 'ID'},
-            {key: 'createdAt', label: 'Created At'},
-            {key: 'lastname', label: 'Lastname'},
-            {key: 'firstname', label: 'Firstname'},
-            {key: 'phone', label: 'Phone pro'},
-            {key: 'phone_perso', label: 'Phone perso'},
-            {key: 'phone_mobile', label: 'Phone mobile'},
-            {key: 'authorId', type: "integer", label: 'Author ID'},
-            {key: 'action', label: 'Action'}
-        ]
-    }
-};
diff --git a/tools/examples/zapier/triggers/order.js b/tools/examples/zapier/triggers/order.js
deleted file mode 100644 (file)
index 061ce21..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-const subscribeHook = (z, bundle) => {
-    // `z.console.log()` is similar to `console.log()`.
-    z.console.log('suscribing hook!');
-
-    // bundle.targetUrl has the Hook URL this app should call when an action is created.
-    const data = {
-        url: bundle.targetUrl,
-        event: bundle.event,
-        module: 'order',
-        action: bundle.inputData.action
-    };
-
-    const url = bundle.authData.url  + '/api/index.php/zapierapi/hook';
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: url,
-        method: 'POST',
-        body: data,
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const unsubscribeHook = (z, bundle) => {
-    // bundle.subscribeData contains the parsed response JSON from the subscribe
-    // request made initially.
-    z.console.log('unsuscribing hook!');
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: bundle.authData.url  + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
-        method: 'DELETE',
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const getOrder = (z, bundle) => {
-    // bundle.cleanedRequest will include the parsed JSON object (if it's not a
-    // test poll) and also a .querystring property with the URL's query string.
-    const order = {
-        id: bundle.cleanedRequest.id,
-        ref: bundle.cleanedRequest.ref,
-        ref_client: bundle.cleanedRequest.ref_client,
-        name: bundle.cleanedRequest.name,
-        firstname: bundle.cleanedRequest.firstname,
-        directions: bundle.cleanedRequest.directions,
-        authorId: bundle.cleanedRequest.authorId,
-        createdAt: bundle.cleanedRequest.createdAt,
-        note_public: bundle.cleanedRequest.note_public,
-        note_private: bundle.cleanedRequest.note_private,
-        action: bundle.cleanedRequest.action
-    };
-
-    return [order];
-};
-
-const getFallbackRealOrder = (z, bundle) => {
-    // For the test poll, you should get some real data, to aid the setup process.
-    const module = bundle.inputData.module;
-    const options = {
-        url: bundle.authData.url  + '/api/index.php/orders/0',
-    };
-
-    return z.request(options).then((response) => [JSON.parse(response.content)]);
-};
-
-// const getActionsChoices = (z, bundle) => {
-//     // For the test poll, you should get some real data, to aid the setup process.
-//     const module = bundle.inputData.module;
-//     const options = {
-//         url: bundle.authData.url  + '/api/index.php/zapierapi/getactionschoices/orders',
-//     };
-
-//     return z.request(options).then((response) => JSON.parse(response.content));
-// };
-
-// We recommend writing your orders separate like this and rolling them
-// into the App definition at the end.
-module.exports = {
-    key: 'order',
-
-    // You'll want to provide some helpful display labels and descriptions
-    // for users. Zapier will put them into the UX.
-    noun: 'Order',
-    display: {
-        label: 'New Order',
-        description: 'Triggers when a new order with action is done in Dolibarr.'
-    },
-
-    // `operation` is where the business logic goes.
-    operation: {
-
-        // `inputFields` can define the fields a user could provide,
-        // we'll pass them in as `bundle.inputData` later.
-        inputFields: [
-            {
-                key: 'action',
-                required: true,
-                type: 'string',
-                helpText: 'Which action of order this should trigger on.',
-                choices: {
-                    create: "Create",
-                    modify: "Modify",
-                    validate: "Validate",
-                }
-            }
-        ],
-
-        type: 'hook',
-
-        performSubscribe: subscribeHook,
-        performUnsubscribe: unsubscribeHook,
-
-        perform: getOrder,
-        performList: getFallbackRealOrder,
-
-        // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
-        // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
-        // returned records, and have obviously dummy values that we can show to any user.
-        sample: {
-            id: 1,
-            createdAt: 1472069465,
-            name: 'Best Spagetti Ever',
-            authorId: 1,
-            directions: '1. Boil Noodles\n2.Serve with sauce',
-            action: 'create'
-        },
-
-        // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
-        // field definitions. The result will be used to augment the sample.
-        // outputFields: () => { return []; }
-        // Alternatively, a static field definition should be provided, to specify labels for the fields
-        outputFields: [
-            {key: 'id', type: "integer", label: 'ID'},
-            {key: 'createdAt', type: "integer", label: 'Created At'},
-            {key: 'name', label: 'Name'},
-            {key: 'directions', label: 'Directions'},
-            {key: 'authorId', type: "integer", label: 'Author ID'},
-            {key: 'module', label: 'Module'},
-            {key: 'action', label: 'Action'}
-        ]
-    }
-};
diff --git a/tools/examples/zapier/triggers/thirdparty.js b/tools/examples/zapier/triggers/thirdparty.js
deleted file mode 100644 (file)
index 76194ac..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-const subscribeHook = (z, bundle) => {
-    // `z.console.log()` is similar to `console.log()`.
-    z.console.log('suscribing hook!');
-
-    // bundle.targetUrl has the Hook URL this app should call when an action is created.
-    const data = {
-        url: bundle.targetUrl,
-        event: bundle.event,
-        module: 'company',
-        action: bundle.inputData.action
-    };
-
-    const url = bundle.authData.url  + '/api/index.php/zapierapi/hook';
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: url,
-        method: 'POST',
-        body: data,
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const unsubscribeHook = (z, bundle) => {
-    // bundle.subscribeData contains the parsed response JSON from the subscribe
-    // request made initially.
-    z.console.log('unsuscribing hook!');
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
-        method: 'DELETE',
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const getThirdparty = (z, bundle) => {
-    // bundle.cleanedRequest will include the parsed JSON object (if it's not a
-    // test poll) and also a .querystring property with the URL's query string.
-    const thirdparty = {
-        id: bundle.cleanedRequest.id,
-        name: bundle.cleanedRequest.name,
-        name_alias: bundle.cleanedRequest.name_alias,
-        firstname: bundle.cleanedRequest.firstname,
-        address: bundle.cleanedRequest.address,
-        zip: bundle.cleanedRequest.zip,
-        town: bundle.cleanedRequest.town,
-        email: bundle.cleanedRequest.email,
-        client: bundle.cleanedRequest.client,
-        fournisseur: bundle.cleanedRequest.fournisseur,
-        code_client: bundle.cleanedRequest.code_client,
-        code_fournisseur: bundle.cleanedRequest.code_fournisseur,
-        idprof1: bundle.cleanedRequest.idprof1,
-        idprof2: bundle.cleanedRequest.idprof2,
-        idprof3: bundle.cleanedRequest.idprof3,
-        idprof4: bundle.cleanedRequest.idprof4,
-        idprof5: bundle.cleanedRequest.idprof5,
-        idprof6: bundle.cleanedRequest.idprof6,
-        authorId: bundle.cleanedRequest.authorId,
-        createdAt: bundle.cleanedRequest.createdAt,
-        action: bundle.cleanedRequest.action
-    };
-
-    return [thirdparty];
-};
-
-const getFallbackRealThirdparty = (z, bundle) => {
-    // For the test poll, you should get some real data, to aid the setup process.
-    const module = bundle.inputData.module;
-    const options = {
-        url: bundle.authData.url + '/api/index.php/thirdparties/0',
-    };
-
-    return z.request(options).then((response) => [JSON.parse(response.content)]);
-};
-
-// const getModulesChoices = (z/*, bundle*/) => {
-//     // For the test poll, you should get some real data, to aid the setup process.
-//     const options = {
-//         url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
-//     };
-
-//     return z.request(options).then((response) => JSON.parse(response.content));
-// };
-// const getModulesChoices = () => {
-
-//     return {
-//         orders: "Order",
-//         invoices: "Invoice",
-//         thirdparties: "Thirdparty",
-//         contacts: "Contacts"
-//     };
-// };
-
-// const getActionsChoices = (z, bundle) => {
-//     // For the test poll, you should get some real data, to aid the setup process.
-//     const module = bundle.inputData.module;
-//     const options = {
-//         url:  url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
-//     };
-
-//     return z.request(options).then((response) => JSON.parse(response.content));
-// };
-
-// We recommend writing your triggers separate like this and rolling them
-// into the App definition at the end.
-module.exports = {
-    key: 'thirdparty',
-
-    // You'll want to provide some helpful display labels and descriptions
-    // for users. Zapier will put them into the UX.
-    noun: 'Thirdparty',
-    display: {
-        label: 'New Thirdparty',
-        description: 'Triggers when a new thirdparty action is done in Dolibarr.'
-    },
-
-    // `operation` is where the business logic goes.
-    operation: {
-
-        // `inputFields` can define the fields a user could provide,
-        // we'll pass them in as `bundle.inputData` later.
-        inputFields: [
-            {
-                key: 'action',
-                required: true,
-                type: 'string',
-                helpText: 'Which action of thirdparty this should trigger on.',
-                choices: {
-                    create: "Create",
-                    modify: "Modify",
-                    validate: "Validate",
-                }
-            }
-        ],
-
-        type: 'hook',
-
-        performSubscribe: subscribeHook,
-        performUnsubscribe: unsubscribeHook,
-
-        perform: getThirdparty,
-        performList: getFallbackRealThirdparty,
-
-        // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
-        // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
-        // returned records, and have obviously dummy values that we can show to any user.
-        sample: {
-            id: 1,
-            createdAt: 1472069465,
-            name: 'DOE',
-            name_alias: 'DOE Ltd',
-            firstname: 'John',
-            authorId: 1,
-            action: 'create'
-        },
-
-        // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
-        // field definitions. The result will be used to augment the sample.
-        // outputFields: () => { return []; }
-        // Alternatively, a static field definition should be provided, to specify labels for the fields
-        outputFields: [
-            {key: 'id', type: "integer", label: 'ID'},
-            {key: 'createdAt', label: 'Created At'},
-            {key: 'name', label: 'Name'},
-            {key: 'name_alias', label: 'Name alias'},
-            {key: 'firstname', label: 'Firstname'},
-            {key: 'authorId', type: "integer", label: 'Author ID'},
-            {key: 'action', label: 'Action'},
-            {key: 'client', label: 'Customer/Prospect 0/1/2/3'},
-            {key: 'fournisseur', label: 'Supplier 0/1'},
-            {key: 'code_client', label: 'Customer code'},
-            {key: 'code_fournisseur', label: 'Supplier code'},
-            {key: 'idprof1', label: 'Id Prof 1'},
-            {key: 'idprof2', label: 'Id Prof 2'},
-            {key: 'idprof3', label: 'Id Prof 3'},
-            {key: 'idprof4', label: 'Id Prof 4'},
-            {key: 'idprof5', label: 'Id Prof 5'},
-            {key: 'idprof6', label: 'Id Prof 6'}
-        ]
-    }
-};
diff --git a/tools/examples/zapier/triggers/ticket.js b/tools/examples/zapier/triggers/ticket.js
deleted file mode 100644 (file)
index c642099..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-const subscribeHook = (z, bundle) => {
-    // `z.console.log()` is similar to `console.log()`.
-    z.console.log('suscribing hook!');
-
-    // bundle.targetUrl has the Hook URL this app should call when an action is created.
-    const data = {
-        url: bundle.targetUrl,
-        event: bundle.event,
-        module: 'ticket',
-        action: bundle.inputData.action
-    };
-
-    const url = bundle.authData.url  + '/api/index.php/zapierapi/hook';
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: url,
-        method: 'POST',
-        body: data,
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const unsubscribeHook = (z, bundle) => {
-    // bundle.subscribeData contains the parsed response JSON from the subscribe
-    // request made initially.
-    z.console.log('unsuscribing hook!');
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
-        method: 'DELETE',
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const getTicket = (z, bundle) => {
-    // bundle.cleanedRequest will include the parsed JSON object (if it's not a
-    // test poll) and also a .querystring property with the URL's query string.
-    const ticket = {
-        id: bundle.cleanedRequest.id,
-        track_id: bundle.cleanedRequest.track_id,
-        subject: bundle.cleanedRequest.subject,
-        message: bundle.cleanedRequest.message,
-        lastname: bundle.cleanedRequest.lastname,
-        firstname: bundle.cleanedRequest.firstname,
-        address: bundle.cleanedRequest.address,
-        zip: bundle.cleanedRequest.zip,
-        town: bundle.cleanedRequest.town,
-        email_from: bundle.cleanedRequest.email_from,
-        login: bundle.cleanedRequest.login,
-        authorId: bundle.cleanedRequest.authorId,
-        createdAt: bundle.cleanedRequest.createdAt,
-        action: bundle.cleanedRequest.action
-    };
-
-    return [ticket];
-};
-
-const getFallbackRealTicket = (z, bundle) => {
-    // For the test poll, you should get some real data, to aid the setup process.
-    const module = bundle.inputData.module;
-    const options = {
-        url: bundle.authData.url + '/api/index.php/tickets/0',
-    };
-
-    return z.request(options).then((response) => [JSON.parse(response.content)]);
-};
-
-// const getModulesChoices = (z/*, bundle*/) => {
-//     // For the test poll, you should get some real data, to aid the setup process.
-//     const options = {
-//         url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
-//     };
-
-//     return z.request(options).then((response) => JSON.parse(response.content));
-// };
-// const getModulesChoices = () => {
-
-//     return {
-//         orders: "Order",
-//         invoices: "Invoice",
-//         thirdparties: "Thirdparty",
-//         users: "User",
-//         tickets: "Ticket",
-//         contacts: "Contacts"
-//     };
-// };
-
-// const getActionsChoices = (z, bundle) => {
-//     // For the test poll, you should get some real data, to aid the setup process.
-//     const module = bundle.inputData.module;
-//     const options = {
-//         url:  url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
-//     };
-
-//     return z.request(options).then((response) => JSON.parse(response.content));
-// };
-
-// We recommend writing your triggers separate like this and rolling them
-// into the App definition at the end.
-module.exports = {
-    key: 'ticket',
-
-    // You'll want to provide some helpful display labels and descriptions
-    // for tickets. Zapier will put them into the UX.
-    noun: 'Ticket',
-    display: {
-        label: 'New Ticket',
-        description: 'Triggers when a new ticket action is done in Dolibarr.'
-    },
-
-    // `operation` is where the business logic goes.
-    operation: {
-
-        // `inputFields` can define the fields a ticket could provide,
-        // we'll pass them in as `bundle.inputData` later.
-        inputFields: [
-            {
-                key: 'action',
-                type: 'string',
-                required: true,
-                helpText: 'Which action of ticket this should trigger on.',
-                choices: {
-                    create: "Create",
-                    modify: "Modify",
-                    validate: "Validate",
-                }
-            }
-        ],
-
-        type: 'hook',
-
-        performSubscribe: subscribeHook,
-        performUnsubscribe: unsubscribeHook,
-
-        perform: getTicket,
-        performList: getFallbackRealTicket,
-
-        // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
-        // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
-        // returned records, and have obviously dummy values that we can show to any user.
-        sample: {
-            id: 1,
-            track_id: 'Xaz123er',
-            subject: 'Subject',
-            message: 'Message',
-            createdAt: 1472069465,
-            lastname: 'DOE',
-            firstname: 'John',
-            email: 'john@doe.com',
-            address: 'Park Avenue',
-            zip: '12345',
-            town: 'NEW-YORK',
-            email_from: 'doe.john@example;com',
-            authorId: 1,
-            action: 'create'
-        },
-
-        // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
-        // field definitions. The result will be used to augment the sample.
-        // outputFields: () => { return []; }
-        // Alternatively, a static field definition should be provided, to specify labels for the fields
-        outputFields: [
-            {
-                key: 'id',
-                type: "integer",
-                label: 'ID'
-            },
-            {
-                key: 'track_id',
-                type: "string",
-                label: 'TrackID'
-            },
-            {
-                key: 'subject',
-                type: "string",
-                label: 'Subject'
-            },
-            {
-                key: 'message',
-                type: "string",
-                label: 'Message'
-            },
-            {
-                key: 'createdAt',
-                type: "integer",
-                label: 'Created At'
-            },
-            {
-                key: 'lastname',
-                label: 'Lastname'
-            },
-            {
-                key: 'firstname',
-                label: 'Firstname'
-            },
-            {
-                key: 'email',
-                label: 'Email'
-            },
-            {
-                key: 'address',
-                label: 'Address'
-            },
-            {
-                key: 'zip',
-                label: 'Zip'
-            },
-            {
-                key: 'town',
-                label: 'Town'
-            },
-            {
-                key: 'email_from',
-                type: 'string',
-                label: 'Email from'
-            },
-            {
-                key: 'authorId',
-                type: "integer",
-                label: 'Author ID'
-            },
-            {
-                key: 'action',
-                type: 'string',
-                label: 'Action'
-            }
-        ]
-    }
-};
diff --git a/tools/examples/zapier/triggers/user.js b/tools/examples/zapier/triggers/user.js
deleted file mode 100644 (file)
index 92209bb..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-const subscribeHook = (z, bundle) => {
-    // `z.console.log()` is similar to `console.log()`.
-    z.console.log('suscribing hook!');
-
-    // bundle.targetUrl has the Hook URL this app should call when an action is created.
-    const data = {
-        url: bundle.targetUrl,
-        event: bundle.event,
-        module: 'user',
-        action: bundle.inputData.action
-    };
-
-    const url = bundle.authData.url  + '/api/index.php/zapierapi/hook';
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: url,
-        method: 'POST',
-        body: data,
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const unsubscribeHook = (z, bundle) => {
-    // bundle.subscribeData contains the parsed response JSON from the subscribe
-    // request made initially.
-    z.console.log('unsuscribing hook!');
-
-    // You can build requests and our client will helpfully inject all the variables
-    // you need to complete. You can also register middleware to control this.
-    const options = {
-        url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
-        method: 'DELETE',
-    };
-
-    // You may return a promise or a normal data structure from any perform method.
-    return z.request(options).then((response) => JSON.parse(response.content));
-};
-
-const getUser = (z, bundle) => {
-    // bundle.cleanedRequest will include the parsed JSON object (if it's not a
-    // test poll) and also a .querystring property with the URL's query string.
-    const user = {
-        id: bundle.cleanedRequest.id,
-        lastname: bundle.cleanedRequest.lastname,
-        firstname: bundle.cleanedRequest.firstname,
-        address: bundle.cleanedRequest.address,
-        zip: bundle.cleanedRequest.zip,
-        town: bundle.cleanedRequest.town,
-        email: bundle.cleanedRequest.email,
-        login: bundle.cleanedRequest.login,
-        authorId: bundle.cleanedRequest.authorId,
-        createdAt: bundle.cleanedRequest.createdAt,
-        action: bundle.cleanedRequest.action
-    };
-
-    return [user];
-};
-
-const getFallbackRealUser = (z, bundle) => {
-    // For the test poll, you should get some real data, to aid the setup process.
-    const module = bundle.inputData.module;
-    const options = {
-        url: bundle.authData.url + '/api/index.php/users/0',
-    };
-
-    return z.request(options).then((response) => [JSON.parse(response.content)]);
-};
-
-// const getModulesChoices = (z/*, bundle*/) => {
-//     // For the test poll, you should get some real data, to aid the setup process.
-//     const options = {
-//         url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
-//     };
-
-//     return z.request(options).then((response) => JSON.parse(response.content));
-// };
-// const getModulesChoices = () => {
-
-//     return {
-//         orders: "Order",
-//         invoices: "Invoice",
-//         thirdparties: "Thirdparty",
-//         users: "User",
-//         contacts: "Contacts"
-//     };
-// };
-
-// const getActionsChoices = (z, bundle) => {
-//     // For the test poll, you should get some real data, to aid the setup process.
-//     const module = bundle.inputData.module;
-//     const options = {
-//         url:  url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
-//     };
-
-//     return z.request(options).then((response) => JSON.parse(response.content));
-// };
-
-// We recommend writing your triggers separate like this and rolling them
-// into the App definition at the end.
-module.exports = {
-    key: 'user',
-
-    // You'll want to provide some helpful display labels and descriptions
-    // for users. Zapier will put them into the UX.
-    noun: 'User',
-    display: {
-        label: 'New User',
-        description: 'Triggers when a new user action is done in Dolibarr.'
-    },
-
-    // `operation` is where the business logic goes.
-    operation: {
-
-        // `inputFields` can define the fields a user could provide,
-        // we'll pass them in as `bundle.inputData` later.
-        inputFields: [
-            {
-                key: 'action',
-                required: true,
-                type: 'string',
-                helpText: 'Which action of user this should trigger on.',
-                choices: {
-                    create: "Create",
-                    modify: "Modify",
-                    validate: "Validate",
-                }
-            }
-        ],
-
-        type: 'hook',
-
-        performSubscribe: subscribeHook,
-        performUnsubscribe: unsubscribeHook,
-
-        perform: getUser,
-        performList: getFallbackRealUser,
-
-        // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
-        // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
-        // returned records, and have obviously dummy values that we can show to any user.
-        sample: {
-            id: 1,
-            createdAt: 1472069465,
-            lastname: 'DOE',
-            firstname: 'John',
-            email: 'john@doe.com',
-            address: 'Park Avenue',
-            zip: '12345',
-            town: 'NEW-YORK',
-            login: 'doe.john',
-            authorId: 1,
-            action: 'create'
-        },
-
-        // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
-        // field definitions. The result will be used to augment the sample.
-        // outputFields: () => { return []; }
-        // Alternatively, a static field definition should be provided, to specify labels for the fields
-        outputFields: [
-            {key: 'id', type: "integer", label: 'ID'},
-            {key: 'createdAt', type: "integer", label: 'Created At'},
-            {key: 'lastname', label: 'Lastname'},
-            {key: 'firstname', label: 'Firstname'},
-            {key: 'email', label: 'Email'},
-            {key: 'address', label: 'Address'},
-            {key: 'zip', label: 'Zip'},
-            {key: 'town', label: 'Town'},
-            {key: 'login', label: 'Login'},
-            {key: 'authorId', type: "integer", label: 'Author ID'},
-            {key: 'action', label: 'Action'}
-        ]
-    }
-};
diff --git a/tools/flatpack/org.flatpak.Dolibarr.json b/tools/flatpack/org.flatpak.Dolibarr.json
deleted file mode 100644 (file)
index 69140d3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-"Help wanted..."
\ No newline at end of file
diff --git a/tools/patch/README b/tools/patch/README
deleted file mode 100644 (file)
index 400fbc4..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-README (English)
-##################################################
-Building a Patch file
-##################################################
-
-This directory contains tools to build a patch 
-after a developer has made changes on files in its
-Dolibarr tree. 
-The output patch file can then be submited on Dolibarr
-dev mailing-list, with explanation on its goal, for
-inclusion in main branch.
diff --git a/tools/patch/buildpatch.sh b/tools/patch/buildpatch.sh
deleted file mode 100644 (file)
index 3bbc6ea..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#/bin/ksh
-#----------------------------------------------------------------------------
-# \file         build/patch/buildpatch.sh
-# \brief        Create patch files
-# \author       (c)2009-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
-#----------------------------------------------------------------------------
-# This script can be used to build a patch after a developer has made
-# changes on files in its Dolibarr tree.
-# The output patch file can then be submited on Dolibarr dev mailing-list,
-# with explanation on its goal, for inclusion in main branch.
-#----------------------------------------------------------------------------
-
-echo ----- Building patch file mypatch.patch -----
-if [ -z "$1" ] || [ -z "$2" ];
-then 
-    echo Usage:   buildpatch.sh  original_dir_path    modified_dir_path
-    echo Example: buildpatch.sh  /mydirA/dolibarrold  /mydirB/dolibarrnew
-else
-    echo Build patch between \"$1\" and \"$2\" 
-    diff -BNaur --exclude=CVS --exclude="*.patch" --exclude=".#*" --exclude="*~" --exclude="*.rej" --exclude="*.orig" --exclude="*.bak" --exclude=conf.php --exclude=documents  $1  $2  > mypatch.patch
-fi