From: Kilian Date: Thu, 22 Feb 2024 14:04:39 +0000 (+0100) Subject: v240222 X-Git-Url: http://cloud.dks.lu/git/?a=commitdiff_plain;ds=sidebyside;p=dolibarr.git v240222 --- diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index de9ce330..00000000 --- a/.gitattributes +++ /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 diff --git a/.gitignore b/.gitignore index d0a99d96..a0867570 100644 --- a/.gitignore +++ b/.gitignore @@ -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 index a5a71898..00000000 --- a/.gitmessage +++ /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 ]=====^| diff --git a/.vscode/sftp.json b/.vscode/sftp.json index e83b408d..2883d6ab 100644 --- a/.vscode/sftp.json +++ b/.vscode/sftp.json @@ -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 index 00000000..0a40a992 --- /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 index dccff0dd..00000000 --- a/doc/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/dolibarr_*.pdf diff --git a/doc/images/README.md b/doc/images/README.md deleted file mode 100644 index e93c9f9c..00000000 --- a/doc/images/README.md +++ /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 index 4a93909a..00000000 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 index 22b04f21..00000000 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 index d5a9cda2..00000000 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 index b0cba0f6..00000000 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 index 7c7cd15c..00000000 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 index 5acfa77e..00000000 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 index 90b2e52f..00000000 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 index ec101a06..00000000 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 index 060a6065..00000000 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 index 1abe4e2c..00000000 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 index 727387b5..00000000 --- a/doc/images/dolibarr_256x256_black.svg +++ /dev/null @@ -1,313 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - D - - diff --git a/doc/images/dolibarr_256x256_color.png b/doc/images/dolibarr_256x256_color.png deleted file mode 100644 index b2d567d6..00000000 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 index 5115a8f7..00000000 --- a/doc/images/dolibarr_256x256_color.svg +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff --git a/doc/images/dolibarr_256x256_white.jpg b/doc/images/dolibarr_256x256_white.jpg deleted file mode 100644 index e5c4e260..00000000 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 index 1f5f7454..00000000 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 index 79a8c9d1..00000000 --- a/doc/images/dolibarr_256x256_white.svg +++ /dev/null @@ -1,327 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff --git a/doc/images/dolibarr_512x512_color.png b/doc/images/dolibarr_512x512_color.png deleted file mode 100644 index 71c2b0cc..00000000 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 index b0cba0f6..00000000 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 index a4a06110..00000000 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 index 63bd8ac3..00000000 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 index 9c9259d0..00000000 --- a/doc/images/dolibarr_logo.svg +++ /dev/null @@ -1,209 +0,0 @@ - - - - - Logo Dolibarr ERP-CRM - - - - - - - - - - - - - - - image/svg+xml - - Logo Dolibarr ERP-CRM - - - - Laurent Destailleur - - - - - Laurent Destailleur - - - - - - - - - - - - - - - - - - - - - - - - - - - ERP/CRM - - - diff --git a/doc/images/dolibarr_screenshot10_1920x1080.jpg b/doc/images/dolibarr_screenshot10_1920x1080.jpg deleted file mode 100644 index 61974758..00000000 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 index 8e8c0136..00000000 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 index c063cca6..00000000 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 index ac238d39..00000000 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 index 19a80907..00000000 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 index 2956a55d..00000000 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 index 00d57fc9..00000000 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 index d41dd87d..00000000 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 index 6eea0a2f..00000000 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 index 8f14c349..00000000 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 index cc2f2e63..00000000 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 index fcf4cac4..00000000 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 index e09a1b33..00000000 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 index a280fe63..00000000 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 index 82ee7170..00000000 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 index 2b19b2ac..00000000 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 index 4aa3ba99..00000000 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 index 2200fd1e..00000000 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 index 333f9609..00000000 --- a/doc/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - -Dolibarr doc directory - - - -This directory contains several subdirectories with entries for informations on Dolibarr.
-But if you are looking for other resources (downloads, documentation, addons, ...), you can find this on Internet on web following sites:
- -
-* Dolibarr portal (official website)
-
-* Dolibarr wiki (documentation)
-
-* Dolibarr demo (online)
-
-* DoliStore (official addons/plugins market place)
- - - \ No newline at end of file diff --git a/doc/install/README b/doc/install/README deleted file mode 100644 index 0192ff27..00000000 --- a/doc/install/README +++ /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 index f4cb3c1a..00000000 --- a/doc/install/README-DE +++ /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 index c362316b..00000000 --- a/doc/install/README-FR +++ /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 index ecde765c..00000000 --- a/doc/user/README +++ /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 index 336e7ab7..00000000 --- a/doc/user/README-DE +++ /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 index f5cb72ea..00000000 --- a/doc/user/README-FR +++ /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 diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index fb69ab53..a5b894dd 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -531,7 +531,7 @@ if ($mode == 'common' || $mode == 'commonkanban') { } print ''; - 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 '
'.$langs->trans("NoDeployedModulesFoundWithThisSearchCriteria").'

