First commit

This commit is contained in:
Theodotos Andreou 2018-01-14 13:10:16 +00:00
commit c6e2478c40
13918 changed files with 2303184 additions and 0 deletions

View file

@ -0,0 +1,198 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
class CRM_SMS_BAO_Provider extends CRM_SMS_DAO_Provider {
/**
* Class constructor.
*/
public function __construct() {
parent::__construct();
}
/**
* @return null|string
*/
public static function activeProviderCount() {
$activeProviders = CRM_Core_DAO::singleValueQuery('SELECT count(id) FROM civicrm_sms_provider WHERE is_active = 1 AND (domain_id = %1 OR domain_id IS NULL)',
array(1 => array(CRM_Core_Config::domainID(), 'Positive')));
return $activeProviders;
}
/**
* Retrieves the list of providers from the database.
*
* $selectArr array of coloumns to fetch
* $getActive boolean to get active providers
*
* @param null $selectArr
* @param null $filter
* @param bool $getActive
* @param string $orderBy
*
* @return array
*/
public static function getProviders($selectArr = NULL, $filter = NULL, $getActive = TRUE, $orderBy = 'id') {
$providers = array();
$temp = array();
$dao = new CRM_SMS_DAO_Provider();
if ($filter && !array_key_exists('is_active', $filter) && $getActive) {
$dao->is_active = 1;
}
if ($filter && is_array($filter)) {
foreach ($filter as $key => $value) {
$dao->$key = $value;
}
}
if ($selectArr && is_array($selectArr)) {
$select = implode(',', $selectArr);
$dao->selectAdd($select);
}
$dao->whereAdd("(domain_id = " . CRM_Core_Config::domainID() . " OR domain_id IS NULL)");
$dao->orderBy($orderBy);
$dao->find();
while ($dao->fetch()) {
CRM_Core_DAO::storeValues($dao, $temp);
$providers[] = $temp;
}
return $providers;
}
/**
* Create or Update an SMS provider
* @param array $params
* @return array saved values
*/
public static function create(&$params) {
$id = CRM_Utils_Array::value('id', $params);
if ($id) {
CRM_Utils_Hook::pre('edit', 'SmsProvider', $id, $params);
}
else {
CRM_Utils_Hook::pre('create', 'SmsProvider', NULL, $params);
}
$provider = new CRM_SMS_DAO_Provider();
if ($id) {
$provider->id = $id;
$provider->find(TRUE);
}
if ($id) {
$provider->domain_id = CRM_Utils_Array::value('domain_id', $params, $provider->domain_id);
}
else {
$provider->domain_id = CRM_Utils_Array::value('domain_id', $params, CRM_Core_Config::domainID());
}
$provider->copyValues($params);
$result = $provider->save();
if ($id) {
CRM_Utils_Hook::post('edit', 'SmsProvider', $provider->id, $provider);
}
else {
CRM_Utils_Hook::post('create', 'SmsProvider', NULL, $provider);
}
return $result;
}
/**
* @param int $id
* @param $is_active
*
* @return bool
*/
public static function setIsActive($id, $is_active) {
return CRM_Core_DAO::setFieldValue('CRM_SMS_DAO_Provider', $id, 'is_active', $is_active);
}
/**
* @param int $providerID
*
* @return null
* @throws Exception
*/
public static function del($providerID) {
if (!$providerID) {
CRM_Core_Error::fatal(ts('Invalid value passed to delete function.'));
}
$dao = new CRM_SMS_DAO_Provider();
$dao->id = $providerID;
$dao->whereAdd = "(domain_id = " . CRM_Core_Config::domainID() . "OR domain_id IS NULL)";
if (!$dao->find(TRUE)) {
return NULL;
}
$dao->delete();
}
/**
* @param int $providerID
* @param null $returnParam
* @param null $returnDefaultString
*
* @return mixed
*/
public static function getProviderInfo($providerID, $returnParam = NULL, $returnDefaultString = NULL) {
static $providerInfo = array();
if (!array_key_exists($providerID, $providerInfo)) {
$providerInfo[$providerID] = array();
$dao = new CRM_SMS_DAO_Provider();
$dao->id = $providerID;
if ($dao->find(TRUE)) {
CRM_Core_DAO::storeValues($dao, $providerInfo[$providerID]);
$inputLines = explode("\n", $providerInfo[$providerID]['api_params']);
$inputVals = array();
foreach ($inputLines as $value) {
if ($value) {
list($key, $val) = explode("=", $value);
$inputVals[trim($key)] = trim($val);
}
}
$providerInfo[$providerID]['api_params'] = $inputVals;
// Replace the api_type ID with the string value
$apiTypes = CRM_Core_OptionGroup::values('sms_api_type');
$apiTypeId = $providerInfo[$providerID]['api_type'];
$providerInfo[$providerID]['api_type'] = CRM_Utils_Array::value($apiTypeId, $apiTypes, $apiTypeId);
}
}
if ($returnParam) {
return CRM_Utils_Array::value($returnParam, $providerInfo[$providerID], $returnDefaultString);
}
return $providerInfo[$providerID];
}
}

View file

@ -0,0 +1,74 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
class CRM_SMS_Controller_Send extends CRM_Core_Controller {
/**
* Class constructor.
*
* @param string $title
* @param bool|int $action
* @param bool $modal
*/
public function __construct($title = NULL, $action = CRM_Core_Action::NONE, $modal = TRUE) {
parent::__construct($title, $modal, NULL, FALSE, TRUE);
$mailingID = CRM_Utils_Request::retrieve('mid', 'String', $this, FALSE, NULL);
// also get the text and html file
$txtFile = CRM_Utils_Request::retrieve('txtFile', 'String',
CRM_Core_DAO::$_nullObject, FALSE, NULL
);
$config = CRM_Core_Config::singleton();
if ($txtFile &&
file_exists($config->uploadDir . $txtFile)
) {
$this->set('textFilePath', $config->uploadDir . $txtFile);
}
$this->_stateMachine = new CRM_SMS_StateMachine_Send($this, $action, $mailingID);
// create and instantiate the pages
$this->addPages($this->_stateMachine, $action);
// add all the actions
$uploadNames = array_merge(array('textFile'),
CRM_Core_BAO_File::uploadNames()
);
$this->addActions(CRM_Core_Config::singleton()->uploadDir,
$uploadNames
);
}
}

View file

