email for the contactform

This commit is contained in:
Ralf Becker 2007-06-06 08:18:45 +00:00
parent df73036d2b
commit 381d421466
6 changed files with 298 additions and 17 deletions

View File

@ -22,15 +22,18 @@ class addressbook_contactform
* Shows the contactform and stores the submitted data * Shows the contactform and stores the submitted data
* *
* @param array $content=null submitted eTemplate content * @param array $content=null submitted eTemplate content
* @param int $addressbook * @param int $addressbook=null int owner-id of addressbook to save contacts too
* @param array $fields * @param array $fields=null field-names to show
* @param string $msg * @param string $msg=null message to show after submitting the form
* @param string $email=null comma-separated email addresses
* @param string $tpl_name=null custom etemplate to use
* @param string $subject=null subject for email
* @return string html content * @return string html content
*/ */
function display($content=null,$addressbook=null,$fields=null,$msg=null) function display($content=null,$addressbook=null,$fields=null,$msg=null,$email=null,$tpl_name=null,$subject=null)
{ {
//echo "<p>addressbook_contactform::display($content,$addressbook,".print_r($fields,true).",$msg)</p>\n"; //echo "<p>addressbook_contactform::display($content,$addressbook,".print_r($fields,true).",$msg)</p>\n";
$tpl = new etemplate('addressbook.contactform'); $tpl = new etemplate($tpl_name ? $tpl_name : 'addressbook.contactform');
if (is_array($content)) if (is_array($content))
{ {
@ -40,13 +43,19 @@ class addressbook_contactform
} }
elseif ($content['submitit']) elseif ($content['submitit'])
{ {
if ($content['owner']) // save the contact in the addressbook
{
$content['addressbook'] = $addressbook;
require_once(EGW_INCLUDE_ROOT.'/addressbook/inc/class.bocontacts.inc.php'); require_once(EGW_INCLUDE_ROOT.'/addressbook/inc/class.bocontacts.inc.php');
$contact = new bocontacts(); $contact = new bocontacts();
if ($content['owner']) // save the contact in the addressbook
{
if ($content['email_contactform']) // only necessary as long addressbook is not doing this itself
{
require_once(EGW_INCLUDE_ROOT.'/addressbook/inc/class.addressbook_tracking.inc.php');
$tracking = new addressbook_tracking($contact);
}
if ($contact->save($content)) if ($contact->save($content))
{ {
$tracking->do_notifications($content,null); // only necessary as long addressbook is not doing this itself
return '<p align="center">'.$content['msg'].'</p>'; return '<p align="center">'.$content['msg'].'</p>';
} }
else else
@ -55,9 +64,22 @@ class addressbook_contactform
lang('The anonymous user has probably no add rights for this addressbook.').'</p>'; lang('The anonymous user has probably no add rights for this addressbook.').'</p>';
} }
} }
else // todo email else // this is only called, if we send only email and dont save it
{ {
return 'email not yet implemented!'; if ($contact['email_contactform'])
{
require_once(EGW_INCLUDE_ROOT.'/addressbook/inc/class.addressbook_tracking.inc.php');
$tracking = new addressbook_tracking($contact);
}
if ($tracking->do_notifications($content,null))
{
return '<p align="center">'.$content['msg'].'</p>';
}
else
{
return '<p align="center">'.lang('There was an error saving your data :-(').'<br />'.
lang('Either the configured email addesses are wrong or the mail configuration.').'</p>';
}
} }
} }
} }
@ -65,6 +87,9 @@ class addressbook_contactform
{ {
$preserv['owner'] = $addressbook; $preserv['owner'] = $addressbook;
$preserv['msg'] = $msg; $preserv['msg'] = $msg;
$preserv['is_contactform'] = true;
$preserv['email_contactform'] = $email;
$preserv['subject_contactform'] = $subject;
if (!$fields) $fields = array('org_name','n_fn','email','tel_work','url','note','captcha'); if (!$fields) $fields = array('org_name','n_fn','email','tel_work','url','note','captcha');
$custom = 1; $custom = 1;
foreach($fields as $name) foreach($fields as $name)

View File

@ -0,0 +1,217 @@
<?php
/**
* Addressbook - history and notifications
*
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @package tracker
* @copyright (c) 2007 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
require_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.bo_tracking.inc.php');
/**
* Addressbook - tracking object
*/
class addressbook_tracking extends bo_tracking
{
/**
* Application we are tracking (required!)
*
* @var string
*/
var $app = 'addressbook';
/**
* Name of the id-field, used as id in the history log (required!)
*
* @var string
*/
var $id_field = 'id';
/**
* Name of the field with the creator id, if the creator of an entry should be notified
*
* @var string
*/
var $creator_field = 'creator';
/**
* Name of the field with the id(s) of assinged users, if they should be notified
*
* @var string
*/
var $assigned_field;
/**
* Translate field-name to 2-char history status
*
* @var array
*/
var $field2history = array(
);
/**
* Should the user (passed to the track method or current user if not passed) be used as sender or get_config('sender')
*
* @var boolean
*/
var $prefer_user_as_sender = true;
/**
* Instance of the bocontacts class calling us
*
* @access private
* @var bocontacts
*/
var $contacts;
/**
* Constructor
*
* @param bocontacts &$bocontacts
* @return tracker_tracking
*/
function addressbook_tracking(&$bocontacts)
{
$this->contacts =& $bocontacts;
}
/**
* Get a notification-config value
*
* @param string $what
* - 'copy' array of email addresses notifications should be copied too, can depend on $data
* - 'lang' string lang code for copy mail
* - 'sender' string send email address
* @param array $data current entry
* @param array $old=null old/last state of the entry or null for a new entry
* @return mixed
*/
function get_config($name,$data,$old)
{
//echo "<p>addressbook_tracking::get_config($name,".print_r($data,true).",...)</p>\n";
switch($name)
{
case 'copy':
if ($data['is_contactform'])
{
return split(', ?',$data['email_contactform']);
}
break;
case 'sender':
if ($data['is_contactform'])
{
//echo "<p>addressbook_tracking::get_config($name,...) email={$data['email']}, n_given={$data['n_given']}, n_family={$data['n_family']}</p>\n";
return $data['email'] ? $data['n_given'].' '.$data['n_family'].' <'.$data['email'].'>' : null;
}
break;
}
return null;
}
/**
* Get the modified / new message (1. line of mail body) for a given entry, can be reimplemented
*
* @param array $data
* @param array $old
* @return string
*/
function get_message($data,$old)
{
if (!$data['modified'] || !$old)
{
return lang('New contact submitted by %1 at %2',
$GLOBALS['egw']->common->grab_owner_name($data['creator']),
$this->datetime($data['created']-$this->tracker->tz_offset_s));
}
return lang('Contact modified by %1 at %2',
$GLOBALS['egw']->common->grab_owner_name($data['modifier']),
$this->datetime($data['modified']-$this->tracker->tz_offset_s));
}
/**
* Get the subject of the notification
*
* @param array $data
* @param array $old
* @return string
*/
function get_subject($data,$old)
{
if ($data['is_contactform'])
{
$prefix = ($data['subject_contactform'] ? $data['subject_contactform'] : lang('Contactform')).': ';
}
return $prefix.parent::get_subject($data,$old);
}
/**
* Get the details of an entry
*
* @param array $data
* @param string $datetime_format of user to notify, eg. 'Y-m-d H:i'
* @param int $tz_offset_s offset in sec to be add to server-time to get the user-time of the user to notify
* @return array of details as array with values for keys 'label','value','type'
*/
function get_details($data)
{
foreach($this->contacts->contact_fields as $name => $label)
{
if (!$data[$name] && $name != 'owner') continue;
switch($name)
{
case 'n_prefix': case 'n_given': case 'n_middle': case 'n_family': case 'n_suffix': // already in n_fn
case 'tid':
break;
case 'created': case 'modified':
$details[$name] = array(
'label' => $label,
'value' => $this->datetime($data[$name]-$this->contacts->tz_offset_s),
);
break;
case 'bday':
if ($data[$name])
{
list($y,$m,$d) = explode('-',$data[$name]);
$details[$name] = array(
'label' => $label,
'value' => $GLOBALS['egw']->common->dateformatorder($y,$m,$d,true),
);
}
break;
case 'owner': case 'creator': case 'modifier':
$details[$name] = array(
'label' => $label,
'value' => $GLOBALS['egw']->common->grab_owner_name($data[$name]),
);
break;
case 'cat_id':
if ($data[$name])
{
$cats = array();
foreach(is_array($data[$name]) ? $data[$name] : explode(',',$data[$name]) as $cat_id)
{
$cats[] = $GLOBALS['egw']->cats->id2name($cat_id);
}
$details[$name] = array(
'label' => $label,
'value' => explode(', ',$cats),
);
}
case 'note':
$details[$name] = array(
'label' => $label,
'value' => $data[$name],
'type' => 'multiline',
);
break;
default:
$details[$name] = array(
'label' => $label,
'value' => $data[$name],
);
break;
}
}
return $details;
}
}

View File

@ -80,6 +80,7 @@ contact copied addressbook de Kontakt kopiert
contact deleted addressbook de Kontakt gelöscht contact deleted addressbook de Kontakt gelöscht
contact fields to show addressbook de Kontaktfelder die angezeigt werden sollen contact fields to show addressbook de Kontaktfelder die angezeigt werden sollen
contact id addressbook de Kontakt ID contact id addressbook de Kontakt ID
contact modified by %1 at %2 addressbook de Kontakt geändert von %1 am %2
contact repository admin de Speicherort Kontakte contact repository admin de Speicherort Kontakte
contact saved addressbook de Kontakt gespeichert contact saved addressbook de Kontakt gespeichert
contact settings admin de Kontakt Einstellungen contact settings admin de Kontakt Einstellungen
@ -97,6 +98,7 @@ credit addressbook de Darlehen
csv-fieldname addressbook de CSV-Feldname csv-fieldname addressbook de CSV-Feldname
csv-filename addressbook de CSV-Dateiname csv-filename addressbook de CSV-Dateiname
custom addressbook de Benutzerdefiniert custom addressbook de Benutzerdefiniert
custom etemplate for the contactform addressbook de Eigenes eTemplate für das Kontaktformular
custom fields addressbook de Benutzerdefinierte Felder custom fields addressbook de Benutzerdefinierte Felder
debug output in browser addressbook de Debugausgaben in Browser debug output in browser addressbook de Debugausgaben in Browser
default address format addressbook de Vorgabe für Format der Adresse default address format addressbook de Vorgabe für Format der Adresse
@ -125,7 +127,9 @@ edit custom field addressbook de Benutzerdefiniertes Feld bearbeiten
edit custom fields admin de Benutzerdefinierte Felder bearbeiten edit custom fields admin de Benutzerdefinierte Felder bearbeiten
edit extra account-data in the addressbook admin de Zusätzliche Benutzerdaten im Adressbuch bearbeiten. edit extra account-data in the addressbook admin de Zusätzliche Benutzerdaten im Adressbuch bearbeiten.
edit phonenumbers - addressbook de Telefonnummern bearbeiten edit phonenumbers - addressbook de Telefonnummern bearbeiten
either the configured email addesses are wrong or the mail configuration. addressbook de Entweder die konfigurierte Email Adresse ist falsch oder die Mail Konfiguration.
email & internet addressbook de E-Mail & Internet email & internet addressbook de E-Mail & Internet
email addresses (comma separated) to send the contact data addressbook de Email Adressen (Komma getrennt) zum Senden der Kontaktdaten
empty for all addressbook de leer für alle empty for all addressbook de leer für alle
enable an extra private addressbook addressbook de Privates Adressbuch einschalten enable an extra private addressbook addressbook de Privates Adressbuch einschalten
enter the path to the exported file here addressbook de Bitte geben Sie den Pfad für die exportierte Datei an enter the path to the exported file here addressbook de Bitte geben Sie den Pfad für die exportierte Datei an
@ -222,6 +226,7 @@ moved addressbook de verschoben
multiple vcard addressbook de Mehrere VCards multiple vcard addressbook de Mehrere VCards
name for the distribution list addressbook de Name für die Verteilerliste name for the distribution list addressbook de Name für die Verteilerliste
name, address addressbook de Name, Adresse name, address addressbook de Name, Adresse
new contact submitted by %1 at %2 addressbook de Neuer Kontakt eingetragen von %1 am %2
no vcard addressbook de Keine VCard no vcard addressbook de Keine VCard
number addressbook de Nummer number addressbook de Nummer
number of records to read (%1) addressbook de Anzahl der einzulesenden Datensätze (%1) number of records to read (%1) addressbook de Anzahl der einzulesenden Datensätze (%1)
@ -281,6 +286,7 @@ start admin de Starten
startrecord addressbook de Startdatensatz startrecord addressbook de Startdatensatz
state common de Bundesland state common de Bundesland
street common de Straße street common de Straße
subject for email addressbook de Betreff der Email
successfully imported %1 records into your addressbook. addressbook de %1 Kontakte wurden erfolgreich in Ihr Adressbuch importiert successfully imported %1 records into your addressbook. addressbook de %1 Kontakte wurden erfolgreich in Ihr Adressbuch importiert
suffix addressbook de Zusatz suffix addressbook de Zusatz
tel home addressbook de Telefon privat tel home addressbook de Telefon privat
@ -332,6 +338,7 @@ you are not permittet to delete this contact addressbook de Sie haben nicht die
you are not permittet to edit this contact addressbook de Sie haben nicht die Berechtigung diesen Kontakt zu bearbeiten you are not permittet to edit this contact addressbook de Sie haben nicht die Berechtigung diesen Kontakt zu bearbeiten
you are not permittet to view this contact addressbook de Sie haben nicht die Berechtigung diesen Kontakt zu betrachen you are not permittet to view this contact addressbook de Sie haben nicht die Berechtigung diesen Kontakt zu betrachen
you can only use ldap as contact repository if the accounts are stored in ldap too! admin de Sie können LDAP nur dann zum Speichern von Kontakten verwenden, wenn die Benutzerkonten auch in LDAP gespeichert sind! you can only use ldap as contact repository if the accounts are stored in ldap too! admin de Sie können LDAP nur dann zum Speichern von Kontakten verwenden, wenn die Benutzerkonten auch in LDAP gespeichert sind!
you can respond by visiting: addressbook de Link zum Anzeigen:
you must select a vcard. (*.vcf) addressbook de Sie müssen eine VCard auswählen (*.vcf) you must select a vcard. (*.vcf) addressbook de Sie müssen eine VCard auswählen (*.vcf)
you must select at least 1 column to display addressbook de Sie müssen mindestens eine Spalte zum Anzeigen auswählen you must select at least 1 column to display addressbook de Sie müssen mindestens eine Spalte zum Anzeigen auswählen
you need to select a distribution list addressbook de Sie müssen eine Verteilerliste auswählen you need to select a distribution list addressbook de Sie müssen eine Verteilerliste auswählen

View File

@ -80,6 +80,7 @@ contact copied addressbook en Contact copied
contact deleted addressbook en Contact deleted contact deleted addressbook en Contact deleted
contact fields to show addressbook en Contact fields to show contact fields to show addressbook en Contact fields to show
contact id addressbook en Contact ID contact id addressbook en Contact ID
contact modified by %1 at %2 addressbook en Contact modified by %1 at %2
contact repository admin en Contact repository contact repository admin en Contact repository
contact saved addressbook en Contact saved contact saved addressbook en Contact saved
contact settings admin en Contact Settings contact settings admin en Contact Settings
@ -97,6 +98,7 @@ credit addressbook en Credit
csv-fieldname addressbook en CSV-Fieldname csv-fieldname addressbook en CSV-Fieldname
csv-filename addressbook en CSV-Filename csv-filename addressbook en CSV-Filename
custom addressbook en Custom custom addressbook en Custom
custom etemplate for the contactform addressbook en Custom eTemplate for the contactform
custom fields addressbook en Custom Fields custom fields addressbook en Custom Fields
debug output in browser addressbook en Debug output in browser debug output in browser addressbook en Debug output in browser
default address format addressbook en Default address format default address format addressbook en Default address format
@ -125,7 +127,9 @@ edit custom field addressbook en Edit Custom Field
edit custom fields admin en Edit Custom Fields edit custom fields admin en Edit Custom Fields
edit extra account-data in the addressbook admin en Edit extra account-data in the addressbook edit extra account-data in the addressbook admin en Edit extra account-data in the addressbook
edit phonenumbers - addressbook en Edit Phonenumbers - edit phonenumbers - addressbook en Edit Phonenumbers -
either the configured email addesses are wrong or the mail configuration. addressbook en Either the configured email addesses are wrong or the mail configuration.
email & internet addressbook en Email & Internet email & internet addressbook en Email & Internet
email addresses (comma separated) to send the contact data addressbook en Email addresses (comma separated) to send the contact data
empty for all addressbook en empty for all empty for all addressbook en empty for all
enable an extra private addressbook addressbook en Enable an extra private addressbook enable an extra private addressbook addressbook en Enable an extra private addressbook
enter the path to the exported file here addressbook en Enter the path to the exported file here enter the path to the exported file here addressbook en Enter the path to the exported file here
@ -222,6 +226,7 @@ moved addressbook en moved
multiple vcard addressbook en Multiple VCard multiple vcard addressbook en Multiple VCard
name for the distribution list addressbook en Name for the distribution list name for the distribution list addressbook en Name for the distribution list
name, address addressbook en Name, Address name, address addressbook en Name, Address
new contact submitted by %1 at %2 addressbook en New contact submitted by %1 at %2
no vcard addressbook en No VCard no vcard addressbook en No VCard
number addressbook en Number number addressbook en Number
number of records to read (%1) addressbook en Number of records to read (%1) number of records to read (%1) addressbook en Number of records to read (%1)
@ -281,6 +286,7 @@ start admin en Start
startrecord addressbook en Startrecord startrecord addressbook en Startrecord
state common en State state common en State
street common en Street street common en Street
subject for email addressbook en Subject for email
successfully imported %1 records into your addressbook. addressbook en Successfully imported %1 record(s) into your addressbook. successfully imported %1 records into your addressbook. addressbook en Successfully imported %1 record(s) into your addressbook.
suffix addressbook en Suffix suffix addressbook en Suffix
tel home addressbook en tel home tel home addressbook en tel home
@ -332,6 +338,7 @@ you are not permittet to delete this contact addressbook en You are not permitte
you are not permittet to edit this contact addressbook en You are not permittet to edit this contact you are not permittet to edit this contact addressbook en You are not permittet to edit this contact
you are not permittet to view this contact addressbook en you are not permittet to view this contact you are not permittet to view this contact addressbook en you are not permittet to view this contact
you can only use ldap as contact repository if the accounts are stored in ldap too! admin en You can only use LDAP as contact repository if the accounts are stored in LDAP too! you can only use ldap as contact repository if the accounts are stored in ldap too! admin en You can only use LDAP as contact repository if the accounts are stored in LDAP too!
you can respond by visiting: addressbook en To view it visit:
you must select a vcard. (*.vcf) addressbook en You must select a vcard. (*.vcf) you must select a vcard. (*.vcf) addressbook en You must select a vcard. (*.vcf)
you must select at least 1 column to display addressbook en You must select at least 1 column to display you must select at least 1 column to display addressbook en You must select at least 1 column to display
you need to select a distribution list addressbook en You need to select a distribution list you need to select a distribution list addressbook en You need to select a distribution list

View File

@ -79,6 +79,17 @@ class module_addressbook_contactform extends sitemgr_module
'' => lang('None'), '' => lang('None'),
)+$uicontacts->get_addressbooks(EGW_ACL_ADD) // add to not show the accounts! )+$uicontacts->get_addressbooks(EGW_ACL_ADD) // add to not show the accounts!
), ),
'arg4' => array(
'type' => 'textfield',
'label' => lang('Email addresses (comma separated) to send the contact data'),
'params' => array('size' => 80),
),
'arg6' => array(
'type' => 'textfield',
'label' => lang('Subject for email'),
'params' => array('size' => 80),
'default' => lang('Contactform'),
),
'arg2' => array( 'arg2' => array(
'type' => 'select', 'type' => 'select',
'label' => lang('Contact fields to show'), 'label' => lang('Contact fields to show'),
@ -93,6 +104,12 @@ class module_addressbook_contactform extends sitemgr_module
'params' => array('size' => 80), 'params' => array('size' => 80),
'default' => lang('Thank you for contacting us.'), 'default' => lang('Thank you for contacting us.'),
), ),
'arg5' => array(
'type' => 'textfield',
'label' => lang('Custom eTemplate for the contactform'),
'params' => array('size' => 40),
'default' => 'addressbook.contactform',
),
); );
return parent::get_user_interface(); return parent::get_user_interface();
} }