'; } - print dol_get_fiche_end(); + //print dol_get_fiche_end(); print '
'; @@ -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 "\n"; // print ''; - print dol_get_fiche_end(); + //print dol_get_fiche_end(); print '
'; @@ -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 "\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 index 2f5096f6..00000000 --- a/htdocs/asterisk/wrapper.php +++ /dev/null @@ -1,216 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 ''."\n"; - print ''."\n"; - print 'Asterisk redirection from Dolibarr...'."\n"; - print ''."\n"; -} - -/** - * Empty footer - * - * @ignore - * @return void - */ -function llxFooter() -{ - print "\n".''."\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 ''."\n"; - $txt = "Failed to execute fsockopen($strHost, $port, \$errno, \$errstr, 10)
\n"; - print $txt; - dol_syslog($txt, LOG_ERR); - $txt = $errstr." (".$errno.")
\n"; - print $txt; - dol_syslog($txt, LOG_ERR); - print ''."\n"; - } else { - $txt = "Call Asterisk dialer for caller: ".$caller.", called: ".$called." clicktodiallogin: ".$login; - dol_syslog($txt); - print ''."\n"; - print ''; - 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 ''."\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(); diff --git a/htdocs/conf/conf.php b/htdocs/conf/conf.php index 407fcc36..f7d5577a 100644 --- a/htdocs/conf/conf.php +++ b/htdocs/conf/conf.php @@ -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 diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index 0eef42b7..53385037 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -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 = ''; diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index ae98d464..5ead30fb 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -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'); diff --git a/htdocs/core/lib/asset.lib.php b/htdocs/core/lib/asset.lib.php index be31f995..2ce62b47 100644 --- a/htdocs/core/lib/asset.lib.php +++ b/htdocs/core/lib/asset.lib.php @@ -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 diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 32859889..0b9985dd 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -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] .= ''.$nbEvent.''; - } - } - $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] .= ''.$nbEvent.''; + // } + // } + // $head[$h][2] = 'agenda'; + // $h++; // Show more tabs from modules // Entries must be declared in modules descriptor with line diff --git a/htdocs/core/lib/contact.lib.php b/htdocs/core/lib/contact.lib.php index 2dbf97d4..766f3af7 100644 --- a/htdocs/core/lib/contact.lib.php +++ b/htdocs/core/lib/contact.lib.php @@ -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 /* diff --git a/htdocs/core/lib/contract.lib.php b/htdocs/core/lib/contract.lib.php index 64040757..de1448cb 100644 --- a/htdocs/core/lib/contract.lib.php +++ b/htdocs/core/lib/contract.lib.php @@ -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'); diff --git a/htdocs/core/lib/fourn.lib.php b/htdocs/core/lib/fourn.lib.php index c658916e..650aa269 100644 --- a/htdocs/core/lib/fourn.lib.php +++ b/htdocs/core/lib/fourn.lib.php @@ -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'); diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index cf028326..efc8d171 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -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'); diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 49e0672e..511c57cc 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -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); diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php index 4b0b487c..cf897523 100644 --- a/htdocs/core/lib/product.lib.php +++ b/htdocs/core/lib/product.lib.php @@ -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'); diff --git a/htdocs/core/lib/resource.lib.php b/htdocs/core/lib/resource.lib.php index ebfbaf22..9b69cf64 100644 --- a/htdocs/core/lib/resource.lib.php +++ b/htdocs/core/lib/resource.lib.php @@ -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'); diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index 64747c1b..f0506f8b 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -379,70 +379,70 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false) print $form->textwithpicto($langs->trans("DefaultSkin"), $langs->trans("ThemeDir").' : '.$dirthemestring); print ''; print ''; - $url = 'https://www.dolistore.com/9-skins'; - print ''; - print $langs->trans('DownloadMoreSkins'); - print img_picto('', 'globe', 'class="paddingleft"'); - print ''; + // $url = 'https://www.dolistore.com/9-skins'; + // print ''; + // print $langs->trans('DownloadMoreSkins'); + // print img_picto('', 'globe', 'class="paddingleft"'); + // print ''; print ''; } print ''; - 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 '
'; $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 '
'; - $file = $dirtheme."/".$subdir."/thumb.png"; - $url = $urltheme."/".$subdir."/thumb.png"; - if (!file_exists($file)) { - $url = DOL_URL_ROOT.'/public/theme/common/nophoto.png'; - } - print ''; - if ($subdir == $conf->global->MAIN_THEME) { - $title = $langs->trans("ThemeCurrentlyActive"); - } else { - $title = $langs->trans("ShowPreview"); - } - print ''.dol_escape_htmltag($title).''; - print '
'; - if ($subdir == $selected_theme) { - print ''; - } else { - print ''; - } - print '
'; - - $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 '
'; + // $file = $dirtheme."/".$subdir."/thumb.png"; + // $url = $urltheme."/".$subdir."/thumb.png"; + // if (!file_exists($file)) { + // $url = DOL_URL_ROOT.'/public/theme/common/nophoto.png'; + // } + // print ''; + // if ($subdir == $conf->global->MAIN_THEME) { + // $title = $langs->trans("ThemeCurrentlyActive"); + // } else { + // $title = $langs->trans("ShowPreview"); + // } + // print ''.dol_escape_htmltag($title).''; + // print '
'; + // if ($subdir == $selected_theme) { + // print ''; + // } else { + // print ''; + // } + // print '
'; + + // $i++; + // } + // } + // } + // } + // } print '
'; diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 16245427..1ccdb4b3 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -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 .= ''."\n"; // TODO If blogpost, use type article - $out .= ''."\n"; - if ($websitepage->image) { - $out .= ''."\n"; - } - $out .= ''."\n"; - - // Twitter - $out .= ''."\n"; - if (!empty($params) && !empty($params['twitter_account'])) { - $out .= ''."\n"; - $out .= ''."\n"; - } - $out .= ''."\n"; - if ($websitepage->description) { - $out .= ''."\n"; - } - if ($websitepage->image) { - $out .= ''."\n"; - } - //$out .= ''; - /* - $out .= ''; - $out .= ''; - $out .= ''; - $out .= ''; - $out .= ''; - $out .= ''; - $out .= ''; - $out .= ''; - $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 .= ''."\n"; // TODO If blogpost, use type article + // // $out .= ''."\n"; + // // if ($websitepage->image) { + // // $out .= ''."\n"; + // // } + // // $out .= ''."\n"; + + // // Twitter + // // $out .= ''."\n"; + // // if (!empty($params) && !empty($params['twitter_account'])) { + // // $out .= ''."\n"; + // // $out .= ''."\n"; + // // } + // // $out .= ''."\n"; + // // if ($websitepage->description) { + // // $out .= ''."\n"; + // // } + // // if ($websitepage->image) { + // // $out .= ''."\n"; + // // } + // //$out .= ''; + // /* + // $out .= ''; + // $out .= ''; + // $out .= ''; + // $out .= ''; + // $out .= ''; + // $out .= ''; + // $out .= ''; + // $out .= ''; + // $out .= ''; + // */ + // } 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 = ''."\n"; - - if ($website->virtualhost) { - $fullurl = $website->virtualhost.'/'.$websitepage->pageurl.'.php'; - $hashtags = trim(join(' #', array_map('trim', explode(',', $websitepage->keywords)))); - - $out .= '\n"; - } else { - $out .= ''."\n"; - } - $out .= ''."\n"; + $out=""; + // $out = ''."\n"; + + // if ($website->virtualhost) { + // $fullurl = $website->virtualhost.'/'.$websitepage->pageurl.'.php'; + // $hashtags = trim(join(' #', array_map('trim', explode(',', $websitepage->keywords)))); + + // $out .= '\n"; + // } else { + // $out .= ''."\n"; + // } + // $out .= ''."\n"; return $out; } diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 5fbe998a..d645aaf3 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1456,21 +1456,21 @@ function get_left_menu_billing($mainmenu, &$newmenu, $usemenuhider = 1, $leftmen $newmenu->add("/fourn/facture/card.php?leftmenu=suppliers_bills&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&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&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&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&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&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&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&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&leftmenu=suppliers_bills_stats", $langs->trans("Statistics"), 1, $user->hasRight('fournisseur', 'facture', 'lire'), '', $mainmenu, 'suppliers_bills_stats'); } // Orders diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_html.modules.php similarity index 76% rename from htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php rename to htdocs/core/modules/propale/doc/doc_generic_proposal_html.modules.php index b7dfc374..f4754ba5 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_html.modules.php @@ -1,48 +1,46 @@ * Copyright (C) 2012 Juanjo Menent - * Copyright (C) 2014 Marcos García * Copyright (C) 2016 Charlie Benke - * Copyright (C) 2018-2021 Philippe Grand - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018-2019 Frédéric France * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 . - * 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 . +* 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.".
\n"; $texte .= '
'; $texte .= ''; $texte .= ''; $texte .= ''; - $texte .= ''; + $texte .= ''; + if ($odtChosen) { + $texte .= ''; + $texte .= ''; + $texte .= ''; + } $texte .= ''; // List of directories area $texte .= ''; $texte .= ' - - - - - - - - - \n"; diff --git a/htdocs/modulebuilder/template/core/triggers/README.md b/htdocs/modulebuilder/template/core/triggers/README.md deleted file mode 100644 index 38d1b1d8..00000000 --- a/htdocs/modulebuilder/template/core/triggers/README.md +++ /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 index 8f7764ad..00000000 --- a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php +++ /dev/null @@ -1,323 +0,0 @@ -. - */ - -/** - * \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 index 260868a1..00000000 --- a/htdocs/modulebuilder/template/css/mymodule.css.php +++ /dev/null @@ -1,110 +0,0 @@ -. - */ - -/** - * \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 index 5a05c701..00000000 --- a/htdocs/modulebuilder/template/doc/Documentation.asciidoc +++ /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 index 4c744210..00000000 --- a/htdocs/modulebuilder/template/doc/Documentation_full_en.example.asciidoc +++ /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 index 2fcb4afc..00000000 --- a/htdocs/modulebuilder/template/img/README.md +++ /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 index fe04cdc2..00000000 --- a/htdocs/modulebuilder/template/js/mymodule.js.php +++ /dev/null @@ -1,99 +0,0 @@ -. - * - * 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 index cc518391..00000000 --- a/htdocs/modulebuilder/template/langs/en_US/mymodule.lang +++ /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 . - -# -# 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 index 0ebae6eb..00000000 --- a/htdocs/modulebuilder/template/lib/mymodule.lib.php +++ /dev/null @@ -1,76 +0,0 @@ -. - */ - -/** - * \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] .= ' ' . $nbExtrafields . ''; - } - $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 index d75f69a4..00000000 --- a/htdocs/modulebuilder/template/lib/mymodule_myobject.lib.php +++ /dev/null @@ -1,110 +0,0 @@ -. - */ - -/** - * \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) ? ''.$nbNote.'' : ''); - } - $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] .= ''.($nbFiles + $nbLinks).''; - } - $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 index 670a1774..00000000 --- a/htdocs/modulebuilder/template/modulebuilder.txt +++ /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 index 3b7b1b13..00000000 --- a/htdocs/modulebuilder/template/mymoduleindex.php +++ /dev/null @@ -1,251 +0,0 @@ - - * Copyright (C) 2004-2015 Laurent Destailleur - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2015 Jean-François Ferry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 '
'; - - -/* 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 '
'; $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 .= '
'; $texte .= ''; $texte .= '
'; - $texte .= ''; + $texte .= ''; $texte .= '
'; // Scan directories $nbofiles = count($listoffiles); - if (!empty($conf->global->MYMODULE_MYOBJECT_ADDON_PDF_ODT_PATH)) { + if (!empty($odtPath)) { $texte .= $langs->trans("NumberOfModelFilesFound").': '; //$texte.=$nbofiles?'':''; $texte .= count($listoffiles); @@ -175,13 +182,38 @@ class doc_generic_myobject_odt extends ModelePDFMyObject $texte .= ''; - } + // Set default template for different status of proposal + if ($odtChosen) { + // Model for creation + $list = ModelePDFPropales::liste_modeles($this->db); + $texte .= ''; + $texte .= ''; + $texte .= ''; + $texte .= '"; + + $texte .= ''; + $texte .= ''; + $texte .= '"; + $texte .= ''; + + $texte .= ''; + $texte .= '"; + $texte .= '
'.$langs->trans("DefaultModelPropalCreate").''; + $texte .= $form->selectarray('value2', $list, getDolGlobalString('PROPALE_ADDON_PDF_HTML_DEFAULT')); + $texte .= "
'.$langs->trans("DefaultModelPropalToBill").''; + $texte .= $form->selectarray('value3', $list, getDolGlobalString('PROPALE_ADDON_PDF_HTML_TOBILL')); + $texte .= "
'.$langs->trans("DefaultModelPropalClosed").''; + $texte .= $form->selectarray('value4', $list, getDolGlobalString('PROPALE_ADDON_PDF_HTML_CLOSED')); + $texte .= "
'; + } + } // Add input to upload a new template file. $texte .= '
'.$langs->trans("UploadNewTemplate"); $maxfilesizearray = getMaxFileSizeArray(); @@ -190,10 +222,9 @@ class doc_generic_myobject_odt extends ModelePDFMyObject $texte .= ''; // MAX_FILE_SIZE must precede the field type=file } $texte .= ' '; - $texte .= ''; + $texte .= ''; $texte .= ''; $texte .= '
'; - $texte .= '
'; @@ -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 index 00000000..797e9dd2 --- /dev/null +++ b/htdocs/core/modules/propale/doc/pdf_peitureteufela.modules.php @@ -0,0 +1,2080 @@ + + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2015 Juanjo Menent + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Cedric Salvador + * Copyright (C) 2015 Marcos García + * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2018 Frédéric France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 . + * 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; + } + } +} diff --git a/htdocs/custom/emailtracker/class/emails.class.php b/htdocs/custom/emailtracker/class/emails.class.php index 5e517bcc..f9a6c386 100644 --- a/htdocs/custom/emailtracker/class/emails.class.php +++ b/htdocs/custom/emailtracker/class/emails.class.php @@ -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)) . ')'; diff --git a/htdocs/custom/emailtracker/core/modules/modEmailTracker.class.php b/htdocs/custom/emailtracker/core/modules/modEmailTracker.class.php index f3d1d890..4981537a 100644 --- a/htdocs/custom/emailtracker/core/modules/modEmailTracker.class.php +++ b/htdocs/custom/emailtracker/core/modules/modEmailTracker.class.php @@ -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. diff --git a/htdocs/custom/emailtracker/tab_invoice_supplier.php b/htdocs/custom/emailtracker/tab_invoice_supplier.php index a952f52b..f73517ab 100644 --- a/htdocs/custom/emailtracker/tab_invoice_supplier.php +++ b/htdocs/custom/emailtracker/tab_invoice_supplier.php @@ -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 = '' . $langs->trans('BackToList') . ''; @@ -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 '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table print '' . "\n"; ?> diff --git a/htdocs/debugbar/class/DataCollector/DolConfigCollector.php b/htdocs/debugbar/class/DataCollector/DolConfigCollector.php deleted file mode 100644 index 715d20ab..00000000 --- a/htdocs/debugbar/class/DataCollector/DolConfigCollector.php +++ /dev/null @@ -1,89 +0,0 @@ -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 index 15d433fd..00000000 --- a/htdocs/debugbar/class/DataCollector/DolExceptionsCollector.php +++ /dev/null @@ -1,35 +0,0 @@ -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 index 893804ae..00000000 --- a/htdocs/debugbar/class/DataCollector/DolLogsCollector.php +++ /dev/null @@ -1,212 +0,0 @@ -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 index b52ac8ff..00000000 --- a/htdocs/debugbar/class/DataCollector/DolMemoryCollector.php +++ /dev/null @@ -1,48 +0,0 @@ -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 index 1fcf60c8..00000000 --- a/htdocs/debugbar/class/DataCollector/DolMessagesCollector.php +++ /dev/null @@ -1,36 +0,0 @@ -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 index 3d6536bd..00000000 --- a/htdocs/debugbar/class/DataCollector/DolPhpCollector.php +++ /dev/null @@ -1,168 +0,0 @@ -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 index ca5aa284..00000000 --- a/htdocs/debugbar/class/DataCollector/DolQueryCollector.php +++ /dev/null @@ -1,117 +0,0 @@ -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 index 93864380..00000000 --- a/htdocs/debugbar/class/DataCollector/DolRequestDataCollector.php +++ /dev/null @@ -1,61 +0,0 @@ - $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 index ed5e979d..00000000 --- a/htdocs/debugbar/class/DataCollector/DolTimeDataCollector.php +++ /dev/null @@ -1,34 +0,0 @@ - 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 index 3193fe26..00000000 --- a/htdocs/debugbar/class/DataCollector/DolibarrCollector.php +++ /dev/null @@ -1,156 +0,0 @@ -trans('Host').': '.$conf->db->host.'
'; - $info .= $langs->trans('Port').': '.$conf->db->port.'
'; - $info .= $langs->trans('Name').': '.$conf->db->name.'
'; - $info .= $langs->trans('User').': '.$conf->db->user.'
'; - $info .= $langs->trans('Type').': '.$conf->db->type.'
'; - $info .= $langs->trans('Prefix').': '.$conf->db->prefix.'
'; - $info .= $langs->trans('Charset').': '.$conf->db->character_set.''; - - 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').': '.DOL_VERSION.'
'; - $info .= $langs->trans('Theme').': '.$conf->theme.'
'; - $info .= $langs->trans('Locale').': '.$conf->global->MAIN_LANG_DEFAULT.'
'; - $info .= $langs->trans('Currency').': '.$conf->currency.'
'; - $info .= $langs->trans('Entity').': '.$conf->entity.'
'; - $info .= $langs->trans('MaxSizeList').': '.($conf->liste_limit ?: $conf->global->MAIN_SIZE_LISTE_LIMIT).'
'; - $info .= $langs->trans('MaxSizeForUploadedFiles').': '.$conf->global->MAIN_UPLOAD_DOC.'
'; - $info .= '$dolibarr_main_prod = '.$dolibarr_main_prod.'
'; - $info .= '$dolibarr_nocsrfcheck = '.$dolibarr_nocsrfcheck.'
'; - $info .= 'MAIN_SECURITY_CSRF_WITH_TOKEN = '.$conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN.'
'; - $info .= 'MAIN_FEATURES_LEVEL = '.$conf->global->MAIN_FEATURES_LEVEL.'
'; - - 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').': '.getDolGlobalString("MAIN_MAIL_SENDMODE").'
'; - $info .= $langs->trans('Server').': '.getDolGlobalString("MAIN_MAIL_SMTP_SERVER").'
'; - $info .= $langs->trans('Port').': '.getDolGlobalString("MAIN_MAIL_SMTP_PORT").'
'; - $info .= $langs->trans('ID').': '.getDolGlobalString("MAIN_MAIL_SMTPS_IDT").'
'; - $info .= $langs->trans('Pwd').': '.preg_replace('/./', '*', getDolGlobalString("MAIN_MAIL_SMTPS_PW")).'
'; - $info .= $langs->trans('TLS/STARTTLS').': '.getDolGlobalString("MAIN_MAIL_EMAIL_TLS").' / '.getDolGlobalString("MAIN_MAIL_EMAIL_STARTTLS").'
'; - $info .= $langs->trans('MAIN_DISABLE_ALL_MAILS').': '.(empty($conf->global->MAIN_DISABLE_ALL_MAILS) ? $langs->trans('No') : $langs->trans('Yes')).'
'; - $info .= 'dolibarr_mailing_limit_sendbyweb = '.$dolibarr_mailing_limit_sendbyweb.'
'; - $info .= 'dolibarr_mailing_limit_sendbycli = '.$dolibarr_mailing_limit_sendbycli.'
'; - $info .= 'dolibarr_mailing_limit_sendbyday = '.$dolibarr_mailing_limit_sendbyday.'
'; - - 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 index bf797e63..00000000 --- a/htdocs/debugbar/class/DebugBar.php +++ /dev/null @@ -1,64 +0,0 @@ -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 index 5863f1d9..00000000 --- a/htdocs/debugbar/class/TraceableDB.php +++ /dev/null @@ -1,723 +0,0 @@ -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 index a0933151..00000000 --- a/htdocs/debugbar/class/autoloader.php +++ /dev/null @@ -1,35 +0,0 @@ - '', 'class' => '') - * - data: alias of title - */ - var TooltipIndicator = PhpDebugBar.DebugBar.TooltipIndicator = PhpDebugBar.DebugBar.Indicator.extend({ - - render: function() { - this.$icon = $('').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'], $('').addClass(csscls('text')).appendTo(this.$el)); - - this.$tooltip = $('').addClass(csscls('tooltip disabled')).appendTo(this.$el); - this.bindAttr('tooltip', function(tooltip) { - if (tooltip['html']) { - tooltipHTML = $('').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 diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index cf337abf..8ccbd7ce 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -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 = ''.$langs->trans("BackToList").''; 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 '
'; print '
'; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index bc0c7b9e..56e230ed 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -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"'; } diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index e3304460..d8211eae 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -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 '
'; print '
'; print '
'; diff --git a/htdocs/fourn/facture/document.php b/htdocs/fourn/facture/document.php index cff4a30f..ea6f1b5a 100644 --- a/htdocs/fourn/facture/document.php +++ b/htdocs/fourn/facture/document.php @@ -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 '
'; print '
'; diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index ad03c482..3eac81ad 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -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 .= '
'; - $tmptitle = $langs->trans('ThirdPartiesOfSaleRepresentative'); - $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, $tmptitle, 'maxwidth200'); - $moreforfilter .= '
'; -} +// if ($user->rights->user->user->lire) { +// $langs->load("commercial"); +// $moreforfilter .= '
'; +// $tmptitle = $langs->trans('ThirdPartiesOfSaleRepresentative'); +// $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$formother->select_salesrepresentatives($search_sale, 'search_sale', $user, 0, $tmptitle, 'maxwidth200'); +// $moreforfilter .= '
'; +// } // If the user can view prospects other than his' -if ($user->rights->user->user->lire) { - $moreforfilter .= '
'; - $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 .= '
'; -} +// if ($user->rights->user->user->lire) { +// $moreforfilter .= '
'; +// $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 .= '
'; +// } // 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 .= '
'; - $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 .= '
'; -} - -if (isModEnabled('categorie')) { - require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; - $moreforfilter .= '
'; - $tmptitle = $langs->trans('SuppliersCategoriesShort'); - $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"').$formother->select_categories('supplier', $search_categ_sup, 'search_categ_sup', 1, $tmptitle); - $moreforfilter .= '
'; -} +// 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 .= '
'; +// $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 .= '
'; +// } + +// if (isModEnabled('categorie')) { +// require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; +// $moreforfilter .= '
'; +// $tmptitle = $langs->trans('SuppliersCategoriesShort'); +// $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"').$formother->select_categories('supplier', $search_categ_sup, 'search_categ_sup', 1, $tmptitle); +// $moreforfilter .= '
'; +// } $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 '
'; 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 ''; } - if (!empty($arrayfields['f.ref']['checked'])) { - print '\n"; - if (!$i) { - $totalarray['nbfield']++; - } - } + // if (!empty($arrayfields['f.ref']['checked'])) { + // print '\n"; + // if (!$i) { + // $totalarray['nbfield']++; + // } + // } // Supplier ref if (!empty($arrayfields['f.ref_supplier']['checked'])) { print ''; if (!$i) { $totalarray['nbfield']++; diff --git a/htdocs/includes/html2pdf/Segment.php b/htdocs/includes/html2pdf/Segment.php new file mode 100644 index 00000000..9ff39516 --- /dev/null +++ b/htdocs/includes/html2pdf/Segment.php @@ -0,0 +1,273 @@ +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>)?(.*)(?:)?\[!--\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; + $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 index 00000000..cb6b352f --- /dev/null +++ b/htdocs/includes/html2pdf/SegmentIterator.php @@ -0,0 +1,58 @@ +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 index 00000000..89ae0230 --- /dev/null +++ b/htdocs/includes/html2pdf/html2pdf.php @@ -0,0 +1,1012 @@ + '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 + // _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: + // {aaa} + // instead of {aaa} so we should enhance this function. + //print $key.'-'.$value.'-'.strpos($this->contentXml, $this->config['DELIMITER_LEFT'] . $key . $this->config['DELIMITER_RIGHT']).'
'; + // 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( + '', + '', + '', + '', + '', + '' + ); + + $customStyles = array(); + $fontDeclarations = array(); + + $convertedValue = $this->_replaceHtmlWithOdtTag($this->_getDataFromHtml($value), $customStyles, $fontDeclarations); + + foreach ($customStyles as $key => $val) { + array_push($automaticStyles, '' . $val . ''); + } + + // 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('', $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 .= ''; + } + } + $this->contentXml = str_replace('', $fonts . '', $this->contentXml); + } else { + if ($value){ + $convertedValue = preg_replace('/(\r\n|\r|\n)/i', "", $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 .= ''; + break; + case 'strong': + case 'b': + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . ''; + break; + case 'i': + case 'em': + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . ''; + break; + case 'u': + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . ''; + break; + case 's': + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . ''; + break; + case 'sub': + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . ''; + break; + case 'sup': + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . ''; + 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 .= ''; + 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 .= ''; + } + break; + case 'color': + if (preg_match('/#[0-9A-Fa-f]{3}(?:[0-9A-Fa-f]{3})?/', $styleValue)) { + $odtStyles .= ''; + } + 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 .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . ''; + } + } + 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 bold with é accent
\n
\nUn texto en español ?" + // Result after clean must be "MYPODUCT - Desc bold with é accent\n\nUn texto en español ?" + + // We want to ignore \n and we want all
to be \n + $value=preg_replace('/(\r\n|\r|\n)/i', '', $value); + $value=preg_replace('/
/i', "\n", $value); + $value=preg_replace('/\/]*>/i', "\n", $value); + $value=preg_replace('/\/]*\/>/i', "\n", $value); + + //$value=preg_replace('//','__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", "", $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; + $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 BEGINxxx into BEGIN xxx + $this->contentXml = preg_replace('/\[!--\sBEGIN]>(row.[\S]*)\s--\]/sm', '[!-- BEGIN \\1 --]', $this->contentXml); + // Replace ENDxxx into END xxx + $this->contentXml = preg_replace('/\[!--\sEND]>(row.[\S]*)\s--\]/sm', '[!-- END \\1 --]', $this->contentXml); + + // Search all possible rows in the document + $reg1 = "#]*>(.*)
#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] . ' --]' => '', + ' '[!-- BEGIN ' . $balise . ' --]' => '[!-- 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('
','',$this->contentXml); + // $this->contentXml = str_replace('
','',$this->contentXml); + // $this->contentXml = str_replace('
','',$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('
' . print_r($this->vars, true) . '
', 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 '
' . print_r(implode(' ', array_keys($this->segments)), true) . '
'; + } + + /** + * 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 + * 2013-03-16T14:06:25 + * + * @return void + */ + public function setMetaData() + { + if (empty($this->creator)) $this->creator=''; + + $this->metaXml = preg_replace('/.*<\/dc:date>/', ''.gmdate("Y-m-d\TH:i:s").'', $this->metaXml); + $this->metaXml = preg_replace('/.*<\/dc:creator>/', ''.(($this->title)?htmlspecialchars($this->creator):"").'', $this->metaXml); + $this->metaXml = preg_replace('/.*<\/dc:title>/', ''.(($this->title)?htmlspecialchars($this->title):"").'', $this->metaXml); + $this->metaXml = preg_replace('/.*<\/dc:subject>/', ''.(($this->title)?htmlspecialchars($this->subject):"").'', $this->metaXml); + + if (count($this->userdefined)) { + foreach ($this->userdefined as $key => $val) { + $this->metaXml = preg_replace('', '', $this->metaXml); + $this->metaXml = preg_replace('/.*<\/meta:user-defined>/', '', $this->metaXml); + $this->metaXml = str_replace('', ''.(($this->title)?htmlspecialchars($val):"").'', $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 = ' '."\n"; + // Append the image to the manifest + $this->manifestXml = str_replace('', $add.'', $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 : "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."
"; + } + 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 index 00000000..45ea50d5 --- /dev/null +++ b/htdocs/includes/html2pdf/zip/PclZipProxy.php @@ -0,0 +1,160 @@ +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 index 00000000..0035858e --- /dev/null +++ b/htdocs/includes/html2pdf/zip/PhpZipProxy.php @@ -0,0 +1,92 @@ +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 index 00000000..6b724859 --- /dev/null +++ b/htdocs/includes/html2pdf/zip/ZipInterface.php @@ -0,0 +1,50 @@ + diff --git a/htdocs/modulebuilder/template/COPYING b/htdocs/includes/html2pdf/zip/pclzip/LICENSE similarity index 84% rename from htdocs/modulebuilder/template/COPYING rename to htdocs/includes/html2pdf/zip/pclzip/LICENSE index 94a04532..dbbe3558 100644 --- a/htdocs/modulebuilder/template/COPYING +++ b/htdocs/includes/html2pdf/zip/pclzip/LICENSE @@ -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. 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. + + + Copyright (C) + + 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 . + +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 +. diff --git a/htdocs/includes/html2pdf/zip/pclzip/composer.json b/htdocs/includes/html2pdf/zip/pclzip/composer.json new file mode 100644 index 00000000..fd36bfbf --- /dev/null +++ b/htdocs/includes/html2pdf/zip/pclzip/composer.json @@ -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 index 00000000..583509c7 --- /dev/null +++ b/htdocs/includes/html2pdf/zip/pclzip/gnu-lgpl.txt @@ -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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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 + + 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. + + + Copyright (C) + + 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. + + , 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 index 00000000..2a1a2b8d --- /dev/null +++ b/htdocs/includes/html2pdf/zip/pclzip/pclzip.lib.php @@ -0,0 +1,5415 @@ +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 index 00000000..f0281349 --- /dev/null +++ b/htdocs/includes/html2pdf/zip/pclzip/readme.txt @@ -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 index 46701a45..00000000 --- a/htdocs/mailmanspip/class/mailmanspip.class.php +++ /dev/null @@ -1,418 +0,0 @@ - - * Copyright (C) 2002-2003 Jean-Louis Bergamo - * Copyright (C) 2004-2013 Laurent Destailleur - * Copyright (C) 2004 Sebastien Di Cintio - * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2009 Regis Houssin - * Copyright (C) 2012 Marcos García - * Copyright (C) 2018 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 index 26b0ecf7..00000000 --- a/htdocs/modulebuilder/README.md +++ /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 index 4c7e597e..00000000 --- a/htdocs/modulebuilder/admin/setup.php +++ /dev/null @@ -1,211 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 = ''.$langs->trans("BackToModuleList").''; - -print ''; -print ''; -print ''; - -print load_fiche_titre($langs->trans("ModuleSetup").' '.$langs->trans('Modulebuilder'), $linkback); - -if (GETPOST('withtab', 'alpha')) { - print dol_get_fiche_head($head, 'modulebuilder', '', -1); -} - -print ''.$langs->trans("ModuleBuilderDesc")."
\n"; - -print '
'; - -print '
'; - - print ''; - // Picto + Ref - print '
'; - 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 '
'; - - print "
'; + + // print ''; + // // Picto + Ref + // print '
'; + // 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 '
'; + + // print "
'; - print $obj->ref_supplier; + print $facturestatic->getNomUrl(1, '', 0, 0, '', 1, -1, 1); + // print $obj->ref_supplier; print '
'; - -print ''; -print ''; -print ''; -print "\n"; - - -if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - // What is use case of this 2 options ? - - print ''; - print ''; - print ''; -} - -print ''; -print ''; -print ''; -print ''; - -print ''; -print ''; -print ''; -print ''; - -if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - print ''; - print ''; - print ''; - print ''; - - print ''; - print ''; - print ''; - print ''; - - print ''; - print ''; - print ''; - print ''; -} - -print ''; -print ''; -print ''; -print ''; - -print ''; -print ''; -print ''; -print ''; - -print ''; -print ''; -print ''; -print ''; - -print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("UseAboutPage").''; - if ($conf->use_javascript_ajax) { - print ajax_constantonoff('MODULEBUILDER_USE_ABOUT'); - } else { - if (empty($conf->global->MODULEBUILDER_USE_ABOUT)) { - print ''.img_picto($langs->trans("Disabled"), 'off').''; - } else { - print ''.img_picto($langs->trans("Enabled"), 'on').''; - } - } - print '
'.$langs->trans("UseSpecificEditorName").''; -print ''; -print '
'.$langs->trans("UseSpecificEditorURL").''; -print ''; -print '
'.$langs->trans("UseSpecificFamily").''; - print ''; - print '
'.$langs->trans("UseSpecificAuthor").''; - print ''; - print '
'.$langs->trans("UseSpecificVersion").''; - print ''; - print '
'.$langs->trans("UseSpecificReadme").''; -print ''; -print '
'.$langs->trans("AsciiToHtmlConverter").''; -print ''; -print ' '.$langs->trans("Example").': asciidoc, asciidoctor'; -print '
'.$langs->trans("AsciiToPdfConverter").''; -print ''; -print ' '.$langs->trans("Example").': asciidoctor-pdf'; -print '
'; - -print $form->buttonsSaveCancel("Save", ''); - -if (GETPOST('withtab', 'alpha')) { - print dol_get_fiche_end(); -} - -print '
'; - -print ''; - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php deleted file mode 100644 index f871d916..00000000 --- a/htdocs/modulebuilder/index.php +++ /dev/null @@ -1,4682 +0,0 @@ - - * Copyright (C) 2018-2019 Nicolas ZABOURI - * - * 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 . - * - * 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 = ''."\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 .= ''.$dirread.''; - 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 ''.$langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').''; -print '
'; - -//print $textforlistofdirs; -//print '
'; -//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).'
'; -$infomodulesfound = '
'.$form->textwithpicto('', $langs->trans("ModuleBuilderDesc3", count($listofmodules)).'

