if ($state['order'] != 'asc' && $state['order'] != 'desc') {
    $state['order'] = 'asc';
}
if (!is_numeric($state['sort']) && $state['sort'] != 'email' && $state['sort'] != 'ip' && $state['sort'] != 'time_registered' && $state['sort'] != 'time_touched') {
    $state['sort'] = 'email';
}
if (!is_numeric($state['status'])) {
    $state['status'] = 1;
}
if (!is_numeric($state['group']) && $state['group'] != 'all') {
    $state['group'] = 'all';
}
if (isset($_REQUEST['searchClear'])) {
    $state['search'] = false;
} elseif (isset($_REQUEST['searchField']) && (is_numeric($_REQUEST['searchField']) || $_REQUEST['searchField'] == 'email' || $_REQUEST['searchField'] == 'ip' || $_REQUEST['searchField'] == 'time_registered' || $_REQUEST['searchField'] == 'time_touched')) {
    $_REQUEST['searchString'] = trim($_REQUEST['searchString']);
    $state['search'] = empty($_REQUEST['searchString']) ? false : array('field' => $_REQUEST['searchField'], 'string' => trim($_REQUEST['searchString']));
}
/**********************************
	DISPLAY METHODS
*********************************/
// Get the *empty* group [no member IDs. 3rd arg is set TRUE]
$group = new PommoGroup($state['group'], $state['status'], $state['search']);
// Calculate and Remember number of pages for this group/status combo
$state['pages'] = is_numeric($group->_tally) && $group->_tally > 0 ? ceil($group->_tally / $state['limit']) : 0;
$smarty->assign('state', $state);
$smarty->assign('tally', $group->_tally);
$smarty->assign('groups', PommoGroup::get());
$smarty->assign('fields', PommoField::get());
$smarty->display('admin/subscribers/subscribers_manage.tpl');
Pommo::kill();
 * the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with program; see the file docs/LICENSE. If not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */
