diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php
index 8334dfb9fa0..797b35f7c75 100644
--- a/htdocs/admin/dict.php
+++ b/htdocs/admin/dict.php
@@ -1070,7 +1070,7 @@ if ($id)
}
print '';
print "";
-
+
if ($tabname[$id] == MAIN_DB_PREFIX.'c_email_templates')
{
print '
* '.$langs->trans("AvailableVariables").": ";
diff --git a/htdocs/comm/mailing/advtargetemailing.php b/htdocs/comm/mailing/advtargetemailing.php
new file mode 100644
index 00000000000..4076217cf88
--- /dev/null
+++ b/htdocs/comm/mailing/advtargetemailing.php
@@ -0,0 +1,1121 @@
+
+*
+*
+* 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 .
+*/
+require '../../main.inc.php';
+
+require_once DOL_DOCUMENT_ROOT . '/comm/mailing/class/mailing.class.php';
+require_once DOL_DOCUMENT_ROOT . '/core/lib/emailing.lib.php';
+require_once DOL_DOCUMENT_ROOT . '/comm/mailing/class/advtargetemailing.class.php';
+require_once DOL_DOCUMENT_ROOT . '/comm/mailing/class/html.formadvtargetemailing.class.php';
+require_once DOL_DOCUMENT_ROOT . '/core/modules/mailings/advthirdparties.modules.php';
+require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php';
+require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
+
+// Translations
+$langs->load("mails");
+$langs->load("companies");
+if (! empty($conf->categorie->enabled)) {
+ $langs->load("categories");
+}
+
+// Security check
+if (! $user->rights->mailing->lire || $user->societe_id > 0)
+ accessforbidden();
+
+$sortfield = GETPOST("sortfield", 'alpha');
+$sortorder = GETPOST("sortorder", 'alpha');
+$page = GETPOST("page", 'int');
+if ($page == - 1) {
+ $page = 0;
+}
+$offset = $conf->liste_limit * $page;
+$pageprev = $page - 1;
+$pagenext = $page + 1;
+if (! $sortorder)
+ $sortorder = "ASC";
+if (! $sortfield)
+ $sortfield = "email";
+
+$id = GETPOST('id', 'int');
+$rowid = GETPOST('rowid', 'int');
+$action = GETPOST("action");
+$search_nom = GETPOST("search_nom");
+$search_prenom = GETPOST("search_prenom");
+$search_email = GETPOST("search_email");
+$template_id = GETPOST('template_id', 'int');
+
+// Do we click on purge search criteria ?
+if (GETPOST("button_removefilter_x")) {
+ $search_nom = '';
+ $search_prenom = '';
+ $search_email = '';
+}
+
+$array_query = array ();
+
+$object = new Mailing($db);
+$advTarget = new AdvanceTargetingMailing($db);
+if (empty($template_id)) {
+ $advTarget->fk_mailing = $id;
+ $result = $advTarget->fetch_by_mailing();
+} else {
+ $result = $advTarget->fetch($template_id);
+}
+
+if ($result < 0) {
+ setEventMessage($advTarget->error, 'errors');
+} else {
+ if (! empty($advTarget->id)) {
+ $array_query = json_decode($advTarget->filtervalue, true);
+ }
+}
+
+/*
+ * Action
+ */
+
+if ($action == 'loadfilter') {
+ if (! empty($template_id)) {
+ $result = $advTarget->fetch($template_id);
+ if ($result < 0) {
+ setEventMessage($advTarget->error, 'errors');
+ } else {
+ if (! empty($advTarget->id)) {
+ $array_query = json_decode($advTarget->filtervalue, true);
+ }
+ }
+ }
+}
+
+if ($action == 'add') {
+
+ $user_contact_query = false;
+
+ $array_query = array ();
+
+ // Get extra fields
+
+ foreach ( $_POST as $key => $value ) {
+ // print '$key='.$key.' $value='.$value.' ';
+ if (preg_match("/^options_.*(?query_thirdparty($array_query);
+ if ($result < 0) {
+ setEventMessage($advTarget->error, 'errors');
+ }
+ /*} else {
+ $advTarget->thirdparty_lines = array ();
+ }*/
+
+ if ($user_contact_query && ($array_query['type_of_target'] == 1 || $array_query['type_of_target'] == 2)) {
+ $result = $advTarget->query_contact($array_query);
+ if ($result < 0) {
+ setEventMessage($advTarget->error, 'errors');
+ }
+ // If use contact but no result use artefact to so not use socid into add_to_target
+ if (count($advTarget->contact_lines) == 0) {
+ $advTarget->contact_lines = array (
+ 0
+ );
+ }
+ } else {
+ $advTarget->contact_lines = array ();
+ }
+
+ if ((count($advTarget->thirdparty_lines) > 0) || (count($advTarget->contact_lines) > 0)) {
+ // Add targets into database
+ $obj = new mailing_advthirdparties($db);
+ $result = $obj->add_to_target($id, $advTarget->thirdparty_lines, $array_query['type_of_target'], $advTarget->contact_lines);
+ } else {
+ $result = 0;
+ }
+
+ if ($result > 0) {
+ $query_temlate_id = '';
+ if (! empty($template_id)) {
+ $query_temlate_id = '&template_id=' . $template_id;
+ }
+ header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id . $query_temlate_id);
+ exit();
+ }
+ if ($result == 0) {
+ setEventMessage($langs->trans("WarningNoEMailsAdded"), 'warnings');
+ }
+ if ($result < 0) {
+ setEventMessage($obj->error, 'errors');
+ }
+}
+
+if ($action == 'clear') {
+ // Chargement de la classe
+ $classname = "MailingTargets";
+ $obj = new $classname($db);
+ $obj->clear_target($id);
+
+ header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
+ exit();
+}
+
+if ($action == 'savefilter' || $action == 'createfilter') {
+
+ $template_name = GETPOST('template_name');
+ $error = 0;
+
+ if ($action == 'createfilter' && empty($template_name)) {
+ setEventMessage($langs->trans('ErrorFieldRequired', $langs->trans('AdvTgtOrCreateNewFilter')), 'errors');
+ $error ++;
+ }
+
+ if (empty($error)) {
+
+ $array_query = array ();
+
+ // Get extra fields
+ foreach ( $_POST as $key => $value ) {
+ if (preg_match("/^options_.*(?filtervalue = json_encode($array_query);
+
+ if ($action == 'createfilter') {
+ $advTarget->name = $template_name;
+ $result = $advTarget->create($user);
+ if ($result < 0) {
+ setEventMessage($advTarget->error, 'errors');
+ }
+ } elseif ($action == 'savefilter') {
+ $result = $advTarget->update($user);
+ if ($result < 0) {
+ setEventMessage($advTarget->error, 'errors');
+ }
+ }
+ $template_id = $advTarget->id;
+ }
+}
+
+if ($action == 'deletefilter') {
+ $result = $advTarget->delete($user);
+ if ($result < 0) {
+ setEventMessage($advTarget->error, 'errors');
+ }
+ header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
+ exit();
+}
+
+if ($action == 'delete') {
+ // Ici, rowid indique le destinataire et id le mailing
+ $sql = "DELETE FROM " . MAIN_DB_PREFIX . "mailing_cibles WHERE rowid=" . $rowid;
+ $resql = $db->query($sql);
+ if ($resql) {
+ if (! empty($id)) {
+ $classname = "MailingTargets";
+ $obj = new $classname($db);
+ $obj->update_nb($id);
+
+ header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
+ exit();
+ } else {
+ header("Location: liste.php");
+ exit();
+ }
+ } else {
+ dol_print_error($db);
+ }
+}
+
+if ($_POST["button_removefilter"]) {
+ $search_nom = '';
+ $search_prenom = '';
+ $search_email = '';
+}
+
+/*
+ * View
+ */
+$extrajs = array (
+ '/includes/multiselect/js/ui.multiselect.js'
+);
+$extracss = array (
+ '/includes/multiselect/css/ui.multiselect.css',
+ '/advtargetemailing/css/advtargetemailing.css'
+);
+
+llxHeader('', $langs->trans("MailAdvTargetRecipients"), '', '', '', '', $extrajs, $extracss);
+
+print '';
+
+$form = new Form($db);
+$formadvtargetemaling = new FormAdvTargetEmailing($db);
+$formcompany = new FormCompany($db);
+$formother = new FormOther($db);
+
+if ($object->fetch($id) >= 0) {
+
+ $head = emailing_prepare_head($object);
+
+ dol_fiche_head($head, 'advtargets', $langs->trans("Mailing"), 0, 'email');
+
+ print '';
+
+ $linkback = '' . $langs->trans("BackToList") . ' ';
+
+ print '' . $langs->trans("Ref") . ' ';
+ print '';
+ print $form->showrefnav($object, 'id', $linkback);
+ print ' ';
+
+ print '' . $langs->trans("MailTitle") . ' ' . $object->titre . ' ';
+
+ print '' . $langs->trans("MailFrom") . ' ' . dol_print_email($object->email_from, 0, 0, 0, 0, 1) . ' ';
+
+ // Errors to
+ print '' . $langs->trans("MailErrorsTo") . ' ' . dol_print_email($object->email_errorsto, 0, 0, 0, 0, 1);
+ print ' ';
+
+ // Status
+ print '' . $langs->trans("Status") . ' ' . $object->getLibStatut(4) . ' ';
+
+ // Nb of distinct emails
+ print '';
+ print $langs->trans("TotalNbOfDistinctRecipients");
+ print ' ';
+ $nbemail = ($object->nbemail ? $object->nbemail : '0');
+ if (! empty($conf->global->MAILING_LIMIT_SENDBYWEB) && $conf->global->MAILING_LIMIT_SENDBYWEB < $nbemail) {
+ $text = $langs->trans('LimitSendingEmailing', $conf->global->MAILING_LIMIT_SENDBYWEB);
+ print $form->textwithpicto($nbemail, $text, 1, 'warning');
+ } else {
+ print $nbemail;
+ }
+ print ' ';
+
+ print '
';
+
+ print "";
+
+ // Show email selectors
+ if ($object->statut == 0 && $user->rights->mailing->creer) {
+ print_fiche_titre($langs->trans("AdvTgtTitle"));
+
+ print '' . "\n";
+ print '
' . "\n";
+ print '
' . "\n";
+
+ print '';
+ print ' ';
+ }
+ if (empty($conf->mailchimp->enabled) || (! empty($conf->mailchimp->enabled) && $object->statut != 3)) {
+ // List of selected targets
+ print "\n\n";
+ print '';
+ }
+}
+
+llxFooter();
+$db->close();
\ No newline at end of file
diff --git a/htdocs/comm/mailing/class/advtargetemailing.class.php b/htdocs/comm/mailing/class/advtargetemailing.class.php
new file mode 100644
index 00000000000..599173a1869
--- /dev/null
+++ b/htdocs/comm/mailing/class/advtargetemailing.class.php
@@ -0,0 +1,778 @@
+
+*
+* 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 class/advtargetemailing.class.php
+ * \ingroup advtargetemailing
+ * \brief This file is an example CRUD class file (Create/Read/Update/Delete)
+
+ */
+
+
+/**
+ * Put your class' description here
+ */
+class AdvanceTargetingMailing extends CommonObject
+{
+
+ var $db; //!< To store db handler
+ var $error; //!< To return error code (or message)
+ var $errors = array(); //!< To return several error codes (or messages)
+ var $element='advtargetemailing'; //!< Id that identify managed objects
+ var $table_element='advtargetemailing'; //!< Name of table without prefix where object is stored
+
+ var $id;
+
+ var $name;
+ var $entity;
+ var $fk_mailing;
+ var $filtervalue;
+ var $fk_user_author;
+ var $datec='';
+ var $fk_user_mod;
+ var $tms='';
+
+ var $select_target_type = array();
+ var $type_statuscommprospect=array();
+ var $thirdparty_lines;
+ var $contact_lines;
+
+
+ /**
+ * Constructor
+ *
+ * @param DoliDb $db Database handler
+ */
+ function __construct($db)
+ {
+ global $langs;
+ $langs->load('customers');
+
+ $this->db = $db;
+
+ $this->select_target_type = array('2'=>$langs->trans('Contacts'),'1'=>$langs->trans('Contacts').'+'.$langs->trans('ThirdParty'),
+ '3'=>$langs->trans('ThirdParty'),
+ );
+ $this->type_statuscommprospect=array(
+ -1=>$langs->trans("StatusProspect-1"),
+ 0=>$langs->trans("StatusProspect0"),
+ 1=>$langs->trans("StatusProspect1"),
+ 2=>$langs->trans("StatusProspect2"),
+ 3=>$langs->trans("StatusProspect3"));
+
+
+ return 1;
+ }
+
+ /**
+ * Create object into database
+ *
+ * @param User $user User that creates
+ * @param int $notrigger 0=launch triggers after, 1=disable triggers
+ * @return int <0 if KO, Id of created object if OK
+ */
+ function create($user, $notrigger=0)
+ {
+ global $conf, $langs;
+ $error=0;
+
+ // Clean parameters
+ if (isset($this->fk_mailing)) $this->fk_mailing=trim($this->fk_mailing);
+ if (isset($this->name)) $this->name=trim($this->name);
+ if (isset($this->filtervalue)) $this->filtervalue=trim($this->filtervalue);
+ if (isset($this->fk_user_author)) $this->fk_user_author=trim($this->fk_user_author);
+ if (isset($this->fk_user_mod)) $this->fk_user_mod=trim($this->fk_user_mod);
+
+
+
+ // Check parameters
+ // Put here code to add control on parameters values
+
+ // Insert request
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."advtargetemailing(";
+
+ $sql.= "name,";
+ $sql.= "entity,";
+ $sql.= "fk_mailing,";
+ $sql.= "filtervalue,";
+ $sql.= "fk_user_author,";
+ $sql.= "datec,";
+ $sql.= "fk_user_mod";
+
+
+ $sql.= ") VALUES (";
+
+ $sql.= " ".(! isset($this->name)?'NULL':"'".$this->db->escape($this->name)."'").",";
+ $sql.= " ".$conf->entity.",";
+ $sql.= " ".(! isset($this->fk_mailing)?'NULL':"'".$this->fk_mailing."'").",";
+ $sql.= " ".(! isset($this->filtervalue)?'NULL':"'".$this->db->escape($this->filtervalue)."'").",";
+ $sql.= " ".$user->id.",";
+ $sql.= " ".$this->db->idate(dol_now()).",";
+ $sql.= " ".$user->id;
+
+
+ $sql.= ")";
+
+ $this->db->begin();
+
+ dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG);
+ $resql=$this->db->query($sql);
+ if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
+
+ if (! $error)
+ {
+ $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."advtargetemailing");
+
+ if (! $notrigger)
+ {
+ // Uncomment this and change MYOBJECT to your own tag if you
+ // want this action calls a trigger.
+
+ //// Call triggers
+ //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+ //$interface=new Interfaces($this->db);
+ //$result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf);
+ //if ($result < 0) { $error++; $this->errors=$interface->errors; }
+ //// End call triggers
+ }
+ }
+
+ // Commit or rollback
+ if ($error)
+ {
+ foreach($this->errors as $errmsg)
+ {
+ dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
+ $this->error.=($this->error?', '.$errmsg:$errmsg);
+ }
+ $this->db->rollback();
+ return -1*$error;
+ }
+ else
+ {
+ $this->db->commit();
+ return $this->id;
+ }
+ }
+
+ /**
+ * Load object in memory from the database
+ *
+ * @param int $id Id object
+ * @return int <0 if KO, >0 if OK
+ */
+ function fetch($id)
+ {
+ global $langs;
+ $sql = "SELECT";
+ $sql.= " t.rowid,";
+
+ $sql.= " t.name,";
+ $sql.= " t.entity,";
+ $sql.= " t.fk_mailing,";
+ $sql.= " t.filtervalue,";
+ $sql.= " t.fk_user_author,";
+ $sql.= " t.datec,";
+ $sql.= " t.fk_user_mod,";
+ $sql.= " t.tms";
+
+ $sql.= " FROM ".MAIN_DB_PREFIX."advtargetemailing as t";
+ $sql.= " WHERE t.rowid = ".$id;
+
+ dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG);
+ $resql=$this->db->query($sql);
+ if ($resql)
+ {
+ if ($this->db->num_rows($resql))
+ {
+ $obj = $this->db->fetch_object($resql);
+
+ $this->id = $obj->rowid;
+
+ $this->name = $obj->name;
+ $this->entity = $obj->entity;
+ $this->fk_mailing = $obj->fk_mailing;
+ $this->filtervalue = $obj->filtervalue;
+ $this->fk_user_author = $obj->fk_user_author;
+ $this->datec = $this->db->jdate($obj->datec);
+ $this->fk_user_mod = $obj->fk_user_mod;
+ $this->tms = $this->db->jdate($obj->tms);
+
+ }
+ $this->db->free($resql);
+
+ return 1;
+ }
+ else
+ {
+ $this->error="Error ".$this->db->lasterror();
+ dol_syslog(get_class($this)."::fetch ".$this->error, LOG_ERR);
+ return -1;
+ }
+ }
+
+ /**
+ * Load object in memory from the database
+ *
+ * @param int $id Id object
+ * @return int <0 if KO, >0 if OK
+ */
+ function fetch_by_mailing($id=0)
+ {
+ global $langs;
+ $sql = "SELECT";
+ $sql.= " t.rowid,";
+
+ $sql.= " t.name,";
+ $sql.= " t.entity,";
+ $sql.= " t.fk_mailing,";
+ $sql.= " t.filtervalue,";
+ $sql.= " t.fk_user_author,";
+ $sql.= " t.datec,";
+ $sql.= " t.fk_user_mod,";
+ $sql.= " t.tms";
+
+ $sql.= " FROM ".MAIN_DB_PREFIX."advtargetemailing as t";
+ if (!empty($id)) {
+ $sql.= " WHERE t.fk_mailing = ".$id;
+ }else {
+ $sql.= " WHERE t.fk_mailing = ".$this->fk_mailing;
+ }
+
+ dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG);
+ $resql=$this->db->query($sql);
+ if ($resql)
+ {
+ if ($this->db->num_rows($resql))
+ {
+ $obj = $this->db->fetch_object($resql);
+
+ $this->id = $obj->rowid;
+
+ $this->name = $obj->name;
+ $this->entity = $obj->entity;
+ $this->fk_mailing = $obj->fk_mailing;
+ $this->filtervalue = $obj->filtervalue;
+ $this->fk_user_author = $obj->fk_user_author;
+ $this->datec = $this->db->jdate($obj->datec);
+ $this->fk_user_mod = $obj->fk_user_mod;
+ $this->tms = $this->db->jdate($obj->tms);
+
+ }
+ $this->db->free($resql);
+
+ return 1;
+ }
+ else
+ {
+ $this->error="Error ".$this->db->lasterror();
+ dol_syslog(get_class($this)."::fetch ".$this->error, LOG_ERR);
+ return -1;
+ }
+ }
+
+ /**
+ * Update object into database
+ *
+ * @param User $user User that modifies
+ * @param int $notrigger 0=launch triggers after, 1=disable triggers
+ * @return int <0 if KO, >0 if OK
+ */
+ function update($user=0, $notrigger=0)
+ {
+ global $conf, $langs;
+ $error=0;
+
+ // Clean parameters
+ if (isset($this->fk_mailing)) $this->fk_mailing=trim($this->fk_mailing);
+ if (isset($this->name)) $this->name=trim($this->name);
+ if (isset($this->filtervalue)) $this->filtervalue=trim($this->filtervalue);
+ if (isset($this->fk_user_author)) $this->fk_user_author=trim($this->fk_user_author);
+ if (isset($this->fk_user_mod)) $this->fk_user_mod=trim($this->fk_user_mod);
+
+
+
+ // Check parameters
+ // Put here code to add a control on parameters values
+
+ // Update request
+ $sql = "UPDATE ".MAIN_DB_PREFIX."advtargetemailing SET";
+
+ $sql.= " name=".(isset($this->name)?"'".$this->db->escape($this->name)."'":"''").",";
+ $sql.= " entity=".$conf->entity.",";
+ $sql.= " fk_mailing=".(isset($this->fk_mailing)?$this->fk_mailing:"null").",";
+ $sql.= " filtervalue=".(isset($this->filtervalue)?"'".$this->db->escape($this->filtervalue)."'":"null").",";
+ $sql.= " fk_user_mod=".$user->id;
+
+ $sql.= " WHERE rowid=".$this->id;
+
+ $this->db->begin();
+
+ dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG);
+ $resql = $this->db->query($sql);
+ if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
+
+ if (! $error)
+ {
+ if (! $notrigger)
+ {
+ // Uncomment this and change MYOBJECT to your own tag if you
+ // want this action calls a trigger.
+
+ //// Call triggers
+ //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+ //$interface=new Interfaces($this->db);
+ //$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf);
+ //if ($result < 0) { $error++; $this->errors=$interface->errors; }
+ //// End call triggers
+ }
+ }
+
+ // Commit or rollback
+ if ($error)
+ {
+ foreach($this->errors as $errmsg)
+ {
+ dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
+ $this->error.=($this->error?', '.$errmsg:$errmsg);
+ }
+ $this->db->rollback();
+ return -1*$error;
+ }
+ else
+ {
+ $this->db->commit();
+ return 1;
+ }
+ }
+
+ /**
+ * Delete object in database
+ *
+ * @param User $user User that deletes
+ * @param int $notrigger 0=launch triggers after, 1=disable triggers
+ * @return int <0 if KO, >0 if OK
+ */
+ function delete($user, $notrigger=0)
+ {
+ global $conf, $langs;
+ $error=0;
+
+ $this->db->begin();
+
+ if (! $error)
+ {
+ if (! $notrigger)
+ {
+ // Uncomment this and change MYOBJECT to your own tag if you
+ // want this action calls a trigger.
+
+ //// Call triggers
+ //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
+ //$interface=new Interfaces($this->db);
+ //$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf);
+ //if ($result < 0) { $error++; $this->errors=$interface->errors; }
+ //// End call triggers
+ }
+ }
+
+ if (! $error)
+ {
+ $sql = "DELETE FROM ".MAIN_DB_PREFIX."advtargetemailing";
+ $sql.= " WHERE rowid=".$this->id;
+
+ dol_syslog(get_class($this)."::delete sql=".$sql);
+ $resql = $this->db->query($sql);
+ if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
+ }
+
+ // Commit or rollback
+ if ($error)
+ {
+ foreach($this->errors as $errmsg)
+ {
+ dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
+ $this->error.=($this->error?', '.$errmsg:$errmsg);
+ }
+ $this->db->rollback();
+ return -1*$error;
+ }
+ else
+ {
+ $this->db->commit();
+ return 1;
+ }
+ }
+
+
+ /**
+ * Save query in database to retreive it
+ *
+ * @param User $user User that deletes
+ * @param array $arrayquery All element to Query
+ * @return int <0 if KO, >0 if OK
+ */
+ function savequery($user,$arrayquery)
+ {
+ global $langs,$conf;
+
+ if (!empty($arrayquery)) {
+ $result=$this->fetch_by_mailing($this->fk_mailing);
+ $this->filtervalue=json_encode($arrayquery);
+ if ($result<0) {
+ return -1;
+ }
+ if (!empty($this->id)) {
+ $this->update($user);
+ }else {
+ $this->create($user);
+ }
+ }
+ }
+
+
+
+ /**
+ * Load object in memory from database
+ *
+ * @param array $arrayquery All element to Query
+ * @return int <0 if KO, >0 if OK
+ */
+ function query_thirdparty($arrayquery)
+ {
+ global $langs,$conf;
+
+ $sql = "SELECT";
+ $sql.= " t.rowid";
+ $sql.= " FROM " . MAIN_DB_PREFIX . "societe as t";
+ $sql.= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "societe_extrafields as te ON te.fk_object=t.rowid ";
+
+ $sqlwhere=array();
+
+ $sqlwhere[]= 't.entity IN ('.getEntity('societe',1).')';
+
+ if (count($arrayquery)>0) {
+
+ if (array_key_exists('cust_saleman', $arrayquery)) {
+ $sql.= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as saleman ON saleman.fk_soc=t.rowid ";
+ }
+ if (array_key_exists('cust_categ', $arrayquery)) {
+ $sql.= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "categorie_societe as custcateg ON custcateg.fk_societe=t.rowid ";
+ }
+
+ if (!empty($arrayquery['cust_name'])) {
+
+ $sqlwhere[]= $this->transformToSQL('t.nom',$arrayquery['cust_name']);
+ }
+ if (!empty($arrayquery['cust_code'])) {
+ $sqlwhere[]= $this->transformToSQL('t.code_client',$arrayquery['cust_code']);
+ }
+ if (!empty($arrayquery['cust_adress'])) {
+ $sqlwhere[]= $this->transformToSQL('t.address',$arrayquery['cust_adress']);
+ }
+ if (!empty($arrayquery['cust_zip'])) {
+ $sqlwhere[]= $this->transformToSQL('t.zip',$arrayquery['cust_zip']);
+ }
+ if (!empty($arrayquery['cust_city'])) {
+ $sqlwhere[]= $this->transformToSQL('t.town',$arrayquery['cust_city']);
+ }
+ if (!empty($arrayquery['cust_mothercompany'])) {
+ $str=$this->transformToSQL('nom',$arrayquery['cust_mothercompany']);
+ $sqlwhere[]= " (t.parent IN (SELECT rowid FROM " . MAIN_DB_PREFIX . "societe WHERE ('.$str.')))";
+ }
+ if (!empty($arrayquery['cust_status']) && count($arrayquery['cust_status'])>0) {
+ $sqlwhere[]= " (t.status IN (".implode(',',$arrayquery['cust_status'])."))";
+ }
+ if (!empty($arrayquery['cust_typecust']) && count($arrayquery['cust_typecust'])>0) {
+ $sqlwhere[]= " (t.client IN (".implode(',',$arrayquery['cust_typecust'])."))";
+ }
+ if (!empty($arrayquery['cust_comm_status']) && count($arrayquery['cust_comm_status']>0)) {
+ $sqlwhere[]= " (t.fk_stcomm IN (".implode(',',$arrayquery['cust_comm_status'])."))";
+ }
+ if (!empty($arrayquery['cust_prospect_status']) && count($arrayquery['cust_prospect_status'])>0) {
+ $sqlwhere[]= " (t.fk_prospectlevel IN ('".implode("','",$arrayquery['cust_prospect_status'])."'))";
+ }
+ if (!empty($arrayquery['cust_typeent']) && count($arrayquery['cust_typeent'])>0) {
+ $sqlwhere[]= " (t.fk_typent IN (".implode(',',$arrayquery['cust_typeent'])."))";
+ }
+ if (!empty($arrayquery['cust_saleman']) && count($arrayquery['cust_saleman'])>0) {
+ $sqlwhere[]= " (saleman.fk_user IN (".implode(',',$arrayquery['cust_saleman'])."))";
+ }
+ if (!empty($arrayquery['cust_country']) && count($arrayquery['cust_country'])>0) {
+ $sqlwhere[]= " (t.fk_pays IN (".implode(',',$arrayquery['cust_country'])."))";
+ }
+ if (!empty($arrayquery['cust_effectif_id']) && count($arrayquery['cust_effectif_id'])>0) {
+ $sqlwhere[]= " (t.fk_effectif IN (".implode(',',$arrayquery['cust_effectif_id'])."))";
+ }
+ if (!empty($arrayquery['cust_categ']) && count($arrayquery['cust_categ'])>0) {
+ $sqlwhere[]= " (custcateg.fk_categorie IN (".implode(',',$arrayquery['cust_categ'])."))";
+ }
+ if (!empty($arrayquery['cust_language']) && count($arrayquery['cust_language'])>0) {
+ $sqlwhere[]= " (t.default_lang IN ('".implode("','",$arrayquery['cust_language'])."'))";
+ }
+
+ //Standard Extrafield feature
+ if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) {
+ // fetch optionals attributes and labels
+ dol_include_once('/core/class/extrafields.class.php');
+ $extrafields = new ExtraFields($this->db);
+ $extralabels=$extrafields->fetch_name_optionals_label('societe');
+
+ foreach($extralabels as $key=>$val) {
+
+ if (($extrafields->attribute_type[$key] == 'varchar') ||
+ ($extrafields->attribute_type[$key] == 'text')) {
+ if (!empty($arrayquery['options_'.$key])) {
+ $sqlwhere[]= " (te.".$key." LIKE '".$arrayquery['options_'.$key]."')";
+ }
+ } elseif (($extrafields->attribute_type[$key] == 'int') ||
+ ($extrafields->attribute_type[$key] == 'double')) {
+ if (!empty($arrayquery['options_'.$key.'_max'])) {
+ $sqlwhere[]= " (te.".$key." >= ".$arrayquery['options_'.$key.'_max']." AND te.".$key." <= ".$arrayquery['options_'.$key.'_min'].")";
+ }
+ } else if (($extrafields->attribute_type[$key] == 'date') ||
+ ($extrafields->attribute_type[$key] == 'datetime')) {
+ if (!empty($arrayquery['options_'.$key.'_end_dt'])){
+ $sqlwhere[]= " (te.".$key." >= '".$this->db->idate($arrayquery['options_'.$key.'_st_dt'])."' AND te.".$key." <= '".$this->db->idate($arrayquery['options_'.$key.'_end_dt'])."')";
+ }
+ }else if ($extrafields->attribute_type[$key] == 'boolean') {
+ if ($arrayquery['options_'.$key]!=''){
+ $sqlwhere[]= " (te.".$key." = ".$arrayquery['options_'.$key].")";
+ }
+ }else{
+ if (is_array($arrayquery['options_'.$key])) {
+ $sqlwhere[]= " (te.".$key." IN ('".implode("','",$arrayquery['options_'.$key])."'))";
+ } elseif (!empty($arrayquery['options_'.$key])) {
+ $sqlwhere[]= " (te.".$key." LIKE '".$arrayquery['options_'.$key]."')";
+ }
+ }
+
+ }
+
+
+ }
+
+ if (count($sqlwhere)>0) $sql.= " WHERE ".implode(" AND ",$sqlwhere);
+
+ }
+
+
+ dol_syslog(get_class($this) . "::query_thirdparty sql=" . $sql, LOG_DEBUG);
+ $resql = $this->db->query($sql);
+ if ($resql) {
+ $this->thirdparty_lines = array();
+ $num = $this->db->num_rows($resql);
+ $i = 0;
+
+ if ($num)
+ {
+ while( $i < $num)
+ {
+ $obj = $this->db->fetch_object($resql);
+
+ $this->thirdparty_lines[$i] = $obj->rowid;
+
+ $i++;
+ }
+ }
+ $this->db->free($resql);
+
+ return $num;
+ } else {
+ $this->error = "Error " . $this->db->lasterror();
+ dol_syslog(get_class($this) . "::query_thirdparty " . $this->error, LOG_ERR);
+ return -1;
+ }
+ }
+
+ /**
+ * Load object in memory from database
+ *
+ * @param array $arrayquery All element to Query
+ * @return int <0 if KO, >0 if OK
+ */
+ function query_contact($arrayquery)
+ {
+ global $langs,$conf;
+
+ $sql = "SELECT";
+ $sql.= " t.rowid";
+ $sql.= " FROM " . MAIN_DB_PREFIX . "socpeople as t";
+ $sql.= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "socpeople_extrafields as te ON te.fk_object=t.rowid ";
+
+ $sqlwhere=array();
+
+ $sqlwhere[]= 't.entity IN ('.getEntity('socpeople',1).')';
+
+ if (count($arrayquery)>0) {
+
+ if (array_key_exists('contact_categ', $arrayquery)) {
+ $sql.= " LEFT OUTER JOIN " . MAIN_DB_PREFIX . "categorie_contact as contactcateg ON contactcateg.fk_socpeople=t.rowid ";
+ }
+
+ if (!empty($arrayquery['contact_lastname'])) {
+ $sqlwhere[]=$this->transformToSQL('t.lastname',$arrayquery['contact_lastname']);
+ }
+ if (!empty($arrayquery['contact_firstname'])) {
+ $sqlwhere[]=$this->transformToSQL('t.firstname',$arrayquery['contact_firstname']);
+ }
+ if (!empty($arrayquery['contact_country']) && count($arrayquery['contact_country'])) {
+ $sqlwhere[]= " (t.fk_pays IN (".implode(',',$arrayquery['contact_country'])."))";
+ }
+ if (!empty($arrayquery['contact_status']) && count($arrayquery['contact_status'])>0) {
+ $sqlwhere[]= " (t.statut IN (".implode(',',$arrayquery['contact_status'])."))";
+ }
+ if (!empty($arrayquery['contact_civility']) && count($arrayquery['contact_civility'])>0) {
+ $sqlwhere[]= " (t.civility IN ('".implode("','",$arrayquery['contact_civility'])."'))";
+ }
+ if ($arrayquery['contact_no_email']!='') {
+ $sqlwhere[]= " (t.no_email='".$arrayquery['contact_no_email']."')";
+ }
+ if ($arrayquery['contact_update_st_dt']!='') {
+ $sqlwhere[]= " (t.tms >= '".$this->db->idate($arrayquery['contact_update_st_dt'])."' AND t.tms <= '".$this->db->idate($arrayquery['contact_update_end_dt'])."')";
+ }
+ if ($arrayquery['contact_create_st_dt']!='') {
+ $sqlwhere[]= " (t.datec >= '".$this->db->idate($arrayquery['contact_create_st_dt'])."' AND t.datec <= '".$this->db->idate($arrayquery['contact_create_end_dt'])."')";
+ }
+ if (!empty($arrayquery['contact_categ']) && count($arrayquery['contact_categ'])>0) {
+ $sqlwhere[]= " (contactcateg.fk_categorie IN (".implode(",",$arrayquery['contact_categ'])."))";
+ }
+
+ //Standard Extrafield feature
+ if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) {
+ // fetch optionals attributes and labels
+ dol_include_once('/core/class/extrafields.class.php');
+ $extrafields = new ExtraFields($this->db);
+ $extralabels=$extrafields->fetch_name_optionals_label('socpeople');
+
+ foreach($extralabels as $key=>$val) {
+
+ if (($extrafields->attribute_type[$key] == 'varchar') ||
+ ($extrafields->attribute_type[$key] == 'text')) {
+ if (!empty($arrayquery['options_'.$key.'_cnct'])) {
+ $sqlwhere[]= " (te.".$key." LIKE '".$arrayquery['options_'.$key.'_cnct']."')";
+ }
+ } elseif (($extrafields->attribute_type[$key] == 'int') ||
+ ($extrafields->attribute_type[$key] == 'double')) {
+ if (!empty($arrayquery['options_'.$key.'_max'.'_cnct'])) {
+ $sqlwhere[]= " (te.".$key." >= ".$arrayquery['options_'.$key.'_max'.'_cnct']." AND te.".$key." <= ".$arrayquery['options_'.$key.'_min'.'_cnct'].")";
+ }
+ } else if (($extrafields->attribute_type[$key] == 'date') ||
+ ($extrafields->attribute_type[$key] == 'datetime')) {
+ if (!empty($arrayquery['options_'.$key.'_end_dt'.'_cnct'])){
+ $sqlwhere[]= " (te.".$key." >= '".$this->db->idate($arrayquery['options_'.$key.'_st_dt'.'_cnct'])."' AND te.".$key." <= '".$this->db->idate($arrayquery['options_'.$key.'_end_dt'.'_cnct'])."')";
+ }
+ }else if ($extrafields->attribute_type[$key] == 'boolean') {
+ if ($arrayquery['options_'.$key.'_cnct']!=''){
+ if ($arrayquery['options_'.$key.'_cnct']==0) {
+ $sqlwhere[]= " (te.".$key." = ".$arrayquery['options_'.$key.'_cnct']." OR ((te.".$key." IS NULL) AND (te.fk_object IS NOT NULL)))";
+ }else {
+ $sqlwhere[]= " (te.".$key." = ".$arrayquery['options_'.$key.'_cnct'].")";
+ }
+ }
+ }else{
+ if (is_array($arrayquery['options_'.$key.'_cnct'])) {
+ $sqlwhere[]= " (te.".$key." IN ('".implode("','",$arrayquery['options_'.$key.'_cnct'])."'))";
+ } elseif (!empty($arrayquery['options_'.$key.'_cnct'])) {
+ $sqlwhere[]= " (te.".$key." LIKE '".$arrayquery['options_'.$key.'_cnct']."')";
+ }
+ }
+
+ }
+
+
+ }
+
+ if (count($sqlwhere)>0) $sql.= " WHERE ".implode(" AND ",$sqlwhere);
+
+ }
+
+
+ dol_syslog(get_class($this) . "::query_contact sql=" . $sql, LOG_DEBUG);
+ $resql = $this->db->query($sql);
+ if ($resql) {
+ $this->contact_lines = array();
+ $num = $this->db->num_rows($resql);
+ $i = 0;
+
+ if ($num)
+ {
+ while( $i < $num)
+ {
+ $obj = $this->db->fetch_object($resql);
+
+ $this->contact_lines[$i] = $obj->rowid;
+
+ $i++;
+ }
+ }
+ $this->db->free($resql);
+
+ return $num;
+ } else {
+ $this->error = "Error " . $this->db->lasterror();
+ dol_syslog(get_class($this) . "::query_contact " . $this->error, LOG_ERR);
+ return -1;
+ }
+ }
+
+
+ /**
+ * Parse criteria to return a SQL qury formated
+ *
+ * @param string $column_to_test column to test
+ * @param string $criteria Use %% as magic caracters. For exemple to find all item like jean, joe, jim , you can input j%% , you can also use ; as separator for value,
+ * and use ! for except this value.
+ * For exemple jean;joe;jim%%;!jimo;!jima%> will target all jean, joe, start with jim but not jimo and not everythnig taht start by jima
+ * @return int <0 if KO, >0 if OK
+ */
+ public function transformToSQL($column_to_test,$criteria) {
+ $return_sql_criteria = '(';
+
+ //This is a multiple value test
+ if (preg_match('/;/',$criteria)) {
+ $return_sql_not_like=array();
+ $return_sql_like=array();
+
+ $criteria_array=explode(';',$criteria);
+ foreach($criteria_array as $inter_criteria) {
+ if (preg_match('/!/',$inter_criteria)) {
+ $return_sql_not_like[]= '('.$column_to_test.' NOT LIKE \''.str_replace('!', '', $inter_criteria).'\')';
+ } else {
+ $return_sql_like[]= '('.$column_to_test.' LIKE \''.$inter_criteria.'\')';
+ }
+ }
+
+ if (count($return_sql_like)>0) {
+ $return_sql_criteria .= '(' . implode (' OR ', $return_sql_like) .')';
+ }
+ if (count($return_sql_not_like)>0) {
+ $return_sql_criteria .= ' AND (' . implode (' AND ', $return_sql_not_like).')';
+ }
+
+ }else {
+ $return_sql_criteria .= $column_to_test . ' LIKE \''.$this->db->escape($criteria).'\'';
+ }
+
+ $return_sql_criteria .= ')';
+
+ return $return_sql_criteria;
+ }
+
+
+}
\ No newline at end of file
diff --git a/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php
new file mode 100644
index 00000000000..9c340e1e33b
--- /dev/null
+++ b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php
@@ -0,0 +1,503 @@
+
+*
+*
+* 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 advtargetemailing/class/html.formadvtragetemaling.class.php
+ * \brief Fichier de la classe des fonctions predefinie de composants html advtargetemaling
+ */
+
+/**
+ * Class to manage building of HTML components
+ */
+class FormAdvTargetEmailing extends Form
+{
+ var $db;
+ var $error;
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db handler
+ */
+ function __construct($db) {
+ global $langs;
+
+ $this->db = $db;
+
+ return 1;
+ }
+
+ /**
+ * Affiche un champs select contenant une liste
+ *
+ * @param array $selected_array à preselectionner
+ * @param string $htmlname select field
+ * @return string select field
+ */
+ function multiselectProspectionStatus($selected_array = array(), $htmlname = 'cust_prospect_status') {
+ global $conf, $langs;
+ $options_array = array ();
+
+ $sql = "SELECT code, label";
+ $sql .= " FROM " . MAIN_DB_PREFIX . "c_prospectlevel";
+ $sql .= " WHERE active > 0";
+ $sql .= " ORDER BY sortorder";
+ dol_syslog ( get_class ( $this ) . '::multiselectProspectionStatus sql=' . $sql, LOG_DEBUG );
+ $resql = $this->db->query ( $sql );
+ if ($resql) {
+ $num = $this->db->num_rows ( $resql );
+ $i = 0;
+ while ( $i < $num ) {
+ $obj = $this->db->fetch_object ( $resql );
+
+ $level = $langs->trans ( $obj->code );
+ if ($level == $obj->code)
+ $level = $langs->trans ( $obj->label );
+ $options_array [$obj->code] = $level;
+
+ $i ++;
+ }
+ } else {
+ dol_print_error ( $this->db );
+ }
+ return $this->advMultiselectarray ( $htmlname, $options_array, $selected_array );
+ }
+
+ /**
+ * Return combo list of activated countries, into language of user
+ *
+ * @param string $htmlname of html select object
+ * @param array $selected_array or Code or Label of preselected country
+ * @return string HTML string with select
+ */
+ function multiselectCountry($htmlname = 'country_id', $selected_array=array()) {
+ global $conf, $langs;
+
+ $langs->load ( "dict" );
+
+ $out = '';
+ $countryArray = array ();
+ $label = array ();
+
+ $options_array = array ();
+
+ $sql = "SELECT rowid, code as code_iso, label";
+ $sql .= " FROM " . MAIN_DB_PREFIX . "c_country";
+ $sql .= " WHERE active = 1 AND code<>''";
+ $sql .= " ORDER BY code ASC";
+
+ dol_syslog ( get_class ( $this ) . "::select_country sql=" . $sql );
+ $resql = $this->db->query ( $sql );
+ if ($resql) {
+
+ $num = $this->db->num_rows ( $resql );
+ $i = 0;
+ if ($num) {
+ $foundselected = false;
+
+ while ( $i < $num ) {
+ $obj = $this->db->fetch_object ( $resql );
+ $countryArray [$i] ['rowid'] = $obj->rowid;
+ $countryArray [$i] ['code_iso'] = $obj->code_iso;
+ $countryArray [$i] ['label'] = ($obj->code_iso && $langs->transnoentitiesnoconv ( "Country" . $obj->code_iso ) != "Country" . $obj->code_iso ? $langs->transnoentitiesnoconv ( "Country" . $obj->code_iso ) : ($obj->label != '-' ? $obj->label : ''));
+ $label [$i] = $countryArray [$i] ['label'];
+ $i ++;
+ }
+
+ array_multisort ( $label, SORT_ASC, $countryArray );
+
+ foreach ( $countryArray as $row ) {
+ $label = dol_trunc ( $row ['label'], $maxlength, 'middle' );
+ if ($row ['code_iso'])
+ $label .= ' (' . $row ['code_iso'] . ')';
+
+ $options_array [$row ['rowid']] = $label;
+ }
+ }
+ } else {
+ dol_print_error ( $this->db );
+ }
+
+ return $this->advMultiselectarray ( $htmlname, $options_array, $selected_array );
+ }
+
+ /**
+ * Return select list for categories (to use in form search selectors)
+ *
+ * @param string $htmlname control name
+ * @param array $selected_array array of data
+ * @param User $user User action
+ * @return string combo list code
+ */
+ function multiselectselectSalesRepresentatives($htmlname, $selected_array, $user) {
+
+ global $conf;
+
+ $options_array = array ();
+
+
+ $sql_usr .= "SELECT DISTINCT u2.rowid, u2.lastname as name, u2.firstname, u2.login";
+ $sql_usr .= " FROM " . MAIN_DB_PREFIX . "user as u2, " . MAIN_DB_PREFIX . "societe_commerciaux as sc";
+ $sql_usr .= " WHERE u2.entity IN (0," . $conf->entity . ")";
+ $sql_usr .= " AND u2.rowid = sc.fk_user ";
+
+ if (! empty ( $conf->global->USER_HIDE_INACTIVE_IN_COMBOBOX ))
+ $sql_usr .= " AND u2.statut<>0 ";
+ $sql_usr .= " ORDER BY name ASC";
+ // print $sql_usr;exit;
+
+ $resql_usr = $this->db->query ( $sql_usr );
+ if ($resql_usr) {
+ while ( $obj_usr = $this->db->fetch_object ( $resql_usr ) ) {
+
+ $label = $obj_usr->firstname . " " . $obj_usr->name . " (" . $obj_usr->login . ')';
+
+ $options_array [$obj_usr->rowid] = $label;
+
+ }
+ $this->db->free ( $resql_usr );
+ } else {
+ dol_print_error ( $this->db );
+ }
+
+ return $this->advMultiselectarray ( $htmlname, $options_array, $selected_array );
+ }
+
+ /**
+ * Return select list for categories (to use in form search selectors)
+ *
+ * @param string $htmlname of combo list (example: 'search_sale')
+ * @param array $selected_array selected array
+ * @return string combo list code
+ */
+ function multiselectselectLanguage($htmlname='', $selected_array=array()) {
+
+ global $conf,$langs;
+
+ $options_array = array ();
+
+ $langs_available=$langs->get_available_languages(DOL_DOCUMENT_ROOT,12);
+
+ foreach ($langs_available as $key => $value)
+ {
+ $label = $value;
+ $options_array [$key] = $label;
+ }
+ asort($options_array);
+ return $this->advMultiselectarray ( $htmlname, $options_array, $selected_array );
+ }
+
+ /**
+ * Return multiselect list of entities for extrafeild type sellist
+ *
+ * @param string $htmlname control name
+ * @param array $sqlqueryparam array
+ * @param array $selected_array array
+ *
+ * @return string HTML combo
+ */
+ function advMultiselectarraySelllist($htmlname, $sqlqueryparam = array(), $selected_array = array()) {
+
+ if (is_array ( $sqlqueryparam )) {
+ $options_array=array();
+
+ $param_list = array_keys ( $sqlqueryparam );
+ $InfoFieldList = explode ( ":", $param_list [0] );
+
+ // 0 1 : tableName
+ // 1 2 : label field name Nom du champ contenant le libelle
+ // 2 3 : key fields name (if differ of rowid)
+ // 3 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
+
+ $keyList = 'rowid';
+
+ if (count ( $InfoFieldList ) >= 3) {
+ if (strpos ( $InfoFieldList [3], 'extra.' ) !== false) {
+ $keyList = 'main.' . $InfoFieldList [2] . ' as rowid';
+ } else {
+ $keyList = $InfoFieldList [2] . ' as rowid';
+ }
+ }
+
+ $sql = 'SELECT ' . $keyList . ', ' . $InfoFieldList [1];
+ $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList [0];
+ if (! empty ( $InfoFieldList [3] )) {
+
+ // We have to join on extrafield table
+ if (strpos ( $InfoFieldList [3], 'extra' ) !== false) {
+ $sql .= ' as main, ' . MAIN_DB_PREFIX . $InfoFieldList [0] . '_extrafields as extra';
+ $sql .= ' WHERE extra.fk_object=main.' . $InfoFieldList [2] . ' AND ' . $InfoFieldList [3];
+ } else {
+ $sql .= ' WHERE ' . $InfoFieldList [3];
+ }
+ }
+ if (! empty ( $InfoFieldList [1] ) && $key == 'ts_payeur') {
+ $sql .= " ORDER BY nom";
+ }
+ // $sql.= ' WHERE entity = '.$conf->entity;
+
+ dol_syslog ( get_class ( $this ) . "::".__METHOD__,LOG_DEBUG);
+ $resql = $this->db->query ( $sql );
+ if ($resql) {
+
+ $num = $this->db->num_rows ( $resql );
+ $i = 0;
+ if ($num) {
+ while ( $i < $num ) {
+ $obj = $this->db->fetch_object ( $resql );
+ $labeltoshow = dol_trunc ( $obj->$InfoFieldList [1], 90 );
+ $options_array[$obj->rowid]=$labeltoshow;
+ $i ++;
+ }
+ }
+ $this->db->free ( $resql );
+ }
+ }
+
+ return $this->advMultiselectarray ( $htmlname, $options_array, $selected_array );
+ }
+
+ /**
+ * Return combo list with people title
+ *
+ * @param string $htmlname Name of HTML select combo field
+ * @param array $selected_array array
+ * @return string HTML combo
+ */
+ function multiselectCivility($htmlname='civilite_id',$selected_array = array())
+ {
+ global $conf,$langs,$user;
+ $langs->load("dict");
+
+ $options_array=array();
+
+
+ $sql = "SELECT rowid, code, label as civilite, active FROM ".MAIN_DB_PREFIX."c_civility";
+ $sql.= " WHERE active = 1";
+
+ dol_syslog(get_class($this)."::".__METHOD__,LOG_DEBUG);
+ $resql=$this->db->query($sql);
+ if ($resql)
+ {
+
+ $num = $this->db->num_rows($resql);
+ $i = 0;
+ if ($num)
+ {
+ while ($i < $num)
+ {
+ $obj = $this->db->fetch_object($resql);
+ // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut
+ $label= ($langs->trans("Civility".$obj->code)!="Civility".$obj->code ? $langs->trans("Civility".$obj->code) : ($obj->civilite!='-'?$obj->civilite:''));
+
+
+ $options_array[$obj->code]=$label;
+
+ $i++;
+ }
+ }
+
+ }
+ else
+ {
+ dol_print_error($this->db);
+ }
+
+ return $this->advMultiselectarray ( $htmlname, $options_array, $selected_array );
+ }
+
+ /**
+ * Return multiselect list of entities.
+ *
+ * @param string $htmlname select
+ * @param array $options_array to manage
+ * @param array $selected_array to manage
+ * @param int $showempty show empty
+ * @return string HTML combo
+ */
+ function advMultiselectarray($htmlname, $options_array = array(), $selected_array = array(), $showempty = 0) {
+ global $conf, $langs;
+
+ $return = '';
+
+ $return .= '';
+ if ($showempty)
+ $return .= ' ';
+
+ // Find if keys is in selected array value
+ if (is_array($selected_array) && count($selected_array)>0) {
+ $intersect_array = array_intersect_key ( $options_array, array_flip ( $selected_array ) );
+ } else {
+ $intersect_array=array();
+ }
+
+ if (count ( $options_array ) > 0) {
+ foreach ( $options_array as $keyoption => $valoption ) {
+ // If key is in intersect table then it have to e selected
+ if (count ( $intersect_array ) > 0) {
+ if (array_key_exists ( $keyoption, $intersect_array )) {
+ $selected = ' selected="selected" ';
+ } else {
+ $selected = '';
+ }
+ }
+
+ $return .= '' . $valoption . ' ';
+ }
+ }
+
+ $return .= ' ';
+
+ return $return;
+ }
+
+ /**
+ * Return combo list with customer categories
+ *
+ * @param string $htmlname Name of categorie
+ * @param array $selected_array value selected
+ * @return string HTML combo
+ */
+ function multiselectCustomerCategories($htmlname='cust_cat',$selected_array = array())
+ {
+ return $this->multiselectCategories($htmlname,$selected_array,2);
+ }
+
+ /**
+ * Return combo list with customer contact
+ *
+ * @param string $htmlname Name of categorie
+ * @param array $selected_array value selected
+ * @return string HTML combo
+ */
+ function multiselectContactCategories($htmlname='contact_cat',$selected_array = array())
+ {
+ return $this->multiselectCategories($htmlname,$selected_array,4);
+ }
+
+ /**
+ * Return combo list of categories
+ *
+ * @param string $htmlname Name of categorie
+ * @param array $selected_array value selected
+ * @param int $type type
+ * @return string HTML combo
+ */
+ public function multiselectCategories($htmlname='',$selected_array = array(), $type=0)
+ {
+ global $conf,$langs,$user;
+ $langs->load("dict");
+
+ $options_array=array();
+
+ $sql = "SELECT rowid, label FROM ".MAIN_DB_PREFIX."categorie";
+ $sql.= " WHERE type=".$type;
+
+ dol_syslog(get_class($this)."::".__METHOD__,LOG_DEBUG);
+ $resql=$this->db->query($sql);
+ if ($resql)
+ {
+
+ $num = $this->db->num_rows($resql);
+ $i = 0;
+ if ($num)
+ {
+ while ($i < $num)
+ {
+ $obj = $this->db->fetch_object($resql);
+
+ $options_array[$obj->rowid]=$obj->label;
+
+ $i++;
+ }
+ }
+
+ }
+ else
+ {
+ dol_print_error($this->db);
+ }
+
+ return $this->advMultiselectarray ( $htmlname, $options_array, $selected_array );
+ }
+
+ /**
+ * selectAdvtargetemailingTemplate
+ *
+ * @param string $htmlname control name
+ * @param number $selected defaut selected
+ * @param number $showempty empty lines
+ *
+ * @return string HTML combo
+ */
+ public function selectAdvtargetemailingTemplate($htmlname='template_id',$selected=0,$showempty=0) {
+ global $conf, $user, $langs;
+
+ $out = '';
+
+ $sql = "SELECT c.rowid, c.name, c.fk_mailing";
+ $sql .= " FROM " . MAIN_DB_PREFIX . "advtargetemailing as c";
+ $sql .= " ORDER BY c.name";
+
+ dol_syslog ( get_class ( $this ) . "::".__METHOD__, LOG_DEBUG );
+ $resql = $this->db->query ( $sql );
+ if ($resql) {
+
+
+ $out .= '';
+ if ($showempty)
+ $out .= ' ';
+ $num = $this->db->num_rows ( $resql );
+ $i = 0;
+ if ($num) {
+ while ( $i < $num ) {
+ $obj = $this->db->fetch_object ( $resql );
+ $label = $obj->name;
+ if (empty($label)) {
+ $label=$obj->fk_mailing;
+ }
+
+ if ($selected > 0 && $selected == $obj->rowid) {
+ $out .= '' . $label . ' ';
+ } else {
+ $out .= '' . $label . ' ';
+ }
+ $i ++;
+ }
+ }
+ $out .= ' ';
+ } else {
+ dol_print_error ( $this->db );
+ }
+ $this->db->free ( $resql );
+ return $out;
+ }
+}
\ No newline at end of file
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 049ccbd1bc9..14dbb304333 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -3237,8 +3237,9 @@ abstract class CommonObject
function printObjectLines($action, $seller, $buyer, $selected=0, $dateSelector=0)
{
global $conf, $hookmanager, $langs, $user;
- global $inputalsopricewithtax, $usemargins, $disableedit, $disablemove, $disableremove; // TODO We should not use global var for this !
-
+ // TODO We should not use global var for this !
+ global $inputalsopricewithtax, $usemargins, $disableedit, $disablemove, $disableremove;
+
// Define usemargins
$usemargins=0;
if (! empty($conf->margin->enabled) && ! empty($this->element) && in_array($this->element,array('facture','propal','commande'))) $usemargins=1;
@@ -3367,7 +3368,7 @@ abstract class CommonObject
{
global $conf,$langs,$user,$object,$hookmanager;
global $form,$bc,$bcdd;
- global $object_rights, $disableedit, $disablemove, $disableremove; // TODO We should not use global var for this !
+ global $object_rights, $disableedit, $disablemove; // TODO We should not use global var for this !
$object_rights = $this->getRights();
diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php
index 97645487d45..8d61733e138 100644
--- a/htdocs/core/class/extrafields.class.php
+++ b/htdocs/core/class/extrafields.class.php
@@ -63,7 +63,7 @@ class ExtraFields
var $errno;
var $attribute_hidden;
-
+
public static $type2label=array(
'varchar'=>'String',
'text'=>'TextLong',
@@ -665,6 +665,7 @@ class ExtraFields
$param=$this->attribute_param[$key];
$perms=$this->attribute_perms[$key];
$list=$this->attribute_list[$key];
+ $hidden=$this->attribute_hidden[$key];
if (empty($showsize))
{
@@ -686,7 +687,7 @@ class ExtraFields
if ($showsize > 48) $showsize=48;
}
}
-
+
if (in_array($type,array('date','datetime')))
{
$tmp=explode(',',$size);
@@ -823,7 +824,7 @@ class ExtraFields
if (strpos($InfoFieldList[4], '$SEL$')!==false) {
$InfoFieldList[4]=str_replace('$SEL$','SELECT',$InfoFieldList[4]);
}
-
+
// current object id can be use into filter
if (strpos($InfoFieldList[4], '$ID$')!==false && !empty($objectid)) {
$InfoFieldList[4]=str_replace('$ID$',$objectid,$InfoFieldList[4]);
@@ -841,14 +842,14 @@ class ExtraFields
$sqlwhere.= ' WHERE '.$InfoFieldList[4];
}
}
- else
+ else
{
$sqlwhere.= ' WHERE 1=1';
}
// Some tables may have field, some other not. For the moment we disable it.
- if (in_array($InfoFieldList[0],array('tablewithentity')))
+ if (in_array($InfoFieldList[0],array('tablewithentity')))
{
- $sqlwhere.= ' AND entity = '.$conf->entity;
+ $sqlwhere.= ' AND entity = '.$conf->entity;
}
$sql.=$sqlwhere;
//print $sql;
@@ -1007,19 +1008,19 @@ class ExtraFields
$sql = 'SELECT ' . $keyList;
$sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0];
if (! empty($InfoFieldList[4])) {
-
+
// can use SELECT request
if (strpos($InfoFieldList[4], '$SEL$')!==false) {
$InfoFieldList[4]=str_replace('$SEL$','SELECT',$InfoFieldList[4]);
}
-
+
// current object id can be use into filter
if (strpos($InfoFieldList[4], '$ID$')!==false && !empty($objectid)) {
$InfoFieldList[4]=str_replace('$ID$',$objectid,$InfoFieldList[4]);
} else {
$InfoFieldList[4]=str_replace('$ID$','0',$InfoFieldList[4]);
}
-
+
// We have to join on extrafield table
if (strpos($InfoFieldList[4], 'extra') !== false) {
$sql .= ' as main, ' . MAIN_DB_PREFIX . $InfoFieldList[0] . '_extrafields as extra';
@@ -1031,13 +1032,13 @@ class ExtraFields
$sqlwhere .= ' WHERE 1=1';
}
// Some tables may have field, some other not. For the moment we disable it.
- if (in_array($InfoFieldList[0], array ('tablewithentity')))
+ if (in_array($InfoFieldList[0], array ('tablewithentity')))
{
$sqlwhere .= ' AND entity = ' . $conf->entity;
}
// $sql.=preg_replace('/^ AND /','',$sqlwhere);
// print $sql;
-
+
$sql .= $sqlwhere;
dol_syslog(get_class($this) . '::showInputField type=chkbxlst',LOG_DEBUG);
$resql = $this->db->query($sql);
@@ -1143,6 +1144,9 @@ class ExtraFields
$out.='Error bad setup of extrafield';
}
}
+ if (!empty($hidden)) {
+ $out=' ';
+ }
/* Add comments
if ($type == 'date') $out.=' (YYYY-MM-DD)';
elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)';
@@ -1171,6 +1175,7 @@ class ExtraFields
$params=$this->attribute_param[$key];
$perms=$this->attribute_perms[$key];
$list=$this->attribute_list[$key];
+ $hidden=$this->attribute_hidden[$key];
$showsize=0;
if ($type == 'date')
@@ -1402,10 +1407,14 @@ class ExtraFields
$showsize=round($size);
if ($showsize > 48) $showsize=48;
}
-
+
//print $type.'-'.$size;
$out=$value;
-
+
+ if (!empty($hidden)) {
+ $out='';
+ }
+
return $out;
}
@@ -1422,7 +1431,7 @@ class ExtraFields
$type=$this->attribute_type[$key];
$align='';
-
+
if ($type == 'date')
{
$align="center";
@@ -1451,10 +1460,10 @@ class ExtraFields
{
$align="center";
}
-
+
return $align;
}
-
+
/**
* Return HTML string to print separator extrafield
*
@@ -1534,7 +1543,7 @@ class ExtraFields
return 0;
}
}
-
+
/**
* return array_options array for object by extrafields value (using for data send by forms)
*
diff --git a/htdocs/core/class/html.formaccounting.class.php b/htdocs/core/class/html.formaccounting.class.php
index 04d643d4b2f..9abf943d948 100644
--- a/htdocs/core/class/html.formaccounting.class.php
+++ b/htdocs/core/class/html.formaccounting.class.php
@@ -82,7 +82,7 @@ class FormAccounting
$sql.= " ORDER BY c.label ASC";
}
- dol_syslog("Form::select_accounting_category", LOG_DEBUG);
+ dol_syslog(get_class($this).'::'.__METHOD__, LOG_DEBUG);
$resql=$db->query($sql);
if ($resql)
{
diff --git a/htdocs/core/lib/emailing.lib.php b/htdocs/core/lib/emailing.lib.php
index 7ca2aba9db2..257f2829704 100644
--- a/htdocs/core/lib/emailing.lib.php
+++ b/htdocs/core/lib/emailing.lib.php
@@ -38,7 +38,7 @@ function emailing_prepare_head(Mailing $object)
$head[$h][1] = $langs->trans("MailCard");
$head[$h][2] = 'card';
$h++;
-
+
if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! $user->rights->mailing->mailing_advance->recipient) {
return $head;
}
@@ -48,11 +48,16 @@ function emailing_prepare_head(Mailing $object)
$head[$h][2] = 'targets';
$h++;
+ $head[$h][0] = DOL_URL_ROOT."/comm/mailing/advtargetemailing.php?id=".$object->id;
+ $head[$h][1] = $langs->trans("MailAdvTargetRecipients");
+ $head[$h][2] = 'advtargets';
+ $h++;
+
$head[$h][0] = DOL_URL_ROOT."/comm/mailing/info.php?id=".$object->id;
$head[$h][1] = $langs->trans("Info");
$head[$h][2] = 'info';
$h++;
-
+
complete_head_from_modules($conf,$langs,$object,$head,$h,'emailing');
complete_head_from_modules($conf,$langs,$object,$head,$h,'emailing','remove');
diff --git a/htdocs/core/modules/mailings/advthirdparties.modules.php b/htdocs/core/modules/mailings/advthirdparties.modules.php
new file mode 100755
index 00000000000..9cb73a75d7a
--- /dev/null
+++ b/htdocs/core/modules/mailings/advthirdparties.modules.php
@@ -0,0 +1,302 @@
+
+ * Copyright (C) 2005-2009 Regis Houssin
+*
+* This file is an example to follow to add your own email selector inside
+* the Dolibarr email tool.
+* Follow instructions given in README file to know what to change to build
+* your own emailing list selector.
+* Code that need to be changed in this file are marked by "CHANGE THIS" tag.
+*/
+
+/**
+ * \file advtargetingemaling/modules/mailings/advthirdparties.modules.php
+ * \ingroup advtargetingemaling
+ * \brief Example file to provide a list of recipients for mailing module
+ */
+
+include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php';
+include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
+include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
+
+
+/**
+ * Class to manage a list of personalised recipients for mailing feature
+ */
+class mailing_advthirdparties extends MailingTargets
+{
+ var $name='ThirdPartyAdvancedTargeting';
+ var $desc="Third parties";
+ var $require_admin=0;
+
+ var $require_module=array("none"); // This module should not be displayed as Selector in mailling
+ var $picto='company';
+ var $db;
+
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db Database handler
+ */
+ function __construct($db)
+ {
+ global $conf;
+
+ $this->db=$db;
+ }
+
+
+ /**
+ * This is the main function that returns the array of emails
+ *
+ * @param int $mailing_id Id of mailing. No need to use it.
+ * @param array $socid Array of id soc to add
+ * @param int $type_of_target define in advtargetemailing.class.php
+ * @param array $contactid Array of contact id to add
+ * @return int <0 if error, number of emails added if ok
+ */
+ function add_to_target($mailing_id,$socid,$type_of_target, $contactid)
+ {
+ global $conf, $langs;
+
+ dol_syslog(get_class($this)."::add_to_target socid=".var_export($socid,true).' contactid='.var_export($contactid,true));
+
+ $cibles = array();
+
+ if (($type_of_target==1) || ($type_of_target==3)) {
+ // Select the third parties from category
+ if (count($socid)>0)
+ {
+ $sql= "SELECT s.rowid as id, s.email as email, s.nom as name, null as fk_contact";
+ $sql.= " FROM ".MAIN_DB_PREFIX."societe as s LEFT OUTER JOIN ".MAIN_DB_PREFIX."societe_extrafields se ON se.fk_object=s.rowid";
+ $sql.= " WHERE s.entity IN (".getEntity('societe', 1).")";
+ $sql.= " AND s.rowid IN (".implode(',',$socid).")";
+ $sql.= " ORDER BY email";
+ }
+
+
+ dol_syslog(get_class($this)."::add_to_target societe sql=".$sql, LOG_DEBUG);
+ // Stock recipients emails into targets table
+ $result=$this->db->query($sql);
+ if ($result)
+ {
+ $num = $this->db->num_rows($result);
+ $i = 0;
+
+ dol_syslog(get_class($this)."::add_to_target mailing ".$num." targets found", LOG_DEBUG);
+
+ $old = '';
+ while ($i < $num)
+ {
+ $obj = $this->db->fetch_object($result);
+
+ if (!empty($obj->email) && filter_var($obj->email, FILTER_VALIDATE_EMAIL)) {
+ if (!array_key_exists($obj->email, $cibles)) {
+ $cibles[$obj->email] = array(
+ 'email' => $obj->email,
+ 'fk_contact' => $obj->fk_contact,
+ 'name' => $obj->name,
+ 'firstname' => $obj->firstname,
+ 'other' => '',
+ 'source_url' => $this->url($obj->id,'thirdparty'),
+ 'source_id' => $obj->id,
+ 'source_type' => 'thirdparty'
+ );
+ }
+ }
+
+ $i++;
+ }
+ }
+ else
+ {
+ dol_syslog($this->db->error());
+ $this->error=$this->db->error();
+ return -1;
+ }
+ }
+
+ if (($type_of_target==1) || ($type_of_target==2)) {
+ // Select the third parties from category
+ if (count($socid)>0 || count($contactid)>0)
+ {
+ $sql= "SELECT socp.rowid as id, socp.email as email, socp.lastname as lastname, socp.firstname as firstname";
+ $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as socp";
+ $sql.= " WHERE socp.entity IN (".getEntity('societe', 1).")";
+ if (count($contactid)>0) {
+ $sql.= " AND socp.rowid IN (".implode(',',$contactid).")";
+ }
+ if (count($socid)>0) {
+ $sql.= " AND socp.fk_soc IN (".implode(',',$socid).")";
+ }
+ $sql.= " ORDER BY email";
+ }
+
+
+ dol_syslog(get_class($this)."::add_to_target contact sql=".$sql);
+ // Stock recipients emails into targets table
+ $result=$this->db->query($sql);
+ if ($result)
+ {
+ $num = $this->db->num_rows($result);
+ $i = 0;
+
+ dol_syslog(get_class($this)."::add_to_target mailing ".$num." targets found");
+
+ $old = '';
+ while ($i < $num)
+ {
+ $obj = $this->db->fetch_object($result);
+
+ if (!empty($obj->email) && filter_var($obj->email, FILTER_VALIDATE_EMAIL)) {
+ if (!array_key_exists($obj->email, $cibles)) {
+ $cibles[$obj->email] = array(
+ 'email' => $obj->email,
+ 'fk_contact' =>$obj->id,
+ 'lastname' => $obj->lastname,
+ 'firstname' => $obj->firstname,
+ 'other' => '',
+ 'source_url' => $this->url($obj->id,'contact'),
+ 'source_id' => $obj->id,
+ 'source_type' => 'contact'
+ );
+ }
+ }
+
+ $i++;
+ }
+ }
+ else
+ {
+ dol_syslog($this->db->error());
+ $this->error=$this->db->error();
+ return -1;
+ }
+ }
+
+
+ dol_syslog(get_class($this)."::add_to_target mailing cibles=".var_export($cibles,true), LOG_DEBUG);
+ return parent::add_to_target($mailing_id, $cibles);
+ }
+
+
+ /**
+ * On the main mailing area, there is a box with statistics.
+ * If you want to add a line in this report you must provide an
+ * array of SQL request that returns two field:
+ * One called "label", One called "nb".
+ *
+ * @return array Array with SQL requests
+ */
+ function getSqlArrayForStats()
+ {
+ // CHANGE THIS: Optionnal
+
+ //var $statssql=array();
+ //$this->statssql[0]="SELECT field1 as label, count(distinct(email)) as nb FROM mytable WHERE email IS NOT NULL";
+ return array();
+ }
+
+
+ /**
+ * Return here number of distinct emails returned by your selector.
+ * For example if this selector is used to extract 500 different
+ * emails from a text file, this function must return 500.
+ *
+ * @return int Nb of recipients
+ */
+ function getNbOfRecipients()
+ {
+ global $conf;
+
+ $sql = "SELECT count(distinct(s.email)) as nb";
+ $sql.= " FROM ".MAIN_DB_PREFIX."societe as s";
+ $sql.= " WHERE s.email != ''";
+ $sql.= " AND s.entity IN (".getEntity('societe', 1).")";
+
+ // La requete doit retourner un champ "nb" pour etre comprise
+ // par parent::getNbOfRecipients
+ return parent::getNbOfRecipients($sql);
+ }
+
+ /**
+ * This is to add a form filter to provide variant of selector
+ * If used, the HTML select must be called "filter"
+ *
+ * @return string A html select zone
+ */
+ function formFilter()
+ {
+ global $conf, $langs;
+
+ $langs->load("companies");
+
+ $s='';
+ $s.='';
+
+ // Show categories
+ $sql = "SELECT rowid, label, type, visible";
+ $sql.= " FROM ".MAIN_DB_PREFIX."categorie";
+ $sql.= " WHERE type in (1,2)"; // We keep only categories for suppliers and customers/prospects
+ // $sql.= " AND visible > 0"; // We ignore the property visible because third party's categories does not use this property (only products categories use it).
+ $sql.= " AND entity = ".$conf->entity;
+ $sql.= " ORDER BY label";
+
+ //print $sql;
+ $resql = $this->db->query($sql);
+ if ($resql)
+ {
+ $num = $this->db->num_rows($resql);
+
+ if (empty($conf->categorie->enabled)) $num=0; // Force empty list if category module is not enabled
+
+ if ($num) $s.=' ';
+ else $s.=''.$langs->trans("ContactsAllShort").' ';
+
+ $i = 0;
+ while ($i < $num)
+ {
+ $obj = $this->db->fetch_object($resql);
+
+ $type='';
+ if ($obj->type == 1) $type=$langs->trans("Supplier");
+ if ($obj->type == 2) $type=$langs->trans("Customer");
+ $s.=''.dol_trunc($obj->label,38,'middle');
+ if ($type) $s.=' ('.$type.')';
+ $s.=' ';
+ $i++;
+ }
+ }
+ else
+ {
+ dol_print_error($this->db);
+ }
+
+ $s.=' ';
+ return $s;
+
+ }
+
+
+ /**
+ * Can include an URL link on each record provided by selector shown on target page.
+ *
+ * @param int $id ID
+ * @param string $type type
+ * @return string Url link
+ */
+ function url($id,$type)
+ {
+ if ($type=='thirdparty') {
+ $companystatic=new Societe($this->db);
+ $companystatic->fetch($id);
+ return $companystatic->getNomUrl(0);
+ } elseif ($type=='contact') {
+ $contactstatic=new Contact($this->db);
+ $contactstatic->fetch($id);
+ return $contactstatic->getNomUrl(0);
+ }
+ }
+
+}
diff --git a/htdocs/core/modules/mailings/modules_mailings.php b/htdocs/core/modules/mailings/modules_mailings.php
index 48252d22a6e..c75e22ed334 100644
--- a/htdocs/core/modules/mailings/modules_mailings.php
+++ b/htdocs/core/modules/mailings/modules_mailings.php
@@ -169,6 +169,7 @@ class MailingTargets // This can't be abstract as it is used for some method
$sql.= (empty($targetarray['source_id']) ? 'null' : "'".$this->db->escape($targetarray['source_id'])."'").",";
$sql .= "'".$this->db->escape(dol_hash($targetarray['email'].';'.$targetarray['lastname'].';'.$mailing_id.';'.$conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY))."',";
$sql .= "'".$this->db->escape($targetarray['source_type'])."')";
+ dol_syslog(get_class($this)."::".__METHOD__,LOG_DEBUG);
$result=$this->db->query($sql);
if ($result)
{
@@ -188,28 +189,26 @@ class MailingTargets // This can't be abstract as it is used for some method
}
}
- dol_syslog(get_class($this)."::add_to_target: sql ".$sql,LOG_DEBUG);
- dol_syslog(get_class($this)."::add_to_target: mailing ".$j." targets added");
+ dol_syslog(get_class($this)."::".__METHOD__.": mailing ".$j." targets added");
//Update the status to show thirdparty mail that don't want to be contacted anymore'
$sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
$sql .= " SET statut=3";
$sql .= " WHERE fk_mailing=".$mailing_id." AND email in (SELECT email FROM ".MAIN_DB_PREFIX."societe where fk_stcomm=-1)";
$sql .= " AND source_type='thirdparty'";
+ dol_syslog(get_class($this)."::".__METHOD__.": mailing update status to display thirdparty mail that do not want to be contacted");
$result=$this->db->query($sql);
- dol_syslog(get_class($this)."::add_to_target: mailing update status to display thirdparty mail that do not want to be contacted sql:".$sql);
+
//Update the status to show contact mail that don't want to be contacted anymore'
$sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
$sql .= " SET statut=3";
$sql .= " WHERE fk_mailing=".$mailing_id." AND source_type='contact' AND (email in (SELECT sc.email FROM ".MAIN_DB_PREFIX."socpeople AS sc ";
- $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe s ON s.fk_stcomm=-1 AND s.rowid=sc.fk_soc)";
- $sql .= " OR no_email=1)";
+ $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid=sc.fk_soc WHERE s.fk_stcomm=-1 OR no_email=1))";
+ dol_syslog(get_class($this)."::".__METHOD__.": mailing update status to display contact mail that do not want to be contacted",LOG_DEBUG);
$result=$this->db->query($sql);
- dol_syslog(get_class($this)."::add_to_target: mailing update status to display contact mail that do not want to be contacted sql:".$sql);
-
$this->update_nb($mailing_id);
diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php
index 25b86cdc0bf..db3e17bc123 100644
--- a/htdocs/core/tpl/admin_extrafields_add.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php
@@ -118,9 +118,7 @@
trans("AlwaysEditable"); ?> >
-global->MAIN_CAN_HIDE_EXTRAFIELDS)) { ?>
trans("Hidden"); ?> >
-
global->MAIN_FEATURES_LEVEL >= 2) { ?>
trans("ByDefaultInList"); ?>
diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php
index f12f90d6206..e17a9073067 100644
--- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php
@@ -110,7 +110,7 @@ elseif (($type== 'sellist') || ($type == 'chkbxlst') || ($type == 'link') )
trans("AttributeCode"); ?>
trans("Type"); ?>
-array('varchar', 'phone', 'mail', 'select'),
@@ -135,7 +135,7 @@ else
{
print $type2label[$type];
print ' ';
-}
+}
?>
@@ -167,11 +167,7 @@ else
trans("AlwaysEditable"); ?> >
-global->MAIN_CAN_HIDE_EXTRAFIELDS)) { ?>
trans("Hidden"); ?> >
-';
-}?>
global->MAIN_FEATURES_LEVEL >= 2) { ?>
trans("ByDefaultInList"); ?>
diff --git a/htdocs/core/tpl/admin_extrafields_view.tpl.php b/htdocs/core/tpl/admin_extrafields_view.tpl.php
index 6acc81f009f..e131b345e1d 100644
--- a/htdocs/core/tpl/admin_extrafields_view.tpl.php
+++ b/htdocs/core/tpl/admin_extrafields_view.tpl.php
@@ -61,7 +61,7 @@ foreach($extrafields->attribute_type as $key => $value)
print ' '.yn($extrafields->attribute_unique[$key])." \n";
print ''.yn($extrafields->attribute_required[$key])." \n";
print ''.yn($extrafields->attribute_alwayseditable[$key])." \n";
- if (! empty($conf->global->MAIN_CAN_HIDE_EXTRAFIELDS)) print ''.yn($extrafields->attribute_hidden[$key])." \n"; // Add hidden option on not working feature. Why hide if user can't see it.
+ print ''.yn($extrafields->attribute_hidden[$key])." \n"; // Add hidden option on not working feature. Why hide if user can't see it.
print ''.img_edit().' ';
print " ".img_delete()." \n";
print " ";
diff --git a/htdocs/includes/multiselect/MIT-LICENSE.txt b/htdocs/includes/multiselect/MIT-LICENSE.txt
new file mode 100755
index 00000000000..1076f8b4b2b
--- /dev/null
+++ b/htdocs/includes/multiselect/MIT-LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2009 Michael Aufreiter, http://www.quasipartikel.at
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/htdocs/includes/multiselect/css/ui.multiselect.css b/htdocs/includes/multiselect/css/ui.multiselect.css
new file mode 100755
index 00000000000..2072baa57c4
--- /dev/null
+++ b/htdocs/includes/multiselect/css/ui.multiselect.css
@@ -0,0 +1,144 @@
+/* Multiselect
+----------------------------------*/
+.multiselect {
+ width: 600px;
+ height: 150px;
+}
+
+.ui-multiselect {
+ border: solid 1px;
+ font-size: 0.8em;
+}
+
+.ui-multiselect ul {
+ -moz-user-select: none;
+}
+
+.ui-multiselect li {
+ margin: 0;
+ padding: 0;
+ cursor: default;
+ line-height: 20px;
+ height: 20px;
+ font-size: 11px;
+ list-style: none;
+}
+
+.ui-multiselect li a {
+ color: #999;
+ text-decoration: none;
+ padding: 0;
+ display: block;
+ float: left;
+ cursor: pointer;
+}
+
+.ui-multiselect li.ui-draggable-dragging {
+ padding-left: 10px;
+}
+
+.ui-multiselect div.selected {
+ position: relative;
+ padding: 0;
+ margin: 0;
+ border: 0;
+ float: left;
+}
+
+.ui-multiselect ul.selected {
+ position: relative;
+ padding: 0;
+ overflow: auto;
+ overflow-x: hidden;
+ background: #fff;
+ margin: 0;
+ list-style: none;
+ border: 0;
+ position: relative;
+ width: 100%;
+}
+
+.ui-multiselect ul.selected li {
+
+}
+
+.ui-multiselect div.available {
+ position: relative;
+ padding: 0;
+ margin: 0;
+ border: 0;
+ float: left;
+ border-left: 1px solid;
+}
+
+.ui-multiselect ul.available {
+ position: relative;
+ padding: 0;
+ overflow: auto;
+ overflow-x: hidden;
+ background: #fff;
+ margin: 0;
+ list-style: none;
+ border: 0;
+ width: 100%;
+}
+
+.ui-multiselect ul.available li {
+ padding-left: 10px;
+}
+
+.ui-multiselect .ui-state-default {
+ border: none;
+ margin-bottom: 1px;
+ position: relative;
+ padding-left: 20px;
+}
+
+.ui-multiselect .ui-state-hover {
+ border: none;
+}
+
+.ui-multiselect .ui-widget-header {
+ border: none;
+ font-size: 11px;
+ margin-bottom: 1px;
+}
+
+.ui-multiselect .add-all {
+ float: right;
+ padding: 7px;
+}
+
+.ui-multiselect .remove-all {
+ float: right;
+ padding: 7px;
+}
+
+.ui-multiselect .search {
+ float: left;
+ padding: 4px;
+}
+
+.ui-multiselect .count {
+ float: left;
+ padding: 7px;
+}
+
+.ui-multiselect li span.ui-icon-arrowthick-2-n-s {
+ position: absolute;
+ left: 2px;
+}
+
+.ui-multiselect li a.action {
+ position: absolute;
+ right: 2px;
+ top: 2px;
+}
+
+.ui-multiselect input.search {
+ height: 14px;
+ padding: 1px;
+ opacity: 0.5;
+ margin: 4px;
+ width: 100px;
+}
\ No newline at end of file
diff --git a/htdocs/includes/multiselect/js/ui.multiselect.js b/htdocs/includes/multiselect/js/ui.multiselect.js
new file mode 100755
index 00000000000..1234fa7a957
--- /dev/null
+++ b/htdocs/includes/multiselect/js/ui.multiselect.js
@@ -0,0 +1,336 @@
+/*
+ * jQuery UI Multiselect
+ *
+ * Authors:
+ * Michael Aufreiter (quasipartikel.at)
+ * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
+ *
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://www.quasipartikel.at/multiselect/
+ *
+ *
+ * Depends:
+ * ui.core.js
+ * ui.sortable.js
+ *
+ * Optional:
+ * localization (http://plugins.jquery.com/project/localisation)
+ * scrollTo (http://plugins.jquery.com/project/ScrollTo)
+ *
+ * Todo:
+ * Make batch actions faster
+ * Implement dynamic insertion through remote calls
+ */
+
+
+(function($) {
+
+$.widget("ui.multiselect", {
+ options: {
+ sortable: true,
+ searchable: true,
+ doubleClickable: true,
+ animated: 'fast',
+ show: 'slideDown',
+ hide: 'slideUp',
+ dividerLocation: 0.6,
+ nodeComparator: function(node1,node2) {
+ var text1 = node1.text(),
+ text2 = node2.text();
+ return text1 == text2 ? 0 : (text1 < text2 ? -1 : 1);
+ }
+ },
+ _create: function() {
+ this.element.hide();
+ this.id = this.element.attr("id");
+ this.container = $('
').insertAfter(this.element);
+ this.count = 0; // number of currently selected options
+ this.selectedContainer = $('
').appendTo(this.container);
+ this.availableContainer = $('
').appendTo(this.container);
+ this.selectedActions = $('').appendTo(this.selectedContainer);
+ this.availableActions = $('').appendTo(this.availableContainer);
+ this.selectedList = $('').bind('selectstart', function(){return false;}).appendTo(this.selectedContainer);
+ this.availableList = $('').bind('selectstart', function(){return false;}).appendTo(this.availableContainer);
+
+ var that = this;
+
+ // set dimensions
+ this.container.width(this.element.width()+1);
+ this.selectedContainer.width(Math.floor(this.element.width()*this.options.dividerLocation));
+ this.availableContainer.width(Math.floor(this.element.width()*(1-this.options.dividerLocation)));
+
+ // fix list height to match depending on their individual header's heights
+ this.selectedList.height(Math.max(this.element.height()-this.selectedActions.height(),1));
+ this.availableList.height(Math.max(this.element.height()-this.availableActions.height(),1));
+
+ if ( !this.options.animated ) {
+ this.options.show = 'show';
+ this.options.hide = 'hide';
+ }
+
+ // init lists
+ this._populateLists(this.element.find('option'));
+
+ // make selection sortable
+ if (this.options.sortable) {
+ this.selectedList.sortable({
+ placeholder: 'ui-state-highlight',
+ axis: 'y',
+ update: function(event, ui) {
+ // apply the new sort order to the original selectbox
+ that.selectedList.find('li').each(function() {
+ if ($(this).data('optionLink'))
+ $(this).data('optionLink').remove().appendTo(that.element);
+ });
+ },
+ receive: function(event, ui) {
+ ui.item.data('optionLink').attr('selected', true);
+ // increment count
+ that.count += 1;
+ that._updateCount();
+ // workaround, because there's no way to reference
+ // the new element, see http://dev.jqueryui.com/ticket/4303
+ that.selectedList.children('.ui-draggable').each(function() {
+ $(this).removeClass('ui-draggable');
+ $(this).data('optionLink', ui.item.data('optionLink'));
+ $(this).data('idx', ui.item.data('idx'));
+ that._applyItemState($(this), true);
+ });
+
+ // workaround according to http://dev.jqueryui.com/ticket/4088
+ setTimeout(function() { ui.item.remove(); }, 1);
+ }
+ });
+ }
+
+ // set up livesearch
+ if (this.options.searchable) {
+ this._registerSearchEvents(this.availableContainer.find('input.search'));
+ } else {
+ $('.search').hide();
+ }
+
+ // batch actions
+ this.container.find(".remove-all").click(function() {
+ that._populateLists(that.element.find('option').removeAttr('selected'));
+ return false;
+ });
+
+ this.container.find(".add-all").click(function() {
+ var options = that.element.find('option').not(":selected");
+ if (that.availableList.children('li:hidden').length > 1) {
+ that.availableList.children('li').each(function(i) {
+ if ($(this).is(":visible")) $(options[i-1]).attr('selected', 'selected');
+ });
+ } else {
+ options.attr('selected', 'selected');
+ }
+ that._populateLists(that.element.find('option'));
+ return false;
+ });
+ },
+ destroy: function() {
+ this.element.show();
+ this.container.remove();
+
+ $.Widget.prototype.destroy.apply(this, arguments);
+ },
+ _populateLists: function(options) {
+ this.selectedList.children('.ui-element').remove();
+ this.availableList.children('.ui-element').remove();
+ this.count = 0;
+
+ var that = this;
+ var items = $(options.map(function(i) {
+ var item = that._getOptionNode(this).appendTo(this.selected ? that.selectedList : that.availableList).show();
+
+ if (this.selected) that.count += 1;
+ that._applyItemState(item, this.selected);
+ item.data('idx', i);
+ return item[0];
+ }));
+
+ // update count
+ this._updateCount();
+ that._filter.apply(this.availableContainer.find('input.search'), [that.availableList]);
+ },
+ _updateCount: function() {
+ this.selectedContainer.find('span.count').text(this.count+" "+$.ui.multiselect.locale.itemsCount);
+ },
+ _getOptionNode: function(option) {
+ option = $(option);
+ var node = $(' '+option.text()+' ').hide();
+ node.data('optionLink', option);
+ return node;
+ },
+ // clones an item with associated data
+ // didn't find a smarter away around this
+ _cloneWithData: function(clonee) {
+ var clone = clonee.clone(false,false);
+ clone.data('optionLink', clonee.data('optionLink'));
+ clone.data('idx', clonee.data('idx'));
+ return clone;
+ },
+ _setSelected: function(item, selected) {
+ item.data('optionLink').attr('selected', selected);
+
+ if (selected) {
+ var selectedItem = this._cloneWithData(item);
+ item[this.options.hide](this.options.animated, function() { $(this).remove(); });
+ selectedItem.appendTo(this.selectedList).hide()[this.options.show](this.options.animated);
+
+ this._applyItemState(selectedItem, true);
+ return selectedItem;
+ } else {
+
+ // look for successor based on initial option index
+ var items = this.availableList.find('li'), comparator = this.options.nodeComparator;
+ var succ = null, i = item.data('idx'), direction = comparator(item, $(items[i]));
+
+ // TODO: test needed for dynamic list populating
+ if ( direction ) {
+ while (i>=0 && i 0 ? i++ : i--;
+ if ( direction != comparator(item, $(items[i])) ) {
+ // going up, go back one item down, otherwise leave as is
+ succ = items[direction > 0 ? i : i+1];
+ break;
+ }
+ }
+ } else {
+ succ = items[i];
+ }
+
+ var availableItem = this._cloneWithData(item);
+ succ ? availableItem.insertBefore($(succ)) : availableItem.appendTo(this.availableList);
+ item[this.options.hide](this.options.animated, function() { $(this).remove(); });
+ availableItem.hide()[this.options.show](this.options.animated);
+
+ this._applyItemState(availableItem, false);
+ return availableItem;
+ }
+ },
+ _applyItemState: function(item, selected) {
+ if (selected) {
+ if (this.options.sortable)
+ item.children('span').addClass('ui-icon-arrowthick-2-n-s').removeClass('ui-helper-hidden').addClass('ui-icon');
+ else
+ item.children('span').removeClass('ui-icon-arrowthick-2-n-s').addClass('ui-helper-hidden').removeClass('ui-icon');
+ item.find('a.action span').addClass('ui-icon-minus').removeClass('ui-icon-plus');
+ this._registerRemoveEvents(item.find('a.action'));
+
+ } else {
+ item.children('span').removeClass('ui-icon-arrowthick-2-n-s').addClass('ui-helper-hidden').removeClass('ui-icon');
+ item.find('a.action span').addClass('ui-icon-plus').removeClass('ui-icon-minus');
+ this._registerAddEvents(item.find('a.action'));
+ }
+
+ this._registerDoubleClickEvents(item);
+ this._registerHoverEvents(item);
+ },
+ // taken from John Resig's liveUpdate script
+ _filter: function(list) {
+ var input = $(this);
+ var rows = list.children('li'),
+ cache = rows.map(function(){
+
+ return $(this).text().toLowerCase();
+ });
+
+ var term = $.trim(input.val().toLowerCase()), scores = [];
+
+ if (!term) {
+ rows.show();
+ } else {
+ rows.hide();
+
+ cache.each(function(i) {
+ if (this.indexOf(term)>-1) { scores.push(i); }
+ });
+
+ $.each(scores, function() {
+ $(rows[this]).show();
+ });
+ }
+ },
+ _registerDoubleClickEvents: function(elements) {
+ if (!this.options.doubleClickable) return;
+ elements.dblclick(function() {
+ elements.find('a.action').click();
+ });
+ },
+ _registerHoverEvents: function(elements) {
+ elements.removeClass('ui-state-hover');
+ elements.mouseover(function() {
+ $(this).addClass('ui-state-hover');
+ });
+ elements.mouseout(function() {
+ $(this).removeClass('ui-state-hover');
+ });
+ },
+ _registerAddEvents: function(elements) {
+ var that = this;
+ elements.click(function() {
+ var item = that._setSelected($(this).parent(), true);
+ that.count += 1;
+ that._updateCount();
+ return false;
+ });
+
+ // make draggable
+ if (this.options.sortable) {
+ elements.each(function() {
+ $(this).parent().draggable({
+ connectToSortable: that.selectedList,
+ helper: function() {
+ var selectedItem = that._cloneWithData($(this)).width($(this).width() - 50);
+ selectedItem.width($(this).width());
+ return selectedItem;
+ },
+ appendTo: that.container,
+ containment: that.container,
+ revert: 'invalid'
+ });
+ });
+ }
+ },
+ _registerRemoveEvents: function(elements) {
+ var that = this;
+ elements.click(function() {
+ that._setSelected($(this).parent(), false);
+ that.count -= 1;
+ that._updateCount();
+ return false;
+ });
+ },
+ _registerSearchEvents: function(input) {
+ var that = this;
+
+ input.focus(function() {
+ $(this).addClass('ui-state-active');
+ })
+ .blur(function() {
+ $(this).removeClass('ui-state-active');
+ })
+ .keypress(function(e) {
+ if (e.keyCode == 13)
+ return false;
+ })
+ .keyup(function() {
+ that._filter.apply(this, [that.availableList]);
+ });
+ }
+});
+
+$.extend($.ui.multiselect, {
+ locale: {
+ addAll:'Add all',
+ removeAll:'Remove all',
+ itemsCount:'items selected'
+ }
+});
+
+
+})(jQuery);
diff --git a/htdocs/install/mysql/tables/llx_advtargetemailing.key.sql b/htdocs/install/mysql/tables/llx_advtargetemailing.key.sql
new file mode 100644
index 00000000000..d56b13b427f
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_advtargetemailing.key.sql
@@ -0,0 +1,17 @@
+--
+-- Copyright (C) 2013 Florian Henry florian.henry@open-concept.pro
+--
+-- 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 .
+
+ALTER TABLE llx_advtargetemailing ADD UNIQUE INDEX uk_advtargetemailing_name (name);
diff --git a/htdocs/install/mysql/tables/llx_advtargetemailing.sql b/htdocs/install/mysql/tables/llx_advtargetemailing.sql
new file mode 100644
index 00000000000..2e4ad958755
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_advtargetemailing.sql
@@ -0,0 +1,31 @@
+-- ============================================================================
+-- Copyright (C) 2013 Florian Henry
+--
+-- 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 .
+--
+-- Table of "Plan de comptes" for accountancy expert module
+-- ============================================================================
+
+CREATE TABLE IF NOT EXISTS llx_advtargetemailing
+(
+ rowid integer NOT NULL auto_increment PRIMARY KEY,
+ name varchar(200) NOT NULL,
+ entity integer NOT NULL DEFAULT 1,
+ fk_mailing integer NOT NULL,
+ filtervalue text,
+ fk_user_author integer NOT NULL,
+ datec datetime NOT NULL,
+ fk_user_mod integer NOT NULL,
+ tms timestamp NOT NULL
+)ENGINE=InnoDB;
diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang
index a5f620c7a7a..16c1d089854 100644
--- a/htdocs/langs/en_US/mails.lang
+++ b/htdocs/langs/en_US/mails.lang
@@ -147,3 +147,25 @@ MailSendSetupIs2=You must first go, with an admin account, into menu %sHome - Se
MailSendSetupIs3=If you have any questions on how to setup your SMTP server, you can ask to %s.
YouCanAlsoUseSupervisorKeyword=You can also add the keyword __SUPERVISOREMAIL__ to have email being sent to the supervisor of user (works only if an email is defined for this supervisor)
NbOfTargetedContacts=Current number of targeted contact emails
+MailAdvTargetRecipients=Advance recipients targeting
+AdvTgtTitle=Fill the input ro preselect the customer (or contact) destinaries
+AdvTgtSearchTextHelp=Use %% as magic caracters. For exemple to find all item like jean, joe, jim , you can input j%% , you can also use ; as separator for value, and use ! for except this value. For exemple jean;joe;jim%%;!jimo;!jima% will target all jean, joe, start with jim but not jimo and not everythnig taht start by jima
+AdvTgtSearchIntHelp=Use interval to select int or float value
+AdvTgtMinVal=Minimum value
+AdvTgtMaxVal=Maximum value
+AdvTgtSearchDtHelp=Use interval to select date value
+AdvTgtStartDt=Start dt.
+AdvTgtEndDt=End dt.
+AdvTgtTypeOfIncudeHelp=Target Email of thirdparty and email of contact of the thridparty, or just thridparty email or just contact email
+AdvTgtTypeOfIncude=Type of targeted email
+AdvTgtContactHelp=Use only if you target contact into "Type of targeted email"
+AddAll=Add all
+RemoveAll=Remove all
+ItemsCount=Item(s)
+AdvTgtNameTemplate=Filter name
+AdvTgtAddContact=Add email according filter criteria
+AdvTgtLoadFilter=Load filter
+AdvTgtDeleteFilter=Delete filter
+AdvTgtSaveFilter=Save filter
+AdvTgtCreateFilter=Create filter
+AdvTgtOrCreateNewFilter=Name of new filter
diff --git a/htdocs/websites/class/websitepage.class.php b/htdocs/websites/class/websitepage.class.php
index b363687765f..aa0063f9a2b 100644
--- a/htdocs/websites/class/websitepage.class.php
+++ b/htdocs/websites/class/websitepage.class.php
@@ -47,7 +47,7 @@ class WebsitePage extends CommonObject
/**
*/
-
+
public $fk_website;
public $pageurl;
public $title;
@@ -61,7 +61,7 @@ class WebsitePage extends CommonObject
/**
*/
-
+
/**
* Constructor
@@ -87,7 +87,7 @@ class WebsitePage extends CommonObject
$error = 0;
$now=dol_now();
-
+
// Clean parameters
if (isset($this->fk_website)) {
$this->fk_website = trim($this->fk_website);
@@ -167,7 +167,7 @@ class WebsitePage extends CommonObject
}
// Commit or rollback
- if ($error)
+ if ($error)
{
$this->db->rollback();
@@ -194,7 +194,7 @@ class WebsitePage extends CommonObject
$sql = 'SELECT';
$sql .= ' t.rowid,';
-
+
$sql .= " t.fk_website,";
$sql .= " t.pageurl,";
$sql .= " t.title,";
@@ -205,7 +205,7 @@ class WebsitePage extends CommonObject
$sql .= " t.date_creation,";
$sql .= " t.date_modification,";
$sql .= " t.tms";
-
+
$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
if (null !== $website_id) {
$sql .= ' WHERE t.fk_website = ' . '\'' . $website_id . '\'';
@@ -221,7 +221,7 @@ class WebsitePage extends CommonObject
$obj = $this->db->fetch_object($resql);
$this->id = $obj->rowid;
-
+
$this->fk_website = $obj->fk_website;
$this->pageurl = $obj->pageurl;
$this->title = $obj->title;
@@ -233,7 +233,7 @@ class WebsitePage extends CommonObject
$this->date_modification = $this->db->jdate($obj->date_modification);
$this->tms = $this->db->jdate($obj->tms);
-
+
}
$this->db->free($resql);
@@ -253,7 +253,6 @@ class WebsitePage extends CommonObject
/**
* Load object in memory from the database
*
- * @param string $website_id Web site id
* @param string $sortorder Sort Order
* @param string $sortfield Sort field
* @param int $limit limit
@@ -262,12 +261,12 @@ class WebsitePage extends CommonObject
* @param string $filtermode Filter mode (AND or OR)
* @return array|int int <0 if KO, array of pages if OK
*/
- public function fetchAll($website_id, $sortorder='', $sortfield='', $limit=0, $offset=0, array $filter = array(), $filtermode='AND')
+ public function fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter = array(), $filtermode='AND')
{
dol_syslog(__METHOD__, LOG_DEBUG);
$records=array();
-
+
$sql = 'SELECT';
$sql .= ' t.rowid,';
$sql .= " t.fk_website,";
@@ -281,18 +280,21 @@ class WebsitePage extends CommonObject
$sql .= " t.date_modification,";
$sql .= " t.tms";
$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element. ' as t';
- $sql .= ' WHERE t.fk_website = '.$website_id;
// Manage filter
$sqlwhere = array();
if (count($filter) > 0) {
foreach ($filter as $key => $value) {
- $sqlwhere [] = $key . ' LIKE \'%' . $this->db->escape($value) . '%\'';
+ if ($key=='t.rowid' || $key=='t.fk_website') {
+ $sqlwhere [] = $key . '='. $value;
+ } else {
+ $sqlwhere [] = $key . ' LIKE \'%' . $this->db->escape($value) . '%\'';
+ }
}
}
if (count($sqlwhere) > 0) {
$sql .= ' AND ' . implode(' '.$filtermode.' ', $sqlwhere);
}
-
+
if (!empty($sortfield)) {
$sql .= $this->db->order($sortfield,$sortorder);
}
@@ -305,7 +307,7 @@ class WebsitePage extends CommonObject
if ($resql) {
$num = $this->db->num_rows($resql);
- while ($obj = $this->db->fetch_object($resql))
+ while ($obj = $this->db->fetch_object($resql))
{
$record = new WebsitePage($this->db);
@@ -349,7 +351,7 @@ class WebsitePage extends CommonObject
dol_syslog(__METHOD__, LOG_DEBUG);
// Clean parameters
-
+
if (isset($this->fk_website)) {
$this->fk_website = trim($this->fk_website);
}
@@ -372,14 +374,14 @@ class WebsitePage extends CommonObject
$this->status = trim($this->status);
}
-
+
// Check parameters
// Put here code to add a control on parameters values
// Update request
$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET';
-
+
$sql .= ' fk_website = '.(isset($this->fk_website)?$this->fk_website:"null").',';
$sql .= ' pageurl = '.(isset($this->pageurl)?"'".$this->db->escape($this->pageurl)."'":"null").',';
$sql .= ' title = '.(isset($this->title)?"'".$this->db->escape($this->title)."'":"null").',';
@@ -391,7 +393,7 @@ class WebsitePage extends CommonObject
$sql .= ' date_modification = '.(! isset($this->date_modification) || dol_strlen($this->date_modification) != 0 ? "'".$this->db->idate($this->date_modification)."'" : 'null').',';
$sql .= ' tms = '.(dol_strlen($this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : "'".$this->db->idate(dol_now())."'");
-
+
$sql .= ' WHERE rowid=' . $this->id;
$this->db->begin();
@@ -561,7 +563,7 @@ class WebsitePage extends CommonObject
$result.= $link . $this->ref . $linkend;
return $result;
}
-
+
/**
* Retourne le libelle du status d'un user (actif, inactif)
*
@@ -616,8 +618,8 @@ class WebsitePage extends CommonObject
if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
}
}
-
-
+
+
/**
* Initialise object with example values
* Id must be 0 if object instance is a specimen
@@ -627,7 +629,7 @@ class WebsitePage extends CommonObject
public function initAsSpecimen()
{
$this->id = 0;
-
+
$this->fk_website = '';
$this->pageurl = '';
$this->title = '';
@@ -639,7 +641,7 @@ class WebsitePage extends CommonObject
$this->date_modification = '';
$this->tms = '';
-
+
}
}
diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php
index 1b7532bd0da..73581307c83 100644
--- a/htdocs/websites/index.php
+++ b/htdocs/websites/index.php
@@ -136,20 +136,20 @@ $filetpl=$pathofwebsite.'/page'.$pageid.'.tpl.php';
if ($action == 'add')
{
$db->begin();
-
+
$objectpage->fk_website = $object->id;
-
+
$objectpage->title = GETPOST('WEBSITE_TITLE');
$objectpage->pageurl = GETPOST('WEBSITE_PAGENAME');
$objectpage->description = GETPOST('WEBSITE_DESCRIPTION');
$objectpage->keywords = GETPOST('WEBSITE_KEYWORD');
-
+
if (empty($objectpage->title))
{
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("WEBSITE_PAGENAME")), null, 'errors');
$error++;
}
-
+
if (! $error)
{
$res = $objectpage->create($user);
@@ -175,27 +175,27 @@ if ($action == 'add')
if ($action == 'update')
{
$db->begin();
-
+
$res = $object->fetch(0, $website);
-
+
$objectpage->fk_website = $object->id;
$objectpage->pageurl = GETPOST('WEBSITE_PAGENAME');
-
+
$res = $objectpage->fetch(0, $object->fk_website, $objectpage->pageurl);
-
+
if ($res > 0)
{
$objectpage->title = GETPOST('WEBSITE_TITLE');
$objectpage->description = GETPOST('WEBSITE_DESCRIPTION');
$objectpage->keyword = GETPOST('WEBSITE_KEYWORD');
-
+
$res = $objectpage->update($user);
if (! $res > 0)
{
$error++;
setEventMessages($objectpage->error, $objectpage->errors, 'errors');
}
-
+
if (! $error)
{
$db->commit();
@@ -316,7 +316,7 @@ if ($action == 'updatemeta')
$res = $objectpage->fetch($pageid, $object->fk_website);
if ($res > 0)
{
- $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME');
+ $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME');
$objectpage->title = GETPOST('WEBSITE_TITLE');
$objectpage->description = GETPOST('WEBSITE_DESCRIPTION');
$objectpage->keywords = GETPOST('WEBSITE_KEYWORDS');
@@ -352,12 +352,12 @@ if ($action == 'updatecontent')
$object->fetch(0, $website);
$objectpage->fk_website = $object->id;
-
+
$res = $objectpage->fetch($pageid, $object->fk_website);
if ($res > 0)
{
$objectpage->content = GETPOST('PAGE_CONTENT');
-
+
// Clean data. We remove all the head section.
$objectpage->content = preg_replace('//s', '', $objectpage->content);
/* $objectpage->content = preg_replace('/ /s', '', $objectpage->content); */
@@ -368,7 +368,7 @@ if ($action == 'updatecontent')
$error++;
setEventMessages($objectpage->error, $objectpage->errors, 'errors');
}
-
+
if (! $error)
{
$db->commit();
@@ -450,7 +450,7 @@ if (count($object->records) > 0)
print '';
print $langs->trans("Website").': ';
print '
';
-
+
// List of websites
print '';
$out='';
@@ -467,22 +467,22 @@ if (count($object->records) > 0)
$out.='>';
$out.=$valwebsite->ref;
$out.='';
- $i++;
+ $i++;
}
$out.='';
print $out;
print '
';
-
+
if ($website)
{
print '
'.$langs->trans("ViewSiteInNewTab").' ';
}
print '
';
-
+
// Button for websites
print '';
-
- if ($action == 'preview')
+
+ if ($action == 'preview')
{
$disabled='';
if (empty($user->rights->websites->create)) $disabled=' disabled="disabled"';
@@ -492,7 +492,7 @@ if (count($object->records) > 0)
print ' ';
print ' ';
}
-
+
if (in_array($action, array('editcss','editmenu','create')))
{
if ($action != 'preview') print ' ';
@@ -501,15 +501,15 @@ if (count($object->records) > 0)
}
print '
';
-
-
+
+
// Part for pages
if ($website)
{
print '';
- $array=$objectpage->fetchAll($object->id);
-
+ $array=$objectpage->fetchAll('','',0,0,array('t.fk_website'=>$object->id));
+
print '';
print '
';
print $langs->trans("Page").': ';
@@ -519,17 +519,17 @@ if (count($object->records) > 0)
$out.='';
if (is_array($array) && count($array) > 0)
{
- foreach($array as $key => $valpage)
- {
- if (empty($pageid) && $action != 'create') $pageid=$valpage->id;
-
- $out.=' 0 && $pageid == $key) $out.=' selected'; // To preselect a value
- $out.='>';
- $out.=$valpage->title;
+ foreach($array as $key => $valpage)
+ {
+ if (empty($pageid) && $action != 'create') $pageid=$valpage->id;
+
+ $out.=' 0 && $pageid == $key) $out.=' selected'; // To preselect a value
+ $out.='>';
+ $out.=$valpage->title;
if ($object->fk_default_home && $key == $object->fk_default_home) $out.=' ('.$langs->trans("HomePage").')';
- $out.=' ';
- }
+ $out.='';
+ }
}
else $out.=' ';
$out.=' ';
@@ -546,20 +546,20 @@ if (count($object->records) > 0)
print '
';
print '
';
print '
';
-
+
print '
';
-
- }
+
+ }
}
else
{
@@ -662,7 +662,7 @@ if ($action == 'editmeta' || $action == 'create')
if (GETPOST('WEBSITE_TITLE')) $pagetitle=GETPOST('WEBSITE_TITLE');
if (GETPOST('WEBSITE_DESCRIPTION')) $pagedescription=GETPOST('WEBSITE_DESCRIPTION');
if (GETPOST('WEBSITE_KEYWORDS')) $pagekeywords=GETPOST('WEBSITE_KEYWORDS');
-
+
print '
';
print $langs->trans('WEBSITE_PAGENAME');
print ' ';
@@ -674,25 +674,25 @@ if ($action == 'editmeta' || $action == 'create')
print ' ';
print ' ';
print ' ';
-
+
print '
';
print $langs->trans('WEBSITE_DESCRIPTION');
print ' ';
print ' ';
print ' ';
-
+
print '
';
print $langs->trans('WEBSITE_KEYWORDS');
print ' ';
print ' ';
print ' ';
-
+
print '';
-
+
dol_fiche_end();
-
+
print '
';
-
+
print ' ';
}
@@ -725,7 +725,7 @@ if ($action == 'preview')
if ($pageid > 0)
{
$objectpage->fetch($pageid);
-
+
print "\n".''."\n";
@@ -773,7 +773,7 @@ if ($action == 'preview')
}
}
-
+
llxFooter();