'.$langs->trans("ModuleBuilderDesc4", $FILEFLAG).'
'.$textforlistofdirs).'
'; - - - -$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()."
\n"; - $loadclasserrormessage .= 'File: '.$e->getFile()."
\n"; - $loadclasserrormessage .= 'Line: '.$e->getLine()."
\n"; - } catch (Exception $e) { - $loadclasserrormessage = $e->getMessage()."
\n"; - $loadclasserrormessage .= 'File: '.$e->getFile()."
\n"; - $loadclasserrormessage .= 'Line: '.$e->getLine()."
\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 ''; - print img_warning('').' '.$langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module).'
'; - print $loadclasserrormessage; - } -} - -print '
'; - - -// Tabs for all modules -$head = array(); -$h = 0; - -$head[$h][0] = $_SERVER["PHP_SELF"].'?module=initmodule'; -$head[$h][1] = ''.$langs->trans("NewModule").''; -$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 = ''.$langs->trans('Home').'-'.$langs->trans("Setup").'-'.$langs->trans("Modules").''; - - // Define $linktoenabledisable to show after module title - if (isModEnabled($modulelowercase)) { // If module is already activated - $linktoenabledisable .= ''; - $linktoenabledisable .= img_picto($langs->trans("Activated"), 'switch_on', '', false, 0, 0, '', '', 1); - $linktoenabledisable .= ''; - - $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 .= ' '.img_picto(ucfirst($page), "setup").''; - // print ''.ucfirst($page).' '; - } else { - if (preg_match('/^([^@]+)@([^@]+)$/i', $urlpage, $regs)) { - $urltouse = dol_buildpath('/'.$regs[2].'/admin/'.$regs[1], 1); - $linktoenabledisable .= ' '.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 8px"').''; - } 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 .= ' '.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 8px"').''; - } - } - } - } elseif (preg_match('/^([^@]+)@([^@]+)$/i', $objMod->config_page_url, $regs)) { - $linktoenabledisable .= '   '.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 8px"').''; - } - } else { - if (!empty($moduleobj)) { - $linktoenabledisable .= ''; - $linktoenabledisable .= img_picto($langs->trans("ModuleIsNotActive", $urltomodulesetup), 'switch_off', 'style="padding-right: 8px"', false, 0, 0, '', 'classfortooltip', 1); - $linktoenabledisable .= "\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] = ''.$linktoenabledisable.''; - } - - $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 '
'; - print ''; - print ''; - print ''; - - //print ''.$langs->trans("ModuleBuilderDesc2", 'conf/conf.php', $newdircustom).'
'; - print '
'; - - print '
'; - - print '
'; - print ''.$langs->trans("IdModule").''; - print '
'; - print ''; - print ''; - print '   ('; - print dolButtonToOpenUrlInDialogPopup('popup_modules_id', $langs->transnoentitiesnoconv("SeeIDsInUse"), $langs->transnoentitiesnoconv("SeeIDsInUse"), '/admin/system/modules.php?mainmenu=home&leftmenu=admintools_info', '', ''); - print ' - '; - print ''.$langs->trans("SeeReservedIDsRangeHere").''; - print ')'; - print ''; - print '
'; - - print '
'; - print ''.$langs->trans("ModuleName").''; - print '
'; - print ''; - print ' '.$form->textwithpicto('', $langs->trans("EnterNameOfModuleDesc")); - print '
'; - - print '
'; - print ''.$langs->trans("Description").''; - print '
'; - print '
'; - print '
'; - - print '
'; - print ''.$langs->trans("Version").''; - print '
'; - print ''; - print '
'; - - print '
'; - print ''.$langs->trans("Family").''; - print '
'; - print ''; - print ajax_combobox("family"); - print '
'; - - print '
'; - print ''.$langs->trans("Picto").''; - print '
'; - print ''; - print $form->textwithpicto('', $langs->trans("Example").': fa-generic, fa-globe, ... any font awesome code.
Advanced syntax is fa-fakey[_faprefix[_facolor[_fasize]]]'); - print '
'; - - print '
'; - print ''.$langs->trans("EditorName").''; - print '
'; - print '
'; - print '
'; - - print '
'; - print ''.$langs->trans("EditorUrl").''; - print '
'; - print '
'; - print '
'; - - print '
'; - print ''; -} elseif ($module == 'deletemodule') { - print ''."\n"; - print '
'; - print ''; - print ''; - print ''; - - print $langs->trans("EnterNameOfModuleToDeleteDesc").'

'; - - print ''; - print ''; - print '
'; -} 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 ''; - - // Note module is inside $dirread - - if ($tab == 'description') { - print ''."\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 ''.$langs->trans("ModuleBuilderDesc".$tab).''; - $infoonmodulepath = ''; - if (realpath($dirread.'/'.$modulelowercase) != $dirread.'/'.$modulelowercase) { - $infoonmodulepath = ''.$langs->trans("RealPathOfModule").' : '.realpath($dirread.'/'.$modulelowercase).'
'; - print ' '.$infoonmodulepath; - } - print '
'; - - print ''; - - print ''; - - print ''; - - print ''; - - print '
'; - print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print '
'.$langs->trans("ReadmeFile").' : '.$pathtofilereadme.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print '
'.$langs->trans("ChangeLog").' : '.$pathtochangelog.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - print '
'; - - print load_fiche_titre($form->textwithpicto($langs->trans("DescriptorFile"), $langs->transnoentitiesnoconv("File").' '.$pathtofile), '', ''); - - if (!empty($moduleobj)) { - print '
'; - print '
'; - - print ''; - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print '
'; - print $langs->trans("Parameter"); - print ''; - print $langs->trans("Value"); - print '
'; - print $langs->trans("IdModule"); - print ''; - print $moduleobj->numero; - print ''; - print '   ('.$langs->trans("SeeIDsInUse").''; - print ' - '.$langs->trans("SeeReservedIDsRangeHere").')'; - print ''; - print '
'; - print $langs->trans("ModuleName"); - print ''; - print $moduleobj->getName(); - print '
'; - print $langs->trans("Description"); - print ''; - print $moduleobj->getDesc(); - print '
'; - print $langs->trans("Version"); - print ''; - print $moduleobj->getVersion(); - print '
'; - print $langs->trans("Family"); - //print "
'crm','financial','hr','projects','products','ecm','technic','interface','other'"; - print '
'; - print $moduleobj->family; - print '
'; - print $langs->trans("Picto"); - print ''; - print $moduleobj->picto; - print '   '.img_picto('', $moduleobj->picto, 'class="valignmiddle pictomodule paddingrightonly"'); - print '
'; - print $langs->trans("EditorName"); - print ''; - print $moduleobj->editor_name; - print '
'; - print $langs->trans("EditorUrl"); - print ''; - if (!empty($moduleobj->editor_url)) { - print ''.$moduleobj->editor_url.' '.img_picto('', 'globe').''; - } - print '
'; - } else { - print $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module).'
'; - } - - if (!empty($moduleobj)) { - print '

'; - - // Readme file - print load_fiche_titre($form->textwithpicto($langs->trans("ReadmeFile"), $langs->transnoentitiesnoconv("File").' '.$pathtofilereadme), '', ''); - - print ''; - if (dol_is_file($dirread.'/'.$pathtofilereadme)) { - print '
'.$moduleobj->getDescLong().'
'; - } else { - print ''.$langs->trans("ErrorFileNotFound", $pathtofilereadme).''; - } - - print '

'; - - // ChangeLog - print load_fiche_titre($form->textwithpicto($langs->trans("ChangeLog"), $langs->transnoentitiesnoconv("File").' '.$pathtochangelog), '', ''); - - print ''; - if (dol_is_file($dirread.'/'.$pathtochangelog)) { - print '
'.$moduleobj->getChangeLog().'
'; - } else { - print ''.$langs->trans("ErrorFileNotFound", $pathtochangelog).''; - } - } - - 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 '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - 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 '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - } else { - print dol_get_fiche_head($head2, $tab, '', -1, '', 0, '', '', $MAXTABFOROBJECT, 'formodulesuffix'); // Level 2 - } - - if ($tab == 'languages') { - print ''."\n"; - if ($action != 'editfile' || empty($file)) { - print ''.$langs->trans("LanguageDefDesc").'
'; - print '
'; - - - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'newlangcode', 0, 0, 1, 0, 0, 'minwidth300', 1); - print '
'; - print '
'; - - print '
'; - print '
'; - - $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 ''; - 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 ''; - } - print '
'.$langs->trans("LanguageFile").' '.basename(dirname($pathtofile)).' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print ''.img_picto($langs->trans("Delete"), 'delete').''; - print '
'; - } else { - // Edit text language file - - //print $langs->trans("UseAsciiDocFormat").'
'; - - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - } - - if ($tab == 'objects') { - print ''."\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] = ''.$langs->trans("NewObjectInModulebuilder").''; - $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 '
'; - print ''; - print ''; - print ''; - print ''; - - print ''.$langs->trans("EnterNameOfObjectDesc").'

'; - - print '
'; - - print '
'; - print ''.$langs->trans("ObjectKey").'   '; - print '
'; - print '
'; - print '
'; - - print '
'; - print ''.$langs->trans("Picto").'   '; - print '
'; - print ''; - print $form->textwithpicto('', $langs->trans("Example").': fa-generic, fa-globe, ... any font awesome code.
Advanced syntax is fa-fakey[_faprefix[_facolor[_fasize]]]'); - print '
'; - - print '
'; - print ''.$langs->trans("DefinePropertiesFromExistingTable").'   '; - print '
'; - print ''; - print $form->textwithpicto('', $langs->trans("DefinePropertiesFromExistingTableDesc").'
'.$langs->trans("DefinePropertiesFromExistingTableDesc2")); - print '
'; - - print '
'; - - print '
'; - print '
'; - print '
'; - print '
'; - print ''; - print '
'; - print '
'; - /* - print '
'; - print ''.$langs->trans("or").''; - print '
'; - print '
'; - //print ' '; - print $langs->trans("InitStructureFromExistingTable"); - print ''; - print ''; - print '
'; - */ - - print '
'; - } elseif ($tabobj == 'deleteobject') { - // Delete object tab - print '
'; - print ''; - print ''; - print ''; - print ''; - - print $langs->trans("EnterNameOfObjectToDeleteDesc").'

'; - - print ''; - print ''; - print '
'; - } 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 ''.$langs->trans('Failed to find the class '.$tabobj.' despite the '.$stringofinclude).'

'; - } - - // 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 ''; - print '
'; - // Main DAO class file - print ' '.$langs->trans("ClassFile").' : '.(dol_is_file($realpathtoclass) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtoclass).(dol_is_file($realpathtoclass) ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - // Image - if (dol_is_file($realpathtopicto)) { - print ' '.$langs->trans("Image").' : '.(dol_is_file($realpathtopicto) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtopicto).(dol_is_file($realpathtopicto) ? '' : '').''; - //print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - } elseif (!empty($tmpobject)) { - print ' '.$langs->trans("Image").' : '.img_picto('', $tmpobject->picto, 'class="pictofixedwidth"'); - print '
'; - } - - // API file - print '
'; - print ' '.$langs->trans("ApiClassFile").' : '.(dol_is_file($realpathtoapi) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtoapi).(dol_is_file($realpathtoapi)?'':'').''; - if (dol_is_file($realpathtoapi)) { - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; - print '   '; - if (empty($conf->global->$const_name)) { // If module is not activated - print ''.$langs->trans("ApiExplorer").''; - } else { - print ''.$langs->trans("ApiExplorer").''; - } - } else { - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; - } - // PHPUnit - print '
'; - print ' '.$langs->trans("TestClassFile").' : '.(dol_is_file($realpathtophpunit) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtophpunit).(dol_is_file($realpathtophpunit)?'':'').''; - if (dol_is_file($realpathtophpunit)) { - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; - } else { - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; - } - print '
'; - - print '
'; - - print ' '.$langs->trans("PageForLib").' : '.(dol_is_file($realpathtolib) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtolib).(dol_is_file($realpathtolib) ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - print ' '.$langs->trans("PageForObjLib").' : '.(dol_is_file($realpathtoobjlib) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtoobjlib).(dol_is_file($realpathtoobjlib) ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - - print '
'; - print ' '.$langs->trans("SqlFile").' : '.(dol_is_file($realpathtosql) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtosql).(dol_is_file($realpathtosql) ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '   '.$langs->trans("DropTableIfEmpty").''; - //print '   '.$langs->trans("RunSql").''; - print '
'; - print ' '.$langs->trans("SqlFileKey").' : '.(dol_is_file($realpathtosqlkey) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlkey).(dol_is_file($realpathtosqlkey) ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - //print '   '.$langs->trans("RunSql").''; - print '
'; - print ' '.$langs->trans("SqlFileExtraFields").' : '.(dol_is_file($realpathtosqlextra) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlextra).(dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey) ? '' : '').''; - if (dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey)) { - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; - print '   '; - print ''.$langs->trans("DropTableIfEmpty").''; - } else { - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; - } - //print '   '.$langs->trans("RunSql").''; - print '
'; - print ' '.$langs->trans("SqlFileKeyExtraFields").' : '.(dol_is_file($realpathtosqlextrakey) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlextrakey).(dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey) ? '' : '').''; - if (dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey)) { - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; - } else { - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; - } - print '
'; - print '
'; - - print '
'; - print ' '.$langs->trans("PageForList").' : '.(dol_is_file($realpathtolist) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtolist).(dol_is_file($realpathtolist) ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - print ' '.$langs->trans("PageForCreateEditView").' : '.(dol_is_file($realpathtocard) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtocard).(dol_is_file($realpathtocard) ? '' : '').'?action=create'; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - // Page contact - print ' '.$langs->trans("PageForContactTab").' : '.(dol_is_file($realpathtocontact) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtocontact).(dol_is_file($realpathtocontact) ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - if (dol_is_file($realpathtocontact)) { - print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; - } else { - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; - } - print '
'; - // Page document - print ' '.$langs->trans("PageForDocumentTab").' : '.(dol_is_file($realpathtodocument) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtodocument).(dol_is_file($realpathtodocument) ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - if (dol_is_file($realpathtodocument)) { - print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; - } else { - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; - } - print '
'; - // Page notes - print ' '.$langs->trans("PageForNoteTab").' : '.(dol_is_file($realpathtonote) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtonote).(dol_is_file($realpathtonote) ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - if (dol_is_file($realpathtonote)) { - print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; - } else { - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; - } - print '
'; - // Page agenda - print ' '.$langs->trans("PageForAgendaTab").' : '.(dol_is_file($realpathtoagenda) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtoagenda).(dol_is_file($realpathtoagenda) ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - if (dol_is_file($realpathtoagenda)) { - print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; - } else { - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; - } - print '
'; - print '
'; - - print '
'; - - print '


'; - - 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 '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - print ''; - print '

'; - - print load_fiche_titre($langs->trans("ObjectProperties"), '', ''); - - print ''."\n"; - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print ''; - print ''; - print ''; - print ''; - - // 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 ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print ''; - print ''; - print ''; - - // 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 ''; - - print ''; - print ''; - if ($action == 'editproperty' && $propname == $propertykey) { - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - } else { - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - // Visibility - print ''; - // Readonly - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - // Key for tooltop - print ''; - print ''; - /*print '';*/ - print ''; - print ''; - print ''; - } - print ''; - } - } else { - if ($tab == 'specifications') { - if ($action != 'editfile' || empty($file)) { - print ''.$langs->trans("SpecDefDesc").'
'; - print '
'; - - $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 ' '.$langs->trans("SpecificationFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - } - } else { - // Use MD or asciidoc - - //print $langs->trans("UseAsciiDocFormat").'
'; - - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print ''; - } - } - print ''; - } - print '
'; - - $htmltext = $langs->trans("PropertyDesc").'

'.$langs->trans("SeeExamples").''; - print $form->textwithpicto($langs->trans("Code"), $htmltext, 1, 'help', 'extracss', 0, 3, 'propertyhelp'); - - print '
'; - print $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey")); - print ''.$form->textwithpicto($langs->trans("Type"), $langs->trans("TypeOfFieldsHelpIntro").'

'.$langs->trans("TypeOfFieldsHelp"), 1, 'help', 'extracss', 0, 3, 'typehelp').'
'.$form->textwithpicto($langs->trans("ArrayOfKeyValues"), $langs->trans("ArrayOfKeyValuesDesc")).''.$form->textwithpicto($langs->trans("NotNull"), $langs->trans("NotNullDesc")).''.$langs->trans("DefaultValue").''.$langs->trans("DatabaseIndex").''.$form->textwithpicto($langs->trans("ForeignKey"), $langs->trans("ForeignKeyDesc"), 1, 'help', 'extracss', 0, 3, 'foreignkeyhelp').''.$langs->trans("Position").''.$form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc"), 1, 'help', 'extracss', 0, 3, 'enabledhelp').''.$form->textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc").'