@ -0,0 +1,352 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*
* Generated from xml/schema/CRM/SMS/Provider.xml
* DO NOT EDIT. Generated by CRM_Core_CodeGen
* (GenCodeChecksum:cae173c565ecbc84ccb905d80f1de8c1)
*/
require_once 'CRM/Core/DAO.php';
require_once 'CRM/Utils/Type.php';
/**
* CRM_SMS_DAO_Provider constructor.
*/
class CRM_SMS_DAO_Provider extends CRM_Core_DAO {
/**
* Static instance to hold the table name.
*
* @var string
*/
static $_tableName = 'civicrm_sms_provider';
/**
* Should CiviCRM log any modifications to this table in the civicrm_log table.
*
* @var boolean
*/
static $_log = false;
/**
* SMS Provider ID
*
* @var int unsigned
*/
public $id;
/**
* Provider internal name points to option_value of option_group sms_provider_name
*
* @var string
*/
public $name;
/**
* Provider name visible to user
*
* @var string
*/
public $title;
/**
*
* @var string
*/
public $username;
/**
*
* @var string
*/
public $password;
/**
* points to value in civicrm_option_value for group sms_api_type
*
* @var int unsigned
*/
public $api_type;
/**
*
* @var string
*/
public $api_url;
/**
* the api params in xml, http or smtp format
*
* @var text
*/
public $api_params;
/**
*
* @var boolean
*/
public $is_default;
/**
*
* @var boolean
*/
public $is_active;
/**
* Which Domain is this sms provider for
*
* @var int unsigned
*/
public $domain_id;
/**
* Class constructor.
*/
function __construct() {
$this->__table = 'civicrm_sms_provider';
parent::__construct();
}
/**
* Returns foreign keys and entity references.
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!isset(Civi::$statics[__CLASS__]['links'])) {
Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName() , 'domain_id', 'civicrm_domain', 'id');
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
}
return Civi::$statics[__CLASS__]['links'];
}
/**
* Returns all the column names of this table
*
* @return array
*/
static function &fields() {
if (!isset(Civi::$statics[__CLASS__]['fields'])) {
Civi::$statics[__CLASS__]['fields'] = array(
'id' => array(
'name' => 'id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('SMS Provider ID') ,
'description' => 'SMS Provider ID',
'required' => true,
'table_name' => 'civicrm_sms_provider',
'entity' => 'Provider',
'bao' => 'CRM_SMS_BAO_Provider',
'localizable' => 0,
) ,
'name' => array(
'name' => 'name',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('SMS Provider Name') ,
'description' => 'Provider internal name points to option_value of option_group sms_provider_name',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_sms_provider',
'entity' => 'Provider',
'bao' => 'CRM_SMS_BAO_Provider',
'localizable' => 0,
) ,
'title' => array(
'name' => 'title',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('SMS Provider Title') ,
'description' => 'Provider name visible to user',
'maxlength' => 64,
'size' => CRM_Utils_Type::BIG,
'table_name' => 'civicrm_sms_provider',
'entity' => 'Provider',
'bao' => 'CRM_SMS_BAO_Provider',
'localizable' => 0,
'html' => array(
'type' => 'Text',
) ,
) ,
'username' => array(
'name' => 'username',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('SMS Provider Username') ,
'maxlength' => 255,
'size' => CRM_Utils_Type::HUGE,
'table_name' => 'civicrm_sms_provider',
'entity' => 'Provider',
'bao' => 'CRM_SMS_BAO_Provider',
'localizable' => 0,
'html' => array(
'type' => 'Text',
) ,
) ,
'password' => array(
'name' => 'password',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('SMS Provider Password') ,
'maxlength' => 255,
'size' => CRM_Utils_Type::HUGE,
'table_name' => 'civicrm_sms_provider',
'entity' => 'Provider',
'bao' => 'CRM_SMS_BAO_Provider',
'localizable' => 0,
'html' => array(
'type' => 'Text',
) ,
) ,
'api_type' => array(
'name' => 'api_type',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('SMS Provider API') ,
'description' => 'points to value in civicrm_option_value for group sms_api_type',
'required' => true,
'table_name' => 'civicrm_sms_provider',
'entity' => 'Provider',
'bao' => 'CRM_SMS_BAO_Provider',
'localizable' => 0,
'html' => array(
'type' => 'Select',
) ,
) ,
'api_url' => array(
'name' => 'api_url',
'type' => CRM_Utils_Type::T_STRING,
'title' => ts('SMS Provider API URL') ,
'maxlength' => 128,
'size' => CRM_Utils_Type::HUGE,
'table_name' => 'civicrm_sms_provider',
'entity' => 'Provider',
'bao' => 'CRM_SMS_BAO_Provider',
'localizable' => 0,
'html' => array(
'type' => 'Text',
) ,
) ,
'api_params' => array(
'name' => 'api_params',
'type' => CRM_Utils_Type::T_TEXT,
'title' => ts('SMS Provider API Params') ,
'description' => 'the api params in xml, http or smtp format',
'table_name' => 'civicrm_sms_provider',
'entity' => 'Provider',
'bao' => 'CRM_SMS_BAO_Provider',
'localizable' => 0,
'html' => array(
'type' => 'Text',
) ,
) ,
'is_default' => array(
'name' => 'is_default',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('SMS Provider is Default?') ,
'table_name' => 'civicrm_sms_provider',
'entity' => 'Provider',
'bao' => 'CRM_SMS_BAO_Provider',
'localizable' => 0,
'html' => array(
'type' => 'CheckBox',
) ,
) ,
'is_active' => array(
'name' => 'is_active',
'type' => CRM_Utils_Type::T_BOOLEAN,
'title' => ts('SMS Provider is Active?') ,
'table_name' => 'civicrm_sms_provider',
'entity' => 'Provider',
'bao' => 'CRM_SMS_BAO_Provider',
'localizable' => 0,
'html' => array(
'type' => 'CheckBox',
) ,
) ,
'domain_id' => array(
'name' => 'domain_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('SMS Domain') ,
'description' => 'Which Domain is this sms provider for',
'table_name' => 'civicrm_sms_provider',
'entity' => 'Provider',
'bao' => 'CRM_SMS_BAO_Provider',
'localizable' => 0,
'FKClassName' => 'CRM_Core_DAO_Domain',
'pseudoconstant' => array(
'table' => 'civicrm_domain',
'keyColumn' => 'id',
'labelColumn' => 'name',
)
) ,
);
CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
}
return Civi::$statics[__CLASS__]['fields'];
}
/**
* Return a mapping from field-name to the corresponding key (as used in fields()).
*
* @return array
* Array(string $name => string $uniqueName).
*/
static function &fieldKeys() {
if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
}
return Civi::$statics[__CLASS__]['fieldKeys'];
}
/**
* Returns the names of this table
*
* @return string
*/
static function getTableName() {
return self::$_tableName;
}
/**
* Returns if this table needs to be logged
*
* @return boolean
*/
function getLog() {
return self::$_log;
}
/**
* Returns the list of fields that can be imported
*
* @param bool $prefix
*
* @return array
*/
static function &import($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'sms_provider', $prefix, array());
return $r;
}
/**
* Returns the list of fields that can be exported
*
* @param bool $prefix
*
* @return array
*/
static function &export($prefix = false) {
$r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'sms_provider', $prefix, array());
return $r;
}
/**
* Returns the list of indices
*/
public static function indices($localize = TRUE) {
$indices = array();
return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
}
}

View file