require '../../../bootstrap.php';
Pommo::requireOnce($pommo->_baseDir . 'inc/helpers/subscribers.php');
Pommo::requireOnce($pommo->_baseDir . 'inc/helpers/fields.php');
Pommo::requireOnce($pommo->_baseDir . 'inc/helpers/groups.php');
$pommo->init();
$logger =& $pommo->_logger;
$dbo =& $pommo->_dbo;
$pommo->toggleEscaping(TRUE);
$state =& PommoAPI::stateInit('subscribers_manage');
$fields = PommoField::get();
$ids = FALSE;
if (!empty($_POST['ids'])) {
    $ids = explode(',', $_POST['ids']);
}
// ====== CSV EXPORT ======
if ($_POST['type'] == 'csv') {
    if (!$ids) {
        $group = new PommoGroup($state['group'], $state['status']);
        $subscribers = $group->members();
    } else {
        $subscribers = PommoSubscriber::get(array('id' => $ids));
    }
    // supply headers
    $o = '"' . Pommo::_T('Email') . '"';
    if (!empty($_POST['registered'])) {
Ejemplo n.º 3
0
 function &search(&$subject)
 {
     $personalizations = array();
     $matches = array();
     $pattern = '/\\[\\[[^\\]]+\\]\\]/';
     if (preg_match_all($pattern, $subject, $matches) < 1) {
         return $personalizations;
     }
     $fields = PommoField::get();
     foreach ($matches[0] as $str) {
         $p = array();
         $p['search'] = $str;
         $a = explode('|', trim($str, '[]'));
         $p['field'] = $a[0];
         $p['default'] = isset($a[1]) ? $a[1] : false;
         foreach ($fields as $f) {
             if ($f['name'] == $p['field']) {
                 $p['field_id'] = $f['id'];
             }
         }
         array_push($personalizations, $p);
     }
     return $personalizations;
 }
Ejemplo n.º 4
0
?>
">
<fieldset>
<legend>Subscribe</legend>

<!--	Email field must be named "Email" -->
<div>
<label for="email"><strong><?php 
echo Pommo::_T('Your Email:');
?>
</strong></label>
<input type="text" name="Email" id="email" maxlength="60" />
</div>

<?php 
$fields =& PommoField::get(array('active' => TRUE, 'byName' => FALSE));
foreach (array_keys($fields) as $field_id) {
    $field =& $fields[$field_id];
    if ($field['required'] == 'on') {
        echo "<!--\tBEGIN INPUT FOR REQUIRED FIELD \"" . $field['name'] . "\" -->\r\n<div>\r\n<label for=\"field" . $field_id . "\"><strong>" . $field['prompt'] . ":</strong></label>\r\n";
    } else {
        echo "<!--\tBEGIN INPUT FOR FIELD \"" . $field['name'] . "\" -->\r\n<div>\r\n<label for=\"field" . $field_id . "\">" . $field['prompt'] . ":</label>\r\n";
    }
    switch ($field['type']) {
        case "checkbox":
            // checkbox
            if (empty($field['normally'])) {
                echo "\r\n<input type=\"checkbox\" name=\"d[" . $field_id . "]\" id=\"field" . $field_id . "\" />";
            } else {
                echo "\r\n<input type=\"checkbox\" name=\"d[" . $field_id . "]\" id=\"field" . $field_id . "\" checked=\"checked\" />";
            }
Ejemplo n.º 5
0
 function prepareForSubscribeForm()
 {
     global $pommo;
     $dbo =& $pommo->_dbo;
     Pommo::requireOnce($pommo->_baseDir . 'inc/helpers/fields.php');
     // Get array of fields. Key is ID, value is an array of the demo's info
     $fields = PommoField::get(array('active' => TRUE, 'byName' => FALSE));
     if (!empty($fields)) {
         $this->assign('fields', $fields);
     }
     foreach ($fields as $field) {
         if ($field['type'] == 'date') {
             $this->assign('datePicker', TRUE);
         }
     }
     // process.php appends serialized values to _GET['input']
     // TODO --> look into this behavior... necessary?
     if (isset($_GET['input'])) {
         $this->assign(unserialize($_GET['input']));
     } elseif (isset($_GET['Email'])) {
         $this->assign(array('Email' => $_GET['Email']));
     }
     $this->assign($_POST);
 }
Ejemplo n.º 6
0
 function subscriberData(&$in, $p = array())
 {
     $defaults = array('prune' => true, 'active' => true, 'log' => true, 'ignore' => false, 'ignoreInactive' => true, 'skipReq' => false);
     $p = PommoAPI::getParams($defaults, $p);
     global $pommo;
     $pommo->requireOnce($GLOBALS['pommo']->_baseDir . 'inc/helpers/fields.php');
     $logger =& $pommo->_logger;
     $fields = PommoField::get(array('active' => $p['active']));
     $valid = true;
     foreach ($fields as $id => $field) {
         $inactive = $field['active'] == 'on' ? false : true;
         if (!isset($in[$id]) && $p['skipReq']) {
             continue;
         }
         $in[$id] = @trim($in[$id]);
         if (empty($in[$id])) {
             unset($in[$id]);
             // don't include blank values
             if ($field['required'] == 'on') {
                 if ($p['log']) {
                     $logger->addErr(sprintf(Pommo::_T('%s is a required field.'), $field['prompt']));
                 }
                 $valid = false;
             }
             continue;
         }
         // shorten
         $in[$id] = substr($in[$id], 0, 255);
         switch ($field['type']) {
             case "checkbox":
                 if (strtolower($in[$id]) == 'true') {
                     $in[$id] = 'on';
                 }
                 if (strtolower($in[$id]) == 'false') {
                     $in[$id] = '';
                 }
                 if ($in[$id] != 'on' && $in[$id] != '') {
                     if ($p['ignore'] || $inactive && $p['ignoreInactive']) {
                         unset($in[$id]);
                         break;
                     }
                     if ($p['log']) {
                         $logger->addErr(sprintf(Pommo::_T('Illegal input for field %s.'), $field['prompt']));
                     }
                     $valid = false;
                 }
                 break;
             case "multiple":
                 if (is_array($in[$id])) {
                     foreach ($in[$id] as $key => $val) {
                         if (!in_array($val, $field['array'])) {
                             if ($p['ignore'] || $inactive && $p['ignoreInactive']) {
                                 unset($in[$id]);
                                 break;
                             }
                             if ($p['log']) {
                                 $logger->addErr(sprintf(Pommo::_T('Illegal input for field %s.'), $field['prompt']));
                             }
                             $valid = false;
                         }
                     }
                 } elseif (!in_array($in[$id], $field['array'])) {
                     if ($p['ignore'] || $inactive && $p['ignoreInactive']) {
                         unset($in[$id]);
                         break;
                     }
                     if ($p['log']) {
                         $logger->addErr(sprintf(Pommo::_T('Illegal input for field %s.'), $field['prompt']));
                     }
                     $valid = false;
                 }
                 break;
             case "date":
                 // convert date to timestamp [float; using adodb time library]
                 if (is_numeric($in[$id])) {
                     $in[$id] = PommoHelper::timeToStr($in[$id]);
                 }
                 $in[$id] = PommoHelper::timeFromStr($in[$id]);
                 if (!$in[$id]) {
                     if ($p['ignore'] || $inactive && $p['ignoreInactive']) {
                         unset($in[$id]);
                         break;
                     }
                     if ($p['log']) {
                         $logger->addErr(sprintf(Pommo::_T('Field (%s) must be a date ('), $field['prompt']));
                     }
                     $valid = false;
                 }
                 break;
             case "number":
                 if (!is_numeric($in[$id])) {
                     if ($p['ignore'] || $inactive && $p['ignoreInactive']) {
                         unset($in[$id]);
                         break;
                     }
                     if ($p['log']) {
                         $logger->addErr(sprintf(Pommo::_T('Field (%s) must be a number.'), $field['prompt']));
                     }
                     $valid = false;
                 }
                 break;
         }
     }
     // prune
     if ($p['prune']) {
         $in = PommoHelper::arrayIntersect($in, $fields);
     }
     return $valid;
 }
Ejemplo n.º 7
0
 case 'delOption':
     // validate field ID
     $field = current(PommoField::get(array('id' => $_REQUEST['field_id'])));
     if ($field['id'] != $_REQUEST['field_id']) {
         die('bad field ID');
     }
     $affected = PommoField::subscribersAffected($field['id'], $_REQUEST['options']);
     if (count($affected) > 0 && empty($_REQUEST['confirmed'])) {
         $msg = sprintf(Pommo::_T('Deleting option %1$s will affect %2$s subscribers who have selected this choice. They will be flagged as needing to update their records.'), '<b>' . $_REQUEST['options'] . '</b>', '<em>' . count($affected) . '</em>');
         $msg .= "\n " . Pommo::_T('Are you sure?');
         $json->add('callbackFunction', 'confirm');
         $json->add('callbackParams', $msg);
         $json->serve();
     } else {
         Pommo::requireOnce($pommo->_baseDir . 'inc/helpers/subscribers.php');
         $options = PommoField::optionDel($field, $_REQUEST['options']);
         if (!options) {
             $json->fail(Pommo::_T('Error with deletion.'));
         }
         // flag subscribers for update
         if (count($affected) > 0) {
             PommoSubscriber::flagByID($affected);
         }
         $json->add('callbackFunction', 'updateOptions');
         $json->add('callbackParams', $options);
         $json->serve();
     }
     break;
 default:
     die('invalid request passed to ' . __FILE__);
     break;
Ejemplo n.º 8
0
    	 *********************************/
    Pommo::requireOnce($pommo->_baseDir . 'inc/classes/json.php');
    $json = new PommoJSON();
    SmartyValidate::connect($smarty);
    if (SmartyValidate::is_valid($_POST)) {
        // __ FORM IS VALID
        // TODO -> Which below logic is better? the computed diff, or send all fields for update?
        /*
        // make a difference between updated & original field
        $update = array_diff_assoc(PommoField::makeDB($_POST),$field);
        // restore the ID
        $update['id'] = $field['id'];
        */
        // let MySQL do the difference processing
        $update = PommoField::makeDB($_POST);
        if (!PommoField::update($update)) {
            $json->fail('error updating field');
        }
        $json->add('callbackFunction', 'updateField');
        $json->add('callbackParams', $update);
        $json->success(Pommo::_T('Settings updated.'));
    } else {
        // __ FORM NOT VALID
        $json->add('fieldErrors', $smarty->getInvalidFields());
        $json->fail(Pommo::_T('Please review and correct errors with your submission.'));
    }
}
$f_text = sprintf(Pommo::_T('%s - Any value will be accepted for text fields. They are useful for collecting names, addresses, etc.'), '<strong>' . $field['name'] . ' (' . Pommo::_T('Text') . ')</strong>');
$f_check = sprintf(Pommo::_T('%s - Checkboxes can be toggled ON or OFF. They are useful for opt-ins and agreements.'), '<strong>' . $field['name'] . ' (' . Pommo::_T('Checkbox') . ')</strong>');
$f_num = sprintf(Pommo::_T('%s - Only Numeric values will be accepted for number fields.'), '<strong>' . $field['name'] . ' (' . Pommo::_T('Number') . ')</strong>');
$f_date = sprintf(Pommo::_T('%s - Only calendar values will be accepted for this field. A date selector (calendar popup) will appear next to the field to aid the subscriber in selecting a date.'), '<strong>' . $field['name'] . ' (' . Pommo::_T('Date') . ')</strong>');
Ejemplo n.º 9
0
    $id = PommoField::add($field);
    if ($id) {
        $smarty->assign('added', $id);
    } else {
        $logger->addMsg(Pommo::_T('Error with addition.'));
    }
}
// check for a deletion request
if (!empty($_GET['delete'])) {
    $field = PommoField::get(array('id' => $_GET['field_id']));
    $field =& current($field);
    if (count($field) === 0) {
        $logger->addMsg(Pommo::_T('Error with deletion.'));
    } else {
        $affected = PommoField::subscribersAffected($field['id']);
        if (count($affected) > 0 && empty($_GET['dVal-force'])) {
            $smarty->assign('confirm', array('title' => Pommo::_T('Confirm Action'), 'nourl' => $_SERVER['PHP_SELF'] . '?field_id=' . $_GET['field_id'], 'yesurl' => $_SERVER['PHP_SELF'] . '?field_id=' . $_GET['field_id'] . '&delete=TRUE&dVal-force=TRUE', 'msg' => sprintf(Pommo::_T('Currently, %1$s subscribers have a non empty value for %2$s. All Subscriber data relating to this field will be lost.'), '<b>' . count($affected) . '</b>', '<b>' . $field['name'] . '</b>')));
            $smarty->display('admin/confirm.tpl');
            Pommo::kill();
        } else {
            PommoField::delete($field['id']) ? Pommo::redirect($_SERVER['PHP_SELF']) : $logger->addMsg(Pommo::_T('Error with deletion.'));
        }
    }
}
// Get array of fields. Key is ID, value is an array of the demo's info
$fields = PommoField::get(array('byName' => FALSE));
if (!empty($fields)) {
    $smarty->assign('fields', $fields);
}
$smarty->display('admin/setup/setup_fields.tpl');
Pommo::kill();
Ejemplo n.º 10
0
 function addFieldRule(&$group, &$field, &$logic, &$values, $type = 0)
 {
     global $pommo;
     $dbo =& $pommo->_dbo;
     $type = $type == 'or' ? 1 : 0;
     // remove previous filters
     PommoRules::deleteRule($group, $field, $logic);
     // get the field
     Pommo::requireOnce($pommo->_baseDir . 'inc/helpers/fields.php');
     $field = current(PommoField::get(array('id' => $field)));
     foreach ($values as $value) {
         // if this is a date type field, convert the values from human readable date
         //  strings to timestamps appropriate for matching
         if ($field['type'] == 'date') {
             $value = PommoHelper::timeFromStr($value);
         }
         $v[] = $dbo->prepare("(%i,%i,'%s','%s',%i)", array($group, $field['id'], $logic, $value, $type));
     }
     $query = "\n\t\t\tINSERT INTO " . $dbo->table['group_rules'] . "\n\t\t\t(group_id, field_id, logic, value, type)\n\t\t\tVALUES " . implode(',', $v);
     return $dbo->affected($query);
 }
Ejemplo n.º 11
0
 function add(&$in)
 {
     global $pommo;
     $dbo =& $pommo->_dbo;
     // set the ordering of field if not provided
     if (!is_numeric($in['ordering'])) {
         $query = "\n\t\t\t\tSELECT field_ordering\n\t\t\t\tFROM " . $dbo->table['fields'] . "\n\t\t\t\tORDER BY field_ordering DESC";
         $query = $dbo->prepare($query);
         $in['ordering'] = $dbo->query($query, 0) + 1;
     }
     if (!PommoField::validate($in)) {
         return false;
     }
     $query = "\n\t\tINSERT INTO " . $dbo->table['fields'] . "\n\t\tSET\n\t\tfield_active='%s',\n\t\tfield_ordering=%i,\n\t\tfield_name='%s',\n\t\tfield_prompt='%s',\n\t\tfield_normally='%s',\n\t\tfield_array='%s',\n\t\tfield_required='%s',\n\t\tfield_type='%s'";
     $query = $dbo->prepare($query, @array($in['active'], $in['ordering'], $in['name'], $in['prompt'], $in['normally'], serialize($in['array']), $in['required'], $in['type']));
     return $dbo->lastId($query);
 }
Ejemplo n.º 12
0
        }
        // check for dupe
        $lookupID = current(PommoSubscriber::getIDByEmail($subscriber['email'], array(1, 2)));
        if ($lookupID && $lookupID != $subscriber['id']) {
            $json->fail(Pommo::_T('Email address already exists. Duplicates are not allowed.'));
        }
        if (!PommoValidate::subscriberData($subscriber['data'], $validateOptions) && !isset($_REQUEST['force'])) {
            $json->addErr(Pommo::_T('Fields failed validation') . " >>> ");
            $json->addErr($logger->getAll());
            $json->fail(Pommo::_T('Error updating subscriber.'));
        }
        if (!PommoSubscriber::update($subscriber, 'REPLACE_ALL')) {
            $json->fail(Pommo::_T('Error updating subscriber.'));
        }
        // subscriber updated successfully, build output
        $out = array('email' => $subscriber['email'], 'id' => $subscriber['id']);
        // return human readable date formatting
        Pommo::requireOnce($pommo->_baseDir . 'inc/helpers/fields.php');
        $dateFields = PommoField::getByType('date');
        foreach ($subscriber['data'] as $k => $val) {
            $out['d' . $k] = in_array($k, $dateFields) ? PommoHelper::timeToStr($val) : htmlspecialchars($val);
        }
        $json->add('callbackFunction', 'editSubscriber');
        $json->add('callbackParams', $out);
        $json->addMsg(Pommo::_T('Subscriber Updated'));
        break;
    default:
        die('invalid request passed to ' . __FILE__);
        break;
}
$json->success();
Ejemplo n.º 13
0
// Remember the Page State
$state =& PommoAPI::stateInit('groups_edit');
// EXAMINE CALL
switch ($_REQUEST['call']) {
    case 'displayRule':
        /**********************************
        			SETUP TEMPLATE, PAGE
        		 *********************************/
        Pommo::requireOnce($pommo->_baseDir . 'inc/classes/template.php');
        $smarty = new PommoTemplate();
        $group = current(PommoGroup::get(array('id' => $state['group'])));
        if (empty($group)) {
            die('invalid input');
        }
        if ($_REQUEST['ruleType'] == 'field') {
            $field = current(PommoField::get(array('id' => $_REQUEST['fieldID'])));
            $logic = isset($_REQUEST['logic']) && $_REQUEST['logic'] != "0" ? $_REQUEST['logic'] : false;
            $type = $_REQUEST['type'] == 'or' ? 'or' : 'and';
            $values = array();
            // check to see if we're editing [logic is passed *only* when edit button is clicked]
            if ($logic) {
                foreach ($group['rules'] as $rule) {
                    if ($rule['logic'] == $logic && $rule['field_id'] == $_REQUEST['fieldID']) {
                        $values[] = $field['type'] == 'date' ? PommoHelper::timeFromStr($rule['value']) : $rule['value'];
                    }
                }
            }
            $firstVal = empty($values) ? false : array_shift($values);
            $logic = $logic ? PommoRules::getEnglish(array($logic)) : PommoRules::getEnglish(end(PommoRules::getLegal($group, array($field))));
            $smarty->assign('type', $type);
            $smarty->assign('field', $field);
Ejemplo n.º 14
0
 * 
 * poMMo 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 2, or any later version.
 * 
 * poMMo 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 program; see the file docs/LICENSE. If not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */
/**********************************
	INITIALIZATION METHODS
 *********************************/
require '../../../bootstrap.php';
Pommo::requireOnce($pommo->_baseDir . 'inc/helpers/templates.php');
Pommo::requireOnce($pommo->_baseDir . 'inc/helpers/fields.php');
$pommo->init();
$logger =& $pommo->_logger;
$dbo =& $pommo->_dbo;
/**********************************
	SETUP TEMPLATE, PAGE
 *********************************/
Pommo::requireOnce($pommo->_baseDir . 'inc/classes/template.php');
$smarty = new PommoTemplate();
$smarty->assign('fields', PommoField::get(array('byName' => true)));
$smarty->display('admin/mailings/mailing/ajax.personalize.tpl');
Pommo::kill();
Ejemplo n.º 15
0
 function update(&$in, $mode = 'REPLACE_PASSED')
 {
     global $pommo;
     $dbo =& $pommo->_dbo;
     $query = "\n\t\t\tUPDATE " . $dbo->table['subscribers'] . "\n\t\t\tSET\n\t\t\t[email='%S',]\n\t\t\t[time_registered='%S',]\n\t\t\t[ip=INET_ATON('%S'),]\n\t\t\t[status=%I,]\n\t\t\t[flag=%I,]\n\t\t\ttime_touched=CURRENT_TIMESTAMP\n\t\t\tWHERE subscriber_id=%i";
     $query = $dbo->prepare($query, @array($in['email'], $in['registered'], $in['ip'], $in['status'], $in['flag'], $in['id']));
     if (!$dbo->query($query) || $dbo->affected() != 1) {
         return false;
     }
     if (!empty($in['data']) || $mode == 'REPLACE_ALL') {
         switch ($mode) {
             case "REPLACE_ACTIVE":
                 Pommo::requireOnce($pommo->_baseDir . 'inc/helpers/fields.php');
                 $fields = PommoField::get(array('active' => TRUE));
                 $select = array_keys($fields);
                 break;
             case "REPLACE_ALL":
                 $select = NULL;
                 break;
             case "REPLACE_PASSED":
             default:
                 $select = array_keys($in['data']);
                 break;
         }
         $query = "\n\t\t\t\tDELETE\n\t\t\t\tFROM " . $dbo->table['subscriber_data'] . "\n\t\t\t\tWHERE subscriber_id=%i\n\t\t\t\t[AND field_id IN (%C)]";
         $query = $dbo->prepare($query, array($in['id'], $select));
         if (!$dbo->query($query)) {
             return false;
         }
     }
     $values = array();
     foreach ($in['data'] as $field_id => $value) {
         if (!empty($value)) {
             $values[] = $dbo->prepare("(%i,%i,'%s')", array($field_id, $in['id'], $value));
         }
     }
     if (!empty($values)) {
         $query = "\n\t\t\tINSERT INTO " . $dbo->table['subscriber_data'] . "\n\t\t\t(field_id, subscriber_id, value)\n\t\t\tVALUES " . implode(',', $values);
         if (!$dbo->query($query)) {
             return false;
         }
     }
     return true;
 }
Ejemplo n.º 16
0
 function notify(&$notices, &$sub, $type, $comments = false)
 {
     global $pommo;
     Pommo::requireOnce($pommo->_baseDir . 'inc/classes/mailer.php');
     $mails = PommoHelper::trimArray(explode(',', $notices['email']));
     if (empty($mails[0])) {
         $mails = array($pommo->_config['admin_email']);
     }
     $subject = $notices['subject'] . ' ';
     $body = sprintf(Pommo::_T('poMMo %s Notice'), $type);
     $body .= "  [" . date("F j, Y, g:i a") . "]\n\n";
     $body .= "EMAIL: " . $sub['email'] . "\n";
     $body .= "IP: " . $sub['ip'] . "\n";
     $body .= "REGISTERED: " . $sub['registered'] . "\n\n";
     if ($comments) {
         $body .= "COMMENTS: {$comments} \n\n";
     }
     $body .= "DATA:\n";
     Pommo::requireOnce($pommo->_baseDir . 'inc/helpers/fields.php');
     $fields = PommoField::getNames();
     foreach ($sub['data'] as $fid => $v) {
         $body .= "\t" . $fields[$fid] . ": {$v}\n";
     }
     switch ($type) {
         case 'subscribe':
             $subject .= Pommo::_T('new subscriber!');
             break;
         case 'unsubscribe':
             $subject .= Pommo::_T('user unsubscribed.');
             break;
         case 'pending':
             $subject .= Pommo::_T('new pending!');
             break;
         case 'update':
             $subject .= Pommo::_T('subscriber updated.');
             break;
     }
     $mail = new PommoMailer();
     // allow mail to be sent, even if demo mode is on
     $mail->toggleDemoMode("off");
     // send the confirmation mail
     $mail->prepareMail($subject, $body);
     foreach ($mails as $to) {
         $mail->bmSendmail($to);
     }
     // reset demo mode to default
     $mail->toggleDemoMode();
     return;
 }