diff --git a/htdocs/adherents/admin/adherent.php b/htdocs/adherents/admin/adherent.php index 51577218eb9..8acf1f1b191 100644 --- a/htdocs/adherents/admin/adherent.php +++ b/htdocs/adherents/admin/adherent.php @@ -7,7 +7,8 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2011-2012 Juanjo Menent * Copyright (C) 2012 J. Fernando Lagrange - * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2015 Jean-François Ferry + * 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 @@ -39,7 +40,12 @@ $langs->loadLangs(array("admin", "members")); if (!$user->admin) accessforbidden(); -$type = array('yesno', 'texte', 'chaine'); +$choices = array('yesno', 'texte', 'chaine'); + +$value = GETPOST('value', 'alpha'); +$label = GETPOST('label', 'alpha'); +$scandir = GETPOST('scandir', 'alpha'); +$type = 'member'; $action = GETPOST('action', 'aZ09'); @@ -48,8 +54,50 @@ $action = GETPOST('action', 'aZ09'); * Actions */ -// -if ($action == 'updateall') { +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + +if ($action == 'set_default') { + $ret = addDocumentModel($value, $type, $label, $scandir); + $res = true; +} elseif ($action == 'del_default') { + $ret = delDocumentModel($value, $type); + if ($ret > 0) { + if ($conf->global->MEMBER_ADDON_PDF_ODT == "$value") { + dolibarr_del_const($db, 'MEMBER_ADDON_PDF_ODT', $conf->entity); + } + } + $res = true; +} elseif ($action == 'setdoc') { + // Set default model + if (dolibarr_set_const($db, "MEMBER_ADDON_PDF_ODT", $value, 'chaine', 0, '', $conf->entity)) { + // La constante qui a ete lue en avant du nouveau set + // on passe donc par une variable pour avoir un affichage coherent + $conf->global->MEMBER_ADDON_PDF_ODT = $value; + } + + // On active le modele + $ret = delDocumentModel($value, $type); + if ($ret > 0) { + $ret = addDocumentModel($value, $type, $label, $scandir); + } + $res = true; +} elseif (preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) { + $code = $reg[1]; + if (dolibarr_set_const($db, $code, 1, 'chaine', 0, '', $conf->entity) > 0) { + header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } else { + dol_print_error($db); + } +} elseif (preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) { + $code = $reg[1]; + if (dolibarr_del_const($db, $code, $conf->entity) > 0) { + header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } else { + dol_print_error($db); + } +} elseif ($action == 'updateall') { $db->begin(); $res1 = $res2 = $res3 = $res4 = $res5 = $res6 = 0; $res1 = dolibarr_set_const($db, 'ADHERENT_LOGIN_NOT_REQUIRED', GETPOST('ADHERENT_LOGIN_NOT_REQUIRED', 'alpha') ? 0 : 1, 'chaine', 0, '', $conf->entity); @@ -86,7 +134,7 @@ if ($action == 'update' || $action == 'add') { $consttype = GETPOST('consttype', 'alpha'); $constnote = GETPOST('constnote'); - $res = dolibarr_set_const($db, $constname, $constvalue, $type[$consttype], 0, $constnote, $conf->entity); + $res = dolibarr_set_const($db, $constname, $constvalue, $choices[$consttype], 0, $constnote, $conf->entity); if (!$res > 0) $error++; @@ -245,6 +293,137 @@ $helptext .= '__COMPANY__, __ADDRESS__, __ZIP__, __TOWN__, __COUNTRY__, __EMAIL_ $helptext .= '__YEAR__, __MONTH__, __DAY__'; form_constantes($constantes, 0, $helptext); +$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + +// Defini tableau def des modeles +$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 load_fiche_titre($langs->trans("MembersDocModules"), '', ''); + +print ''; +print ''; +print ''; +print ''; +print '\n"; +print '\n"; +print ''; +print ''; +print "\n"; + +clearstatcache(); + +foreach ($dirmodels as $reldir) { + foreach (array('', '/doc') as $valdir) { + $dir = dol_buildpath($reldir."core/modules/member".$valdir); + 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('/\.class\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) { + if (file_exists($dir.'/'.$file)) { + $name = substr($file, 4, dol_strlen($file) - 14); + $classname = substr($file, 0, dol_strlen($file) - 10); + + 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 '"; + } + + // Defaut + 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("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 "'; + if ($conf->global->MEMBER_ADDON_PDF == $name) { + print img_picto($langs->trans("Default"), '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') + { + print ''.img_object($langs->trans("Preview"), 'contract').''; + } else { + print img_object($langs->trans("PreviewNotAvailable"), 'generic'); + } + print '
'; +print "
"; print dol_get_fiche_end(); diff --git a/htdocs/core/actions_setmoduleoptions.inc.php b/htdocs/core/actions_setmoduleoptions.inc.php index 1cc9a55deb2..24220f79f8c 100644 --- a/htdocs/core/actions_setmoduleoptions.inc.php +++ b/htdocs/core/actions_setmoduleoptions.inc.php @@ -100,7 +100,7 @@ if ($action == 'setModuleOptions') } if ($upload_dir) { - $result = dol_add_file_process($upload_dir, 0, 1, 'uploadfile', ''); + $result = dol_add_file_process($upload_dir, 1, 1, 'uploadfile', ''); if ($result <= 0) $error++; } } diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 6015bbceece..f3b1e7afc81 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -77,11 +77,11 @@ abstract class CommonDocGenerator public function get_substitutionarray_user($user, $outputlangs) { // phpcs:enable - global $conf; + global $conf, $extrafields; $logotouse = $conf->user->dir_output.'/'.get_exdir($user->id, 2, 0, 1, $user, 'user').'/'.$user->photo; - return array( + $array_user = array( 'myuser_lastname'=>$user->lastname, 'myuser_firstname'=>$user->firstname, 'myuser_fullname'=>$user->getFullName($outputlangs, 1), @@ -101,6 +101,53 @@ abstract class CommonDocGenerator 'myuser_job'=>$user->job, 'myuser_web'=>'' // url not exist in $user object ); + // Retrieve extrafields + if (is_array($user->array_options) && count($user->array_options)) { + $array_user = $this->fill_substitutionarray_with_extrafields($user, $array_user, $extrafields, 'myuser', $outputlangs); + } + return $array_user; + } + + + /** + * Define array with couple substitution key => substitution value + * + * @param Adherent $member Member + * @param Translate $outputlangs Language object for output + * @return array Array of substitution key->code + */ + public function getSubstitutionarrayMember($member, $outputlangs) + { + global $conf, $extrafields; + + $logotouse = $conf->adherent->dir_output.'/'.get_exdir($member->id, 2, 0, 1, $member, 'user').'/'.$member->photo; + + $array_member = array( + 'mymember_lastname' => $member->lastname, + 'mymember_firstname' => $member->firstname, + 'mymember_fullname' => $member->getFullName($outputlangs, 1), + 'mymember_login' => $member->login, + 'mymember_address' => $member->address, + 'mymember_zip' => $member->zip, + 'mymember_town' => $member->town, + 'mymember_country_code' => $member->country_code, + 'mymember_country' => $member->country, + 'mymember_state_code' => $member->state_code, + 'mymember_state' => $member->state, + 'mymember_phone_perso' => $member->phone_perso, + 'mymember_phone_pro' => $member->phone, + 'mymember_phone_mobile' => $member->phone_mobile, + 'mymember_email' => $member->email, + 'mymember_logo' => $logotouse, + 'mymember_gender' => $member->gender, + 'mymember_birth_locale' => dol_print_date($member->birth, 'day', 'tzuser', $outputlangs), + 'mymember_birth' => dol_print_date($member->birth, 'day', 'tzuser'), + ); + // Retrieve extrafields + if (is_array($member->array_options) && count($member->array_options)) { + $array_member = $this->fill_substitutionarray_with_extrafields($member, $array_member, $extrafields, 'mymember', $outputlangs); + } + return $array_member; } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 221c69b659a..c673896e627 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4570,13 +4570,17 @@ abstract class CommonObject { foreach (array('doc', 'pdf') as $prefix) { - if (in_array(get_class($this), array('Adherent'))) $file = $prefix."_".$modele.".class.php"; // Member module use prefix_module.class.php - else $file = $prefix."_".$modele.".modules.php"; + if (in_array(get_class($this), array('Adherent'))) { + // Member module use prefix_modele.class.php + $file = $prefix."_".$modele.".class.php"; + } else { + // Other module use prefix_modele.modules.php + $file = $prefix."_".$modele.".modules.php"; + } // On verifie l'emplacement du modele $file = dol_buildpath($reldir.$modelspath.$file, 0); - if (file_exists($file)) - { + if (file_exists($file)) { $filefound = $file; $classname = $prefix.'_'.$modele; break; diff --git a/htdocs/core/modules/member/doc/doc_generic_member_odt.class.php b/htdocs/core/modules/member/doc/doc_generic_member_odt.class.php new file mode 100644 index 00000000000..cfa8c75ec11 --- /dev/null +++ b/htdocs/core/modules/member/doc/doc_generic_member_odt.class.php @@ -0,0 +1,427 @@ + + * Copyright (C) 2012 Juanjo Menent + * 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/member/doc/doc_generic_member_odt.modules.php + * \ingroup societe + * \brief File of class to build ODT documents for members + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/member/modules_member.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'; + + +/** + * Class to build documents using ODF templates generator + */ +class doc_generic_member_odt extends ModelePDFMember +{ + /** + * @var Societe Issuer + */ + public $emetteur; + + /** + * @var array Minimum version of PHP required by module. + * e.g.: PHP ≥ 5.6 = array(5, 6) + */ + public $phpmin = array(5, 6); + + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $conf, $langs, $mysoc; + + // Load translation files required by the page + $langs->loadLangs(array("main", "companies")); + + $this->db = $db; + $this->name = "ODT templates"; + $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'MEMBER_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan + + // Page size for A4 format + $this->type = 'odt'; + $this->page_largeur = 0; + $this->page_hauteur = 0; + $this->format = array($this->page_largeur, $this->page_hauteur); + $this->marge_gauche = 0; + $this->marge_droite = 0; + $this->marge_haute = 0; + $this->marge_basse = 0; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 0; // Gere option tva MEMBER_TVAOPTION + $this->option_modereg = 0; // Affiche mode reglement + $this->option_condreg = 0; // Affiche conditions reglement + $this->option_codeproduitservice = 0; // Affiche code produit-service + $this->option_multilang = 1; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 0; // Support add of a watermark on drafts + + // Recupere emetteur + $this->emetteur = $mysoc; + if (!$this->emetteur->country_code) $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default if not defined + } + + + /** + * Return description of a module + * + * @param Translate $langs Lang object to use for output + * @return string Description + */ + public function info($langs) + { + global $conf, $langs; + + // Load translation files required by the page + $langs->loadLangs(array('companies', 'errors')); + + $form = new Form($this->db); + + $texte = $this->description.".
\n"; + $texte .= '
'; + $texte .= ''; + $texte .= ''; + $texte .= ''; + $texte .= ''; + + // List of directories area + $texte .= ''; + + $texte .= ''; + $texte .= ''; + + $texte .= '
'; + $texttitle = $langs->trans("ListOfDirectories"); + $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->MEMBER_ADDON_PDF_ODT_PATH))); + $listoffiles = array(); + foreach ($listofdir as $key=>$tmpdir) + { + $tmpdir = trim($tmpdir); + $tmpdir = preg_replace('/DOL_DATA_ROOT/', DOL_DATA_ROOT, $tmpdir); + if (!$tmpdir) { + unset($listofdir[$key]); continue; + } + if (!is_dir($tmpdir)) $texttitle .= img_warning($langs->trans("ErrorDirNotFound", $tmpdir), 0); + else { + $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.(ods|odt)'); + if (count($tmpfiles)) $listoffiles = array_merge($listoffiles, $tmpfiles); + } + } + $texthelp = $langs->trans("ListOfDirectoriesForModelGenODT"); + // Add list of substitution keys + $texthelp .= '
'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
'; + $texthelp .= $langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + + $texte .= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1); + $texte .= '
'; + $texte .= ''; + $texte .= '
'; + $texte .= ''; + $texte .= '
'; + + // Scan directories + if (count($listofdir)) + { + $texte .= $langs->trans("NumberOfModelFilesFound").': '.count($listoffiles).''; + $texte .= ''; + } + // Add input to upload a new template file. + $texte .= '
'.$langs->trans("UploadNewTemplate").' '; + $texte .= ''; + $texte .= ''; + $texte .= '
'; + $texte .= '
'; + $texte .= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte .= '
'; + $texte .= '
'; + + return $texte; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Function to build a document on disk using the generic odt module. + * + * @param Adherent $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 string $mode Tell if doc module is called for 'member', ... + * @param int $nooutput 1=Generate only file on disk and do not return it on response + * @return int 1 if OK, <=0 if KO + */ + public function write_file($object, $outputlangs, $srctemplatepath, $mode = 'member', $nooutput = 0) + { + // phpcs:enable + global $user, $langs, $conf, $mysoc, $hookmanager; + + if (empty($srctemplatepath)) { + dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); + return -1; + } + + // Add odtgeneration hook + if (!is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; + + if (!is_object($outputlangs)) $outputlangs = $langs; + $sav_charset_output = $outputlangs->charset_output; + $outputlangs->charset_output = 'UTF-8'; + + // Load translation files required by the page + $outputlangs->loadLangs(array("main", "companies", "bills", "dict")); + + if ($conf->adherent->dir_output) { + // If $object is id instead of object + if (!is_object($object)) { + $id = $object; + $object = new User($this->db); + $result = $object->fetch($id); + if ($result < 0) { + dol_print_error($this->db, $object->error); + return -1; + } + } + + $object->fetch_thirdparty(); + + $dir = $conf->adherent->dir_output; + $objectref = dol_sanitizeFileName($object->ref); + if (!preg_match('/specimen/i', $objectref)) $dir .= "/".$objectref; + $file = $dir."/".$objectref.".odt"; + + if (!file_exists($dir)) { + if (dol_mkdir($dir) < 0) { + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return -1; + } + } + + if (file_exists($dir)) { + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile = basename($srctemplatepath); + $newfiletmp = preg_replace('/\.od(t|s)/i', '', $newfile); + $newfiletmp = preg_replace('/template_/i', '', $newfiletmp); + $newfiletmp = preg_replace('/modele_/i', '', $newfiletmp); + + $newfiletmp = $objectref.'_'.$newfiletmp; + + // Get extension (ods or odt) + $newfileformat = substr($newfile, strrpos($newfile, '.') + 1); + if (!empty($conf->global->MAIN_DOC_USE_TIMING)) { + $format = $conf->global->MAIN_DOC_USE_TIMING; + if ($format == '1') $format = '%Y%m%d%H%M%S'; + $filename = $newfiletmp.'-'.dol_print_date(dol_now(), $format).'.'.$newfileformat; + } else { + $filename = $newfiletmp.'.'.$newfileformat; + } + $file = $dir.'/'.$filename; + //print "newdir=".$dir; + //print "newfile=".$newfile; + //print "file=".$file; + //print "conf->adherent->dir_temp=".$conf->adherent->dir_temp; + + dol_mkdir($conf->adherent->dir_temp); + + + // If CUSTOMER contact defined on member, 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 (!empty($usecontact)) { + // On peut utiliser le nom de la societe du contact + if (!empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) { + $socobject = $object->contact; + } else { + $socobject = $object->thirdparty; + // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + $contactobject = $object->contact; + } + } else { + $socobject = $object->thirdparty; + } + + // Open and load template + require_once ODTPHP_PATH.'odf.php'; + try { + $odfHandler = new odf( + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->adherent->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' + ) + ); + } catch (Exception $e) + { + $this->error = $e->getMessage(); + dol_syslog($e->getMessage(), LOG_WARNING); + return -1; + } + + // Make substitutions into odt + $array_member = $this->getSubstitutionarrayMember($object, $outputlangs); + $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs); + $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs); + $array_other = $this->get_substitutionarray_other($outputlangs); + // retrieve contact information for use in object as contact_xxx tags + $array_thirdparty_contact = array(); + if ($usecontact && is_object($contactobject)) $array_thirdparty_contact = $this->get_substitutionarray_contact($contactobject, $outputlangs, 'contact'); + + $tmparray = array_merge($array_member, $array_soc, $array_thirdparty, $array_other, $array_thirdparty_contact); + complete_substitutions_array($tmparray, $outputlangs, $object); + $tags = ''; + foreach ($tmparray as $key => $value) { + $tags .= '{' . $key . '} => ' . $value ."\n"; + } + $tmparray = array_merge($tmparray, array('__ALL_TAGS__' => $tags)); + // Call the ODTSubstitution hook + $parameters = array( + 'file'=>$file, + 'object'=>$object, + 'outputlangs'=>$outputlangs, + 'substitutionarray'=>&$tmparray + ); + $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + foreach ($tmparray as $key=>$value) { + try { + if (preg_match('/logo$/', $key)) { + // Image + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } else { + // Text + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } catch (OdfException $e) { + dol_syslog($e->getMessage(), LOG_WARNING); + } + } + + // Replace labels translated + $tmparray = $outputlangs->get_translations_for_substitutions(); + foreach ($tmparray as $key=>$value) + { + try { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } catch (OdfException $e) + { + dol_syslog($e->getMessage(), LOG_WARNING); + } + } + + // Call the beforeODTSave hook + $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); + $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)) { + try { + $odfHandler->exportAsAttachedPDF($file); + } catch (Exception $e) { + $this->error = $e->getMessage(); + dol_syslog($e->getMessage(), LOG_WARNING); + return -1; + } + } else { + try { + $odfHandler->saveToDisk($file); + } catch (Exception $e) { + $this->error = $e->getMessage(); + dol_syslog($e->getMessage(), LOG_WARNING); + return -1; + } + } + + $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + + if (!empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $odfHandler = null; // Destroy object + + $this->result = array('fullpath'=>$file); + + return 1; // Success + } else { + $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); + return -1; + } + } + + return -1; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * get substitution array for object + * + * @param Adherent $object member + * @param Translate $outputlangs translation object + * @param string $array_key key for array + * @return array array of substitutions + */ + public function get_substitutionarray_object($object, $outputlangs, $array_key = 'object') + { + // phpcs:enable + $array_other = array(); + foreach ($object as $key => $value) { + if (!is_array($value) && !is_object($value)) { + $array_other[$array_key.'_'.$key] = $value; + } + } + return $array_other; + } +} diff --git a/htdocs/core/modules/member/modules_member.class.php b/htdocs/core/modules/member/modules_member.class.php new file mode 100644 index 00000000000..2166fd9ccb7 --- /dev/null +++ b/htdocs/core/modules/member/modules_member.class.php @@ -0,0 +1,66 @@ + + * Copyright (C) 2004-2010 Laurent Destailleur + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2005-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 . + * or see https://www.gnu.org/ + */ + + +/** + * \class ModeleProductCode + * \brief Parent class for product code generators + */ + +/** + * \file htdocs/core/modules/member/modules_member.php + * \ingroup members + * \brief File with parent class for generating members to PDF + */ + + require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php'; + +/** + * Parent class to manage intervention document templates + */ +abstract class ModelePDFMember extends CommonDocGenerator +{ + /** + * @var string Error code (or message) + */ + public $error = ''; + + + // 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 + + $type = 'member'; + $list = array(); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $list = getListOfModels($db, $type, $maxfilenamelength); + return $list; + } +} diff --git a/htdocs/core/modules/modAdherent.class.php b/htdocs/core/modules/modAdherent.class.php index d9a4f72465d..1db3e2b7d50 100644 --- a/htdocs/core/modules/modAdherent.class.php +++ b/htdocs/core/modules/modAdherent.class.php @@ -60,7 +60,10 @@ class modAdherent extends DolibarrModules $this->picto = 'member'; // Data directories to create when module is enabled - $this->dirs = array("/adherent/temp"); + $this->dirs = array( + "/adherent/temp", + "/doctemplates/members", + ); // Config pages $this->config_page_url = array("adherent.php@adherents"); @@ -178,6 +181,13 @@ class modAdherent extends DolibarrModules $this->const[$r][4] = 0; $r++; + $this->const[$r][0] = "MEMBER_ADDON_PDF_ODT_PATH"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/members"; + $this->const[$r][3] = ""; + $this->const[$r][4] = 0; + $r++; + // Boxes //------- diff --git a/htdocs/core/modules/user/doc/index.html b/htdocs/core/modules/user/doc/index.html new file mode 100644 index 00000000000..e69de29bb2d