@ -0,0 +1,338 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* Choose include / exclude groups and mass sms.
*/
class CRM_SMS_Form_Group extends CRM_Contact_Form_Task {
/**
* Set variables up before form is built.
*/
public function preProcess() {
if (!CRM_SMS_BAO_Provider::activeProviderCount()) {
CRM_Core_Error::fatal(ts('The <a href="%1">SMS Provider</a> has not been configured or is not active.', array(1 => CRM_Utils_System::url('civicrm/admin/sms/provider', 'reset=1'))));
}
$session = CRM_Core_Session::singleton();
$session->replaceUserContext(CRM_Utils_System::url('civicrm/mailing/browse', 'reset=1&sms=1'));
}
/**
* Set default values for the form.
* The default values are retrieved from the database.
*/
public function setDefaultValues() {
$mailingID = CRM_Utils_Request::retrieve('mid', 'Integer', $this, FALSE, NULL);
$continue = CRM_Utils_Request::retrieve('continue', 'String', $this, FALSE, NULL);
$defaults = array();
if ($mailingID) {
$mailing = new CRM_Mailing_DAO_Mailing();
$mailing->id = $mailingID;
$mailing->addSelect('name');
$mailing->find(TRUE);
$defaults['name'] = $mailing->name;
if (!$continue) {
$defaults['name'] = ts('Copy of %1', array(1 => $mailing->name));
}
else {
// CRM-7590, reuse same mailing ID if we are continuing
$this->set('mailing_id', $mailingID);
}
$dao = new CRM_Mailing_DAO_MailingGroup();
$mailingGroups = array();
$dao->mailing_id = $mailingID;
$dao->find();
while ($dao->fetch()) {
$mailingGroups[$dao->entity_table][$dao->group_type][] = $dao->entity_id;
}
$defaults['includeGroups'] = $mailingGroups['civicrm_group']['Include'];
$defaults['excludeGroups'] = CRM_Utils_Array::value('Exclude', $mailingGroups['civicrm_group']);
$defaults['includeMailings'] = CRM_Utils_Array::value('Include', CRM_Utils_Array::value('civicrm_mailing', $mailingGroups));
$defaults['excludeMailings'] = CRM_Utils_Array::value('Exclude', CRM_Utils_Array::value('civicrm_mailing', $mailingGroups));
}
return $defaults;
}
/**
* Build the form object.
*/
public function buildQuickForm() {
// Get the context.
$context = $this->get('context');
$this->assign('context', $context);
$this->add('text', 'name', ts('Name Your SMS'),
CRM_Core_DAO::getAttribute('CRM_Mailing_DAO_Mailing', 'name'),
TRUE
);
// Get the mailing groups.
$groups = CRM_Core_PseudoConstant::nestedGroup('Mailing');
// Get the sms mailing list.
$mailings = CRM_Mailing_PseudoConstant::completed('sms');
if (!$mailings) {
$mailings = array();
}
// run the groups through a hook so users can trim it if needed
CRM_Utils_Hook::mailingGroups($this, $groups, $mailings);
$select2style = array(
'multiple' => TRUE,
'style' => 'width: 100%; max-width: 60em;',
'class' => 'crm-select2',
'placeholder' => ts('- select -'),
);
$this->add('select', 'includeGroups',
ts('Include Group(s)'),
$groups,
TRUE,
$select2style
);
$this->add('select', 'excludeGroups',
ts('Exclude Group(s)'),
$groups,
FALSE,
$select2style
);
$this->add('select', 'includeMailings',
ts('INCLUDE Recipients of These Message(s)'),
$mailings,
FALSE,
$select2style
);
$this->add('select', 'excludeMailings',
ts('EXCLUDE Recipients of These Message(s)'),
$mailings,
FALSE,
$select2style
);
$this->addFormRule(array('CRM_SMS_Form_Group', 'formRule'));
$buttons = array(
array(
'type' => 'next',
'name' => ts('Next'),
'spacing' => '&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;',
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
);
$this->addButtons($buttons);
$this->assign('groupCount', count($groups));
$this->assign('mailingCount', count($mailings));
}
public function postProcess() {
$values = $this->controller->exportValues($this->_name);
$groups = array();
foreach (array(
'name',
'group_id',
'is_sms',
) as $n) {
if (!empty($values[$n])) {
$params[$n] = $values[$n];
}
}
$qf_Group_submit = $this->controller->exportValue($this->_name, '_qf_Group_submit');
$this->set('name', $params['name']);
$inGroups = $values['includeGroups'];
$outGroups = $values['excludeGroups'];
$inMailings = $values['includeMailings'];
$outMailings = $values['excludeMailings'];
if (is_array($inGroups)) {
foreach ($inGroups as $key => $id) {
if ($id) {
$groups['include'][] = $id;
}
}
}
if (is_array($outGroups)) {
foreach ($outGroups as $key => $id) {
if ($id) {
$groups['exclude'][] = $id;
}
}
}
$mailings = array();
if (is_array($inMailings)) {
foreach ($inMailings as $key => $id) {
if ($id) {
$mailings['include'][] = $id;
}
}
}
if (is_array($outMailings)) {
foreach ($outMailings as $key => $id) {
if ($id) {
$mailings['exclude'][] = $id;
}
}
}
$session = CRM_Core_Session::singleton();
$params['groups'] = $groups;
$params['mailings'] = $mailings;
$ids = array();
if ($this->get('mailing_id')) {
// don't create a new mass sms if already exists
$ids['mailing_id'] = $this->get('mailing_id');
$groupTableName = CRM_Contact_BAO_Group::getTableName();
$mailingTableName = CRM_Mailing_BAO_Mailing::getTableName();
// delete previous includes/excludes, if mailing already existed
foreach (array(
'groups',
'mailings',
) as $entity) {
$mg = new CRM_Mailing_DAO_MailingGroup();
$mg->mailing_id = $ids['mailing_id'];
$mg->entity_table = ($entity == 'groups') ? $groupTableName : $mailingTableName;
$mg->find();
while ($mg->fetch()) {
$mg->delete();
}
}
}
else {
// new mailing, so lets set the created_id
$session = CRM_Core_Session::singleton();
$params['created_id'] = $session->get('userID');
$params['created_date'] = date('YmdHis');
}
$mailing = CRM_Mailing_BAO_Mailing::create($params, $ids);
$this->set('mailing_id', $mailing->id);
// also compute the recipients and store them in the mailing recipients table
CRM_Mailing_BAO_Mailing::getRecipients($mailing->id,
$mailing->id,
TRUE,
FALSE,
'sms'
);
$count = CRM_Mailing_BAO_Recipients::mailingSize($mailing->id);
$this->set('count', $count);
$this->assign('count', $count);
$this->set('groups', $groups);
$this->set('mailings', $mailings);
if ($qf_Group_submit) {
$status = ts("Your Mass SMS has been saved.");
CRM_Core_Session::setStatus($status, ts('Saved'), 'success');
$url = CRM_Utils_System::url('civicrm/mailing', 'reset=1&sms=1');
return $this->controller->setDestination($url);
}
}
/**
* Display Name of the form.
*
*
* @return string
*/
public function getTitle() {
return ts('Select Recipients');
}
/**
* Global validation rules for the form.
*
* @param array $fields
* Posted values of the form.
*
* @return array
* list of errors to be posted back to the form
*/
public static function formRule($fields) {
$errors = array();
if (isset($fields['includeGroups']) &&
is_array($fields['includeGroups']) &&
isset($fields['excludeGroups']) &&
is_array($fields['excludeGroups'])
) {
$checkGroups = array();
$checkGroups = array_intersect($fields['includeGroups'], $fields['excludeGroups']);
if (!empty($checkGroups)) {
$errors['excludeGroups'] = ts('Cannot have same groups in Include Group(s) and Exclude Group(s).');
}
}
if (isset($fields['includeMailings']) &&
is_array($fields['includeMailings']) &&
isset($fields['excludeMailings']) &&
is_array($fields['excludeMailings'])
) {
$checkMailings = array();
$checkMailings = array_intersect($fields['includeMailings'], $fields['excludeMailings']);
if (!empty($checkMailings)) {
$errors['excludeMailings'] = ts('Cannot have same sms in Include mailing(s) and Exclude mailing(s).');
}
}
return empty($errors) ? TRUE : $errors;
}
}

View file

@ -0,0 +1,182 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* SMS Form.
*/
class CRM_SMS_Form_Provider extends CRM_Core_Form {
protected $_id = NULL;
public function preProcess() {
$this->_id = $this->get('id');
$this->setPageTitle(ts('SMS Provider'));
if ($this->_id) {
$refreshURL = CRM_Utils_System::url('civicrm/admin/sms/provider',
"reset=1&action=update&id={$this->_id}",
FALSE, NULL, FALSE
);
}
else {
$refreshURL = CRM_Utils_System::url('civicrm/admin/sms/provider',
"reset=1&action=add",
FALSE, NULL, FALSE
);
}
$this->assign('refreshURL', $refreshURL);
}
/**
* Build the form object.
*/
public function buildQuickForm() {
parent::buildQuickForm();
$this->addButtons(array(
array(
'type' => 'next',
'name' => $this->_action & CRM_Core_Action::DELETE ? ts('Delete') : ts('Save'),
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
));
if ($this->_action & CRM_Core_Action::DELETE) {
return;
}
$attributes = CRM_Core_DAO::getAttribute('CRM_SMS_DAO_Provider');
$providerNames = CRM_Core_OptionGroup::values('sms_provider_name', FALSE, FALSE, FALSE, NULL, 'label');
$apiTypes = CRM_Core_OptionGroup::values('sms_api_type', FALSE, FALSE, FALSE, NULL, 'label');
$this->add('select', 'name', ts('Name'), array('' => '- select -') + $providerNames, TRUE);
$this->add('text', 'title', ts('Title'),
$attributes['title'], TRUE
);
$this->addRule('title', ts('This Title already exists in Database.'), 'objectExists', array(
'CRM_SMS_DAO_Provider',
$this->_id,
));
$this->add('text', 'username', ts('Username'),
$attributes['username'], TRUE
);
$this->add('password', 'password', ts('Password'),
$attributes['password'], TRUE
);
$this->add('select', 'api_type', ts('API Type'), $apiTypes, TRUE);
$this->add('text', 'api_url', ts('API Url'), $attributes['api_url'], TRUE);
$this->add('textarea', 'api_params', ts('API Parameters'),
"cols=50 rows=6", TRUE
);
$this->add('checkbox', 'is_active', ts('Is this provider active?'));
$this->add('checkbox', 'is_default', ts('Is this a default provider?'));
}
/**
* Set the default values of various form elements.
*
* @return array
*/
public function setDefaultValues() {
$defaults = array();
$name = CRM_Utils_Request::retrieve('key', 'String', $this, FALSE, NULL);
if ($name) {
$defaults['name'] = $name;
$provider = CRM_SMS_Provider::singleton(array('provider' => $name));
$defaults['api_url'] = $provider->_apiURL;
}
if (!$this->_id) {
$defaults['is_active'] = $defaults['is_default'] = 1;
return $defaults;
}
$dao = new CRM_SMS_DAO_Provider();
$dao->id = $this->_id;
if ($name) {
$dao->name = $name;
}
if (!$dao->find(TRUE)) {
return $defaults;
}
CRM_Core_DAO::storeValues($dao, $defaults);
return $defaults;
}
/**
* Process the form submission.
*/
public function postProcess() {
CRM_Utils_System::flushCache('CRM_SMS_DAO_Provider');
if ($this->_action & CRM_Core_Action::DELETE) {
CRM_SMS_BAO_Provider::del($this->_id);
CRM_Core_Session::setStatus(ts('Selected Provider has been deleted.'), ts('Deleted'), 'success');
return;
}
$recData = $values = $this->controller->exportValues($this->_name);
$recData['is_active'] = CRM_Utils_Array::value('is_active', $recData, 0);
$recData['is_default'] = CRM_Utils_Array::value('is_default', $recData, 0);
if ($this->_action && (CRM_Core_Action::UPDATE || CRM_Core_Action::ADD)) {
if ($this->_id) {
$recData['id'] = $this->_id;
}
civicrm_api3('SmsProvider', 'create', $recData);
}
}
}

View file

@ -0,0 +1,196 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
class CRM_SMS_Form_Schedule extends CRM_Core_Form {
/**
* Set variables up before form is built.
*/
public function preProcess() {
$this->_mailingID = $this->get('mailing_id');
if (!$this->_mailingID) {
$this->_mailingID = CRM_Utils_Request::retrieve('mid', 'Integer', $this, TRUE);
}
}
/**
* Set default values for the form.
*/
public function setDefaultValues() {
$defaults = array();
$count = $this->get('count');
$this->assign('count', $count);
$defaults['now'] = 1;
return $defaults;
}
/**
* Build the form object for the last step of the sms wizard.
*/
public function buildQuickform() {
$this->addDateTime('start_date', ts('Schedule SMS'), FALSE, array('formatType' => 'mailing'));
$this->addElement('checkbox', 'now', ts('Send Immediately'));
$this->addFormRule(array('CRM_SMS_Form_Schedule', 'formRule'), $this);
$buttons = array(
array(
'type' => 'back',
'name' => ts('Previous'),
),
array(
'type' => 'next',
'name' => ts('Submit Mass SMS'),
'spacing' => '&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;',
'isDefault' => TRUE,
'js' => array('onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');"),
),
array(
'type' => 'cancel',
'name' => ts('Continue Later'),
),
);
$this->addButtons($buttons);
$preview = array();
$preview['type'] = CRM_Core_DAO::getFieldValue('CRM_Mailing_DAO_Mailing', $this->_mailingID, 'body_html') ? 'html' : 'text';
$preview['viewURL'] = CRM_Utils_System::url('civicrm/mailing/view', "reset=1&id={$this->_mailingID}");
$this->assign_by_ref('preview', $preview);
}
/**
* Form rule to validate the date selector and/or if we should deliver
* immediately.
*
* Warning: if you make changes here, be sure to also make them in
* Retry.php
*
* @param array $params
* The form values.
*
* @param $files
* @param $self
*
* @return bool
* True if either we deliver immediately, or the date is properly
* set.
*/
public static function formRule($params, $files, $self) {
if (!empty($params['_qf_Schedule_submit'])) {
CRM_Core_Session::setStatus(ts("Your Mass SMS has been saved. Click the 'Continue' action to resume working on it."), ts('Saved'), 'success');
$url = CRM_Utils_System::url('civicrm/mailing/browse/unscheduled', 'scheduled=false&reset=1&sms=1');
CRM_Utils_System::redirect($url);
}
if (isset($params['now']) || CRM_Utils_Array::value('_qf_Schedule_back', $params) == ts('Previous')) {
return TRUE;
}
if (CRM_Utils_Date::format(CRM_Utils_Date::processDate($params['start_date'],
$params['start_date_time']
)) < CRM_Utils_Date::format(date('YmdHi00'))
) {
return array(
'start_date' => ts('Start date cannot be earlier than the current time.'),
);
}
return TRUE;
}
/**
* Process the posted form values. Create and schedule a Mass SMS.
*/
public function postProcess() {
$params = array();
$params['mailing_id'] = $ids['mailing_id'] = $this->_mailingID;
if (empty($params['mailing_id'])) {
CRM_Core_Error::fatal(ts('Could not find a mailing id'));
}
foreach (array('now', 'start_date', 'start_date_time') as $parameter) {
$params[$parameter] = $this->controller->exportValue($this->_name, $parameter);
}
if ($params['now']) {
$params['scheduled_date'] = date('YmdHis');
}
else {
$params['scheduled_date'] = CRM_Utils_Date::processDate($params['start_date'] . ' ' . $params['start_date_time']);
}
$session = CRM_Core_Session::singleton();
// set the scheduled_id
$params['scheduled_id'] = $session->get('userID');
$params['scheduled_date'] = date('YmdHis');
// set approval details if workflow is not enabled
if (!CRM_Mailing_Info::workflowEnabled()) {
$params['approver_id'] = $session->get('userID');
$params['approval_date'] = date('YmdHis');
$params['approval_status_id'] = 1;
}
if ($params['now']) {
$params['scheduled_date'] = date('YmdHis');
}
else {
$params['scheduled_date'] = CRM_Utils_Date::processDate($params['start_date'] . ' ' . $params['start_date_time']);
}
// Build the mailing object.
CRM_Mailing_BAO_Mailing::create($params, $ids);
$session = CRM_Core_Session::singleton();
$session->pushUserContext(CRM_Utils_System::url('civicrm/mailing/browse/scheduled',
'reset=1&scheduled=true&sms=1'
));
}
/**
* Display Name of the form.
*
*
* @return string
*/
public function getTitle() {
return ts('Schedule or Send');
}
}

View file

@ -0,0 +1,440 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* This file is used to build the form configuring mass sms details.
*/
class CRM_SMS_Form_Upload extends CRM_Core_Form {
public $_mailingID;
public function preProcess() {
$this->_mailingID = $this->get('mailing_id');
if (CRM_Core_Permission::check('administer CiviCRM')) {
$this->assign('isAdmin', 1);
}
}
/**
* Set default values for the form.
*/
public function setDefaultValues() {
$mailingID = CRM_Utils_Request::retrieve('mid', 'Integer', $this, FALSE, NULL);
// Need to differentiate new/reuse mailing, CRM-2873.
$reuseMailing = FALSE;
if ($mailingID) {
$reuseMailing = TRUE;
}
else {
$mailingID = $this->_mailingID;
}
$count = $this->get('count');
$this->assign('count', $count);
$this->set('skipTextFile', FALSE);
$defaults = array();
if ($mailingID) {
$dao = new CRM_Mailing_DAO_Mailing();
$dao->id = $mailingID;
$dao->find(TRUE);
$dao->storeValues($dao, $defaults);
// We don't want to retrieve template details once it is
// set in session.
$templateId = $this->get('template');
$this->assign('templateSelected', $templateId ? $templateId : 0);
if (isset($defaults['msg_template_id']) && !$templateId) {
$defaults['SMStemplate'] = $defaults['msg_template_id'];
$messageTemplate = new CRM_Core_DAO_MessageTemplate();
$messageTemplate->id = $defaults['msg_template_id'];
$messageTemplate->selectAdd();
$messageTemplate->selectAdd('msg_text');
$messageTemplate->find(TRUE);
$defaults['sms_text_message'] = $messageTemplate->msg_text;
}
if (isset($defaults['body_text'])) {
$defaults['sms_text_message'] = $defaults['body_text'];
$this->set('textFile', $defaults['body_text']);
$this->set('skipTextFile', TRUE);
}
}
// Fix for CRM-2873.
if (!$reuseMailing) {
$textFilePath = $this->get('textFilePath');
if ($textFilePath &&
file_exists($textFilePath)
) {
$defaults['sms_text_message'] = file_get_contents($textFilePath);
if (strlen($defaults['sms_text_message']) > 0) {
$this->set('skipTextFile', TRUE);
}
}
}
$defaults['upload_type'] = 1;
return $defaults;
}
/**
* Build the form object.
*/
public function buildQuickForm() {
$session = CRM_Core_Session::singleton();
$config = CRM_Core_Config::singleton();
$options = array();
$tempVar = FALSE;
$this->assign('max_sms_length', CRM_SMS_Provider::MAX_SMS_CHAR);
// this seems so hacky, not sure what we are doing here and why. Need to investigate and fix
$session->getVars($options,
"CRM_SMS_Controller_Send_{$this->controller->_key}"
);
$providers = CRM_SMS_BAO_Provider::getProviders(array('id', 'title'));
if (empty($providers)) {
//redirect user to configure sms provider.
$url = CRM_Utils_System::url('civicrm/admin/sms/provider', 'action=add&reset=1');
$status = ts("There is no SMS Provider Configured. You can add here <a href='%1'>Add SMS Provider</a>", array(1 => $url));
$session->setStatus($status);
}
else {
$providerSelect[''] = '- select -';
foreach ($providers as $provider) {
$providerSelect[$provider['id']] = $provider['title'];
}
}
$this->add('select', 'sms_provider_id',
ts('SMS Provider'), $providerSelect, TRUE
);
$attributes = array('onclick' => "showHideUpload();");
$options = array(ts('Upload Content'), ts('Compose On-screen'));
$this->addRadio('upload_type', ts('I want to'), $options, $attributes, "&nbsp;&nbsp;");
CRM_Mailing_BAO_Mailing::commonCompose($this);
$this->addElement('file', 'textFile', ts('Upload TEXT Message'), 'size=30 maxlength=60');
$this->setMaxFileSize(1024 * 1024);
$this->addRule('textFile', ts('File size should be less than 1 MByte'), 'maxfilesize', 1024 * 1024);
$this->addRule('textFile', ts('File must be in UTF-8 encoding'), 'utf8File');
$this->addFormRule(array('CRM_SMS_Form_Upload', 'formRule'), $this);
$buttons = array(
array(
'type' => 'back',
'name' => ts('Previous'),
),
array(
'type' => 'upload',
'name' => ts('Next'),
'spacing' => '&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;',
'isDefault' => TRUE,
),
array(
'type' => 'cancel',
'name' => ts('Cancel'),
),
);
$this->addButtons($buttons);
}
public function postProcess() {
$params = $ids = array();
$uploadParams = array('from_name');
$formValues = $this->controller->exportValues($this->_name);
foreach ($uploadParams as $key) {
if (!empty($formValues[$key])) {
$params[$key] = $formValues[$key];
$this->set($key, $formValues[$key]);
}
}
if (!$formValues['upload_type']) {
$contents = NULL;
if (isset($formValues['textFile']) &&
!empty($formValues['textFile'])
) {
$contents = file_get_contents($formValues['textFile']['name']);
$this->set($key, $formValues['textFile']['name']);
}
if ($contents) {
$params['body_text'] = $contents;
}
else {
$params['body_text'] = 'NULL';
}
}
else {
$text_message = $formValues['sms_text_message'];
$params['body_text'] = $text_message;
$this->set('textFile', $params['body_text']);
$this->set('text_message', $params['body_text']);
}
$params['name'] = $this->get('name');
$session = CRM_Core_Session::singleton();
$params['contact_id'] = $session->get('userID');
$composeFields = array(
'SMStemplate',
'SMSsaveTemplate',
'SMSupdateTemplate',
'SMSsaveTemplateName',
);
$msgTemplate = NULL;
// Mail template is composed.
if ($formValues['upload_type']) {
$composeParams = array();
foreach ($composeFields as $key) {
if (!empty($formValues[$key])) {
$composeParams[$key] = $formValues[$key];
$this->set($key, $formValues[$key]);
}
}
if (!empty($composeParams['SMSupdateTemplate'])) {
$templateParams = array(
'msg_text' => $text_message,
'is_active' => TRUE,
'is_sms' => TRUE,
);
$templateParams['id'] = $formValues['SMStemplate'];
$msgTemplate = CRM_Core_BAO_MessageTemplate::add($templateParams);
}
if (!empty($composeParams['SMSsaveTemplate'])) {
$templateParams = array(
'msg_text' => $text_message,
'is_active' => TRUE,
'is_sms' => TRUE,
);
$templateParams['msg_title'] = $composeParams['SMSsaveTemplateName'];
$msgTemplate = CRM_Core_BAO_MessageTemplate::add($templateParams);
}
if (isset($msgTemplate->id)) {
$params['msg_template_id'] = $msgTemplate->id;
}
else {
$params['msg_template_id'] = CRM_Utils_Array::value('SMStemplate', $formValues);
}
$this->set('template', $params['msg_template_id']);
}
$ids['mailing_id'] = $this->_mailingID;
// Get the from email address.
$params['sms_provider_id'] = $formValues['sms_provider_id'];
// Get the from Name.
$params['from_name'] = CRM_Core_DAO::getFieldValue('CRM_SMS_DAO_Provider', $params['sms_provider_id'], 'username');
// Build SMS in mailing table.
CRM_Mailing_BAO_Mailing::create($params, $ids);
}
/**
* Validation.
*
* @param array $params
* (ref.) an assoc array of name/value pairs.
*
* @param $files
* @param $self
*
* @return bool|array
* mixed true or array of errors
*/
public static function formRule($params, $files, $self) {
if (!empty($_POST['_qf_Import_refresh'])) {
return TRUE;
}
$errors = array();
$template = CRM_Core_Smarty::singleton();
$domain = CRM_Core_BAO_Domain::getDomain();
$mailing = new CRM_Mailing_BAO_Mailing();
$mailing->id = $self->_mailingID;
$mailing->find(TRUE);
$session = CRM_Core_Session::singleton();
$values = array(
'contact_id' => $session->get('userID'),
'version' => 3,
);
require_once 'api/api.php';
$contact = civicrm_api('contact', 'get', $values);
// CRM-4524.
$contact = reset($contact['values']);
$verp = array_flip(array('optOut', 'reply', 'unsubscribe', 'resubscribe', 'owner'));
foreach ($verp as $key => $value) {
$verp[$key]++;
}
$urls = array_flip(array('forward', 'optOutUrl', 'unsubscribeUrl', 'resubscribeUrl'));
foreach ($urls as $key => $value) {
$urls[$key]++;
}
$skipTextFile = $self->get('skipTextFile');
if (!$params['upload_type']) {
if ((!isset($files['textFile']) || !file_exists($files['textFile']['tmp_name']))) {
if (!($skipTextFile)) {
$errors['textFile'] = ts('Please provide a Text');
}
}
}
else {
if (empty($params['sms_text_message'])) {
$errors['sms_text_message'] = ts('Please provide a Text');
}
else {
if (!empty($params['text_message'])) {
$messageCheck = CRM_Utils_Array::value('text_message', $params);
if ($messageCheck && (strlen($messageCheck) > CRM_SMS_Provider::MAX_SMS_CHAR)) {
$errors['text_message'] = ts("You can configure the SMS message body up to %1 characters", array(1 => CRM_SMS_Provider::MAX_SMS_CHAR));
}
}
}
if (!empty($params['SMSsaveTemplate']) && empty($params['SMSsaveTemplateName'])) {
$errors['SMSsaveTemplateName'] = ts('Please provide a Template Name.');
}
}
if (($params['upload_type'] || file_exists(CRM_Utils_Array::value('tmp_name', $files['textFile']))) ||
(!$params['upload_type'] && $params['text_message'])
) {
if (!$params['upload_type']) {
$str = file_get_contents($files['textFile']['tmp_name']);
$name = $files['textFile']['name'];
}
else {
$str = $params['sms_text_message'];
$name = 'text message';
}
$dataErrors = array();
// Do a full token replacement on a dummy verp, the current
// contact and domain, and the first organization.
// here we make a dummy mailing object so that we
// can retrieve the tokens that we need to replace
// so that we do get an invalid token error
// this is qute hacky and I hope that there might
// be a suggestion from someone on how to
// make it a bit more elegant
$dummy_mail = new CRM_Mailing_BAO_Mailing();
$mess = "body_text";
$dummy_mail->$mess = $str;
$tokens = $dummy_mail->getTokens();
$str = CRM_Utils_Token::replaceSubscribeInviteTokens($str);
$str = CRM_Utils_Token::replaceDomainTokens($str, $domain, NULL, $tokens['text']);
$str = CRM_Utils_Token::replaceMailingTokens($str, $mailing, NULL, $tokens['text']);
$str = CRM_Utils_Token::replaceOrgTokens($str, $org);
$str = CRM_Utils_Token::replaceActionTokens($str, $verp, $urls, NULL, $tokens['text']);
$str = CRM_Utils_Token::replaceContactTokens($str, $contact, NULL, $tokens['text']);
$unmatched = CRM_Utils_Token::unmatchedTokens($str);
$contentCheck = CRM_Utils_String::htmlToText($str);
if (!empty($unmatched) && 0) {
foreach ($unmatched as $token) {
$dataErrors[] = '<li>' . ts('Invalid token code') . ' {' . $token . '}</li>';
}
}
if (strlen($contentCheck) > CRM_SMS_Provider::MAX_SMS_CHAR) {
$dataErrors[] = '<li>' . ts('The body of the SMS cannot exceed %1 characters.', array(1 => CRM_SMS_Provider::MAX_SMS_CHAR)) . '</li>';
}
if (!empty($dataErrors)) {
$errors['textFile'] = ts('The following errors were detected in %1:', array(
1 => $name,
)) . ' <ul>' . implode('', $dataErrors) . '</ul>';
}
}
$templateName = CRM_Core_BAO_MessageTemplate::getMessageTemplates();
if (!empty($params['SMSsaveTemplate']) && in_array(CRM_Utils_Array::value('SMSsaveTemplateName', $params), $templateName)
) {
$errors['SMSsaveTemplate'] = ts('Duplicate Template Name.');
}
return empty($errors) ? TRUE : $errors;
}
/**
* Display Name of the form.
*
*
* @return string
*/
public function getTitle() {
return ts('SMS Content');
}
/**
* List available tokens for this form.
*
* @return array
*/
public function listTokens() {
$tokens = CRM_Core_SelectValues::contactTokens();
return $tokens;
}
}

View file

@ -0,0 +1,68 @@
<?php
/**
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
class CRM_SMS_Message {
/**
* @var String
* What address is this SMS message coming from.
*/
public $from = '';
/**
* @var String
* What address is this SMS message going to.
*/
public $to = '';
/**
* @var Integer
* Contact ID that is matched to the From address
*/
public $fromContactID = NULL;
/**
* @var Integer
* Contact ID that is matched to the To address
*/
public $toContactID = NULL;
/**
* @var String
* Body content of the message
*/
public $body = '';
/**
* @var Integer
* Trackable ID in the system to match to
*/
public $trackID = NULL;
}

View file

@ -0,0 +1,46 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
class CRM_SMS_Page_Callback {
public function run() {
$provider = CRM_SMS_Provider::singleton($_REQUEST);
if (array_key_exists('status', $_REQUEST)) {
$provider->callback();
}
else {
$provider->inbound();
}
}
}

View file

@ -0,0 +1,190 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* Page for displaying list of Providers
*/
class CRM_SMS_Page_Provider extends CRM_Core_Page_Basic {
public $useLivePageJS = TRUE;
/**
* The action links that we need to display for the browse screen.
*
* @var array
*/
static $_links = NULL;
/**
* Get BAO Name.
*
* @return string
* Classname of BAO.
*/
public function getBAOName() {
return 'CRM_SMS_BAO_Provider';
}
/**
* Get action Links.
*
* @return array
* (reference) of action links
*/
public function &links() {
if (!(self::$_links)) {
self::$_links = array(
CRM_Core_Action::UPDATE => array(
'name' => ts('Edit'),
'url' => 'civicrm/admin/sms/provider',
'qs' => 'action=update&id=%%id%%&reset=1',
'title' => ts('Edit Provider'),
),
CRM_Core_Action::DELETE => array(
'name' => ts('Delete'),
'url' => 'civicrm/admin/sms/provider',
'qs' => 'action=delete&id=%%id%%',
'title' => ts('Delete Provider'),
),
CRM_Core_Action::ENABLE => array(
'name' => ts('Enable'),
'ref' => 'crm-enable-disable',
'title' => ts('Enable Provider'),
),
CRM_Core_Action::DISABLE => array(
'name' => ts('Disable'),
'ref' => 'crm-enable-disable',
'title' => ts('Disable Provider'),
),
);
}
return self::$_links;
}
/**
* Run the page.
*
* This method is called after the page is created. It checks for the
* type of action and executes that action.
* Finally it calls the parent's run method.
*/
public function run() {
// set title and breadcrumb
CRM_Utils_System::setTitle(ts('Settings - SMS Provider'));
$breadCrumb = array(
array(
'title' => ts('SMS Provider'),
'url' => CRM_Utils_System::url('civicrm/admin/sms/provider',
'reset=1'
),
),
);
CRM_Utils_System::appendBreadCrumb($breadCrumb);
$this->_id = CRM_Utils_Request::retrieve('id', 'String',
$this, FALSE, 0
);
$this->_action = CRM_Utils_Request::retrieve('action', 'String',
$this, FALSE, 0
);
return parent::run();
}
/**
* Browse all Providers.
*
* @param array $action
*/
public function browse($action = NULL) {
$providers = CRM_SMS_BAO_Provider::getProviders();
$rows = array();
foreach ($providers as $provider) {
$action = array_sum(array_keys($this->links()));
// update enable/disable links.
if ($provider['is_active']) {
$action -= CRM_Core_Action::ENABLE;
}
else {
$action -= CRM_Core_Action::DISABLE;
}
$apiTypes = CRM_Core_OptionGroup::values('sms_api_type', FALSE, FALSE, FALSE, NULL, 'label');
$provider['api_type'] = $apiTypes[$provider['api_type']];
$provider['action'] = CRM_Core_Action::formLink(self::links(), $action,
array('id' => $provider['id']),
ts('more'),
FALSE,
'sms.provider.row',
'SMSProvider',
$provider['id']
);
$rows[] = $provider;
}
$this->assign('rows', $rows);
}
/**
* Get name of edit form.
*
* @return string
* Classname of edit form.
*/
public function editForm() {
return 'CRM_SMS_Form_Provider';
}
/**
* Get edit form name.
*
* @return string
* name of this page.
*/
public function editName() {
return 'SMS Provider';
}
/**
* Get user context.
*
* @param null $mode
*
* @return string
* user context.
*/
public function userContext($mode = NULL) {
return 'civicrm/admin/sms/provider';
}
}

View file

@ -0,0 +1,385 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
abstract class CRM_SMS_Provider {
/**
* We only need one instance of this object. So we use the singleton
* pattern and cache the instance in this variable
*
* @var object
*/
static private $_singleton = array();
const MAX_SMS_CHAR = 460;
/**
* Singleton function used to manage this object.
*
* @param array $providerParams
* @param bool $force
*
* @return object
*/
public static function &singleton($providerParams = array(), $force = FALSE) {
$mailingID = CRM_Utils_Array::value('mailing_id', $providerParams);
$providerID = CRM_Utils_Array::value('provider_id', $providerParams);
$providerName = CRM_Utils_Array::value('provider', $providerParams);
if (!$providerID && $mailingID) {
$providerID = CRM_Core_DAO::getFieldValue('CRM_Mailing_DAO_Mailing', $mailingID, 'sms_provider_id', 'id');
$providerParams['provider_id'] = $providerID;
}
if ($providerID) {
$providerName = CRM_SMS_BAO_Provider::getProviderInfo($providerID, 'name');
}
if (!$providerName) {
CRM_Core_Error::fatal('Provider not known or not provided.');
}
$providerName = CRM_Utils_Type::escape($providerName, 'String');
$cacheKey = "{$providerName}_" . (int) $providerID . "_" . (int) $mailingID;
if (!isset(self::$_singleton[$cacheKey]) || $force) {
$ext = CRM_Extension_System::singleton()->getMapper();
if ($ext->isExtensionKey($providerName)) {
$paymentClass = $ext->keyToClass($providerName);
require_once "{$paymentClass}.php";
}
else {
CRM_Core_Error::fatal("Could not locate extension for {$providerName}.");
}
self::$_singleton[$cacheKey] = $paymentClass::singleton($providerParams, $force);
}
return self::$_singleton[$cacheKey];
}
/**
* Send an SMS Message via the API Server.
*
* @param array $recipients
* @param string $header
* @param string $message
* @param int $dncID
*/
abstract public function send($recipients, $header, $message, $dncID = NULL);
/**
* Return message text.
*
* Child class could override this function to have better control over the message being sent.
*
* @param string $message
* @param int $contactID
* @param array $contactDetails
*
* @return string
*/
public function getMessage($message, $contactID, $contactDetails) {
$html = $message->getHTMLBody();
$text = $message->getTXTBody();
return $html ? $html : $text;
}
/**
* Get recipient details.
*
* @param array $fields
* @param array $additionalDetails
*
* @return mixed
*/
public function getRecipientDetails($fields, $additionalDetails) {
// we could do more altering here
$fields['To'] = $fields['phone'];
return $fields;
}
/**
* @param int $apiMsgID
* @param $message
* @param array $headers
* @param int $jobID
* @param int $userID
*
* @return self|null|object
* @throws CRM_Core_Exception
*/
public function createActivity($apiMsgID, $message, $headers = array(), $jobID = NULL, $userID = NULL) {
if ($jobID) {
$sql = "
SELECT scheduled_id FROM civicrm_mailing m
INNER JOIN civicrm_mailing_job mj ON mj.mailing_id = m.id AND mj.id = %1";
$sourceContactID = CRM_Core_DAO::singleValueQuery($sql, array(1 => array($jobID, 'Integer')));
}
elseif ($userID) {
$sourceContactID = $userID;
}
else {
$session = CRM_Core_Session::singleton();
$sourceContactID = $session->get('userID');
}
if (!$sourceContactID) {
$sourceContactID = CRM_Utils_Array::value('Contact', $headers);
}
if (!$sourceContactID) {
return FALSE;
}
$activityTypeID = CRM_Core_OptionGroup::getValue('activity_type', 'SMS delivery', 'name');
// note: lets not pass status here, assuming status will be updated by callback
$activityParams = array(
'source_contact_id' => $sourceContactID,
'target_contact_id' => $headers['contact_id'],
'activity_type_id' => $activityTypeID,
'activity_date_time' => date('YmdHis'),
'details' => $message,
'result' => $apiMsgID,
);
return CRM_Activity_BAO_Activity::create($activityParams);
}
/**
* @param string $name
* @param $type
* @param bool $abort
* @param null $default
* @param string $location
*
* @return mixed
*/
public function retrieve($name, $type, $abort = TRUE, $default = NULL, $location = 'REQUEST') {
static $store = NULL;
$value = CRM_Utils_Request::retrieve($name, $type, $store,
FALSE, $default, $location
);
if ($abort && $value === NULL) {
CRM_Core_Error::debug_log_message("Could not find an entry for $name in $location");
echo "Failure: Missing Parameter<p>";
exit();
}
return $value;
}
/**
* @param $from
* @param $body
* @param null $to
* @param int $trackID
*
* @return self|null|object
* @throws CRM_Core_Exception
*/
public function processInbound($from, $body, $to = NULL, $trackID = NULL) {
$message = new CRM_SMS_Message();
$message->from = $from;
$message->to = $to;
$message->body = $body;
$message->trackID = $trackID;
// call hook_civicrm_inboundSMS
CRM_Utils_Hook::inboundSMS($message);
if (!$message->fromContactID) {
// find sender by phone number if $fromContactID not set by hook
$formatFrom = '%' . $this->formatPhone($this->stripPhone($message->from), $like, "like");
$message->fromContactID = CRM_Core_DAO::singleValueQuery("SELECT contact_id FROM civicrm_phone JOIN civicrm_contact ON civicrm_contact.id = civicrm_phone.contact_id WHERE !civicrm_contact.is_deleted AND phone LIKE %1", array(
1 => array($formatFrom, 'String')));
}
if (!$message->fromContactID) {
// unknown mobile sender -- create new contact
// use fake @mobile.sms email address for new contact since civi
// requires email or name for all contacts
$locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
$phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id');
$phoneloc = array_search('Home', $locationTypes);
$phonetype = array_search('Mobile', $phoneTypes);
$stripFrom = $this->stripPhone($message->from);
$contactparams = array(
'contact_type' => 'Individual',
'email' => array(
1 => array(
'location_type_id' => $phoneloc,
'email' => $stripFrom . '@mobile.sms',
),
),
'phone' => array(
1 => array(
'phone_type_id' => $phonetype,
'location_type_id' => $phoneloc,
'phone' => $stripFrom,
),
),
);
$fromContact = CRM_Contact_BAO_Contact::create($contactparams, FALSE, TRUE, FALSE);
$message->fromContactID = $fromContact->id;
}
if (!$message->toContactID) {
// find recipient if $toContactID not set by hook
if ($message->to) {
$message->toContactID = CRM_Core_DAO::singleValueQuery("SELECT contact_id FROM civicrm_phone JOIN civicrm_contact ON civicrm_contact.id = civicrm_phone.contact_id WHERE !civicrm_contact.is_deleted AND phone LIKE %1", array(
1 => array('%' . $message->to, 'String')));
}
else {
$message->toContactID = $message->fromContactID;
}
}
if ($message->fromContactID) {
$actStatusIDs = array_flip(CRM_Core_OptionGroup::values('activity_status'));
$activityTypeID = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Inbound SMS');
// note: lets not pass status here, assuming status will be updated by callback
$activityParams = array(
'source_contact_id' => $message->toContactID,
'target_contact_id' => $message->fromContactID,
'activity_type_id' => $activityTypeID,
'activity_date_time' => date('YmdHis'),
'status_id' => $actStatusIDs['Completed'],
'details' => $message->body,
'phone_number' => $message->from,
);
if ($message->trackID) {
$activityParams['result'] = CRM_Utils_Type::escape($message->trackID, 'String');
}
$result = CRM_Activity_BAO_Activity::create($activityParams);
CRM_Core_Error::debug_log_message("Inbound SMS recorded for cid={$message->fromContactID}.");
return $result;
}
}
/**
* @param $phone
*
* @return mixed|string
*/
public function stripPhone($phone) {
$newphone = preg_replace('/[^0-9x]/', '', $phone);
while (substr($newphone, 0, 1) == "1") {
$newphone = substr($newphone, 1);
}
while (strpos($newphone, "xx") !== FALSE) {
$newphone = str_replace("xx", "x", $newphone);
}
while (substr($newphone, -1) == "x") {
$newphone = substr($newphone, 0, -1);
}
return $newphone;
}
/**
* @param $phone
* @param $kind
* @param string $format
*
* @return mixed|string
*/
public function formatPhone($phone, &$kind, $format = "dash") {
$phoneA = explode("x", $phone);
switch (strlen($phoneA[0])) {
case 0:
$kind = "XOnly";
$area = "";
$exch = "";
$uniq = "";
$ext = $phoneA[1];
break;
case 7:
$kind = $phoneA[1] ? "LocalX" : "Local";
$area = "";
$exch = substr($phone, 0, 3);
$uniq = substr($phone, 3, 4);
$ext = $phoneA[1];
break;
case 10:
$kind = $phoneA[1] ? "LongX" : "Long";
$area = substr($phone, 0, 3);
$exch = substr($phone, 3, 3);
$uniq = substr($phone, 6, 4);
$ext = $phoneA[1];
break;
default:
$kind = "Unknown";
return $phone;
}
switch ($format) {
case "like":
$newphone = '%' . $area . '%' . $exch . '%' . $uniq . '%' . $ext . '%';
$newphone = str_replace('%%', '%', $newphone);
$newphone = str_replace('%%', '%', $newphone);
return $newphone;
case "dash":
$newphone = $area . "-" . $exch . "-" . $uniq . " x" . $ext;
$newphone = trim(trim(trim($newphone, "x"), "-"));
return $newphone;
case "bare":
$newphone = $area . $exch . $uniq . "x" . $ext;
$newphone = trim(trim(trim($newphone, "x"), "-"));
return $newphone;
case "area":
return $area;
default:
return $phone;
}
}
/**
* @param $values
*
* @return string
*/
public function urlEncode($values) {
$uri = '';
foreach ($values as $key => $value) {
$value = urlencode($value);
$uri .= "&{$key}={$value}";
}
if (!empty($uri)) {
$uri = substr($uri, 1);
}
return $uri;
}
}

View file

@ -0,0 +1,59 @@
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2017 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2017
*/
/**
* State machine for managing different states of the Import process.
*/
class CRM_SMS_StateMachine_Send extends CRM_Core_StateMachine {
/**
* Class constructor.
*
* @param object $controller
* @param \const|int $action
*
* @return \CRM_SMS_StateMachine_Send CRM_SMS_StateMachine
*/
public function __construct($controller, $action = CRM_Core_Action::NONE) {
parent::__construct($controller, $action);
$this->_pages = array(
'CRM_SMS_Form_Group' => NULL,
'CRM_SMS_Form_Upload' => NULL,
'CRM_SMS_Form_Schedule' => NULL,
);
$this->addSequentialPages($this->_pages, $action);
}
}