'.$langs->trans("ItCanBeAnExpression"), 1, 'help', 'extracss', 0, 3, 'visiblehelp').'
'.$langs->trans("NotEditable").''.$langs->trans("AlwaysEditable").''.$form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")).''.$form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")).''.$langs->trans("CSSClass").''.$langs->trans("CSSViewClass").''.$langs->trans("CSSListClass").''.$langs->trans("KeyForTooltip").''.$langs->trans("ShowOnCombobox").''.$langs->trans("Disabled").''.$form->textwithpicto($langs->trans("Validate"), $langs->trans("ValidateModBuilderDesc")).''.$langs->trans("Comment").'
'; - print ''; - print '
'; - print dol_escape_htmltag($propname); - print ''; - print dol_escape_htmltag($proplabel); - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''.dol_escape_htmltag($proptype).''; - print ''; - if ($proparrayofkeyval) { - print ''; - print dol_escape_htmltag(json_encode($proparrayofkeyval, JSON_UNESCAPED_UNICODE)); - print ''; - } - print ''; - print dol_escape_htmltag($propnotnull); - print ''; - print dol_escape_htmltag($propdefault); - print ''; - print $propindex ? '1' : ''; - print ''; - print $propforeignkey ? dol_escape_htmltag($propforeignkey) : ''; - print ''; - print dol_escape_htmltag($propposition); - print ''; - print $propenabled ? dol_escape_htmltag($propenabled) : ''; - print ''; - print $propvisible ? dol_escape_htmltag($propvisible) : '0'; - print ''; - print $propnoteditable ? dol_escape_htmltag($propnoteditable) : ''; - print ''; - print $propalwayseditable ? dol_escape_htmltag($propalwayseditable) : ''; - print ''; - print $propsearchall ? '1' : ''; - print ''; - print $propisameasure ? dol_escape_htmltag($propisameasure) : ''; - print ''; - print $propcss ? dol_escape_htmltag($propcss) : ''; - print ''; - print $propcssview ? dol_escape_htmltag($propcssview) : ''; - print ''; - print $propcsslist ? dol_escape_htmltag($propcsslist) : ''; - print ''; - print $prophelp ? dol_escape_htmltag($prophelp) : ''; - print ''; - print $propshowoncombobox ? dol_escape_htmltag($propshowoncombobox) : ''; - print ''; - print $propdisabled?$propdisabled:''; - print ''; - print $propvalidate ? dol_escape_htmltag($propvalidate) : ''; - print ''; - print ''; - print dol_escape_htmltag($propcomment); - print ''; - print ''; - if ($propname != 'rowid') { - print ''.img_edit().''; - print ''.img_delete().''; - } - print '
'.$langs->trans('Property $field not found into the class. The class was probably not generated by modulebuilder.').'
'; - print '
'; - - print ''; - } else { - print ''.$langs->trans('Failed to init the object with the new '.$tabobj.'($db)').''; - } - } 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 '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - } - - print dol_get_fiche_end(); // Level 3 - } - - if ($tab == 'dictionaries') { - print ''."\n"; - $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; - - $dicts = $moduleobj->dictionaries; - - if ($action != 'editfile' || empty($file)) { - print ''; - $htmlhelp = $langs->trans("DictionariesDefDescTooltip", '{s1}'); - $htmlhelp = str_replace('{s1}', ''.$langs->trans('Setup').' - '.$langs->trans('Dictionaries').'', $htmlhelp); - print $form->textwithpicto($langs->trans("DictionariesDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'
'; - print '
'; - print '
'; - - print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - if (is_array($dicts) && !empty($dicts)) { - print ' '.$langs->trans("LanguageFile").' :
'; - print ''.$dicts['langs'].''; - print '
'; - } - - print ''."\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] = ''.$langs->trans("NewDictionary").''; - $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 '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - print '
'; - print ''; - - print ''; - 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 "\n"; - - if (!empty($dicts) && is_array($dicts) && !empty($dicts['tabname']) && is_array($dicts['tabname'])) { - $i = 0; - $maxi = count($dicts['tabname']); - while ($i < $maxi) { - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - $i++; - } - } else { - print ''; - } - - print '
'; - print ($i + 1); - print ''; - print $dicts['tabname'][$i]; - print ''; - print $dicts['tablib'][$i]; - print ''; - print $dicts['tabsql'][$i]; - print ''; - print $dicts['tabsqlsort'][$i]; - print ''; - print $dicts['tabfield'][$i]; - print ''; - print $dicts['tabfieldvalue'][$i]; - print ''; - print $dicts['tabfieldinsert'][$i]; - print ''; - print $dicts['tabrowid'][$i]; - print ''; - print $dicts['tabcond'][$i]; - print '
'.$langs->trans("None").'
'; - print '
'; - - print '
'; - - print dol_get_fiche_head($head3, $tabdic, '', -1, ''); // Level 3 - - if ($tabdic == 'newdictionary') { - // New dic tab - print '
'; - print ''; - print ''; - print ''; - print ''; - - print ''.$langs->trans("EnterNameOfDictionaryDesc").'

'; - - print '
'; - //print '
'; - //print '
'; - print ''; - /*print '
'; - print '
'; - print '
'; - print ''.$langs->trans("or").''; - print '
'; - print '
'; - //print ' '; - print $langs->trans("InitStructureFromExistingTable"); - print ''; - print ''; - print '
'; - */ - print '
'; - } elseif ($tabdic == 'deletedictionary') { - // Delete dic tab - print '
'; - print ''; - print ''; - print ''; - print ''; - - print $langs->trans("EnterNameOfObjectToDeleteDesc").'

'; - - print ''; - print ''; - print '
'; - } else { - print $langs->trans("FeatureNotYetAvailable"); - } - - print dol_get_fiche_end(); - } else { - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - } - - if ($tab == 'menus') { - print ''."\n"; - $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; - - $menus = $moduleobj->menu; - - if ($action != 'editfile' || empty($file)) { - print ''; - $htmlhelp = $langs->trans("MenusDefDescTooltip", '{s1}'); - $htmlhelp = str_replace('{s1}', ''.$langs->trans('Setup').' - '.$langs->trans('Menus').'', $htmlhelp); - print $form->textwithpicto($langs->trans("MenusDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'
'; - print '
'; - print '
'; - - print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - - print '
'; - print load_fiche_titre($langs->trans("ListOfMenusEntries"), '', ''); - - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - print '
'; - print ''; - - print ''; - 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 "\n"; - - if (count($menus)) { - $i = 0; - foreach ($menus as $menu) { - $i++; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - } - } else { - print ''; - } - - print '
'; - print $i; - print ''; - print dol_escape_htmltag($menu['type']); - print ''; - print dol_escape_htmltag($menu['fk_menu']); - print ''; - print dol_escape_htmltag($menu['titre']); - print ''; - print dol_escape_htmltag($menu['mainmenu']); - print ''; - print dol_escape_htmltag($menu['leftmenu']); - print ''; - print dol_escape_htmltag($menu['url']); - print ''; - print dol_escape_htmltag($menu['langs']); - print ''; - print dol_escape_htmltag($menu['position']); - print ''; - print dol_escape_htmltag($menu['enabled']); - print ''; - print dol_escape_htmltag($menu['perms']); - print ''; - print dol_escape_htmltag($menu['target']); - print ''; - 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 '
'.$langs->trans("None").'
'; - print '
'; - - print '
'; - } else { - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - } - - if ($tab == 'permissions') { - print ''."\n"; - $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; - - $perms = $moduleobj->rights; - - if ($action != 'editfile' || empty($file)) { - print ''; - $htmlhelp = $langs->trans("PermissionsDefDescTooltip", '{s1}'); - $htmlhelp = str_replace('{s1}', ''.$langs->trans('DefaultRights').'', $htmlhelp); - print $form->textwithpicto($langs->trans("PermissionsDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'
'; - print '
'; - print '
'; - - print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - - print '
'; - print load_fiche_titre($langs->trans("ListOfPermissionsDefined"), '', ''); - - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - print '
'; - print ''; - - print ''; - 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 "\n"; - - if (count($perms)) { - foreach ($perms as $perm) { - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - } - } else { - print ''; - } - - print '
'; - print $perm[0]; - print ''; - print $langs->trans($perm[1]); - print ''; - print $perm[4]; - print ''; - print $perm[5]; - print '
'.$langs->trans("None").'
'; - print '
'; - - print '
'; - } else { - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - } - - if ($tab == 'hooks') { - print ''."\n"; - if ($action != 'editfile' || empty($file)) { - print ''.$langs->trans("HooksDefDesc").'
'; - print '
'; - - print ''; - - $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; - print ''; - - print ''; - print ''; - } else { - print ''.$langs->trans("FileNotYetGenerated").''; - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; - print ''; - } - print ''; - } else { - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print ''; - } - } - - if ($tab == 'triggers') { - print ''."\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 ''.$langs->trans("TriggerDefDesc").'
'; - print '
'; - - print '
'; - print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - $pathtohook = strtolower($module).'/class/actions_'.strtolower($module).'.class.php'; - print ' '.$langs->trans("HooksFile").' : '; - if (dol_is_file($dirins.'/'.$pathtohook)) { - print ''.$pathtohook.''; - print ''.img_picto($langs->trans("Edit"), 'edit').' '; - print ''.img_picto($langs->trans("Delete"), 'delete').'
'; - - $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; - print ''; - - if (!empty($triggers)) { - foreach ($triggers as $trigger) { - $pathtofile = $trigger['relpath']; - - print ''; - print ''; - print ''; - } - } else { - print ''; - print ''; - print ''; - } - - print '
'; - print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - print ' '.$langs->trans("TriggersFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').'
'; - print ' '.$langs->trans("TriggersFile"); - print ' : '.$langs->trans("FileNotYetGenerated").''; - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').'
'; - } else { - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - } - - if ($tab == 'css') { - print ''."\n"; - if ($action != 'editfile' || empty($file)) { - print ''.$langs->trans("CSSDesc").'
'; - print '
'; - - print ''; - - print ''; - print ''; - } else { - print ''.$langs->trans("FileNotYetGenerated").''; - print ''; - } - print ''; - } else { - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print ''; - } - } - - if ($tab == 'js') { - print ''."\n"; - if ($action != 'editfile' || empty($file)) { - print ''.$langs->trans("JSDesc").'
'; - print '
'; - - print '
'; - $pathtohook = strtolower($module).'/css/'.strtolower($module).'.css.php'; - print ' '.$langs->trans("CSSFile").' : '; - if (dol_is_file($dirins.'/'.$pathtohook)) { - print ''.$pathtohook.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').''.img_picto('Generate', 'generate', 'class="paddingleft"').'
'; - - print ''; - print ''; - } else { - print ''.$langs->trans("FileNotYetGenerated").''; - print ''; - } - print ''; - } else { - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print ''; - } - } - - if ($tab == 'widgets') { - print ''."\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 ''.$langs->trans("WidgetDesc").'
'; - print '
'; - - print '
'; - $pathtohook = strtolower($module).'/js/'.strtolower($module).'.js.php'; - print ' '.$langs->trans("JSFile").' : '; - if (dol_is_file($dirins.'/'.$pathtohook)) { - print ''.$pathtohook.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').''.img_picto('Generate', 'generate', 'class="paddingleft"').'
'; - if (!empty($widgets)) { - foreach ($widgets as $widget) { - $pathtofile = $widget['relpath']; - - print ''; - print ''; - } - } else { - print ''; - } - print '
'.$langs->trans("WidgetFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print ''.img_picto($langs->trans("Delete"), 'delete').'
'.$langs->trans("WidgetFile").' : '.$langs->trans("NoWidget").''; - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; - print '
'; - } else { - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - } - - if ($tab == 'exportimport') { - print ''."\n"; - $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; - - $exportlist = $moduleobj->export_label; - $importlist = $moduleobj->import_label; - - if ($action != 'editfile' || empty($file)) { - print ''.$langs->transnoentities('ImportExportProfiles').'
'; - print '
'; - - print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print '
'.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - } else { - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - } - - if ($tab == 'cli') { - print ''."\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 ''.$langs->trans("CLIDesc").'
'; - print '
'; - - print ''; - if (!empty($clifiles)) { - foreach ($clifiles as $clifile) { - $pathtofile = $clifile['relpath']; - - print ''; - print ''; - print ''; - } - } else { - print ''; - } - print '
'.$langs->trans("CLIFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').'
'.$langs->trans("CLIFile").' : '.$langs->trans("FileNotYetGenerated"); ''; - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; - print '
'; - } else { - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - } - - if ($tab == 'cron') { - print ''."\n"; - $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; - - $cronjobs = $moduleobj->cronjobs; - - if ($action != 'editfile' || empty($file)) { - print ''.str_replace('{s1}', ''.$langs->transnoentities('CronList').'', $langs->trans("CronJobDefDesc", '{s1}')).'
'; - print '
'; - - print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - - print '
'; - print load_fiche_titre($langs->trans("CronJobProfiles"), '', ''); - - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - print '
'; - print ''; - - print ''; - 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 "\n"; - - if (count($cronjobs)) { - foreach ($cronjobs as $cron) { - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - } - } else { - print ''; - } - - print '
'; - print $cron['label']; - print ''; - if ($cron['jobtype'] == 'method') { - $text = $langs->trans("CronClass"); - $texttoshow = $langs->trans('CronModule').': '.$module.'
'; - $texttoshow .= $langs->trans('CronClass').': '.$cron['class'].'
'; - $texttoshow .= $langs->trans('CronObject').': '.$cron['objectname'].'
'; - $texttoshow .= $langs->trans('CronMethod').': '.$cron['method']; - $texttoshow .= '
'.$langs->trans('CronArgs').': '.$cron['parameters']; - $texttoshow .= '
'.$langs->trans('Comment').': '.$langs->trans($cron['comment']); - } elseif ($cron['jobtype'] == 'command') { - $text = $langs->trans('CronCommand'); - $texttoshow = $langs->trans('CronCommand').': '.dol_trunc($cron['command']); - $texttoshow .= '
'.$langs->trans('CronArgs').': '.$cron['parameters']; - $texttoshow .= '
'.$langs->trans('Comment').': '.$langs->trans($cron['comment']); - } - print $form->textwithpicto($text, $texttoshow, 1); - print '
'; - 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 ''; - print $cron['status']; - print ''; - if (!empty($cron['comment'])) { - print $cron['comment']; - } - print '
'.$langs->trans("None").'
'; - print '
'; - - print '
'; - } else { - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - } - - if ($tab == 'specifications') { - print ''."\n"; - $specs = dol_dir_list(dol_buildpath($modulelowercase.'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$', array('\/temp\/')); - - if ($action != 'editfile' || empty($file)) { - print ''.$langs->trans("SpecDefDesc").'
'; - print '
'; - - print ''; - 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 ''; - print ''; - print ''; - } - } else { - print ''; - print ''; - } - print '
'; - print ' '.$langs->trans("SpecificationFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').'
'; - print ' '.$langs->trans("SpecificationFile").' : '.$langs->trans("FileNotYetGenerated").''; - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').'
'; - } else { - // Use MD or asciidoc - - //print $langs->trans("UseAsciiDocFormat").'
'; - - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - - print '


'; - - $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 ' '.$langs->trans("PathToModuleDocumentation", "HTML").' : '; - if (!dol_is_file($outputfiledoc)) { - print ''.$langs->trans("FileNotYetGenerated").''; - } else { - print ''; - print ''; - print $outputfiledoc; - print ''; - print ''; - print ' ('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledoc), 'dayhour').')'; - print ' '.img_picto($langs->trans("Delete"), 'delete').''; - } - print '

'; - - // PDF - print ' '.$langs->trans("PathToModuleDocumentation", "PDF").' : '; - if (!dol_is_file($outputfiledocpdf)) { - print ''.$langs->trans("FileNotYetGenerated").''; - } else { - print ''; - print ''; - print $outputfiledocpdf; - print ''; - print ''; - print ' ('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledocpdf), 'dayhour').')'; - print ' '.img_picto($langs->trans("Delete"), 'delete').''; - } - print '
'; - - print '
'; - - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print '
'; - } - - if ($tab == 'buildpackage') { - print ''."\n"; - print ''.$langs->trans("BuildPackageDesc").''; - print '
'; - - if (!class_exists('ZipArchive') && !defined('ODTPHP_PATHTOPCLZIP')) { - print img_warning().' '.$langs->trans("ErrNoZipEngine"); - print '
'; - } - - $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 '
'; - - print ' '.$langs->trans("PathToModulePackage").' : '; - if (!dol_is_file($outputfilezip)) { - print ''.$langs->trans("FileNotYetGenerated").''; - } else { - $relativepath = $modulelowercase.'/bin/'.$FILENAMEZIP; - print ''.$outputfilezip.''; - print ' ('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfilezip), 'dayhour').')'; - print ' '.img_picto($langs->trans("Delete"), 'delete').''; - } - print ''; - - print '
'; - - print '
'; - - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - print '
'; - } - - if ($tab == 'tabs') { - $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; - - $tabs = $moduleobj->tabs; - - if ($action != 'editfile' || empty($file)) { - print ''; - $htmlhelp = $langs->trans("TabsDefDescTooltip", '{s1}'); - $htmlhelp = str_replace('{s1}', ''.$langs->trans('Setup').' - '.$langs->trans('Tabs').'', $htmlhelp); - print $form->textwithpicto($langs->trans("TabsDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'
'; - print '
'; - print '
'; - - print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - - print '
'; - print load_fiche_titre($langs->trans("ListOfTabsEntries"), '', ''); - - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - print '
'; - print ''; - - print ''; - 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 "\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 ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - - print ''; - } - } else { - print ''; - } - - print '
'; - print dol_escape_htmltag($parts[0]); - print ''; - if ($tabName[0] === "+") { - print '' . dol_escape_htmltag($tabName) . ''; - } else { - print '' . dol_escape_htmltag($tabName) . ''; - } - print ''; - print dol_escape_htmltag($tabTitle); - print ''; - print dol_escape_htmltag($langFile); - print ''; - print dol_escape_htmltag($condition); - print ''; - print dol_escape_htmltag($path); - print '
'.$langs->trans("None").'
'; - print '
'; - - print '
'; - } else { - $fullpathoffile = dol_buildpath($file, 0); - - $content = file_get_contents($fullpathoffile); - - // New module - print '
'; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print '
'; - print ''; - print '   '; - print ''; - print '
'; - - print '
'; - } - } - - 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 index effcde14..00000000 --- a/htdocs/modulebuilder/template/ChangeLog.md +++ /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 index 03cf25d7..00000000 --- a/htdocs/modulebuilder/template/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# MYMODULE FOR [DOLIBARR ERP CRM](https://www.dolibarr.org) - -## Features - -Description of the module... - - - -Other external modules are available on [Dolistore.com](https://www.dolistore.com). - -## Translations - -Translations can be completed manually by editing files into directories *langs*. - - - - - -## 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 index 6e169cad..00000000 --- a/htdocs/modulebuilder/template/admin/about.php +++ /dev/null @@ -1,105 +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 . - */ - -/** - * \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 = ''.$langs->trans("BackToModuleList").''; - -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 index 07653753..00000000 --- a/htdocs/modulebuilder/template/admin/myobject_extrafields.php +++ /dev/null @@ -1,147 +0,0 @@ - - * Copyright (C) 2003 Jean-Louis Bergamo - * Copyright (C) 2004-2011 Laurent Destailleur - * Copyright (C) 2012 Regis Houssin - * Copyright (C) 2014 Florian Henry - * Copyright (C) 2015 Jean-François Ferry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 = ''.$langs->trans("BackToModuleList").''; -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 '
'; - print ''.$langs->trans("NewAttribute").''; - print "
"; - } -} - - -/* - * Creation of an optional field - */ -if ($action == 'create') { - print '
'; - 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 "
"; - 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 index dea2a1a5..00000000 --- a/htdocs/modulebuilder/template/admin/setup.php +++ /dev/null @@ -1,588 +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 . - */ - -/** - * \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 = ''.$langs->trans("BackToModuleList").''; - -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 ''.$langs->trans("MyModuleSetupPage").'

'; - - -if ($action == 'edit') { - print $formSetup->generateOutput(true); - print '
'; -} elseif (!empty($formSetup->items)) { - print $formSetup->generateOutput(); - print '
'; - print ''.$langs->trans("Modify").''; - print '
'; -} else { - print '
'.$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 ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''."\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 ''; - - // Show example of numbering model - print ''."\n"; - - print ''; - - $mytmpinstance = new $myTmpObjectKey($db); - $mytmpinstance->initAsSpecimen(); - - // Info - $htmltooltip = ''; - $htmltooltip .= ''.$langs->trans("Version").': '.$module->getVersion().'
'; - - $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.'
'; - } else { - $htmltooltip .= $langs->trans($module->error).'
'; - } - } - - print ''; - - print "\n"; - } - } - } - closedir($handle); - } - } - } - print "
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->name."\n"; - print $module->info(); - print ''; - $tmp = $module->getExample(); - if (preg_match('/^Error/', $tmp)) { - $langs->load("errors"); - print '
'.$langs->trans($tmp).'
'; - } elseif ($tmp == 'NotConfigured') { - print $langs->trans($tmp); - } else { - print $tmp; - } - print '
'; - $constforvar = 'MYMODULE_'.strtoupper($myTmpObjectKey).'_ADDON'; - if (getDolGlobalString($constforvar) == $file) { - print img_picto($langs->trans("Activated"), 'switch_on'); - } else { - print ''; - print img_picto($langs->trans("Disabled"), 'switch_off'); - print ''; - } - print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); - print '

\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 "\n"; - print "\n"; - print ''; - print ''; - print '\n"; - print '\n"; - print ''; - print ''; - print "\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 ''; - - // Active - if (in_array($name, $def)) { - print ''; - } else { - print '"; - } - - // Default - print ''; - - // Info - $htmltooltip = ''.$langs->trans("Name").': '.$module->name; - $htmltooltip .= '
'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown")); - if ($module->type == 'pdf') { - $htmltooltip .= '
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; - } - $htmltooltip .= '
'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file; - - $htmltooltip .= '

