diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php
new file mode 100644
index 00000000000..2408bcbc8e6
--- /dev/null
+++ b/htdocs/admin/emailcollector_card.php
@@ -0,0 +1,404 @@
+
+ * 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/admin/emailcollectore/emailcollector_card.php
+ * \ingroup emailcollector
+ * \brief Page to create/edit/view emailcollector
+ */
+
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php';
+
+include_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php';
+include_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php';
+dol_include_once('/emailcollector/class/emailcollector.class.php');
+dol_include_once('/emailcollector/lib/emailcollector.lib.php');
+
+if (!$user->admin)
+ accessforbidden();
+
+// Load traductions files requiredby by page
+$langs->loadLangs(array("admin", "other"));
+
+// Get parameters
+$id = GETPOST('id', 'int');
+$ref = GETPOST('ref', 'alpha');
+$action = GETPOST('action', 'alpha');
+$confirm = GETPOST('confirm', 'alpha');
+$cancel = GETPOST('cancel', 'aZ09');
+$contextpage= GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'myobjectcard'; // To manage different context of search
+$backtopage = GETPOST('backtopage', 'alpha');
+
+// Initialize technical objects
+$object = new EmailCollector($db);
+$extrafields = new ExtraFields($db);
+$diroutputmassaction = $conf->emailcollector->dir_output . '/temp/massgeneration/' . $user->id;
+$hookmanager->initHooks(array('emailcollectorcard')); // Note that conf->hooks_modules contains array
+// Fetch optionals attributes and labels
+$extralabels = $extrafields->fetch_name_optionals_label('emailcollector');
+$search_array_options = $extrafields->getOptionalsFromPost($extralabels, '', 'search_');
+
+// Initialize array of search criterias
+$search_all = trim(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 // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
+
+// Security check - Protection if external user
+//if ($user->societe_id > 0) access_forbidden();
+//if ($user->societe_id > 0) $socid = $user->societe_id;
+//$isdraft = (($object->statut == MyObject::STATUS_DRAFT) ? 1 : 0);
+//$result = restrictedArea($user, 'mymodule', $object->id, '', '', 'fk_soc', 'rowid', $isdraft);
+
+
+/*
+ * Actions
+ *
+ * Put here all code to do according to value of "action" parameter
+ */
+
+$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;
+
+ $permissiontoadd=1;
+ $permissiontodelete=1;
+ if (empty($backtopage)) $backtopage = dol_buildpath('/emailcollector/emailcollector_card.php',1).'?id='.($id > 0 ? $id : '__ID__');
+ $backurlforlist = dol_buildpath('/emailcollector/emailcollector_list.php', 1);
+
+ // Actions cancel, add, update, delete or clone
+ include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
+
+ // Actions when linking object each other
+ include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
+
+ // Actions when printing a doc from card
+ include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
+}
+
+
+
+/*
+ * View
+ *
+ * Put here all code to build page
+ */
+
+$form = new Form($db);
+$formfile = new FormFile($db);
+
+llxHeader('', 'EmailCollector', '');
+
+// Example : Adding jquery code
+print '';
+
+// Part to create
+if ($action == 'create') {
+ print load_fiche_titre($langs->trans("NewEmailCollector", $langs->transnoentitiesnoconv("EmailCollector")));
+
+ print '
';
+ }
+ */
+
+ //Select mail models is same action as presend
+ /*
+ if (GETPOST('modelselected')) $action = 'presend';
+
+ // Presend form
+ $modelmail='inventory';
+ $defaulttopic='InformationMessage';
+ $diroutput = $conf->product->dir_output.'/inventory';
+ $trackid = 'stockinv'.$object->id;
+
+ include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
+ */
+}
+
+// End of page
+llxFooter();
+$db->close();
diff --git a/htdocs/admin/emailcollector_list.php b/htdocs/admin/emailcollector_list.php
new file mode 100644
index 00000000000..6de67299871
--- /dev/null
+++ b/htdocs/admin/emailcollector_list.php
@@ -0,0 +1,551 @@
+
+ *
+ * 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/admin/emailcollector_list.php
+ * \ingroup emailcollector
+ * \brief List page for emailcollector
+ */
+
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php';
+
+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';
+dol_include_once('/emailcollector/class/emailcollector.class.php');
+
+if (!$user->admin) accessforbidden();
+
+// Load traductions files requiredby by page
+$langs->loadLangs(array("admin", "other"));
+
+$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'):'emailcollectorlist'; // 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')
+
+$id = GETPOST('id','int');
+
+// Load variable for pagination
+$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
+$sortfield = GETPOST('sortfield','alpha');
+$sortorder = GETPOST('sortorder','alpha');
+$page = 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;
+//if (! $sortfield) $sortfield="p.date_fin";
+//if (! $sortorder) $sortorder="DESC";
+
+// Initialize technical objects
+$object = new EmailCollector($db);
+$extrafields = new ExtraFields($db);
+$diroutputmassaction = $conf->emailcollector->dir_output . '/temp/massgeneration/' . $user->id;
+$hookmanager->initHooks(array('emailcollectorlist')); // Note that conf->hooks_modules contains array
+// Fetch optionals attributes and labels
+$extralabels = $extrafields->fetch_name_optionals_label('emailcollector');
+$search_array_options = $extrafields->getOptionalsFromPost($extralabels, '', 'search_');
+
+// Default sort order (if not yet defined by previous GETPOST)
+if (! $sortfield) $sortfield="t.".key($object->fields); // Set here default search field. By default 1st field in definition.
+if (! $sortorder) $sortorder="ASC";
+
+// Security check
+$socid=0;
+if ($user->societe_id > 0) // Protection if external user
+{
+ //$socid = $user->societe_id;
+ accessforbidden();
+}
+//$result = restrictedArea($user, 'emailcollector', $id, '');
+
+// Initialize array of search criterias
+$search_all=trim(GETPOST("search_all",'alpha'));
+$search=array();
+foreach($object->fields as $key => $val)
+{
+ if (GETPOST('search_'.$key,'alpha')) $search[$key]=GETPOST('search_'.$key,'alpha');
+}
+
+// List of fields to search into when doing a "search in all"
+$fieldstosearchall = array();
+foreach($object->fields as $key => $val)
+{
+ if ($val['searchall']) $fieldstosearchall['t.'.$key]=$val['label'];
+}
+
+// Definition of fields for list
+$arrayfields=array();
+foreach($object->fields 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 (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');
+
+
+
+/*
+ * Actions
+ *
+ * Put here all code to do according to value of "$action" parameter
+ */
+
+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]='';
+ }
+ $toselect='';
+ $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='EmailCollector';
+ $objectlabel='EmailCollector';
+ $permtoread = $user->rights->emailcollector->read;
+ $permtodelete = $user->rights->emailcollector->delete;
+ $uploaddir = $conf->emailcollector->dir_output;
+ include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
+}
+
+
+
+/*
+ * View
+ *
+ * Put here all code to render page
+ */
+
+$form=new Form($db);
+
+$now=dol_now();
+
+//$help_url="EN:Module_EmailCollector|FR:Module_EmailCollector_FR|ES:Módulo_EmailCollector";
+$help_url='';
+$title = $langs->trans('ListOf', $langs->transnoentitiesnoconv("EmailCollector"));
+
+
+// Build and execute select
+// --------------------------------------------------------------------
+$sql = 'SELECT ';
+foreach($object->fields as $key => $val)
+{
+ $sql.='t.'.$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.' 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.=$hookmanager->resPrint;
+$sql=preg_replace('/, $/','', $sql);
+$sql.= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
+if (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)";
+if ($object->ismultientitymanaged == 1) $sql.= " WHERE t.entity IN (".getEntity($object->element).")";
+else $sql.=" WHERE 1 = 1";
+foreach($search as $key => $val)
+{
+ if ($key == 'status' && $search[$key] == -1) continue;
+ $mode_search=(($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key]))?1:0);
+ if ($search[$key] != '') $sql.=natural_search($key, $search[$key], (($key == 'status')?2:$mode_search));
+}
+if ($search_all) $sql.= natural_search(array_keys($fieldstosearchall), $search_all);
+// 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.'.$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); // Note that $action and $object may have been modified by hook
+ $sql.=$hookmanager->resPrint;
+ $sql=preg_replace('/, $/','', $sql);
+ */
+
+$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_URL_ROOT.'/emailcollector/emailcollector_card.php?id='.$id);
+ exit;
+}
+
+
+// Output page
+// --------------------------------------------------------------------
+
+llxHeader('', $title, $help_url);
+
+// Example : Adding jquery code
+print '';
+
+$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);
+foreach($search as $key => $val)
+{
+ $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';
+
+// List of mass actions available
+$arrayofmassactions = array(
+//'presend'=>$langs->trans("SendByMail"),
+//'builddoc'=>$langs->trans("PDFMerge"),
+);
+if ($user->rights->emailcollector->delete) $arrayofmassactions['predelete']=$langs->trans("Delete");
+if (GETPOST('nomassaction','int') || in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array();
+$massactionbutton=$form->selectMassAction('', $arrayofmassactions);
+
+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=$user->rights->emailcollector->read;
+ $delallowed=$user->rights->emailcollector->create;
+
+ print $formfile->showdocuments('massfilesarea_emailcollector','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,'','','',null,$hidegeneratedfilelistifempty);
+}
+
+// End of page
+llxFooter();
+$db->close();
diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php
index 2e489f6ba65..79d633027e0 100644
--- a/htdocs/core/class/translate.class.php
+++ b/htdocs/core/class/translate.class.php
@@ -577,7 +577,7 @@ class Translate
//$newstr=$this->getLabelFromKey($db,$reg[1],'c_ordersource','code','label');
}
- if (! empty($conf->global->MAIN_FEATURES_LEVEL) && $conf->global->MAIN_FEATURES_LEVEL >= 2) dol_syslog(__METHOD__." missing translation for key '".$newstr."' in ".$_SERVER["PHP_SELF"], LOG_DEBUG);
+ if (! empty($conf->global->MAIN_FEATURES_LEVEL) && $conf->global->MAIN_FEATURES_LEVEL >= 2) dol_syslog(__METHOD__." MAIN_FEATURES_LEVEL=DEVELOP: missing translation for key '".$newstr."' in ".$_SERVER["PHP_SELF"], LOG_DEBUG);
return $newstr;
}
diff --git a/htdocs/core/modules/modEmailCollector.class.php b/htdocs/core/modules/modEmailCollector.class.php
index 6d266fbe6f7..26d78a7fb0e 100644
--- a/htdocs/core/modules/modEmailCollector.class.php
+++ b/htdocs/core/modules/modEmailCollector.class.php
@@ -83,7 +83,7 @@ class modEmailCollector extends DolibarrModules
$this->dirs = array();
// Config pages. Put here list of php page, stored into dav/admin directory, to use to setup module.
- $this->config_page_url = array("emailcollector.php");
+ $this->config_page_url = array("emailcollector_list.php");
// Dependencies
$this->hidden = false; // A condition to hide module
diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php
new file mode 100644
index 00000000000..4a7986e5d8a
--- /dev/null
+++ b/htdocs/emailcollector/class/emailcollector.class.php
@@ -0,0 +1,641 @@
+
+ *
+ * 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 emailcollector/class/emailcollector.class.php
+ * \ingroup emailcollector
+ * \brief This file is a CRUD class file for EmailCollector (Create/Read/Update/Delete)
+ */
+
+// Put here all includes required by your class file
+require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
+//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
+//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
+
+/**
+ * Class for EmailCollector
+ */
+class EmailCollector extends CommonObject
+{
+ /**
+ * @var string ID to identify managed object
+ */
+ public $element = 'emailcollector';
+ /**
+ * @var string Name of table without prefix where object is stored
+ */
+ public $table_element = 'emailcollector_emailcollector';
+ /**
+ * @var int Does emailcollector 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 emailcollector support extrafields ? 0=No, 1=Yes
+ */
+ public $isextrafieldmanaged = 0;
+ /**
+ * @var string String with name of icon for emailcollector. Must be the part after the 'object_' into object_emailcollector.png
+ */
+ public $picto = 'generic';
+
+
+ /**
+ * 'type' if the field format.
+ * '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. Using a negative value means field is not shown by default on list but can be selected for viewing)
+ * '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
+ * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel")
+ */
+
+ // BEGIN MODULEBUILDER PROPERTIES
+ /**
+ * @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','visible'=>2, 'enabled'=>1, 'position'=>1, 'notnull'=>1, 'index'=>1),
+ 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'notnull'=>1, 'index'=>1, 'position'=>20),
+ 'ref' =>array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1),
+ 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'notnull'=>-1, 'searchall'=>1),
+ 'description' => array('type'=>'text', 'label'=>'Description', 'visible'=>-1, 'enabled'=>1, 'position'=>60, 'notnull'=>-1, 'searchall'=>1),
+ 'host' => array('type'=>'varchar(255)', 'label'=>'EMailHost', 'visible'=>1, 'enabled'=>1, 'position'=>100, 'notnull'=>1, 'searchall'=>1, 'comment'=>"IMPA server",),
+ 'user' => array('type'=>'varchar(128)', 'label'=>'User', 'visible'=>1, 'enabled'=>1, 'position'=>101, 'notnull'=>1, 'index'=>1, 'comment'=>"IMAP login",),
+ 'password' => array('type'=>'password', 'label'=>'Password', 'visible'=>-1, 'enabled'=>1, 'position'=>102, 'notnull'=>1, 'comment'=>"IMAP password",),
+ 'source_directory' => array('type'=>'varchar(255)', 'label'=>'MailboxSourceDirectory', 'visible'=>-1, 'enabled'=>1, 'position'=>103, 'notnull'=>-1, 'default' => 'Inbox'),
+ 'filter' => array('type'=>'text', 'label'=>'Filter', 'visible'=>1, 'enabled'=>1, 'position'=>105),
+ 'actiontodo' => array('type'=>'varchar(255)', 'label'=>'ActionToDo', 'visible'=>1, 'enabled'=>1, 'position'=>106),
+ 'target_directory' => array('type'=>'varchar(255)', 'label'=>'MailboxTargetDirectory', 'visible'=>1, 'enabled'=>1, 'position'=>110, 'notnull'=>1, 'comment'=>"Where to store messages once processed"),
+ 'datelastresult' => array('type'=>'datetime', 'label'=>'DateLastResult', 'visible'=>-2, 'enabled'=>1, 'position'=>121, 'notnull'=>-1,),
+ 'lastresult' => array('type'=>'varchar(255)', 'label'=>'LastResult', 'visible'=>1, 'enabled'=>1, 'position'=>122, 'notnull'=>-1,),
+ 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'visible'=>0, 'enabled'=>1, 'position'=>61, 'notnull'=>-1,),
+ 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'visible'=>0, 'enabled'=>1, 'position'=>62, 'notnull'=>-1,),
+ 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'visible'=>-2, 'enabled'=>1, 'position'=>500, 'notnull'=>1,),
+ 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'visible'=>-2, 'enabled'=>1, 'position'=>501, 'notnull'=>1,),
+ //'date_validation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>502),
+ 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'visible'=>-2, 'enabled'=>1, 'position'=>510, 'notnull'=>1,),
+ 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'visible'=>-2, 'enabled'=>1, 'position'=>511, 'notnull'=>-1,),
+ //'fk_user_valid' =>array('type'=>'integer', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>512),
+ 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'visible'=>-2, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1,),
+ 'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Inactive', '1'=>'Active'))
+ );
+
+
+ /**
+ * @var int ID
+ */
+ public $rowid;
+
+ /**
+ * @var string Ref
+ */
+ public $ref;
+
+ /**
+ * @var int Entity
+ */
+ public $entity;
+
+ /**
+ * @var string label
+ */
+ public $label;
+
+ public $amount;
+
+ /**
+ * @var int Status
+ */
+ public $status;
+
+ public $date_creation;
+ public $tms;
+
+ /**
+ * @var int ID
+ */
+ public $fk_user_creat;
+
+ /**
+ * @var int ID
+ */
+ public $fk_user_modif;
+
+ public $import_key;
+
+
+ public $host;
+ public $user;
+ public $password;
+ public $source_directory;
+ public $filter;
+ public $actiontodo;
+ public $target_directory;
+ public $datelastresult;
+ public $lastresult;
+ // END MODULEBUILDER PROPERTIES
+
+
+
+ /**
+ * 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 (empty($conf->multicompany->enabled) && 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 and 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->element);
+ foreach($object->array_options as $key => $option)
+ {
+ $shortkey = preg_replace('/options_/', '', $key);
+ if (! empty($extrafields->attributes[$this->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;
+ }
+
+ // 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 EmailCollectorLine
+
+ return count($this->lines)?1:0;
+ }*/
+
+ /**
+ * Fetch all account and load objects into an array
+ *
+ * @return array Array with key => EmailCollector object
+ * @author
+ */
+ public function fetchAll(User $user, $activeOnly = 0, $sortfield = 's.rowid', $sortorder = 'ASC', $limit = 100, $page = 0)
+ {
+ global $langs;
+
+ $obj_ret = array();
+
+ $socid = $user->societe_id ? $user->societe_id : '';
+
+ // If the internal user must only see his customers, force searching by him
+ if (! $user->rights->societe->client->voir && !$socid) {
+ $search_sale = $user->id;
+ }
+ $sql = "SELECT s.rowid";
+ //if ((!$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
+ // $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
+ //}
+ $sql.= " FROM ".MAIN_DB_PREFIX."emailcollector as s";
+
+ //if ((!$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.= ", ".MAIN_DB_PREFIX."c_stcomm as st";
+ //$sql.= " WHERE s.fk_stcomm = st.id";
+
+ // Example of use $mode
+ //if ($mode == 1) $sql.= " AND s.client IN (1, 3)";
+ //if ($mode == 2) $sql.= " AND s.client IN (2, 3)";
+
+ $sql.= ' WHERE s.entity IN ('.getEntity('emailcollector').')';
+ //if ((!$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
+ // $sql.= " AND s.fk_soc = sc.fk_soc";
+ //}
+ //if ($socid) {
+ // $sql.= " AND s.fk_soc = ".$socid;
+ //}
+ if ($activeOnly) {
+ $sql.= " AND s.status = 1";
+ }
+ $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);
+
+ if ($result) {
+ $num = $this->db->num_rows($result);
+ while ($i < $num) {
+ $obj = $this->db->fetch_object($result);
+ $emailcollector_static = new EmailCollector($this->db);
+ if ($emailcollector_static->fetch($obj->rowid)) {
+ $obj_ret[] = $emailcollector_static;
+ }
+ $i++;
+ }
+ } else {
+ dol_syslog(__METHOD__.':: Error when retrieve emailcollector list', LOG_ERR);
+ $ret = -1;
+ }
+ if (! count($obj_ret)) {
+ dol_syslog(__METHOD__.':: No emailcollector found', LOG_DEBUG);
+ }
+
+ return $obj_ret;
+ }
+
+ /**
+ * 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 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
+ */
+ function getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
+ {
+ global $db, $conf, $langs, $hookmanager;
+ global $dolibarr_main_authentication, $dolibarr_main_demo;
+ global $menumanager;
+
+ if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips
+
+ $result = '';
+ $companylink = '';
+
+ $label = '' . $langs->trans("EmailCollector") . '';
+ $label.= ' ';
+ $label.= '' . $langs->trans('Ref') . ': ' . $this->ref;
+
+ $url = dol_buildpath('/admin/emailcollector_card.php', 1).'?id='.$this->id;
+
+ if ($option != 'nolink')
+ {
+ // Add param to save lastsearch_values or not
+ $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
+ if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
+ $add_save_lastsearch_values=1;
+ }
+ if ($add_save_lastsearch_values) {
+ $url.='&save_lastsearch_values=1';
+ }
+ }
+
+ $linkclose='';
+ if (empty($notooltip))
+ {
+ if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
+ {
+ $label=$langs->trans("ShowEmailCollector");
+ $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
+ }
+ $linkclose.=' title="'.dol_escape_htmltag($label, 1).'"';
+ $linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"';
+
+ /*
+ $hookmanager->initHooks(array('myobjectdao'));
+ $parameters=array('id'=>$this->id);
+ $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
+ if ($reshook > 0) $linkclose = $hookmanager->resPrint;
+ */
+ }
+ 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)) : '');
+
+ global $action,$hookmanager;
+ $hookmanager->initHooks(array('emailcollectordao'));
+ $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 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.NotCamelCaps
+ /**
+ * 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))
+ {
+ global $langs;
+ //$langs->load("mymodule");
+ $this->labelstatus[1] = $langs->trans('Enabled');
+ $this->labelstatus[0] = $langs->trans('Disabled');
+ }
+
+ if ($mode == 0)
+ {
+ return $this->labelstatus[$status];
+ }
+ elseif ($mode == 1)
+ {
+ return $this->labelstatus[$status];
+ }
+ elseif ($mode == 2)
+ {
+ if ($status == 1) return img_picto($this->labelstatus[$status],'statut4').' '.$this->labelstatus[$status];
+ elseif ($status == 0) return img_picto($this->labelstatus[$status],'statut5').' '.$this->labelstatus[$status];
+ }
+ elseif ($mode == 3)
+ {
+ if ($status == 1) return img_picto($this->labelstatus[$status],'statut4');
+ elseif ($status == 0) return img_picto($this->labelstatus[$status],'statut5');
+ }
+ elseif ($mode == 4)
+ {
+ if ($status == 1) return img_picto($this->labelstatus[$status],'statut4').' '.$this->labelstatus[$status];
+ elseif ($status == 0) return img_picto($this->labelstatus[$status],'statut5').' '.$this->labelstatus[$status];
+ }
+ elseif ($mode == 5)
+ {
+ if ($status == 1) return $this->labelstatus[$status].' '.img_picto($this->labelstatus[$status],'statut4');
+ elseif ($status == 0) return $this->labelstatus[$status].' '.img_picto($this->labelstatus[$status],'statut5');
+ }
+ elseif ($mode == 6)
+ {
+ if ($status == 1) return $this->labelstatus[$status].' '.img_picto($this->labelstatus[$status],'statut4');
+ elseif ($status == 0) return $this->labelstatus[$status].' '.img_picto($this->labelstatus[$status],'statut5');
+ }
+ }
+
+ /**
+ * Charge les informations d'ordre info dans l'objet commande
+ *
+ * @param int $id Id of order
+ * @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 = '.$id;
+ $result=$this->db->query($sql);
+ if ($result)
+ {
+ if ($this->db->num_rows($result))
+ {
+ $obj = $this->db->fetch_object($result);
+ $this->id = $obj->rowid;
+ if ($obj->fk_user_author)
+ {
+ $cuser = new User($this->db);
+ $cuser->fetch($obj->fk_user_author);
+ $this->user_creation = $cuser;
+ }
+
+ if ($obj->fk_user_valid)
+ {
+ $vuser = new User($this->db);
+ $vuser->fetch($obj->fk_user_valid);
+ $this->user_validation = $vuser;
+ }
+
+ if ($obj->fk_user_cloture)
+ {
+ $cluser = new User($this->db);
+ $cluser->fetch($obj->fk_user_cloture);
+ $this->user_cloture = $cluser;
+ }
+
+ $this->date_creation = $this->db->jdate($obj->datec);
+ $this->date_modification = $this->db->jdate($obj->datem);
+ $this->date_validation = $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()
+ {
+ $this->initAsSpecimenCommon();
+ }
+
+
+ /**
+ * Action executed by scheduler
+ * CAN BE A CRON TASK. In such a case, paramerts 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($param1, $param2, ...)
+ 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;
+ }
+}
diff --git a/htdocs/emailcollector/lib/emailcollector.lib.php b/htdocs/emailcollector/lib/emailcollector.lib.php
new file mode 100644
index 00000000000..e7cc3bcb3a0
--- /dev/null
+++ b/htdocs/emailcollector/lib/emailcollector.lib.php
@@ -0,0 +1,85 @@
+.
+ */
+
+/**
+ * \file emailcollector/lib/emailcollector.lib.php
+ * \ingroup emailcollector
+ * \brief Library files with common functions for EmailCollector
+ */
+
+
+/**
+ * Prepare array of tabs for EmailCollector
+ *
+ * @param EmailCollector $object EmailCollector
+ * @return array Array of tabs
+ */
+function emailcollectorPrepareHead($object)
+{
+ global $db, $langs, $conf;
+
+ $langs->load("emailcollector@emailcollector");
+
+ $h = 0;
+ $head = array();
+
+ $head[$h][0] = dol_buildpath("/admin/emailcollector_card.php", 1).'?id='.$object->id;
+ $head[$h][1] = $langs->trans("Card");
+ $head[$h][2] = 'card';
+ $h++;
+
+ /*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('/emailcollector/emailcollector_note.php', 1).'?id='.$object->id;
+ $head[$h][1] = $langs->trans('Notes');
+ if ($nbNote > 0) $head[$h][1].= ' '.$nbNote.'';
+ $head[$h][2] = 'note';
+ $h++;
+ }*/
+
+ /*require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+ require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
+ $upload_dir = $conf->emailcollector->dir_output . "/emailcollector/" . 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("/emailcollector/emailcollector_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++;
+
+ $head[$h][0] = dol_buildpath("/emailcollector/emailcollector_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:@emailcollector:/emailcollector/mypage.php?id=__ID__'
+ //); // to add new tab
+ //$this->tabs = array(
+ // 'entity:-tabname:Title:@emailcollector:/emailcollector/mypage.php?id=__ID__'
+ //); // to remove a tab
+ complete_head_from_modules($conf, $langs, $object, $head, $h, 'emailcollector');
+
+ return $head;
+}
diff --git a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
index a7efecbdc5f..5abc1772eef 100644
--- a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
+++ b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
@@ -137,3 +137,46 @@ CREATE TABLE llx_takepos_floor_tables(
UPDATE llx_c_payment_term SET decalage = nbjour, nbjour = 0 where decalage IS NULL AND type_cdr = 2;
UPDATE llx_holiday SET ref = rowid WHERE ref IS NULL;
+
+
+
+CREATE TABLE llx_emailcollector_emailcollector(
+ -- BEGIN MODULEBUILDER FIELDS
+ rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
+ entity integer DEFAULT 1 NOT NULL,
+ ref varchar(128) NOT NULL,
+ label varchar(255),
+ description text,
+ host varchar(255),
+ user varchar(128),
+ password varchar(128),
+ source_directory varchar(255),
+ filter text,
+ actiontodos varchar(255),
+ target_directory varchar(255),
+ datelastresult datetime,
+ lastresult varchar(255),
+ note_public text,
+ note_private text,
+ date_creation datetime NOT NULL,
+ tms timestamp NOT NULL,
+ fk_user_creat integer NOT NULL,
+ fk_user_modif integer,
+ import_key varchar(14),
+ status integer NOT NULL,
+ -- END MODULEBUILDER FIELDS
+) ENGINE=innodb;
+
+-- BEGIN MODULEBUILDER INDEXES
+ALTER TABLE llx_emailcollector_emailcollector ADD INDEX idx_emailcollector_rowid (rowid);
+ALTER TABLE llx_emailcollector_emailcollector ADD INDEX idx_emailcollector_entity (entity);
+ALTER TABLE llx_emailcollector_emailcollector ADD INDEX idx_emailcollector_status (status);
+-- END MODULEBUILDER INDEXES
+
+--ALTER TABLE llx_emailcollector_emailcollector ADD UNIQUE INDEX uk_emailcollector_emailcollector_fieldxyz(fieldx, fieldy);
+
+--ALTER TABLE llx_emailcollector_emailcollector ADD CONSTRAINT llx_emailcollector_emailcollector_field_id FOREIGN KEY (fk_field) REFERENCES llx_myotherobject(rowid);
+
+
+
+
diff --git a/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.key.sql b/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.key.sql
new file mode 100644
index 00000000000..e2447c206f5
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.key.sql
@@ -0,0 +1,26 @@
+-- Copyright (C) 2018 Laurent Destailleur
+--
+-- 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 http://www.gnu.org/licenses/.
+
+
+-- BEGIN MODULEBUILDER INDEXES
+ALTER TABLE llx_emailcollector_emailcollector ADD INDEX idx_emailcollector_rowid (rowid);
+ALTER TABLE llx_emailcollector_emailcollector ADD INDEX idx_emailcollector_entity (entity);
+ALTER TABLE llx_emailcollector_emailcollector ADD INDEX idx_emailcollector_status (status);
+-- END MODULEBUILDER INDEXES
+
+--ALTER TABLE llx_emailcollector_emailcollector ADD UNIQUE INDEX uk_emailcollector_emailcollector_fieldxyz(fieldx, fieldy);
+
+--ALTER TABLE llx_emailcollector_emailcollector ADD CONSTRAINT llx_emailcollector_emailcollector_field_id FOREIGN KEY (fk_field) REFERENCES llx_myotherobject(rowid);
+
diff --git a/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.sql b/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.sql
new file mode 100644
index 00000000000..98426cd85a7
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.sql
@@ -0,0 +1,42 @@
+-- Copyright (C) 2018 Laurent Destailleur
+--
+-- 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 http://www.gnu.org/licenses/.
+
+
+CREATE TABLE llx_emailcollector_emailcollector(
+ -- BEGIN MODULEBUILDER FIELDS
+ rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
+ entity integer DEFAULT 1 NOT NULL,
+ ref varchar(128) NOT NULL,
+ label varchar(255),
+ description text,
+ host varchar(255),
+ user varchar(128),
+ password varchar(128),
+ source_directory varchar(255),
+ filter text,
+ actiontodo varchar(255),
+ target_directory varchar(255),
+ datelastresult datetime,
+ lastresult varchar(255),
+ note_public text,
+ note_private text,
+ date_creation datetime NOT NULL,
+ tms timestamp NOT NULL,
+ fk_user_creat integer NOT NULL,
+ fk_user_modif integer,
+ import_key varchar(14),
+ status integer NOT NULL,
+ -- END MODULEBUILDER FIELDS
+) ENGINE=innodb;
diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php
index 706b90f6eac..71446c53211 100644
--- a/htdocs/modulebuilder/template/class/myobject.class.php
+++ b/htdocs/modulebuilder/template/class/myobject.class.php
@@ -98,7 +98,7 @@ class MyObject extends CommonObject
'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')),
+ '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')),
);
/**
@@ -198,8 +198,17 @@ class MyObject extends CommonObject
}
}
- // Translate some data
- $this->fields['status']['arrayofkeyval']=array(0=>$langs->trans('Draft'), 1=>$langs->trans('Active'), -1=>$langs->trans('Cancel'));
+ // 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);
+ }
+ }
+ }
}
/**
diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php
index 81715228033..2fd970a33a4 100644
--- a/htdocs/modulebuilder/template/myobject_card.php
+++ b/htdocs/modulebuilder/template/myobject_card.php
@@ -347,7 +347,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
print '';
print '';
print '';
- print '';
print ' ';
diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php
index ece26aba6cb..beb03c183a6 100644
--- a/htdocs/modulebuilder/template/myobject_list.php
+++ b/htdocs/modulebuilder/template/myobject_list.php
@@ -292,7 +292,7 @@ if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) &&
{
$obj = $db->fetch_object($resql);
$id = $obj->rowid;
- header("Location: ".DOL_URL_ROOT.'/mymodule/myobject_card.php?id='.$id);
+ header("Location: ".dol_buildpath('/mymodule/myobject_card.php', 1).'?id='.$id);
exit;
}
@@ -352,7 +352,7 @@ print '';
$newcardbutton='';
//if ($user->rights->mymodule->creer)
//{
- $newcardbutton=''.$langs->trans('New').'';
+ $newcardbutton=''.$langs->trans('New').'';
$newcardbutton.= '';
$newcardbutton.= '';
//}