View File

@ -306,7 +306,7 @@ class bo_tracking
{ {
if (!$email) return false; if (!$email) return false;
//echo "<p>botracker::send_notification(,'$email',$user_or_lang)</p>\n"; //echo "<p>bo_trackering::send_notification(,'$email',$user_or_lang)</p>\n";
//echo "old"; _debug_array($old); //echo "old"; _debug_array($old);
//echo "data"; _debug_array($data); //echo "data"; _debug_array($data);
@ -366,7 +366,7 @@ class bo_tracking
} }
$send->AddCustomHeader("X-eGroupWare-type: {$this->app}update"); $send->AddCustomHeader("X-eGroupWare-type: {$this->app}update");
$sender = $this->get_sender($user,$data,$old); $sender = $this->get_sender($data,$old);
if (preg_match('/^(.+) *<(.+)>/',$sender,$matches)) // allow to use eg. "Ralf Becker <ralf@egw.org>" as sender if (preg_match('/^(.+) *<(.+)>/',$sender,$matches)) // allow to use eg. "Ralf Becker <ralf@egw.org>" as sender
{ {
$send->From = $matches[2]; $send->From = $matches[2];
@ -393,6 +393,7 @@ class bo_tracking
} }
} }
//echo "<p>bo_trackering::send_notification(): sending <pre>".print_r($send,true)."</pre>\n";
if (!$send->Send()) if (!$send->Send())
{ {
$this->errors[] = lang('Error while notifying %1: %2',$email,$send->ErrorInfo); $this->errors[] = lang('Error while notifying %1: %2',$email,$send->ErrorInfo);
@ -418,6 +419,7 @@ class bo_tracking
* The default implementation prefers depending on the prefer_user_as_sender class-var the user over * The default implementation prefers depending on the prefer_user_as_sender class-var the user over
* what is returned by get_config('sender'). * what is returned by get_config('sender').
* *
* @param int $user account_lid of user
* @param array $data * @param array $data
* @param array $old * @param array $old
* @return string * @return string
@ -425,15 +427,21 @@ class bo_tracking
function get_sender($data,$old) function get_sender($data,$old)
{ {
$sender = $this->get_config('sender',$data,$old); $sender = $this->get_config('sender',$data,$old);
//echo "<p>bo_tracking::get_sender() get_config('sender',...)='".htmlspecialchars($sender)."'</p>\n";
if (($this->prefer_user_as_sender || !$sender) && $this->user && if (($this->prefer_user_as_sender || !$sender) && $this->user &&
($email = $GLOBALS['egw']->accounts->id2name($this->user,'account_email'))) ($email = $GLOBALS['egw']->accounts->id2name($this->user,'account_email')))
{ {
$name = $GLOBALS['egw']->accounts->id2name($this->user,'account_fullname'); $name = $GLOBALS['egw']->accounts->id2name($this->user,'account_fullname');
return $name ? $name.' <'.$email.'>' : $email; $sender = $name ? $name.' <'.$email.'>' : $email;
} }
return $sender ? $sender : 'eGroupWare '.lang($this->app).' <noreply@'.$GLOBALS['egw_info']['server']['mail_suffix']; elseif(!$sender)
{
$sender = 'eGroupWare '.lang($this->app).' <noreply@'.$GLOBALS['egw_info']['server']['mail_suffix'].'>';
}
//echo "<p>bo_tracking::get_sender()='".htmlspecialchars($sender)."'</p>\n";
return $sender;
} }
/** /**
@ -528,7 +536,7 @@ class bo_tracking
foreach($this->get_details($data) as $name => $detail) foreach($this->get_details($data) as $name => $detail)
{ {
$modified = $old && $data[$name] != $old[$name]; $modified = $old && $data[$name] != $old[$name];
if ($modified) error_log("data[$name]='{$data[$name]}', old[$name]='{$old[$name]}' --> modified=".(int)$modified); //if ($modified) error_log("data[$name]='{$data[$name]}', old[$name]='{$old[$name]}' --> modified=".(int)$modified);
if (empty($detail['value']) && !$modified) continue; // skip unchanged, empty values if (empty($detail['value']) && !$modified) continue; // skip unchanged, empty values
$body .= $this->format_line($html_email,$detail['type'],$modified, $body .= $this->format_line($html_email,$detail['type'],$modified,