'.$langs->trans("FeaturesSupported").':'; - $htmltooltip .= '
'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1); - $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); - - print ''; - - // Preview - print ''; - - print "\n"; - } - } - } - } - } - } - } - } - - print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; - print (empty($module->name) ? $name : $module->name); - print "\n"; - if (method_exists($module, 'info')) { - print $module->info($langs); - } else { - print $module->description; - } - print ''."\n"; - print ''; - print img_picto($langs->trans("Enabled"), 'switch_on'); - print ''; - print ''."\n"; - print 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; - print "'; - $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 'scandir).'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; - } else { - print 'scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; - } - print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); - print ''; - if ($module->type == 'pdf') { - $newname = preg_replace('/_'.preg_quote(strtolower($myTmpObjectKey), '/').'/', '', $name); - print ''.img_object($langs->trans("Preview"), 'pdf').''; - } else { - print img_object($langs->trans("PreviewNotAvailable"), 'generic'); - } - print '
'; - } -} - -if (empty($setupnotempty)) { - print '
'.$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 index 3e22eb25..00000000 --- a/htdocs/modulebuilder/template/ajax/myobject.php +++ /dev/null @@ -1,68 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 index 837a8694..00000000 --- a/htdocs/modulebuilder/template/build/doxygen/mymodule.doxyfile +++ /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 ... \endif and \cond -# ... \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: -# -# -# -# where is the value of the INPUT_FILTER tag, and 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 + S -# (what the is depends on the OS and browser, but it is typically -# , /
'; - } 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 = '
'; - $return .= '
'; - $return .= ''; - $return .= img_picto('', $this->picto); - $return .= ''; - $return .= '
'; - $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; - if (property_exists($this, 'label')) { - $return .= '
'.$this->label.''; - } - if (method_exists($this, 'getLibStatut')) { - $return .= '
'.$this->getLibStatut(5).'
'; - } - $return .= '
'; - $return .= '
'; - $return .= '
'; - - 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 index 3989bca5..00000000 --- a/htdocs/modulebuilder/template/core/boxes/README.md +++ /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 index 7ea4b553..00000000 --- a/htdocs/modulebuilder/template/core/boxes/mymodulewidget1.php +++ /dev/null @@ -1,217 +0,0 @@ - - * Copyright (C) 2018-2021 Frédéric France - * 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 . - */ - -/** - * \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' => '

Another text

', - - // 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 index ad0814f7..00000000 --- a/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php +++ /dev/null @@ -1,199 +0,0 @@ - - * - * 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 .= ''; - $s .= '
'; - - 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 ''.img_object('', "generic").''; - } - - - // 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 index 99cd900b..00000000 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ /dev/null @@ -1,501 +0,0 @@ - - * Copyright (C) 2018-2019 Nicolas ZABOURI - * Copyright (C) 2019-2020 Frédéric France - * 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 . - */ - -/** - * \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 index 05486989..00000000 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php +++ /dev/null @@ -1,1343 +0,0 @@ - - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2008 Raphael Bertrand - * Copyright (C) 2010-2014 Juanjo Menent - * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2012 Cédric Salvador - * Copyright (C) 2012-2014 Raphaël Doursenaud - * Copyright (C) 2015 Marcos García - * Copyright (C) 2017 Ferran Marcet - * Copyright (C) 2018 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 . - * 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 index cce647de..00000000 --- a/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_advanced.php +++ /dev/null @@ -1,146 +0,0 @@ - - * Copyright (C) 2004-2007 Laurent Destailleur - * Copyright (C) 2005-2009 Regis Houssin - * Copyright (C) 2008 Raphael Bertrand (Resultic) - * Copyright (C) 2019 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 . - * 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')."
\n"; - $texte .= '
'; - $texte .= ''; - $texte .= ''; - $texte .= ''; - $texte .= ''; - - $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 .= ''; - $texte .= ''; - $texte .= ''; - $texte .= ''; - - $texte .= '
'.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).' 
'; - $texte .= '
'; - - 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 index f21ffe88..00000000 --- a/htdocs/modulebuilder/template/core/modules/mymodule/mod_myobject_standard.php +++ /dev/null @@ -1,161 +0,0 @@ - - * Copyright (C) 2005-2009 Regis Houssin - * - * 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 . - * 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 index c2eeb232..00000000 --- a/htdocs/modulebuilder/template/core/modules/mymodule/modules_myobject.php +++ /dev/null @@ -1,194 +0,0 @@ - - * Copyright (C) 2004-2011 Laurent Destailleur - * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2012 Juanjo Menent - * Copyright (C) 2014 Marcos García - * - * 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 . - * 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 index 21cb16c3..00000000 --- a/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php +++ /dev/null @@ -1,58 +0,0 @@ - - * - * 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 . - */ - -// 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 "\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'; - } - ?> -
trans("MyObject"); ?>getNomUrl(1); ?>date, 'day'); ?>getLibStatut(7); ?>">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?>
'; - print ''; - print ''; - - $var = true; - if ($num > 0) - { - $i = 0; - while ($i < $num) - { - - $obj = $db->fetch_object($resql); - print ''; - print ''; - print ''; - $i++; - $total += $obj->total_ttc; - } - if ($total>0) - { - - print '"; - } - } - else - { - - print ''; - } - print "
'.$langs->trans("DraftMyObjects").($num?''.$num.'':'').'
'; - - $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 ''; - print ''.price($obj->total_ttc).'
'.$langs->trans("Total").''.price($total)."
'.$langs->trans("NoOrder").'

"; - - $db->free($resql); - } - else - { - dol_print_error($db); - } -} -END MODULEBUILDER DRAFT MYOBJECT */ - - -print '
'; - - -$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 ''; - print ''; - print ''; - print ''; - print ''; - 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 ''; - print ''; - print '"; - print '"; - print ''; - $i++; - } - - $db->free($resql); - } else { - print ''; - } - print "
'; - print $langs->trans("BoxTitleLatestModifiedMyObjects", $max); - print ''.$langs->trans("DateModificationShort").'
'.$myobjectstatic->getNomUrl(1).''; - print "'.dol_print_date($db->jdate($objp->tms), 'day')."
'.$langs->trans("None").'

"; - } -} -*/ - -print '
'; - -// 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 index 6abb64d7..00000000 --- a/htdocs/modulebuilder/template/myobject_agenda.php +++ /dev/null @@ -1,321 +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 . - */ - -/** - * \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 = ''.$langs->trans("BackToList").''; - - $morehtmlref = '
'; - /* - // 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.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); - // Project - if (!empty($conf->project->enabled)) { - $langs->load("projects"); - $morehtmlref.='
'.$langs->trans('Project') . ' '; - if ($permissiontoadd) { - if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - } - $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.='
'; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.='
'; - } 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 .= '
'; - - - dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - - print '
'; - print '
'; - - $object->info($object->id); - dol_print_object_info($object, 1); - - print '
'; - - 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.='trans("AddAnAction"),'filenew'); - //$out.=""; - } - - $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 '
'; - - $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 index dc8dafd4..00000000 --- a/htdocs/modulebuilder/template/myobject_card.php +++ /dev/null @@ -1,621 +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 . - */ - -/** - * \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 ''; - - -// 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 '
'; - print ''; - print ''; - if ($backtopage) { - print ''; - } - if ($backtopageforcancel) { - print ''; - } - - print dol_get_fiche_head(array(), ''); - - // Set some default values - //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; - - print ''."\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 '
'."\n"; - - print dol_get_fiche_end(); - - print $form->buttonsSaveCancel("Create"); - - print '
'; - - //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 '
'; - print ''; - print ''; - print ''; - if ($backtopage) { - print ''; - } - if ($backtopageforcancel) { - print ''; - } - - print dol_get_fiche_head(); - - print ''."\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 '
'; - - print dol_get_fiche_end(); - - print $form->buttonsSaveCancel(); - - print '
'; -} - -// 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 .= '
'; - $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 = ''.$langs->trans("BackToList").''; - - $morehtmlref = '
'; - /* - // 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 .= '
'.$object->thirdparty->getNomUrl(1, 'customer'); - if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) { - $morehtmlref .= ' ('.$langs->trans("OtherOrders").')'; - } - // Project - if (isModEnabled('project')) { - $langs->load("projects"); - $morehtmlref .= '
'; - if ($permissiontoadd) { - $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); - if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; - } - $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 .= ' - '.dol_escape_htmltag($proj->title).''; - } - } - } - } - */ - $morehtmlref .= '
'; - - - dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - - - print '
'; - print '
'; - print '
'; - print ''."\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 '
'; - print '
'; - print '
'; - - print '
'; - - print dol_get_fiche_end(); - - - /* - * Lines - */ - - if (!empty($object->table_element_line)) { - // Show object lines - $result = $object->getLinesArray(); - - print '
- - - - - - '; - - if (!empty($conf->use_javascript_ajax) && $object->status == 0) { - include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; - } - - print '
'; - if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { - print ''; - } - - 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 '
'; - } - print '
'; - - print "
\n"; - } - - - // Buttons for actions - - if ($action != 'presend' && $action != 'editline') { - print '
'."\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 '
'."\n"; - } - - - // Select mail models is same action as presend - if (GETPOST('modelselected')) { - $action = 'presend'; - } - - if ($action != 'presend') { - print '
'; - print ''; // 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 '
'; - - $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 '
'; - } - - //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 index 95682012..00000000 --- a/htdocs/modulebuilder/template/myobject_contact.php +++ /dev/null @@ -1,228 +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 . - */ - -/** - * \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 = ''.$langs->trans("BackToList").''; - - $morehtmlref = '
'; - /* - // 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.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); - // Project - if (!empty($conf->project->enabled)) - { - $langs->load("projects"); - $morehtmlref.='
'.$langs->trans('Project') . ' '; - if ($permissiontoadd) - { - if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $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.='
'; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.='
'; - } 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 .= '
'; - - dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0, '', '', 1); - - print dol_get_fiche_end(); - - print '
'; - - // 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 index ff1756e2..00000000 --- a/htdocs/modulebuilder/template/myobject_document.php +++ /dev/null @@ -1,261 +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 . - */ - -/** - * \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 = ''.$langs->trans("BackToList").''; - -$morehtmlref = '
'; -/* - // 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.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); - // Project - if (!empty($conf->project->enabled)) - { - $langs->load("projects"); - $morehtmlref.='
'.$langs->trans('Project') . ' '; - if ($permissiontoadd) - { - if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $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.='
'; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.='
'; - } 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 .= '
'; - -dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - -print '
'; - -print '
'; -print ''; - -// Number of files -print ''; - -// Total size -print ''; - -print '
'.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
'.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
'; - -print '
'; - -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 index abef03f2..00000000 --- a/htdocs/modulebuilder/template/myobject_list.php +++ /dev/null @@ -1,850 +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 . - */ - -/** - * \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 ''; - -$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 '
'."\n"; -if ($optioncss != '') { - print ''; -} -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; - - -$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 ''."\n"; - print '
'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
'."\n"; -} - -$moreforfilter = ''; -/*$moreforfilter.='
'; -$moreforfilter.= $langs->trans('MyFilter') . ': '; -$moreforfilter.= '
';*/ - -$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 '
'; - print $moreforfilter; - print '
'; -} - -$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 '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table -print ''."\n"; - -// Fields title search -// -------------------------------------------------------------------- -print ''; -// Action column -if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; -} -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 ''; - } -} -// 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 ''; -}*/ -// Action column -if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; -} -print ''."\n"; - -$totalarray = array(); -$totalarray['nbfield'] = 0; - -// Fields title label -// -------------------------------------------------------------------- -print ''; -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 ''; - $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 ''."\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 ''; - } - } else { - // Show here line of result - $j = 0; - print ''; - // Action column - if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; - 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 ''; - 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 ''; - 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 ''; - }*/ - // Action column - if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - - print ''."\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 ''; -} - - -$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 '
'; - $searchpicto = $form->showFilterButtons('left'); - print $searchpicto; - print ''; - 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 '
'; - print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); - print '
'; - print '
'; - print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); - print '
'; - } 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 ''; - } - print '
'; - $searchpicto = $form->showFilterButtons(); - print $searchpicto; - print '
'.$langs->trans("AnotherField").'
'; - print '
'; - } - // Output Kanban - print $object->getKanbanView(''); - if ($i == ($imaxinloop - 1)) { - print '
'; - print '
'; - 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 ''; - } - print ''.$obj->anotherfield.''; - 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 ''; - } - print '
'.$langs->trans("NoRecordFound").'
'."\n"; -print '
'."\n"; - -print '
'."\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('&', '&', $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 index 1f3bf7c9..00000000 --- a/htdocs/modulebuilder/template/myobject_note.php +++ /dev/null @@ -1,221 +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 . - */ - -/** - * \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 = ''.$langs->trans("BackToList").''; - - $morehtmlref = '
'; - /* - // 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.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); - // Project - if (!empty($conf->project->enabled)) - { - $langs->load("projects"); - $morehtmlref.='
'.$langs->trans('Project') . ' '; - if ($permissiontoadd) - { - if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $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.='
'; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.='
'; - } 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 .= '
'; - - - dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - - - print '
'; - print '
'; - - - $cssclass = "titlefield"; - include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; - - print '
'; - - 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 index e335eb0e..00000000 --- a/htdocs/modulebuilder/template/scripts/mymodule.php +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env 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 . - */ - -/** - * \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 index 37860e8b..00000000 --- a/htdocs/modulebuilder/template/sql/data.sql +++ /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 . - - --- 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 index 5026bb4f..00000000 --- a/htdocs/modulebuilder/template/sql/dolibarr_allversions.sql +++ /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 index fc6b7b0d..00000000 --- a/htdocs/modulebuilder/template/sql/llx_mymodule_myobject.key.sql +++ /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 index cc9cca0c..00000000 --- a/htdocs/modulebuilder/template/sql/llx_mymodule_myobject.sql +++ /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 index 4c005e9d..00000000 --- a/htdocs/modulebuilder/template/sql/llx_mymodule_myobject_extrafields.key.sql +++ /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 index e0fc9ff4..00000000 --- a/htdocs/modulebuilder/template/sql/llx_mymodule_myobject_extrafields.sql +++ /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 index 2988bd71..00000000 --- a/htdocs/modulebuilder/template/sql/update_x.x.x-y.y.y.sql +++ /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 index 9701e27d..00000000 --- a/htdocs/modulebuilder/template/test/phpunit/MyModuleFunctionalTest.php +++ /dev/null @@ -1,304 +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 . - */ - -/** - * \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 index 31084cf7..00000000 --- a/htdocs/modulebuilder/template/test/phpunit/MyObjectTest.php +++ /dev/null @@ -1,200 +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 . - */ - -/** - * \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 index 36c5b2ea..00000000 --- a/htdocs/opensurvey/card.php +++ /dev/null @@ -1,438 +0,0 @@ - - * Copyright (C) 2014 Marcos García - * Copyright (C) 2018-2020 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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("@", "
", $toutsujet); -$toutsujet = str_replace("°", "'", $toutsujet); - -print '
'."\n"; -print ''; -print ''; - -$head = opensurvey_prepare_head($object); - - -print dol_get_fiche_head($head, 'general', $langs->trans("Survey"), -1, 'poll'); - -$morehtmlref = ''; - -$linkback = ''.$langs->trans("BackToList").''; - -dol_banner_tab($object, 'id', $linkback, 1, 'id_sondage', 'id_sondage', $morehtmlref); - - -print '
'; - -print '
'; -print '
'; -print ''; - -// Type -$type = ($object->format == "A") ? 'classic' : 'date'; -print ''; - -// Title -print ''; - -// Description -print ''; - -// Receive an email with each vote -print ''; - -// Users can comment -print ''; - -// Users can see others vote -print ''; - -print '
'.$langs->trans("Type").''; -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").'
'; -$adresseadmin = $object->mail_admin; -print $langs->trans("Title").''; -if ($action == 'edit') { - print ''; -} else { - print dol_htmlentities($object->title); -} -print '
'.$langs->trans("Description").''; -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 '
'.$langs->trans('ToReceiveEMailForEachVote').''; -if ($action == 'edit') { - print '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 '
'.$langs->trans('CanComment').''; -if ($action == 'edit') { - print 'allow_comments ? 'checked="checked"' : '').'">'; -} else { - print yn($object->allow_comments); -} -print '
'.$langs->trans('CanSeeOthersVote').''; -if ($action == 'edit') { - print 'allow_spy ? 'checked="checked"' : '').'">'; -} else { - print yn($object->allow_spy); -} -print '
'; - -print '
'; -print '
'; -print '
'; - -print ''; - -// Expire date -print ''; - -// Author -print ''; - -// Link -print ''; - -// 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 '
'.$langs->trans('ExpireDate').''; -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 '
'; -print $langs->trans("Author").''; -if ($object->fk_user_creat > 0) { - print $userstatic->getLoginUrl(1); -} else { - if ($action == 'edit') { - print ''; - } else { - print dol_print_email($object->mail_admin, 0, 0, 1, 0, 1, 1); - } -} -print '
'.$langs->trans("UrlForSurvey", '').''; - -// 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 ''; -if ($action != 'edit') { - print ajax_autoselect("opensurveyurl", $url, 'image'); -} - -print '
'; -print '
'; - -print '
'; -print '
'; - -print dol_get_fiche_end(); - -if ($action == 'edit') { - print $form->buttonsSaveCancel(); -} - -print '
'."\n"; - - - -// Action bar - -print '
'; - -if ($action != 'edit' && $user->rights->opensurvey->write) { - // Modify button - print ''.$langs->trans("Modify").''; - - if ($object->status == Opensurveysondage::STATUS_VALIDATED) { - // Close button - print ''.$langs->trans("Close").''; - } - if ($object->status == Opensurveysondage::STATUS_CLOSED) { - // Re-Open - print ''.$langs->trans("ReOpen").''; - } - - // Delete - print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?suppressionsondage=1&id='.urlencode($numsondage).'&action=delete&token='.newToken(), 'delete', $permissiontodelete); -} - -print '
'; - -if ($action == 'delete') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?&id='.urlencode($numsondage), $langs->trans("RemovePoll"), $langs->trans("ConfirmRemovalOfPoll", $id), 'delete_confirm', '', '', 1); -} - - - - -print '
'."\n"; -print ''; -print ''; -print ''; -print ''; - -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 ' '.img_picto('', 'delete.png', '', false, 0, 0, '', '', 0).' '; - } - - print dol_htmlentities($comment->usercomment).': '.dol_nl2br(dol_htmlentities($comment->comment))."
"; - } -} else { - print ''.$langs->trans("NoCommentYet").'
'; -} - -print '
'; - -// Add comment -if ($object->allow_comments) { - print $langs->trans("AddACommentForPoll").'
'; - print '
'."\n"; - print $langs->trans("Name").': '."\n"; - print '
'."\n"; -} - -print '
'; - -// 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 index f5dadd90..00000000 --- a/htdocs/opensurvey/class/opensurveysondage.class.php +++ /dev/null @@ -1,708 +0,0 @@ - - * Copyright (C) 2014 Marcos García - * Copyright (C) 2020 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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).' '.$langs->trans("ShowSurvey").''; - $label .= '
'; - $label .= ''.$langs->trans('Ref').': '.$this->ref.'
'; - $label .= ''.$langs->trans('Title').': '.$this->title.'
'; - - $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 = ''; - $linkend = ''; - - $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 index e7f0d279..00000000 --- a/htdocs/opensurvey/css/style.css +++ /dev/null @@ -1,531 +0,0 @@ -/* Copyright (C) 2004-2015 Laurent Destailleur - * Copyright (C) 2006 Rodolphe Quiedeville - * Copyright (C) 2007-2012 Regis Houssin - * Copyright (C) 2011 Philippe Grand - * Copyright (C) 2012 Juanjo Menent - * - * 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 . - */ - -.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 index a8a23178..00000000 --- a/htdocs/opensurvey/exportcsv.php +++ /dev/null @@ -1,142 +0,0 @@ - - * Copyright (C) 2014 Marcos García - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 index e70c50cf..00000000 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 index 98f05261..00000000 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 index 25741057..00000000 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 index 068a2325..00000000 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 index 9ba72ef5..00000000 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 index 4759abec..00000000 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 index 8f3d9e8c..00000000 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 index 8295e6ef..00000000 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 index 269ab632..00000000 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 index daf6bef6..00000000 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 index b2257c3e..00000000 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 index 4cb84811..00000000 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 index 0344414e..00000000 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 index 3f29b48d..00000000 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 index cc5e8f4b..00000000 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 index 35e2b013..00000000 --- a/htdocs/opensurvey/index.php +++ /dev/null @@ -1,89 +0,0 @@ - - * Copyright (C) 2019 Nicolas ZABOURI - * Copyright (C) 2019 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 '
'; - -print '
'; -print ''; -print ''; -print ''; -print ''; -print ""; -//print ''; -print '
'.$langs->trans("OpenSurveyArea").'
'.$langs->trans("NbOfSurveys").''.$nbsondages.'
'.$langs->trans("Total").''; -//print $total; -//print '
'; -print '
'; - -print '
'; - -$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 index c9c75b01..00000000 --- a/htdocs/opensurvey/lib/opensurvey.lib.php +++ /dev/null @@ -1,278 +0,0 @@ - - * Copyright (C) 2014 Marcos García - * -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*/ - -/** - * \file htdocs/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] .= ''.($nbVotes).''; - } - $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) ? '
' : '').'
'; - - top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss, 0, 1); // Show html headers - - print ''; - - print ''."\n"; - print '
'."\n"; - print '
'."\n"; - print ''; - print ''."\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 ''."\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&entity='.$conf->entity.'&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&entity='.$conf->entity.'&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 '
'; - print '
'; - print ''; - print '
'; - if (empty($conf->global->MAIN_HIDE_POWERED_BY)) { - print ''; - } - print '
'; - } - - if (!empty($conf->global->OPENSURVEY_IMAGE_PUBLIC_INTERFACE)) { - print '
'; - print ''; - print '
'; - } - - print '

