';
- foreach ($listoffiles as $file)
- {
- $texte .= $file['name'].'
';
}
diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
index 08c69fed93f..792587f6205 100644
--- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
+++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
@@ -170,8 +170,7 @@ class doc_generic_invoice_odt extends ModelePDFFactures
{
$texte .= '
';
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
index be91acd7a3f..e0fccd309ab 100644
--- a/htdocs/core/modules/member/doc/doc_generic_member_odt.class.php
+++ b/htdocs/core/modules/member/doc/doc_generic_member_odt.class.php
@@ -156,9 +156,11 @@ class doc_generic_member_odt extends ModelePDFMember
if (count($listofdir))
{
$texte .= $langs->trans("NumberOfModelFilesFound").':
';
+
+ $texte .= '
';
+ // Show list of found files
foreach ($listoffiles as $file) {
- $texte .= $file['name'].'
';
+ $texte .= '- '.$file['name'].'
'.img_picto('', 'listlight').'';
}
$texte .= '
';
}
diff --git a/htdocs/core/modules/modTicket.class.php b/htdocs/core/modules/modTicket.class.php
index def2a7f7e69..448d1eb694b 100644
--- a/htdocs/core/modules/modTicket.class.php
+++ b/htdocs/core/modules/modTicket.class.php
@@ -105,9 +105,11 @@ class modTicket extends DolibarrModules
// Example:
$this->const = array(
1 => array('TICKET_ENABLE_PUBLIC_INTERFACE', 'chaine', '0', 'Enable ticket public interface', 0),
- 2 => array('TICKET_ADDON', 'chaine', 'mod_ticket_simple', 'Ticket ref module', 0)
+ 2 => array('TICKET_ADDON', 'chaine', 'mod_ticket_simple', 'Ticket ref module', 0),
+ 3 => array('TICKET_ADDON_PDF_ODT_PATH', 'chaine', 'DOL_DATA_ROOT/doctemplates/tickets', 'Ticket templates ODT/ODS directory for templates', 0)
);
+
$this->tabs = array(
'thirdparty:+ticket:Tickets:@ticket:$user->rights->ticket->read:/ticket/list.php?socid=__ID__',
'project:+ticket:Tickets:@ticket:$user->rights->ticket->read:/ticket/list.php?projectid=__ID__',
@@ -280,12 +282,36 @@ class modTicket extends DolibarrModules
*/
public function init($options = '')
{
+ global $conf, $langs;
+
+ // Permissions
+ $this->remove($options);
+
+ //ODT template
+ $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/tickets/template_ticket.odt';
+ $dirodt = DOL_DATA_ROOT.'/doctemplates/tickets';
+ $dest = $dirodt.'/template_order.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(
array("sql" => "insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (110120, 'ticket', 'internal', 'SUPPORTTEC', 'Utilisateur assigné au ticket', 1);", "ignoreerror" => 1),
array("sql" => "insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (110121, 'ticket', 'internal', 'CONTRIBUTOR', 'Intervenant', 1);", "ignoreerror" => 1),
array("sql" => "insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (110122, 'ticket', 'external', 'SUPPORTCLI', 'Contact client suivi incident', 1);", "ignoreerror" => 1),
array("sql" => "insert into llx_c_type_contact(rowid, element, source, code, libelle, active ) values (110123, 'ticket', 'external', 'CONTRIBUTOR', 'Intervenant', 1);", "ignoreerror" => 1),
+ "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'TICKET_ADDON_PDF_ODT_PATH' AND type = 'ticket' AND entity = ".$conf->entity,
+ "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('TICKET_ADDON_PDF_ODT_PATH','ticket',".$conf->entity.")"
);
return $this->_init($sql, $options);
diff --git a/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php b/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php
index eeaeb2c8e54..06e52390451 100644
--- a/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php
+++ b/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php
@@ -169,10 +169,10 @@ class doc_generic_mo_odt extends ModelePDFMo
if ($nbofiles)
{
- $texte .= '
';
- foreach ($listoffiles as $file)
- {
- $texte .= $file['name'].'
';
+ $texte .= '
';
}
diff --git a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php
index c6e07911ff7..bfd35e70095 100644
--- a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php
+++ b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php
@@ -440,10 +440,10 @@ class doc_generic_project_odt extends ModelePDFProjects
if ($nbofiles)
{
- $texte .= '
';
- foreach ($listoffiles as $file)
- {
- $texte .= $file['name'].'
';
+ $texte .= '
';
}
diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php
index edd777901ec..4ff95328029 100644
--- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php
+++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php
@@ -409,10 +409,10 @@ class doc_generic_task_odt extends ModelePDFTask
if ($nbofiles)
{
- $texte .= '
';
- foreach ($listoffiles as $file)
- {
- $texte .= $file['name'].'
';
+ $texte .= '
';
}
diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
index 7ca3ef79546..7b2ac19a016 100644
--- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
+++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
@@ -174,8 +174,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales
{
$texte .= '
';
// Show list of found files
- foreach ($listoffiles as $file)
- {
+ foreach ($listoffiles as $file) {
$texte .= '- '.$file['name'].'
'.img_picto('', 'listlight').'';
}
$texte .= '
';
diff --git a/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php b/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php
index 1105a5f6d4c..22ef687d13b 100644
--- a/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php
+++ b/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php
@@ -163,11 +163,11 @@ class doc_generic_reception_odt extends ModelePdfReception
}
if ($nbofiles)
{
- $texte .= '
';
- foreach ($listoffiles as $file)
- {
- $texte .= $file['name'].'
';
- }
+ $texte .= '
';
+ // Show list of found files
+ foreach ($listoffiles as $file) {
+ $texte .= '- '.$file['name'].'
'.img_picto('', 'listlight').'';
+ }
$texte .= '
';
}
diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php
index 66064cc4946..7b6ec019683 100644
--- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php
+++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php
@@ -152,10 +152,10 @@ class doc_generic_odt extends ModeleThirdPartyDoc
if ($nbofiles)
{
- $texte .= '
';
- foreach ($listoffiles as $file)
- {
- $texte .= $file['name'].'
';
+ $texte .= '
';
}
diff --git a/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php b/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php
index 1b3053aaaaf..c0614bd811e 100644
--- a/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php
+++ b/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php
@@ -166,10 +166,10 @@ class doc_generic_stock_odt extends ModelePDFStock
if ($nbofiles)
{
- $texte .= '
';
- foreach ($listoffiles as $file)
- {
- $texte .= $file['name'].'
';
+ $texte .= '
';
}
diff --git a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php
index 18c3a9a3574..1b58934b611 100644
--- a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php
+++ b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php
@@ -170,10 +170,10 @@ class doc_generic_supplier_order_odt extends ModelePDFSuppliersOrders
if ($nbofiles)
{
- $texte .= '
';
- foreach ($listoffiles as $file)
- {
- $texte .= $file['name'].'
';
+ $texte .= '
';
}
diff --git a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php
index 918f5fd9215..8c42681e986 100644
--- a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php
+++ b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php
@@ -174,10 +174,10 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
if ($nbofiles)
{
- $texte .= '
';
- foreach ($listoffiles as $file)
- {
- $texte .= $file['name'].'
';
+ $texte .= '
';
diff --git a/htdocs/core/modules/ticket/doc/doc_generic_ticket_odt.modules.php b/htdocs/core/modules/ticket/doc/doc_generic_ticket_odt.modules.php
new file mode 100644
index 00000000000..35afdcf7192
--- /dev/null
+++ b/htdocs/core/modules/ticket/doc/doc_generic_ticket_odt.modules.php
@@ -0,0 +1,429 @@
+
+ * Copyright (C) 2012 Juanjo Menent
+ * 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 .
+* or see https://www.gnu.org/
+*/
+
+/**
+ * \file htdocs/core/modules/ticket/doc/doc_generic_ticket_odt.modules.php
+ * \ingroup ticket
+ * \brief File of class to build ODT documents for tickets
+ */
+
+require_once DOL_DOCUMENT_ROOT.'/core/modules/ticket/modules_ticket.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_ticket_odt extends ModelePDFTicket
+{
+ /**
+ * @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 = 'TICKET_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 USER_TVAOPTION
+ $this->option_multilang = 1; // Dispo en plusieurs langues
+ $this->option_freetext = 0; // 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 .= '';
+
+ return $texte;
+ }
+
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+ /**
+ * Function to build a document on disk using the generic odt module.
+ *
+ * @param User $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
+ * @param int $hidedesc Do not show desc
+ * @param int $hideref Do not show ref
+ * @return int 1 if OK, <=0 if KO
+ */
+ public function write_file($object, $outputlangs, $srctemplatepath, $hidedetails = 0, $hidedesc = 0, $hideref = 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->user->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->user->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->user->dir_temp=".$conf->user->dir_temp;
+
+ dol_mkdir($conf->user->dir_temp);
+
+
+ // If CUSTOMER contact defined on user, 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))
+ {
+ if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !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->user->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_user = $this->get_substitutionarray_user($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_user, $array_soc, $array_thirdparty, $array_other, $array_thirdparty_contact);
+ complete_substitutions_array($tmparray, $outputlangs, $object);
+ $object->fetch_optionals();
+ // 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 User $object user
+ * @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/ticket/doc/index.html b/htdocs/core/modules/ticket/doc/index.html
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/htdocs/core/modules/ticket/modules_ticket.php b/htdocs/core/modules/ticket/modules_ticket.php
index f1d67cf5025..1d2bc944022 100644
--- a/htdocs/core/modules/ticket/modules_ticket.php
+++ b/htdocs/core/modules/ticket/modules_ticket.php
@@ -19,8 +19,8 @@
*/
/**
- * \file htdocs/core/modules/ticket/modules_ticket.php
- * \ingroup project
+ * \file htdocs/core/modules/ticket/modules_ticket.php
+ * \ingroup ticket
* \brief File that contain parent class for projects models
* and parent class for projects numbering models
*/
diff --git a/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php b/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php
index 2a326282fa0..2e39bf53ea2 100644
--- a/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php
+++ b/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php
@@ -187,9 +187,10 @@ class doc_generic_user_odt extends ModelePDFUser
$texte .= "";
$texte .= '';
}
- $texte .= '';
+ $texte .= '
';
+ // Show list of found files
foreach ($listoffiles as $file) {
- $texte .= $file['name'].'
';
+ $texte .= '- '.$file['name'].'
'.img_picto('', 'listlight').'';
}
$texte .= '
';
}
diff --git a/htdocs/install/doctemplates/tickets/template_ticket.odt b/htdocs/install/doctemplates/tickets/template_ticket.odt
new file mode 100644
index 00000000000..09ea9d52c59
Binary files /dev/null and b/htdocs/install/doctemplates/tickets/template_ticket.odt differ