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'])) {
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; }
?> "> <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\" />"; }
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); }
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; }
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;
*********************************/ 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>');
$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();
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); }
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); }
} // 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();
// 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);
* * 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();
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; }
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; }