'; -} - -/** - * Show footer for new member - * - * @return void - */ -function llxFooterSurvey() -{ - print '
'; - print '
'; - print '
'; - - printCommonFooter('public'); - - dol_htmloutput_events(); - - print "\n"; - print "\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 index 5700909c..00000000 --- a/htdocs/opensurvey/list.php +++ /dev/null @@ -1,576 +0,0 @@ - - * Copyright (C) 2014 Marcos García - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 '
'; -if ($optioncss != '') { - print ''; -} -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; - -$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 '
'.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'
'; -} - -$moreforfilter = ''; -/*$moreforfilter.='
'; -$moreforfilter.= $langs->trans('MyFilter') . ': '; -$moreforfilter.= '
';*/ - -$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 '
'; - print $moreforfilter; - print '
'; -} - -$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 '
'; -print ''."\n"; - -// Fields title search -// -------------------------------------------------------------------- -print ''; -// Action column -if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; -} -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -$arraystatus = array('-1'=>' ', '0'=>$langs->trans("Draft"), '1'=>$langs->trans("Opened"), '2'=>$langs->trans("Closed")); -print ''; -// Extra fields -include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; - -// Fields from hook -$parameters = array('arrayfields'=>$arrayfields); -$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -// Action column -if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; -} -print ''."\n"; - - -// Fields title label -// -------------------------------------------------------------------- -print ''; -// 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 ''."\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 ''; - // Action column - if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; - } - // Ref - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - - // Title - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - - // Type - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - - // Nb of voters - print''."\n"; - if (!$i) { - $totalarray['nbfield']++; - } - - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - - print ''."\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 ''; - } - if (!$i) { - $totalarray['nbfield']++; - } - - print ''."\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 ''; -} - - -$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 '
'; - $searchpicto = $form->showFilterButtons('left'); - print $searchpicto; - print ''.$form->selectarray('search_status', $arraystatus, $search_status, 0, 0, 0, '', 0, 0, 0, '', 'onroghtofpage').''; - $searchpicto = $form->showFilterButtons(); - print $searchpicto; - print '
'; - 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 ''; - } - print ''; - print $opensurvey_static->getNomUrl(1); - print ''.dol_htmlentities($obj->title).''; - $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 ''; - // 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 ''.$nbuser.''.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 ''.dol_print_date($db->jdate($obj->tms), 'dayhour'); - print ''.$opensurvey_static->getLibStatut(5).''; - 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 ''; - } - print '
'.$langs->trans("NoRecordFound").'
'."\n"; -print '
'."\n"; - -print '
'."\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('&', '&', $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 index d8405c31..00000000 --- a/htdocs/opensurvey/results.php +++ /dev/null @@ -1,1170 +0,0 @@ - - * Copyright (C) 2014 Marcos García - * Copyright (C) 2018 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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("@", "
", $toutsujet); -$toutsujet = str_replace("°", "'", $toutsujet); - - -print '
'."\n"; -print ''; - -$head = opensurvey_prepare_head($object); - -print dol_get_fiche_head($head, 'preview', $langs->trans("Survey"), -1, 'poll'); - -$morehtmlref = ''; - -$linkback = ''.$langs->trans("BackToList").''; - -dol_banner_tab($object, 'id', $linkback, 1, 'id_sondage', 'id_sondage', $morehtmlref); - - -print '
'; - -print '
'; -print '
'; -print ''; - -// Type -$type = ($object->format == "A") ? 'classic' : 'date'; -print ''; - -// Title -print ''; - -// Description -print ''; - -// EMail -//If linked user, then emails are going to be sent to users' email -if (!$object->fk_user_creat) { - print ''; -} - -print '
'.$langs->trans("Type").''; -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").'
'; -$adresseadmin = $object->mail_admin; -print $langs->trans("Title").''; -if ($action == 'edit') { - print ''; -} else { - print dol_htmlentities($object->title); -} -print '
'.$langs->trans("Description").''; -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 '
'.$langs->trans("EMail").''; - if ($action == 'edit') { - print ''; - } else { - print dol_print_email($object->mail_admin, 0, 0, 1, 0, 1, 1); - } - print '
'; - -print '
'; -print '
'; -print '
'; - -print ''; - - -// Expire date -print ''; - -// Author -print ''; - -// Link -print ''; - -print '
'.$langs->trans('ExpireDate').''; -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 '
'; -print $langs->trans("Author").''; -if ($object->fk_user_creat) { - print $userstatic->getLoginUrl(1); -} else { - print dol_htmlentities($object->nom_admin); -} -print '
'.$langs->trans("UrlForSurvey", '').''; - -// 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 = ''; -print $urllink; -if ($action != 'edit') { - print ajax_autoselect("opensurveyurl", $url, 'image'); -} - -print '
'; -print '
'; - -print '
'; -print '
'; - -print dol_get_fiche_end(); - -print '
'."\n"; - - -// Buttons - -print ''; - - -// Show form to add a new field/column -if (GETPOST('ajoutsujet')) { - // Security check - if (!$user->rights->opensurvey->write) { - accessforbidden(); - } - - print '
'."\n"; - print ''; - print ''; - - print '
'."\n"; - print "

\n"; - - // Add new column - if ($object->format == "A") { - print $langs->trans("AddNewColumn").':

'; - print $langs->trans("Title").'
'; - $tmparray = array('checkbox'=>$langs->trans("CheckBox"), 'yesno'=>$langs->trans("YesNoList"), 'foragainst'=>$langs->trans("PourContreList")); - print $langs->trans("Type").' '.$form->selectarray("typecolonne", $tmparray, GETPOST('typecolonne')).'

'; - print ''; - print ''; - print '     '; - print ''; - print '

'."\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").':

'."\n"; - print ''."\n"; - - print $formother->select_month('', 'nouveaumois', 1); - - print ' '; - - print $formother->selectyear('', 'nouvelleannee', 1, 0, 5, 0, 1); - - print '

'.$langs->trans("AddStartHour").':

'."\n"; - print ''."\n"; - print ''."\n"; - print '

'.$langs->trans("AddEndHour").':

'."\n"; - print ''."\n"; - print ''."\n"; - - print '

'; - print' '."\n"; - print '   '; - print ''; - } - - print ''."\n"; - print '



'."\n"; - print '
'."\n"; - - exit; -} - -if ($user->rights->opensurvey->write) { - print ''; - $s = $langs->trans("PollAdminDesc", '{s1}', $langs->trans("Add")); - print str_replace('{s1}', img_picto('', 'delete'), $s); - print '
'; -} - -$nbcolonnes = substr_count($object->sujet, ',') + 1; - -print '
'."\n"; -print ''; -print ''; - -print '
'."\n"; - -// Start to show survey result -print ''."\n"; - -//reformatage des données des sujets du sondage -$toutsujet = explode(",", $object->sujet); -$toutsujet = str_replace("°", "'", $toutsujet); - -print ''."\n"; -print ''."\n"; -print ''."\n"; - -// loop to show the delete link -if ($user->rights->opensurvey->write) { - for ($i = 0; isset($toutsujet[$i]); $i++) { - print ''."\n"; - } -} - -print ''."\n"; - - -// Show choice titles -if ($object->format == "D") { - //affichage des sujets du sondage - print ''."\n"; - print ''."\n"; - print ''."\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 ''."\n"; - $colspan = 1; - } - } - - if ($user->rights->opensurvey->write) { - print ''."\n"; - } - - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\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 ''."\n"; - - $colspan = 1; - } - } - - if ($user->rights->opensurvey->write) { - print ''."\n"; - } - - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\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 ''."\n"; - - $colspan = 1; - } - } - - if ($user->rights->opensurvey->write) { - print ''."\n"; - } - print ''."\n"; - - //affichage des horaires - if (strpos($object->sujet, '@') !== false) { - print ''."\n"; - print ''."\n"; - print ''."\n"; - - for ($i = 0; isset($toutsujet[$i]); $i++) { - $heures = explode('@', $toutsujet[$i]); - if (isset($heures[1])) { - print ''."\n"; - } else { - print ''."\n"; - } - } - - if ($user->rights->opensurvey->write) { - print ''."\n"; - } - - print ''."\n"; - } -} else { - // Show titles - print ''."\n"; - print ''."\n"; - print ''."\n"; - - for ($i = 0; isset($toutsujet[$i]); $i++) { - $tmp = explode('@', $toutsujet[$i]); - print ''."\n"; - } - - print ''."\n"; - print ''."\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 ''."\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 ''."\n"; - } else { - print ''."\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 ''."\n"; - } elseif (((string) $car) == "0") { - print ''."\n"; - } else { - print ''."\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 ''."\n"; - } elseif (((string) $car) == "0") { - print ''."\n"; - } else { - print ''."\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 ''."\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 ''."\n"; - } else { - print ''."\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 ''."\n"; - } elseif (((string) $car) == "0") { - print ''."\n"; - } else { - print ''."\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 ''."\n"; - } elseif (((string) $car) == "0") { - print ''."\n"; - } else { - print ''."\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 ''."\n"; - } - - //demande de confirmation pour modification de ligne - for ($i = 0; $i < $nblines; $i++) { - if (GETPOSTISSET("modifierligne".$i)) { - if ($compteur == $i) { - print ''."\n"; - } - } - } - - $compteur++; - print ''."\n"; -} - -// Add line to add new record -if (empty($testligneamodifier)) { - print ''."\n"; - print ''."\n"; - print ''."\n"; - - for ($i = 0; $i < $nbcolonnes; $i++) { - print ''."\n"; - } - - // Affichage du bouton de formulaire pour inscrire un nouvel utilisateur dans la base - print ''."\n"; - print ''."\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 ''."\n"; -print ''."\n"; -print ''."\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 ''."\n"; -} -print ''; -// Show picto winner -if ($nbofcheckbox >= 2) { - print ''."\n"; - print ''."\n"; - print ''."\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 ''."\n"; - } else { - print ''."\n"; - } - } - print ''."\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 '
'.date('Y', intval($toutsujet[$i])).''; - print 'id_sondage.'">'.$langs->trans("Add").'
'.dol_print_date($cur, "%B").'id_sondage.'">'.$langs->trans("Add").'
'.dol_print_date($cur, "%a %e").'id_sondage.'">'.$langs->trans("Add").'
'.dol_htmlentities($heures[1]).'id_sondage.'">'.$langs->trans("Add").'
'.dol_htmlentities($tmp[0]).'
'."\n"; - - if ($user->rights->opensurvey->write) { - print ''."\n"; - } - - // Name - print ''.dol_htmlentities($obj->name).'OKKO'.$langs->trans("Yes").''.$langs->trans("No").' '.$langs->trans("For").''.$langs->trans("Against").' '; - if (empty($listofanswers[$i]['format']) || !in_array($listofanswers[$i]['format'], array('yesno', 'foragainst'))) { - print ''; - } - if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') { - $arraychoice = array('2'=>' ', '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'=>' ', '0'=>$langs->trans("Against"), '1'=>$langs->trans("For")); - print $form->selectarray("choix".$i, $arraychoice, $car); - } - print 'OKKO'.$langs->trans("For").''.$langs->trans("Against").' '.$langs->trans("For").''.$langs->trans("Against").' '; - print ''; - print ''; - print '
'."\n"; - print ''."\n"; - print ''; - if (empty($listofanswers[$i]['format']) || !in_array($listofanswers[$i]['format'], array('yesno', 'foragainst'))) { - print ''; - } - if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') { - $arraychoice = array('2'=>' ', '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'=>' ', '0'=>$langs->trans("Against"), '1'=>$langs->trans("For")); - print $form->selectarray("choix".$i, $arraychoice); - } - print '
'.$langs->trans("Total").''; - 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.'
'.$langs->trans("No").': '.$showsumagainst; - } - if (!empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') { - print $langs->trans("For").': '.$showsumfor.'
'.$langs->trans("Against").': '.$showsumagainst; - } - print '
'."\n"; -print '
'."\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 '

'."\n"; - - if (isset($meilleurecolonne) && $compteursujet == "1") { - print " ".$langs->trans('TheBestChoice').": ".$meilleursujet." ".$langs->trans("with")." ".$meilleurecolonne." ".$vote_str.".\n"; - } elseif (isset($meilleurecolonne)) { - print " ".$langs->trans('TheBestChoices').": ".$meilleursujet." ".$langs->trans("with")." ".$meilleurecolonne." ".$vote_str.".\n"; - } - print '


'."\n"; -} - -print '
'."\n"; - -print ''."\n"; - -llxFooter(); - -$db->close(); diff --git a/htdocs/opensurvey/wizard/choix_autre.php b/htdocs/opensurvey/wizard/choix_autre.php deleted file mode 100644 index bbc13d5d..00000000 --- a/htdocs/opensurvey/wizard/choix_autre.php +++ /dev/null @@ -1,162 +0,0 @@ - - * Copyright (C) 2014 Marcos García - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 '
'."\n"; -print ''; - -print load_fiche_titre($langs->trans("CreatePoll").' (2 / 2)'); - - -print '
'.$langs->trans("PollOnChoice").'

'."\n"; - -print '
'."\n"; -print ''."\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 ''."\n"; -} - -print '
'.$langs->trans("TitleChoice").' '.$j.': '; - $tmparray = array('checkbox'=>$langs->trans("CheckBox"), 'yesno'=>$langs->trans("YesNoList"), 'foragainst'=>$langs->trans("PourContreList")); - print '   '.$langs->trans("Type").' '.$form->selectarray("typecolonne[]", $tmparray, $_SESSION["typecolonne$i"]); - print '
'."\n"; - -//ajout de cases supplementaires -print ''."\n"; -print ''."\n"; -print '
'.$langs->trans("5MoreChoices").'
'."\n"; -print'
'."\n"; - -print ''."\n"; -print ''."\n"; -print '
'."\n"; - -//fin du formulaire et bandeau de pied -print ''."\n"; - - -print ''."\n"; -print '


'."\n"; -print '
'."\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 index d8f89b18..00000000 --- a/htdocs/opensurvey/wizard/choix_date.php +++ /dev/null @@ -1,575 +0,0 @@ - - * Copyright (C) 2014 Marcos García - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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(',', '@'), $_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 '
'."\n"; -print ''; - -print load_fiche_titre($langs->trans("CreatePoll").' (2 / 2)'); - -//affichage de l'aide pour les jours -print '
'."\n"; -print $langs->trans("OpenSurveyStep2")."\n"; -print '
'."\n"; - -//debut du tableau qui affiche le calendrier -print '
'."\n"; -print '
'."\n"; -print ''."\n"; // The div class=center has no effect on table, so we must keep the align=center for table -print ''; -print ''; -print ''."\n"; -print '
'.$motmois.' '.$_SESSION["annee"].'
'; -print ''; -print '
'; -print '
'."\n"; -print '
'."\n"; - -print '
'."\n"; -print ''."\n"; // The div class=center has no effect on table, so we must keep the align=center for table -print ''."\n"; - -//affichage des jours de la semaine en haut du tableau -for ($i = 0; $i < 7; $i++) { - print ''; -} - -print ''."\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 ''."\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 ''."\n"; - } - - // On affiche les jours precedants en gris et incliquables - if ($i < $premierjourmois) { - print ''."\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 ''."\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 ''."\n"; - } else { - // grey button - print ''."\n"; - } - } - } -} - -//fin du tableau -print ''."\n"; -print '
'.dol_print_date(mktime(0, 0, 0, 0, $i, 10), '%A').'
'.$numerojour.'
'."\n"; -print '
'."\n"; - -print '
'."\n"; - -// affichage de tous les jours choisis -if (issetAndNoEmpty('totalchoixjour', $_SESSION) || $erreur) { - //affichage des jours - print '
'."\n"; - print '
'; - print ''.$langs->trans("SelectedDays").':'."
\n"; - print $langs->trans("SelectDayDesc")."
\n"; - print '

'; - - print ''."\n"; - print ''."\n"; - print ''."\n"; - - for ($i = 0; $i < $_SESSION["nbrecaseshoraires"]; $i++) { - $j = $i + 1; - print ''."\n"; - } - - if ($_SESSION["nbrecaseshoraires"] < 10) { - print ''."\n"; - } - - print ''."\n"; - - //affichage de la liste des jours choisis - $nbofchoice = count($_SESSION["totalchoixjour"]); - - for ($i = 0; $i < $nbofchoice; $i++) { - print ''."\n"; - print ''; - - //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 ''."\n"; - } else { - //sinon la case est vide normalement - print ''."\n"; - } - } - print ''."\n"; - } - - print '
'.$langs->trans("Time").' '.$j.'
'.dol_print_date($_SESSION["totalchoixjour"][$i], 'daytext').' ('.dol_print_date($_SESSION["totalchoixjour"][$i], '%A').')
'."\n"; - - // show buttons to cancel, delete days or create survey - print ''."\n"; - print ''."\n"; - print ''."\n"; - print''."\n"; - print ''."\n"; - print '


'."\n"; -} - -print ''."\n"; -print ''."\n"; -print ''."\n"; -//fin du formulaire et bandeau de pied -print ''."\n"; -//bandeau de pied -print '



'."\n"; -print '
'."\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 index 48e6b56c..00000000 --- a/htdocs/opensurvey/wizard/create_survey.php +++ /dev/null @@ -1,214 +0,0 @@ - - * Copyright (C) 2014 Marcos García - * Copyright (C) 2015-2016 Alexandre Spangaro - * Copyright (C) 2018 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 '
'."\n"; -print ''; - -print dol_get_fiche_head(); - -// Affichage des différents champs textes a remplir -print ''."\n"; - -print ''."\n"; -if (!$_SESSION["title"] && (GETPOST('creation_sondage_date') || GETPOST('creation_sondage_autre'))) { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PollTitle")), null, 'errors'); -} - -print ''."\n"; -print ''."\n"; -print ''."\n"; - -print ''."\n"; -print '
'.$langs->trans("PollTitle").'
'.$langs->trans("Description").''; -$doleditor = new DolEditor('description', $_SESSION["description"], '', 120, 'dolibarr_notes', 'In', 1, 1, 1, ROWS_7, '90%'); -$doleditor->Create(0, ''); -print '
'.$langs->trans("ExpireDate").''; - -print $form->selectDate($champdatefin ? $champdatefin : -1, 'champdatefin', '', '', '', "add", 1, 0); - -print '
'."\n"; - -print dol_get_fiche_end(); - -//focus javascript sur le premier champ -print ''."\n"; - -print '
'."\n"; - -// Check or not - -if ($_SESSION["mailsonde"]) { - $cochemail = "checked"; -} - -print '
'."\n"; - -if ($_SESSION['allow_comments']) { - $allow_comments = 'checked'; -} -if (GETPOSTISSET('allow_comments')) { - $allow_comments = GETPOST('allow_comments') ? 'checked' : ''; -} -print '
'."\n"; - -if ($_SESSION['allow_spy']) { - $allow_spy = 'checked'; -} -if (GETPOSTISSET('allow_spy')) { - $allow_spy = GETPOST('allow_spy') ? 'checked' : ''; -} -print '
'."\n"; - -if (GETPOST('choix_sondage')) { - if (GETPOST('choix_sondage') == 'date') { - print ''; - } else { - print ''; - } - print ''; - print '
trans("TypeDate") : $langs->trans("TypeClassic")).')">'; -} else { - // Show image to selecte between date survey or other survey - print '
'."\n"; - print ' '."\n"; - print ''."\n"; - print ' '."\n"; - print ''."\n"; - print '
'.$langs->trans("CreateSurveyDate").'
'.$langs->trans("CreateSurveyStandard").'
'."\n"; -} -print '


'."\n"; -print '
'."\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 index b8ccd0d8..00000000 --- a/htdocs/opensurvey/wizard/index.php +++ /dev/null @@ -1,70 +0,0 @@ - - * Copyright (C) 2014 Marcos García - * Copyright (C) 2016 Regis Houssin - * Copyright (C) 2019 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 . - */ - - -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 '
'; -print ''; -print '
'; -print '

'.$langs->trans("OrganizeYourMeetingEasily").'

'; -print '
'; -print '
'; -print '
'; -print '
'; -print ''; -print '
'; -print '
'; -print '
'; -print ''; -print '
'; -print '
'; -print '
'; -print '
'; - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/paybox/admin/paybox.php b/htdocs/paybox/admin/paybox.php deleted file mode 100644 index 9b3a2a74..00000000 --- a/htdocs/paybox/admin/paybox.php +++ /dev/null @@ -1,299 +0,0 @@ - - * Copyright (C) 2005-2010 Laurent Destailleur - * Copyright (C) 2011-2012 Juanjo Menent - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 = ''.$langs->trans("BackToModuleList").''; -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 '
'; -print ''; -print ''; - -print dol_get_fiche_head($head, 'payboxaccount', '', -1); - -print $langs->trans("PayBoxDesc")."
\n"; -print '
'; - -print ''; -print ''; -print ''; -print ''; -print "\n"; - - -print ''; - - -print ''; - - -print ''; - -print ''; - -print ''; -print ''; -print ''; -print "\n"; - -/* - -print ''; -*/ - -/* - -print ''; -*/ - - -print ''; - - -print ''; - - -if (isModEnabled("banque")) { - print ''; -} - - -print ''; - - -print ''; - -print ''; - - -print ''; - - -print ''; - -// Payment token for URL -print ''; - -print ''; - -print '
'.$langs->trans("AccountParameter").''.$langs->trans("Value").'
'; -print ''.$langs->trans("PAYBOX_PBX_SITE").''; -print ''; -print '
'.$langs->trans("Example").': 1999888 ('.$langs->trans("Test").')
'; -print '
'; -print ''.$langs->trans("PAYBOX_PBX_RANG").''; -print ''; -print '
'.$langs->trans("Example").': 99 ('.$langs->trans("Test").')
'; -print '
'; -print ''.$langs->trans("PAYBOX_PBX_IDENTIFIANT").''; -print ''; -print '
'.$langs->trans("Example").': 2 ('.$langs->trans("Test").')
'; -print '
'; -print ''.$langs->trans("PAYBOX_HMAC_KEY").''; -print ''; -print '
'.$langs->trans("Example").': 1A2B3C4D5E6F
'; -print '
'.$langs->trans("UsageParameter").''.$langs->trans("Value").'
'; -print $langs->trans("PAYBOX_IBS_DEVISE").''; -print ''; -print '
'.$langs->trans("Example").': 978 (EUR)'; -print '
'; -print $langs->trans("PAYBOX_CGI_URL_V1").''; -print ''; -print '
'.$langs->trans("Example").': http://mysite/cgi-bin/module_linux.cgi'; -print '
'; -print ''.$langs->trans("PAYBOX_CGI_URL_V2").''; -print ''; -print '
'.$langs->trans("Example").' (preprod): https://preprod-tpeweb.paybox.com/php/'; -print '
'.$langs->trans("Example").' (prod): https://tpeweb.paybox.com/php/
'; -print '
'; -print $langs->trans("PublicVendorName").''; -print ''; -print '
'.$langs->trans("Example").': '.$mysoc->name.''; -print '
'; - print $langs->trans("BankAccount").''; - $form->select_comptes($conf->global->PAYBOX_BANK_ACCOUNT_FOR_PAYMENTS, 'PAYBOX_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1); - print '
'; -print $langs->trans("CSSUrlForPaymentForm").''; -print ''; -print '
'.$langs->trans("Example").': http://mysite/mycss.css
'; -print '
'; -print $langs->trans("MessageForm").''; -$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 '
'; -print $langs->trans("MessageOK").''; -$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 '
'; -print $langs->trans("MessageKO").''; -$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 '
'; -print $langs->trans("ONLINE_PAYMENT_SENDEMAIL").''; -print ''; -print '   '.$langs->trans("Example").': myemail@myserver.com, Payment service <myemail2@myserver2.com>'; -print '
'; -print $langs->trans("SecurityToken").''; -print ''; -if (!empty($conf->use_javascript_ajax)) { - print ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token" class="linkobject"'); -} -print '
'; -print $langs->trans("SecurityTokenIsUnique").''; -print $form->selectyesno("PAYMENT_SECURITY_TOKEN_UNIQUE", (empty($conf->global->PAYMENT_SECURITY_TOKEN) ? 0 : $conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE), 1); -print '
'; - -print dol_get_fiche_end(); - -print $form->buttonsSaveCancel("Modify", ''); - -print '
'; - -print '

