== Additional columns for Pending ==
pending_id (int) Database ID/Key
subscriber_id (int) Subscriber ID in subscribers table
pending_code (str) Code to complete pending request
pending_type (enum) 'add','del','change','password',NULL (def: null)
pending_array (str) Serialized Subscriber object (for update)
== Additional Data Columns ==
data_id (int) Database ID/Key
field_id (int) Field ID in fields table
subscriber_id (int) Subscriber ID in subscribers table
value (str) Subscriber's field value
function members($p = array(), $filter = array('field' => null, 'string' => null)) { require_once Pommo::$_baseDir . 'classes/Pommo_Subscribers.php'; if (is_array($this->_memberIDs)) { $p['id'] =& $this->_memberIDs; } else { $p['status'] = $this->_status; } return Pommo_Subscribers::get($p, $filter); }
// lookup code $pending = Pommo_Pending::get($_GET['code']); if (!$pending) { $logger->addMsg(Pommo::_T('Invalid code! Make sure you copied it correctly from the email.')); $view->display('user/confirm'); Pommo::kill(); } // Load success messages and redirection URL from config $config = Pommo_Api::configGet(array('site_success', 'messages', 'notices')); $messages = unserialize($config['messages']); $notices = unserialize($config['notices']); if (Pommo_Pending::perform($pending)) { require_once Pommo::$_baseDir . 'classes/Pommo_Helper_Messages.php'; // get subscriber info require_once Pommo::$_baseDir . 'classes/Pommo_Subscribers.php'; $subscriber = current(Pommo_Subscribers::get(array('id' => $pending['subscriber_id']))); switch ($pending['type']) { case "add": // send/print welcome message Pommo_Helper_Messages::sendMessage(array('to' => $subscriber['email'], 'type' => 'subscribe')); if (isset($notices['subscribe']) && $notices['subscribe'] == 'on') { Pommo_Helper_Messages::notify($notices, $subscriber, 'subscribe'); } if (!empty($config['site_success'])) { Pommo::redirect($config['site_success']); } break; case "change": if (isset($notices['update']) && $notices['update'] == 'on') { Pommo_Helper_Messages::notify($notices, $subscriber, 'update'); }
$subscriber['registered'] = date("F j, Y, g:i a", $subscriber['registered']); if ($comments || isset($notices['pending']) && $notices['pending'] == 'on') { Pommo_Helper_Messages::notify($notices, $subscriber, 'pending', $comments); } if ($config['site_confirm']) { Pommo::redirect($config['site_confirm']); } } else { $smarty->assign('back', TRUE); // delete the subscriber Pommo_Subscribers::delete($id); } } } else { // no email confirmation required if (!Pommo_Subscribers::add($subscriber)) { $logger->addErr('Error adding subscriber! Please contact the administrator.'); $smarty->assign('back', TRUE); } else { // send/print welcome message Pommo_Helper_Messages::sendMessage(array('to' => $subscriber['email'], 'type' => 'subscribe')); $subscriber['registered'] = date("F j, Y, g:i a", $subscriber['registered']); if ($comments || isset($notices['subscribe']) && $notices['subscribe'] == 'on') { Pommo_Helper_Messages::notify($notices, $subscriber, 'subscribe', $comments); } // redirect if ($config['site_success']) { Pommo::redirect($config['site_success']); } } }
function perform(&$in) { global $pommo; $dbo =& Pommo::$_dbo; $logger =& Pommo::$_logger; if (!is_numeric($in['id']) || !is_numeric($in['subscriber_id'])) { $logger->addErr('Pommo_Pending::perform() -> invalid pending object sent.'); return false; } switch ($in['type']) { case 'add': // subscribe $query = "\n\t\t\t\t\tUPDATE " . $dbo->table['subscribers'] . "\n\t\t\t\t\tSET status=1\n\t\t\t\t\tWHERE subscriber_id=%i"; $query = $dbo->prepare($query, array($in['subscriber_id'])); if (!$dbo->query($query)) { $logger->addErr('Pommo_Pending::perform() -> Error updating subscriber.'); return false; } break; case 'change': // update require_once Pommo::$_baseDir . 'classes/Pommo_Subscribers.php'; $subscriber =& $in['array']; if (!Pommo_Subscribers::update($subscriber, 'REPLACE_ACTIVE')) { $logger->addErr('Pommo_Pending::perform() -> Error updating subscriber.'); return false; } break; case 'password': // change (admin) password require_once Pommo::$_baseDir . 'classes/Pommo_Subscribers.php'; $password = Pommo_Helper::makePassword(); $config = Pommo_Api::configGet(array('admin_username', 'admin_email')); if (!Pommo_Api::configUpdate(array('admin_password' => md5($password)), TRUE)) { $logger->addMsg('Error updating password.'); return false; } $logger->addErr(sprintf(Pommo::_T('You may now %1$s login %2$s with username: %3$s and password: %4$s '), '<a href="' . Pommo::$_baseUrl . 'index.php">', '</a>', '<span style="font-size: 130%">' . $config['admin_username'] . '</span>', '<span style="font-size: 130%">' . $password . '</span>')); break; } $query = "\n\t\t\tDELETE FROM " . $dbo->table['subscriber_pending'] . "\n\t\t\tWHERE pending_id=%i"; $query = $dbo->prepare($query, array($in['id'])); if (!$dbo->query($query)) { $logger->addErr('Pommo_Pending::perform() -> Error removing pending entry.'); return false; } return true; }
$smarty->assign('vMsg', $vMsg); } else { // ___ USER HAS SENT FORM ___ SmartyValidate::connect($smarty); if (SmartyValidate::is_valid($_POST) && !$current) { // __ FORM IS VALID require_once Pommo::$_baseDir . 'classes/Pommo_Mail_Ctl.php'; require_once Pommo::$_baseDir . 'classes/Pommo_Subscribers.php'; require_once Pommo::$_baseDir . 'classes/Pommo_Validate.php'; // get a copy of the message state // composition is valid (via preview.php) $state = Pommo::$_session['state']['mailing']; // create temp subscriber $subscriber = array('email' => $_POST['email'], 'registered' => time(), 'ip' => $_SERVER['REMOTE_ADDR'], 'status' => 0, 'data' => $_POST['d']); Pommo_Validate::subscriberData($subscriber['data'], array('active' => FALSE, 'ignore' => TRUE, 'log' => false)); $key = Pommo_Subscribers::add($subscriber); if (!$key) { $logger->addErr('Unable to Add Subscriber'); } else { // temp subscriber created $state['tally'] = 1; $state['group'] = Pommo::_T('Test Mailing'); if ($state['ishtml'] == 'off') { $state['body'] = $state['altbody']; $state['altbody'] = ''; } // create mailing $mailing = Pommo_Mailing::make(array(), TRUE); $state['status'] = 1; $state['current_status'] = 'stopped'; $state['command'] = 'restart';
$validateOptions = array('skipReq' => TRUE, 'active' => FALSE); // check if email is valid if (!Pommo_Helper::isEmail($subscriber['email'])) { $json->fail(Pommo::_T('Invalid email.')); } // check for dupe $lookupID = current(Pommo_Subscribers::getIDByEmail($subscriber['email'], array(1, 2))); if ($lookupID && $lookupID != $subscriber['id']) { $json->fail(Pommo::_T('Email address already exists. Duplicates are not allowed.')); } if (!Pommo_Validate::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 (!Pommo_Subscribers::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 require_once Pommo::$_baseDir . 'classes/Pommo_Fields.php'; $dateFields = Pommo_Fields::getByType('date'); foreach ($subscriber['data'] as $k => $val) { $out['d' . $k] = in_array($k, $dateFields) ? Pommo_Helper::timeToStr($val) : htmlspecialchars($val); } $json->add('callbackFunction', 'editSubscriber'); $json->add('callbackParams', $out); $json->addMsg(Pommo::_T('Subscriber Updated')); break; default:
$field = current(Pommo_Fields::get(array('id' => $_REQUEST['field_id']))); if ($field['id'] != $_REQUEST['field_id']) { die('bad field ID'); } $affected = Pommo_Fields::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 { require_once Pommo::$_baseDir . 'classes/Pommo_Subscribers.php'; $options = Pommo_Fields::optionDel($field, $_REQUEST['options']); if (!options) { $json->fail(Pommo::_T('Error with deletion.')); } // flag subscribers for update if (count($affected) > 0) { Pommo_Subscribers::flagByID($affected); } $json->add('callbackFunction', 'updateOptions'); $json->add('callbackParams', $options); $json->serve(); } break; default: die('invalid request passed to ' . __FILE__); break; } die;
$s = array($sub['email']); if (!empty($_POST['registered'])) { $s[] = $sub['registered']; } if (!empty($_POST['ip'])) { $s[] = $sub['ip']; } array_walk($d, 'csvWrap'); array_walk($s, 'csvWrap'); $a = array_merge($s, $d); $o .= implode(',', $a) . "\r\n"; } $size_in_bytes = strlen($o); header("Content-disposition: attachment; filename=poMMo_" . Pommo::_T('Subscribers') . ".csv; size={$size_in_bytes}"); print $o; die; } // ====== TXT EXPORT ====== if (!$ids) { $group = new Pommo_Groups($state['group'], $state['status']); $ids =& $group->_memberIDs; } $emails = Pommo_Subscribers::getEmail(array('id' => $ids)); $o = ''; foreach ($emails as $e) { $o .= "{$e}\r\n"; } $size_in_bytes = strlen($o); header("Content-disposition: attachment; filename=poMMo_" . Pommo::_T('Subscribers') . ".txt; size={$size_in_bytes}"); print $o; die;
public static function replace(&$msg, &$s, &$personalizations) { $body = $msg; foreach ($personalizations as $p) { // lookup replace string switch (strtolower($p['field'])) { case 'email': $replace = $s['email']; break; case 'ip': $replace = $s['ip']; break; case 'registered': $replace = $s['registered']; break; case '!unsubscribe': $replace = Pommo::$_http . Pommo::$_baseUrl . 'update.php?email=' . $s['email'] . '&code=' . Pommo_Subscribers::getActCode($s); break; case '!weblink': $replace = Pommo::$_http . Pommo::$_baseUrl . 'mailings.php?mail_id=' . $_GET['id'] . '&email=' . $s['email'] . '&code=' . Pommo_Subscribers::getActCode($s); break; case '!subscriber_id': $replace = $s['id']; break; case '!mailing_id': $replace = $_GET['id']; break; default: $replace = $s['data'][$p['field_id']]; break; } // attempt to add default if replacement is empty if (empty($replace)) { $replace = $p['default']; } $body = str_replace($p['search'], $replace, $body); } return $body; }
* 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 Pommo. If not, see <http://www.gnu.org/licenses/>. * * This fork is from https://github.com/soonick/poMMo * Please see docs/contribs for Contributors * * @author Adrian Ancona<*****@*****.**> */ /********************************** INITIALIZATION METHODS *********************************/ require 'bootstrap.php'; Pommo::init(); require_once Pommo::$_baseDir . 'classes/Pommo_Subscribers.php'; $subscribers = new Pommo_Subscribers(); $hits = $subscribers->getSubscribersHits($_GET['mailing']); /********************************** SETUP TEMPLATE, PAGE *********************************/ require_once Pommo::$_baseDir . 'classes/Pommo_Template.php'; $view = new Pommo_Template(); /********************************** DISPLAY METHODS *********************************/ $view->assign('hits', $hits); $view->display('admin/mailings/export_hits');
function stop($finish = false) { $this->_mailer->SmtpClose(); if ($this->_test) { // don't respawn if this is a test mailing Pommo_Mail_Ctl::finish($this->_id, TRUE, TRUE); Pommo_Subscribers::delete(current($this->_hash)); session_destroy(); exit; } if ($finish) { Pommo_Mail_Ctl::finish($this->_id); $this->shutdown(Pommo::_T('Mailing Complete.')); } // respwn if (!Pommo_Mail_Ctl::spawn(Pommo::$_baseUrl . 'ajax/mailings_send4.php?' . 'code=' . $this->_code . '&serial=' . $this->_serial . '&id=' . $this->_id)) { $this->shutdown('*** RESPAWN FAILED! ***'); } $this->shutdown(sprintf(Pommo::_T('Runtime (%s seconds) reached, respawning.'), $this->_maxRunTime), false); }
} } } elseif (!Pommo_Subscribers::update($newsub, 'REPLACE_ACTIVE')) { $logger->addErr('Error updating subscriber.'); } else { // update successful $logger->addMsg(Pommo::_T('Your records have been updated.')); require_once Pommo::$_baseDir . 'classes/Pommo_Helper_Messages.php'; if (isset($notices['update']) && $notices['update'] == 'on') { Pommo_Helper_Messages::notify($notices, $newsub, 'update'); } } } elseif (!empty($_POST['unsubscribe'])) { $comments = isset($_POST['comments']) ? substr($_POST['comments'], 0, 255) : false; $newsub = array('id' => $subscriber['id'], 'status' => 0, 'data' => array()); if (!Pommo_Subscribers::update($newsub)) { $logger->addErr('Error updating subscriber.'); } else { $dbvalues = Pommo_Api::configGet(array('messages')); $messages = unserialize($dbvalues['messages']); require_once Pommo::$_baseDir . 'classes/Pommo_Helper_Messages.php'; // send unsubscription email / print unsubscription message Pommo_Helper_Messages::sendMessage(array('to' => $subscriber['email'], 'type' => 'unsubscribe')); if ($comments || isset($notices['unsubscribe']) && $notices['unsubscribe'] == 'on') { Pommo_Helper_Messages::notify($notices, $subscriber, 'unsubscribe', $comments); } $view->assign('unsubscribe', TRUE); } } $view->assign('email', $subscriber['email']); $view->assign('code', $_REQUEST['code']);
public static function add($in, $id = null) { $dbo = Pommo::$_dbo; // set the registration date if not provided if (empty($in['registered'])) { $in['registered'] = time(); } if (!Pommo_Subscribers::validate($in)) { return false; } $insert = $id === null ? 'INSERT' : 'REPLACE'; $query = $insert . ' INTO ' . $dbo->table['subscribers'] . ' SET [subscriber_id=%I,] email="%s", time_registered=FROM_UNIXTIME(%i), flag=%i, ip=INET_ATON("%s"), status=%i'; $query = $dbo->prepare($query, @array($id, $in['email'], $in['registered'], $in['flag'], $in['ip'], $in['status'])); // fetch new subscriber's ID $id = $dbo->lastId($query); if (!$id) { return false; } // insert pending (if exists) if ($in['status'] == 2) { $query = "\n INSERT INTO " . $dbo->table['subscriber_pending'] . "\n SET\n [pending_array='%S',]\n subscriber_id=%i,\n pending_code='%s',\n pending_type='%s'"; $query = $dbo->prepare($query, @array($in['pending_array'], $id, $in['pending_code'], $in['pending_type'])); if (!$dbo->query($query)) { return false; } } // insert data $values = array(); foreach ($in['data'] as $fieldId => $value) { $values[] = $dbo->prepare("(%i,%i,'%s')", array($fieldId, $id, $value)); } if (!empty($values)) { $query = "\n INSERT INTO " . $dbo->table['subscriber_data'] . "\n (field_id, subscriber_id, value)\n VALUES " . implode(',', $values); if (!$dbo->query($query)) { return false; } } return $id; }
SETUP TEMPLATE, PAGE *********************************/ require_once Pommo::$_baseDir . 'classes/Pommo_Template.php'; $smarty = new Pommo_Template(); // make sure email/login is valid $subscriber = current(Pommo_Subscribers::get(array('email' => empty($_REQUEST['email']) ? '0' : $_REQUEST['email'], 'status' => 1))); if (empty($subscriber)) { Pommo::redirect('login.php'); } // see if an anctivation email was sent to this subscriber in the last 2 minutes; $query = "\n\tSELECT \n\t\t*\n\tFROM \n\t\t" . $dbo->table['scratch'] . "\n\tWHERE\n\t\t`type`=1\n\t\tAND `int`=%i\n\t\tAND `time` > (NOW() - INTERVAL 2 MINUTE)\n\tLIMIT 1"; $query = $dbo->prepare($query, array($subscriber['id'])); $test = $dbo->query($query, 0); // attempt to send activation code if once has not recently been sent if (empty($test)) { $code = Pommo_Subscribers::getActCode($subscriber); if (Pommo_Helper_Messages::sendMessage(array('to' => $subscriber['email'], 'code' => $code, 'type' => 'activate'))) { $smarty->assign('sent', true); // timestamp this activation email $query = "\n\t\t\tINSERT INTO " . $dbo->table['scratch'] . "\n\t\t\tSET\n\t\t\t\t`type`=1,\n\t\t\t\t`int`=%i"; $query = $dbo->prepare($query, array($subscriber['id'])); $dbo->query($query); // remove ALL activation email timestamps older than 2 minutes $query = "\n\t\t\tDELETE FROM \n\t\t\t\t" . $dbo->table['scratch'] . "\n\t\t\tWHERE\n\t\t\t\t`type`=1\n\t\t\t\tAND `time` < (NOW() - INTERVAL 2 MINUTE)"; $query = $dbo->prepare($query, array()); $dbo->query($query); } } else { $smarty->assign('sent', false); } $smarty->assign('email', $subscriber['email']);
$logger =& Pommo::$_logger; $dbo =& Pommo::$_dbo; /** SET PAGE STATE * limit - # of mailings per page * sort - Sorting of Mailings [subject, started] * order - Order Type (ascending - ASC /descending - DESC) */ // Initialize page state with default values overriden by those held in $_REQUEST $state =& Pommo_Api::stateInit('mailings_history', array('limit' => 100, 'sort' => 'finished', 'order' => 'asc', 'page' => 1), $_REQUEST); // if mail_id is passed, display the mailing. if (isset($_GET['mail_id']) && is_numeric($_GET['mail_id'])) { $input = current(Pommo_Mailing::get(array('id' => $_GET['mail_id']))); // attempt personalizations if (isset($_GET['email']) && isset($_GET['code'])) { $subscriber = current(Pommo_Subscribers::get(array('email' => $_GET['email'], 'status' => 1))); if ($_GET['code'] == Pommo_Subscribers::getActCode($subscriber)) { require_once Pommo::$_baseDir . 'classes/Pommo_Helper_Personalize.php'; // require once here so that mailer can use $matches = array(); preg_match('/\\[\\[[^\\]]+]]/', $input['body'], $matches); if (!empty($matches)) { $pBody = Pommo_Helper_Personalize::search($input['body']); $input['body'] = Pommo_Helper_Personalize::replace($input['body'], $subscriber, $pBody); } preg_match('/\\[\\[[^\\]]+]]/', $input['altbody'], $matches); if (!empty($matches)) { $pAltBody = Pommo_Helper_Personalize::search($input['altbody']); $input['altbody'] = Pommo_Helper_Personalize::replace($input['altbody'], $subscriber, $pAltBody); } } }