'; - -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 index 4bd819f5..00000000 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 index 7f41d45d..00000000 --- a/htdocs/paybox/lib/paybox.lib.php +++ /dev/null @@ -1,229 +0,0 @@ - - * Copyright (C) 2005-2007 Regis Houssin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 ''."\n"; - print ''."\n"; - print "\n"; - print ''."\n"; - print ''."\n"; - print "\n"; - - // Formulaire pour module Paybox - print '
'."\n"; - - // For Paybox V2 (PBX_xxx) - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''."\n"; - // Footprint of parameters - print ''."\n"; - print '
'."\n"; - - - print "\n"; - print ''."\n"; - print "\n"; - print ''."\n"; - print "\n"; - - return; -} diff --git a/htdocs/paypal/admin/paypal.php b/htdocs/paypal/admin/paypal.php deleted file mode 100644 index 68759eeb..00000000 --- a/htdocs/paypal/admin/paypal.php +++ /dev/null @@ -1,387 +0,0 @@ - - * Copyright (C) 2005-2013 Laurent Destailleur - * Copyright (C) 2011-2012 Regis Houssin - * Copyright (C) 2011-2012 Juanjo Menent - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("ModuleSetup").' PayPal', $linkback); - -$head = paypaladmin_prepare_head(); - -print '
'; -print ''; -print ''; - - -print dol_get_fiche_head($head, 'paypalaccount', '', -1); - -print ''.$langs->trans("PaypalDesc")."
\n"; - -// Test if php curl exist -if (!function_exists('curl_version')) { - $langs->load("errors"); - setEventMessages($langs->trans("ErrorPhpCurlNotInstalled"), null, 'errors'); -} - - -print '
'; - -print '
'; -print ''; - -// Account Parameters -print ''; -print ''; -print ''; -print "\n"; - -print ''; -print ''; - -print ''; - - -print ''; - - -print ''; - - -print ''; - -print '
'.$langs->trans("AccountParameter").''.$langs->trans("Value").'
'; -print $langs->trans("PaypalLiveEnabled").''; -if (empty($conf->global->PAYPAL_API_SANDBOX)) { - print ''; - print img_picto($langs->trans("Activated"), 'switch_on'); -} else { - print ''; - print img_picto($langs->trans("Disabled"), 'switch_off'); -} -print '
'; -print $langs->trans("PAYPAL_API_USER").''; -print ''; -print '   '.$langs->trans("Example").': admin-facilitator_api1.example.com, paypal_api1.mywebsite.com'; -print '
'; -print $langs->trans("PAYPAL_API_PASSWORD").''; -print ''; -print '
'; -print $langs->trans("PAYPAL_API_SIGNATURE").''; -print ''; -print '
'.$langs->trans("Example").': ASsqXEmw4KzmX-CPChWSVDNCNfd.A3YNR7uz-VncXXAERFDFDFDF'; -print '
'; -print $langs->trans("PAYPAL_SSLVERSION").''; -print $form->selectarray("PAYPAL_SSLVERSION", array('1'=> $langs->trans('TLSv1'), '6'=> $langs->trans('TLSv1.2')), $conf->global->PAYPAL_SSLVERSION); -print '
'; -print '
'; - -print '
'; - - -print '
'; -print ''; - -// Usage Parameters -print ''; -print ''; -print ''; -print "\n"; - - -print ''; - -/* -print ''; -*/ - - -print ''; - -if (isModEnabled("banque")) { - print ''; -} - -print ''; - - -print ''; - - -print ''; - - -print ''; - - -print ''; - - -print ''; - -print '
'.$langs->trans("UsageParameter").''.$langs->trans("Value").'
'; -print $langs->trans("PAYPAL_API_INTEGRAL_OR_PAYPALONLY").''; -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 '
'; -print ''.$langs->trans("PAYPAL_API_EXPRESS").''; -print $form->selectyesno("PAYPAL_API_EXPRESS",$conf->global->PAYPAL_API_EXPRESS); -print '
'; -print $langs->trans("PublicVendorName").''; -print ''; -print '   '.$langs->trans("Example").': '.$mysoc->name.''; -print '
'; - print $langs->trans("BankAccount").''; - print img_picto('', 'bank_account').' '; - $form->select_comptes($conf->global->PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS, 'PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1); - print '
'; -print $langs->trans("CSSUrlForPaymentForm").''; -print ''; -print '   '.$langs->trans("Example").': http://mysite/mycss.css'; -print '
'; -print $langs->trans("PAYPAL_ADD_PAYMENT_URL").''; -print $form->selectyesno("PAYPAL_ADD_PAYMENT_URL", $conf->global->PAYPAL_ADD_PAYMENT_URL, 1); -print '
'; -print $langs->trans("MessageForm").''; -$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 '
'; -print $langs->trans("MessageOK").''; -$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 '
'; -print $langs->trans("MessageKO").''; -$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 '
'; -print $langs->trans("ONLINE_PAYMENT_SENDEMAIL").''; -print ''; -print '   '.$langs->trans("Example").': myemail@myserver.com, Payment service <myemail2@myserver2.com>'; -print '
'; -print '
'; - -print '
'; - -print '
'; -print ''; - -print ''; -print ''; -print ''; -print "\n"; - -// Payment token for URL -print ''; - -print ''; - -print '
'.$langs->trans("UrlGenerationParameters").''.$langs->trans("Value").'
'; -print $langs->trans("SecurityToken").''; -print ''; -if (!empty($conf->use_javascript_ajax)) { - print ' '.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 '
'; -print $langs->trans("SecurityTokenIsUnique").''; -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 '
'; -print '
'; - -print dol_get_fiche_end(); - -print $form->buttonsSaveCancel("Modify", ''); - -print '
'; - -print '

'; - -// Help doc -print ''.$langs->trans("InformationToFindParameters", "Paypal").':
'; -if (!empty($conf->use_javascript_ajax)) { - print ''.$langs->trans("ClickHere").'...'; -} - -$realpaypalurl = 'www.paypal.com'; -$sandboxpaypalurl = 'developer.paypal.com'; - -print '
'; -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.
-1. Log in to your PayPal account (on real paypal '.$realpaypalurl.' (or sandbox '.$sandboxpaypalurl.').
-2. Click the "Profile" or "Preferencies" subtab located under the My Account heading.
-3. Click the link "API Access".
-4. Click the View API Certificate link in the right column.
-5. Click the Request API signature radio button on the Request API Credentials page.
-6. Complete the Request API Credential Request form by clicking the agreement checkbox and clicking Submit.
-7. Save the values for API Username, Password and Signature (make sure this long character signature is copied).
-8. Click the "Modify" button after copying your API Username, Password, and Signature. -'; -print '
'; - -if (!empty($conf->use_javascript_ajax)) { - print "\n".''; -} - -print '

'; - -$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 index 872a0356..00000000 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 index 79003956..00000000 --- a/htdocs/paypal/lib/paypal.lib.php +++ /dev/null @@ -1,617 +0,0 @@ - - * Copyright (C) 2011-2012 Regis Houssin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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).
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).
\n"; - } else { - $mesg = $langs->trans('SetExpressCheckoutAPICallFailed')."
\n"; - $mesg .= $langs->trans('DetailedErrorMessage').": ".$ErrorLongMsg."
\n"; - $mesg .= $langs->trans('ShortErrorMessage').": ".$ErrorShortMsg."
\n"; - $mesg .= $langs->trans('ErrorCode').": ".$ErrorCode."
\n"; - $mesg .= $langs->trans('ErrorSeverityCode').": ".$ErrorSeverityCode."
\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."
"; - print $USE_PROXY."-".$gv_ApiErrorURL."
"; - 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 index 713c3043..00000000 --- a/htdocs/paypal/lib/paypalfunctions.lib.php +++ /dev/null @@ -1,81 +0,0 @@ - - * Copyright (C) 2011 Regis Houssin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 index 1c5a507b..00000000 --- a/htdocs/stripe/admin/stripe.php +++ /dev/null @@ -1,627 +0,0 @@ - - * Copyright (C) 2017 Olivier Geffroy - * Copyright (C) 2017 Saasprov - * Copyright (C) 2018-2022 Thibault FOUCART - * Copyright (C) 2018 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("ModuleSetup").' Stripe', $linkback); - -$head = stripeadmin_prepare_head(); - -print '
'; -print ''; -print ''; - -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 ''.$langs->trans("StripeDesc")."
\n"; - -print '
'; - -print '
'; -print ''; -print ''; -print ''; -print ''; -print ''; -print "\n"; - -print ''; -print ''; - -if (empty($conf->stripeconnect->enabled)) { - print ''; - - print ''; - - print ''; -} else { - print ''; - print ''; -} - -if (empty($conf->stripeconnect->enabled)) { - print ''; - - print ''; - - print ''; -} else { - print ''; - print ''; -} - - -print '
'.$langs->trans("AccountParameter").''.$langs->trans("Value").'
'; -print $langs->trans("StripeLiveEnabled").''; -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 '
'; - print ''.$langs->trans("STRIPE_TEST_PUBLISHABLE_KEY").''; - print ''; - print '
'; - print ''.$langs->trans("STRIPE_TEST_SECRET_KEY").''; - print ''; - print '
'; - print ''.$langs->trans("STRIPE_TEST_WEBHOOK_KEY").''; - if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - print ''; - print '
'; - } - print ''; - $out = img_picto('', 'globe').' '.$langs->trans("ToOfferALinkForTestWebhook").' '; - $url = dol_buildpath('/public/stripe/ipn.php?test', 3); - $out .= ''; - $out .= ajax_autoselect("onlinetestwebhookurl", 0); - print '
'.$out; - print '
'; - 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 ''; - print img_picto($langs->trans("Activated"), 'switch_on'); - } else { - print ''; - print img_picto($langs->trans("Disabled"), 'switch_off'); - } - //print $endpoint; - } else { - print img_picto($langs->trans("Inactive"), 'statut5'); - } - } - print'
'.$langs->trans("StripeConnect").''.$langs->trans("StripeConnect_Mode").'
'; - 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 '
'; - print ''.$langs->trans("STRIPE_LIVE_PUBLISHABLE_KEY").''; - print ''; - print '
'; - print ''.$langs->trans("STRIPE_LIVE_SECRET_KEY").''; - print ''; - print '
'; - print ''.$langs->trans("STRIPE_LIVE_WEBHOOK_KEY").''; - if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - print ''; - print '
'; - } - print ''; - $out = img_picto('', 'globe', 'class="pictofixedwidth"').' '.$langs->trans("ToOfferALinkForLiveWebhook").' '; - $url = dol_buildpath('/public/stripe/ipn.php', 3); - $out .= ''; - $out .= ajax_autoselect("onlinelivewebhookurl", 0); - print '
'.$out; - print '
'; - 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 ''; - print img_picto($langs->trans("Activated"), 'switch_on'); - } else { - print ''; - print img_picto($langs->trans("Disabled"), 'switch_off'); - } - //print $endpoint; - } else { - print img_picto($langs->trans("Inactive"), 'statut5'); - } - } - print '
'.$langs->trans("StripeConnect").''.$langs->trans("StripeConnect_Mode").'
'; -print '
'; - -print '
'; - - -print '
'; -print ''; -print ''; -print ''; -print ''; -print "\n"; - -print ''; - -print ''; - -print ''; - -if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { // What is this for ? - print ''; -} - -// Card Present for Stripe Terminal -if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code - print ''; -} - -// Locations for Stripe Terminal -if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code - print ''; -} - -// Activate Payment Request API -if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code - print ''; -} - -// Activate SEPA DIRECT_DEBIT -if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code - print ''; -} - -// Activate Klarna -if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code - print ''; -} - -// Activate Bancontact -if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code - print ''; -} - -// Activate iDEAL -if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code - print ''; -} - -// Activate Giropay -if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code - print ''; -} - -// Activate Sofort -if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // TODO Not used by current code - print ''; -} - -print ''; - -print ''; - -print ''; - -print ''; - -print ''; - -print '
'.$langs->trans("UsageParameter").''.$langs->trans("Value").'
'; -print $langs->trans("PublicVendorName").''; -print ''; -print '   '.$langs->trans("Example").': '.$mysoc->name.''; -print '
'; -print $langs->trans("StripeUserAccountForActions").''; -print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers(getDolGlobalString('STRIPE_USER_ACCOUNT_FOR_ACTIONS'), 'STRIPE_USER_ACCOUNT_FOR_ACTIONS', 0); -print '
'; -print $langs->trans("BankAccount").''; -print img_picto('', 'bank_account', 'class="pictofixedwidth"'); -$form->select_comptes(getDolGlobalString('STRIPE_BANK_ACCOUNT_FOR_PAYMENTS'), 'STRIPE_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1); -print '
'; - print $langs->trans("BankAccountForBankTransfer").''; - print img_picto('', 'bank_account', 'class="pictofixedwidth"'); - $form->select_comptes(getDolGlobalString('STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS'), 'STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS', 0, '', 1); - print '
'; - print $langs->trans("STRIPE_CARD_PRESENT").''; - 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 '
'; - print $langs->trans("TERMINAL_LOCATION").''; - $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 '
'; - print $langs->trans("STRIPE_PAYMENT_REQUEST_API").' ?? Not used, what is it for ??'; - 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 '
'; - print $langs->trans("STRIPE_SEPA_DIRECT_DEBIT").''; - 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 '
'; - print $langs->trans("STRIPE_KLARNA").''; - 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 '   '.$langs->trans("ExampleOnlyForKlarnaCustomers").''; - print '
'; - print $langs->trans("STRIPE_BANCONTACT").''; - 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 '   '.$langs->trans("ExampleOnlyForBECustomers").''; - print '
'; - print $langs->trans("STRIPE_IDEAL").''; - 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 '   '.$langs->trans("ExampleOnlyForNLCustomers").''; - print '
'; - print $langs->trans("STRIPE_GIROPAY").''; - 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 '   '.$langs->trans("ExampleOnlyForDECustomers").''; - print '
'; - print $langs->trans("STRIPE_SOFORT").''; - 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 '   '.$langs->trans("ExampleOnlyForATBEDEITNLESCustomers").''; - print '
'; -print $langs->trans("CSSUrlForPaymentForm").''; -print ''; -print '   '.$langs->trans("Example").': http://mysite/mycss.css'; -print '
'; -print $langs->trans("MessageForm").''; -$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 '
'; -print $langs->trans("MessageOK").''; -$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 '
'; -print $langs->trans("MessageKO").''; -$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 '
'; -print $langs->trans("ONLINE_PAYMENT_SENDEMAIL").''; -print img_picto('', 'email', 'class="pictofixedwidth"'); -print ''; -print '   '.$langs->trans("Example").': myemail@myserver.com, Payment service <myemail2@myserver2.com>'; -print '
'; -print '
'; - -print '
'; - -print '
'; -print ''; - -print ''; -print ''; -print ''; -print "\n"; - -// Payment token for URL -print ''; - -print ''; - -print '
'.$langs->trans("UrlGenerationParameters").''.$langs->trans("Value").'
'; -print $langs->trans("SecurityToken").''; -print ''; -if (!empty($conf->use_javascript_ajax)) { - print ' '.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 '
'; -print $langs->trans("SecurityTokenIsUnique").''; -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 '
'; -print '
'; - -print dol_get_fiche_end(); - -print $form->buttonsSaveCancel("Save", ''); - -print '
'; - -print '

'; - - -$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".''; -} - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/stripe/ajax/ajax.php b/htdocs/stripe/ajax/ajax.php deleted file mode 100644 index 5fa4da88..00000000 --- a/htdocs/stripe/ajax/ajax.php +++ /dev/null @@ -1,124 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 index 0aee0c11..00000000 --- a/htdocs/stripe/charge.php +++ /dev/null @@ -1,299 +0,0 @@ - - * Copyright (C) 2019 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 . - */ - -// 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 '
'; - if ($optioncss != '') { - print ''; - } - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print ''."\n"; - - print ''; - 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 "\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 ''; - } - - //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."
"; - $label .= $langs->trans("Network").": ".$charge->outcome->network_status."
"; - $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 ''; - - 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 "\n"; - - // Stripe customer - print "\n"; - - // Link - print "\n"; - - // Origin - print "\n"; - - // Date payment - print '\n"; - // Type - print ''; - // Amount - print '"; - // Status - print '\n"; - - print "\n"; - - $i++; - } - } - - print '
'.$e->getMessage().'
"; - print "".img_picto($langs->trans('ShowInStripe'), 'globe')." ".$charge->id.""; - if ($charge->payment_intent) { - print '
'.$charge->payment_intent.''; - } - print "
"; - 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 ''.img_picto($langs->trans('ShowInStripe'), 'globe').' '.$charge->customer.''; - } - print ""; - if ($societestatic->id > 0) { - print $societestatic->getNomUrl(1); - } elseif ($memberstatic->id > 0) { - print $memberstatic->getNomUrl(1); - } - print ""; - 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 "".img_picto('', 'order')." ".$object->ref.""; - } 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 "".img_picto('', 'bill')." ".$object->ref.""; - } else { - print $FULLTAG; - } - } else { - print $FULLTAG; - } - print "'.dol_print_date($charge->created, 'dayhour')."'; - print $type; - print ''.price(($charge->amount - $charge->amount_refunded) / 100, 0, '', 1, - 1, - 1, strtoupper($charge->currency))."'; - print $status; - print "
'; - print '
'; - print '
'; -} - -// 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 index 8e5cd833..00000000 --- a/htdocs/stripe/class/actions_stripe.class.php +++ /dev/null @@ -1,218 +0,0 @@ - - * Copyright (C) 2011 Herve Prot - * Copyright (C) 2014 Philippe Grand - * - * 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 .= ''; - $this->resprints .= '
'; - $this->resprints .= $langs->trans('StripeCustomer'); - $this->resprints .= ''; - // $this->resprints.= ''.img_edit().''; - $this->resprints .= '
'; - $this->resprints .= ''; - $this->resprints .= ''; - $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 .= ''; - } elseif (is_object($object) && $object->element == 'member') { - $this->resprints .= ''; - $this->resprints .= '
'; - $this->resprints .= $langs->trans('StripeCustomer'); - $this->resprints .= ''; - $this->resprints .= '
'; - $this->resprints .= ''; - $this->resprints .= ''; - $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 .= ''; - - $this->resprints .= ''; - $this->resprints .= '
'; - $this->resprints .= $langs->trans('SubscriptionStripe'); - $this->resprints .= ''; - $this->resprints .= '
'; - $this->resprints .= ''; - $this->resprints .= ''; - $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 .= ''; - } elseif (is_object($object) && $object->element == 'adherent_type') { - $this->resprints .= ''; - $this->resprints .= '
'; - $this->resprints .= $langs->trans('PlanStripe'); - $this->resprints .= ''; - // $this->resprints.= ''.img_edit().''; - $this->resprints .= '
'; - $this->resprints .= ''; - $this->resprints .= ''; - $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 .= ''; - } - 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 ''.$langs->trans("StripeConnectPay").''; - } else { - print ''.$langs->trans("StripeConnectPay").''; - } - } elseif ($resteapayer == 0) { - print ''.$langs->trans("StripeConnectPay").''; - } - } else { - print ''.$langs->trans("StripeConnectPay").''; - } - } elseif (is_object($object) && $object->element == 'invoice_supplier') { - print ''.$langs->trans("StripeConnectPay").''; - } elseif (is_object($object) && $object->element == 'member') { - print ''.$langs->trans("StripeAutoSubscription").''; - } - return 0; - } -} diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php deleted file mode 100644 index 7fc11568..00000000 --- a/htdocs/stripe/class/stripe.class.php +++ /dev/null @@ -1,1293 +0,0 @@ - - * - * 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 . - */ - -// 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 = ' '.img_picto($langs->trans('ShowInStripe'), 'globe').''; - - //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 = ' '.img_picto($langs->trans('ShowInStripe'), 'globe').''; - - //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:
".$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 index 453eeb2a..00000000 --- a/htdocs/stripe/config.php +++ /dev/null @@ -1,55 +0,0 @@ - - * Copyright (C) 2017 Saasprov - * Copyright (C) 2017 Ferran Marcet - * - * 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 . - * - * 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 index b0503a71..00000000 --- a/htdocs/stripe/lib/stripe.lib.php +++ /dev/null @@ -1,126 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 '


'."\n"; - print '
'."\n"; - print $fromcompany->name.'
'; - print $line1.'
'; - print $line2; - print '
'."\n"; -} diff --git a/htdocs/stripe/payout.php b/htdocs/stripe/payout.php deleted file mode 100644 index 36c798c8..00000000 --- a/htdocs/stripe/payout.php +++ /dev/null @@ -1,178 +0,0 @@ - - * Copyright (C) 2019 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 . - */ - -// 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 '
'; - if ($optioncss != '') { - print ''; - } - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print ''."\n"; - - print ''; - 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 "\n"; - - print "\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 ''; - - // 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 "\n"; - - // Date payment - print '\n"; - // Date payment - print '\n"; - // Type - print ''; - // Amount - print '"; - // Status - print "'; - print "\n"; - } - } catch (Exception $e) { - print ''; - } - print "
".img_picto($langs->trans('ShowInStripe'), 'globe')." ".$payout->id."'.dol_print_date($payout->created, 'dayhour')."'.dol_print_date($payout->arrival_date, 'dayhour')."'.$payout->description.''.price(($payout->amount) / 100, 0, '', 1, -1, -1, strtoupper($payout->currency)).""; - 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 '
'.$e->getMessage().'
"; - print '
'; - print '
'; -} - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/stripe/transaction.php b/htdocs/stripe/transaction.php deleted file mode 100644 index 29eec246..00000000 --- a/htdocs/stripe/transaction.php +++ /dev/null @@ -1,242 +0,0 @@ - - * Copyright (C) 2018-2021 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * 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 . - */ - -// 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 '
'; - if ($optioncss != '') { - print ''; - } - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - $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 '
'; - print ''."\n"; - - print ''; - 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 "\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 ''; - - // 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 ""; - } else { - print "\n"; - } - - // Stripe customer - //print "\n"; - // Link - /*print "\n";*/ - // Origine - //print "\n"; - // Date payment - print '\n"; - // Type - print ''; - // Amount - print '"; - print '"; - // Status - print "'; - print "\n"; - } - } catch (Exception $e) { - print ''; - } - print "
".$txn->type."".img_picto($langs->trans('ShowInStripe'), 'globe')." ".$txn->source."".$charge->customer.""; - if ($societestatic->id > 0) { - print $societestatic->getNomUrl(1); - } - if ($memberstatic->id > 0) { - print $memberstatic->getNomUrl(1); - } - print ""; - ////if ($charge->metadata->dol_type=="order"){ - // $object = new Commande($db); - // $object->fetch($charge->metadata->dol_id); - // print "".img_picto('', 'object_order')." ".$object->ref.""; - //} elseif ($charge->metadata->dol_type=="invoice"){ - // $object = new Facture($db); - // $object->fetch($charge->metadata->dol_id); - // print "".img_picto('', 'object_invoice')." ".$object->ref.""; - //} - //print "'.dol_print_date($txn->created, 'dayhour')."'.$txn->type.''.price(($txn->amount) / 100, 0, '', 1, - 1, - 1, strtoupper($txn->currency))."'.price(($txn->fee) / 100, 0, '', 1, - 1, - 1, strtoupper($txn->currency)).""; - 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 '
'.$e->getMessage().'
"; - print '
'; - print '
'; -} - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/zapier/README.md b/htdocs/zapier/README.md deleted file mode 100644 index 66c4385e..00000000 --- a/htdocs/zapier/README.md +++ /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 index 71120a38..00000000 --- a/htdocs/zapier/admin/about.php +++ /dev/null @@ -1,88 +0,0 @@ - - * Copyright (C) 2019 Frédéric FRANCE - * - * - * 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 . - * - */ - -/** - * \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 = ''.$langs->trans("BackToModuleList").''; - -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 index 6737d233..00000000 --- a/htdocs/zapier/admin/setup.php +++ /dev/null @@ -1,129 +0,0 @@ - - * Copyright (C) 2019 Frédéric FRANCE - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file 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 = ''.$langs->trans("BackToModuleList").''; - -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 '
'; - print ''; - print ''; - - print ''; - print ''; - - foreach ($arrayofparameters as $key => $val) { - print ''; - } - print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; - print $form->textwithpicto($langs->trans($key), $langs->trans($key.'Tooltip')); - print '
'; - - print '
'; - print ''; - print '
'; - - print '
'; - print '
'; -} else { - if (!empty($arrayofparameters)) { - print ''; - print ''; - - foreach ($arrayofparameters as $key => $val) { - print ''; - } - - print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; - print $form->textwithpicto($langs->trans($key), $langs->trans($key.'Tooltip')); - print ''.getDolGlobalString($key).'
'; - - print '
'; - print ''.$langs->trans("Modify").''; - print '
'; - } else { - // Setup page goes here - echo '

'.$langs->trans("ZapierSetupPage").'

'; - //print '
'.$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 index 3db40064..00000000 --- a/htdocs/zapier/class/api_zapier.class.php +++ /dev/null @@ -1,387 +0,0 @@ - - * Copyright (C) 2019-2020 Frédéric France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 index 9b5b7335..00000000 --- a/htdocs/zapier/class/hook.class.php +++ /dev/null @@ -1,707 +0,0 @@ - - * Copyright (C) 2019 Frédéric France - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/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 = ''.$langs->trans("Hook").''; - $label .= '
'; - $label .= ''.$langs->trans('Ref').': '.$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 = ''; - $linkend = ''; - - $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 index 5b6a3bd3..00000000 --- a/htdocs/zapier/lib/zapier.lib.php +++ /dev/null @@ -1,60 +0,0 @@ - - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file 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 index 00000000..6ab84881 --- /dev/null +++ b/installer/install_creorga.ps1 @@ -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 index 00000000..b2b3f4eb --- /dev/null +++ b/installer/installlist.json @@ -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 index 00000000..b82cfc88 --- /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 index e25307c9..00000000 --- a/tools/doap/README +++ /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 index 75a5cced..00000000 --- a/tools/doxygen/dolibarr-doxygen-build.pl +++ /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 () { - 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 index 9233bd9e..00000000 --- a/tools/doxygen/dolibarr-doxygen-filter.pl +++ /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 () -{ - 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 index 6d05037e..00000000 --- a/tools/doxygen/dolibarr-doxygen-getversion.pl +++ /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 index 31400661..00000000 --- a/tools/doxygen/dolibarr-doxygen.doxyfile +++ /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 , where is the value of -# the FILE_VERSION_FILTER tag, and 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 , where -# is the value of the INPUT_FILTER tag, and 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 -# -# Qt Help Project / Custom Filters. - -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. - -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 index 2615af0b..00000000 --- a/tools/doxygen/doxygen_footer.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - -
- - - - - - - - - \ No newline at end of file diff --git a/tools/doxygen/doxygen_header.html b/tools/doxygen/doxygen_header.html deleted file mode 100644 index f60f4829..00000000 --- a/tools/doxygen/doxygen_header.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - -Dolibarr source code documentation - - - - - - - - - - - -
-
-
-
- -
-
- - - - - -
$projectname
- $projectnumber
- - - - -
-
- -
-
-
- -
-
-
-
- -
- - - - diff --git a/tools/examples/zapier/.editorconfig b/tools/examples/zapier/.editorconfig deleted file mode 100644 index 9228bbb1..00000000 --- a/tools/examples/zapier/.editorconfig +++ /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 index 3e9263e3..00000000 --- a/tools/examples/zapier/.gitignore +++ /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 index 5b8db590..00000000 --- a/tools/examples/zapier/.travis.yml +++ /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 index e452cc2a..00000000 --- a/tools/examples/zapier/README.md +++ /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 index e3aa4e69..00000000 --- a/tools/examples/zapier/action.json +++ /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 index fceedd4a..00000000 --- a/tools/examples/zapier/authentication.js +++ /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 index bcb849ad..00000000 --- a/tools/examples/zapier/creates/contact.js +++ /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 index 152f1129..00000000 --- a/tools/examples/zapier/creates/member.js +++ /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 index 2abeef6a..00000000 --- a/tools/examples/zapier/creates/thirdparty.js +++ /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 index fdd1ed29..00000000 --- a/tools/examples/zapier/index.js +++ /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 index 88529287..00000000 --- a/tools/examples/zapier/package.json +++ /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 ", - "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 index e69de29b..00000000 diff --git a/tools/examples/zapier/searches/contact.js b/tools/examples/zapier/searches/contact.js deleted file mode 100644 index b52b8d3e..00000000 --- a/tools/examples/zapier/searches/contact.js +++ /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 index f1a84061..00000000 --- a/tools/examples/zapier/searches/member.js +++ /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 index e1e6878f..00000000 --- a/tools/examples/zapier/searches/thirdparty.js +++ /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 index 220e48f5..00000000 --- a/tools/examples/zapier/test/index.js +++ /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 index 0e152473..00000000 --- a/tools/examples/zapier/triggers/action.js +++ /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 index 2ba3bd22..00000000 --- a/tools/examples/zapier/triggers/contact.js +++ /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 index 3385cdca..00000000 --- a/tools/examples/zapier/triggers/member.js +++ /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 index 061ce218..00000000 --- a/tools/examples/zapier/triggers/order.js +++ /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 index 76194acb..00000000 --- a/tools/examples/zapier/triggers/thirdparty.js +++ /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 index c642099b..00000000 --- a/tools/examples/zapier/triggers/ticket.js +++ /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 index 92209bb8..00000000 --- a/tools/examples/zapier/triggers/user.js +++ /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 index 69140d32..00000000 --- a/tools/flatpack/org.flatpak.Dolibarr.json +++ /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 index 400fbc4f..00000000 --- a/tools/patch/README +++ /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 index 3bbc6ea3..00000000 --- a/tools/patch/buildpatch.sh +++ /dev/null @@ -1,21 +0,0 @@ -#/bin/ksh -#---------------------------------------------------------------------------- -# \file build/patch/buildpatch.sh -# \brief Create patch files -# \author (c)2009-2011 Laurent Destailleur -#---------------------------------------------------------------------------- -# 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