slug = $slug;
$this->options = $this->parse_options($options);
// if checkbox name is not set, set a good custom value
if ($this->checkbox_name === '') {
$this->checkbox_name = '_mc4wp_subscribe_' . $this->slug;
}
}
/**
* Return array of default options
*
* @return array
*/
protected function get_default_options()
{
return array(
'css' => 0,
'double_optin' => 1,
'enabled' => 0,
'implicit' => 0,
'label' => __('Sign me up for the newsletter!', 'mailchimp-for-wp'),
'lists' => array(),
'precheck' => 0,
'replace_interests' => 0,
'update_existing' => 0,
'wrap_p' => 1,
);
}
/**
* @param array $options
*
* @return array
*/
protected function parse_options(array $options)
{
$slug = $this->slug;
$default_options = $this->get_default_options();
$options = array_merge($default_options, $options);
/**
* Filters options for a specific integration
*
* The dynamic portion of the hook, `$slug`, refers to the slug of the ingration.
*
* @param array $integration_options
*/
return (array) apply_filters('mc4wp_integration_' . $slug . '_options', $options);
}
/**
* Initialize the integration
*/
public function initialize()
{
$this->add_required_hooks();
$this->add_hooks();
}
/**
* Adds the required hooks for core functionality, like adding checkbox reset CSS.
*/
protected function add_required_hooks()
{
if ($this->options['css'] && ! $this->options['implicit']) {
add_action('wp_head', array( $this, 'print_css_reset' ));
}
}
/**
* Was integration triggered?
*
* Will always return true when integration is implicit. Otherwise, will check value of checkbox.
*
* @param int $object_id Useful when overriding method. (optional)
* @return bool
*/
public function triggered($object_id = null)
{
return $this->options['implicit'] || $this->checkbox_was_checked();
}
/**
* Adds the hooks which are specific to this integration
*/
abstract protected function add_hooks();
/**
* Print CSS reset
*
* @hooked `wp_head`
*/
public function print_css_reset()
{
$css = file_get_contents(MC4WP_PLUGIN_DIR . '/assets/css/checkbox-reset.css');
// replace selector by integration specific selector so the css affects just this checkbox
$css = str_ireplace('__INTEGRATION_SLUG__', $this->slug, $css);
printf('', $css);
}
/**
* Get the text for the label element
*
* @return string
*/
public function get_label_text()
{
$integration = $this;
$label = $this->options['label'];
if (empty($label)) {
$default_options = $this->get_default_options();
$label = $default_options['label'];
}
/**
* Filters the checkbox label
*
* @since 3.0
*
* @param string $label
* @param MC4WP_Integration $integration
* @ignore
*/
$label = (string) apply_filters('mc4wp_integration_checkbox_label', $label, $integration);
return $label;
}
/**
* Was the integration checkbox checked?
*
* @return bool
*/
public function checkbox_was_checked()
{
$data = $this->get_data();
return isset($data[ $this->checkbox_name ]) && (int) $data[ $this->checkbox_name ] === 1;
}
/**
* Get a string of attributes for the HTML element wrapping the checkbox + label
*
* @return string
*/
protected function get_wrapper_attributes()
{
$html_attrs = array(
'class' => sprintf('mc4wp-checkbox mc4wp-checkbox-%s %s', $this->slug, join(' ', $this->wrapper_classes)),
);
return $this->array_to_attr_string($html_attrs);
}
/**
* Get a string of attributes for the checkbox element.
*
* @return string
*/
protected function get_checkbox_attributes()
{
$integration = $this;
$slug = $this->slug;
$attributes = array();
if ($this->options['precheck']) {
$attributes['checked'] = 'checked';
}
if (! empty($this->checkbox_classes)) {
$attributes['class'] = join(' ', $this->checkbox_classes);
}
/**
* Filters the attributes array.
*
* @param array $attributes
* @param MC4WP_Integration $integration
* @ignore
*/
$attributes = (array) apply_filters('mc4wp_integration_checkbox_attributes', $attributes, $integration);
/**
* Filters the attributes array.
*
* The dynamic portion of the hook, `$slug`, refers to the slug for this integration.
*
* @param array $attributes
* @param MC4WP_Integration $integration
* @ignore
*/
$attributes = (array) apply_filters('mc4wp_integration_' . $slug . '_checkbox_attributes', $attributes, $integration);
return $this->array_to_attr_string($attributes);
}
/**
* Outputs a checkbox
*/
public function output_checkbox()
{
echo $this->get_checkbox_html();
}
/**
* Get HTML string for the checkbox row (incl. wrapper, label, etc.)
*
* @return string
*/
public function get_checkbox_html()
{
$show_checkbox = empty($this->options['implicit']);
$integration_slug = $this->slug;
/**
* Filters whether to show the sign-up checkbox for this integration.
*
* @param bool $show_checkbox
* @param string $integration_slug
*/
$show_checkbox = (bool) apply_filters('mc4wp_integration_show_checkbox', $show_checkbox, $integration_slug);
if (! $show_checkbox) {
return '';
}
ob_start();
echo sprintf('', MC4WP_VERSION);
/** @ignore */
do_action('mc4wp_integration_before_checkbox_wrapper', $this);
/** @ignore */
do_action('mc4wp_integration_' . $this->slug . '_before_checkbox_wrapper', $this);
$wrapper_tag = $this->options['wrap_p'] ? 'p' : 'span';
$wrapper_attrs = $this->get_wrapper_attributes();
// Hidden field to make sure "0" is sent to server
echo sprintf('', esc_attr($this->checkbox_name));
echo sprintf('<%s %s>', $wrapper_tag, $wrapper_attrs);
echo '';
echo sprintf('%s>', $wrapper_tag);
/** @ignore */
do_action('mc4wp_integration_after_checkbox_wrapper', $this);
/** @ignore */
do_action('mc4wp_integration_' . $this->slug . '_after_checkbox_wrapper', $this);
echo '';
$html = ob_get_clean();
return $html;
}
/**
* Get the selected Mailchimp lists
*
* @return array Array of List ID's
*/
public function get_lists()
{
$data = $this->get_data();
$integration = $this;
$slug = $this->slug;
// get checkbox lists options
$lists = $this->options['lists'];
// get lists from request, if set.
if (! empty($data['_mc4wp_lists'])) {
$lists = $data['_mc4wp_lists'];
// ensure lists is an array
if (! is_array($lists)) {
$lists = explode(',', $lists);
$lists = array_map('trim', $lists);
}
}
/**
* Allow plugins to filter final lists value. This filter is documented elsewhere.
*
* @since 2.0
* @see MC4WP_Form::get_lists
* @ignore
*/
$lists = (array) apply_filters('mc4wp_lists', $lists);
/**
* Filters the Mailchimp lists this integration should subscribe to
*
* @since 3.0
*
* @param array $lists
* @param MC4WP_Integration $integration
*/
$lists = (array) apply_filters('mc4wp_integration_lists', $lists, $integration);
/**
* Filters the Mailchimp lists a specific integration should subscribe to
*
* The dynamic portion of the hook, `$slug`, refers to the slug of the integration.
*
* @since 3.0
*
* @param array $lists
* @param MC4WP_Integration $integration
*/
$lists = (array) apply_filters('mc4wp_integration_' . $slug . '_lists', $lists, $integration);
return $lists;
}
/**
* Makes a subscription request
*
* @param array $data
* @param int $related_object_id
*
* @return boolean
*/
protected function subscribe(array $data, $related_object_id = 0)
{
$integration = $this;
$slug = $this->slug;
$mailchimp = new MC4WP_MailChimp();
$log = $this->get_log();
$list_ids = $this->get_lists();
/** @var MC4WP_MailChimp_Subscriber $subscriber */
$subscriber = null;
$result = false;
// validate lists
if (empty($list_ids)) {
$log->warning(sprintf('%s > No Mailchimp lists were selected', $this->name));
return false;
}
/**
* Filters data for integration requests.
*
* @param array $data
*/
$data = apply_filters('mc4wp_integration_data', $data);
/**
* Filters data for a specific integration request.
*
* The dynamic portion of the hook, `$slug`, refers to the integration slug.
*
* @param array $data
* @param int $related_object_id
*/
$data = apply_filters("mc4wp_integration_{$slug}_data", $data, $related_object_id);
$email_type = mc4wp_get_email_type();
$mapper = new MC4WP_List_Data_Mapper($data, $list_ids);
/** @var MC4WP_MailChimp_Subscriber[] $map */
$map = $mapper->map();
foreach ($map as $list_id => $subscriber) {
$subscriber->status = $this->options['double_optin'] ? 'pending' : 'subscribed';
$subscriber->email_type = $email_type;
$subscriber->ip_signup = mc4wp_get_request_ip_address();
/** @ignore (documented elsewhere) */
$subscriber = apply_filters('mc4wp_subscriber_data', $subscriber);
if (! $subscriber instanceof MC4WP_MailChimp_Subscriber) {
continue;
}
/**
* Filters subscriber data before it is sent to Mailchimp. Only fires for integration requests.
*
* @param MC4WP_MailChimp_Subscriber $subscriber
*/
$subscriber = apply_filters('mc4wp_integration_subscriber_data', $subscriber);
if (! $subscriber instanceof MC4WP_MailChimp_Subscriber) {
continue;
}
/**
* Filters subscriber data before it is sent to Mailchimp. Only fires for integration requests.
*
* The dynamic portion of the hook, `$slug`, refers to the integration slug.
*
* @param MC4WP_MailChimp_Subscriber $subscriber
* @param int $related_object_id
*/
$subscriber = apply_filters("mc4wp_integration_{$slug}_subscriber_data", $subscriber, $related_object_id);
if (! $subscriber instanceof MC4WP_MailChimp_Subscriber) {
continue;
}
$result = $mailchimp->list_subscribe($list_id, $subscriber->email_address, $subscriber->to_array(), $this->options['update_existing'], $this->options['replace_interests']);
}
// if result failed, show error message
if (! $result) {
// log error
if ((int) $mailchimp->get_error_code() === 214) {
$log->warning(sprintf('%s > %s is already subscribed to the selected list(s)', $this->name, $subscriber->email_address));
} else {
$log->error(sprintf('%s > Mailchimp API Error: %s', $this->name, $mailchimp->get_error_message()));
}
// bail
return false;
}
$log->info(sprintf('%s > Successfully subscribed %s', $this->name, $subscriber->email_address));
/**
* Runs right after someone is subscribed using an integration
*
* @since 3.0
*
* @param MC4WP_Integration $integration
* @param string $email_address
* @param array $merge_vars
* @param MC4WP_MailChimp_Subscriber[] $subscriber_data
* @param int $related_object_id
*/
do_action('mc4wp_integration_subscribed', $integration, $subscriber->email_address, $subscriber->merge_fields, $map, $related_object_id);
return true;
}
/**
* Are the required dependencies for this integration installed?
*
* @return bool
*/
public function is_installed()
{
return false;
}
/**
* Which UI elements should we show on the settings page for this integration?
*
* @return array
*/
public function get_ui_elements()
{
return array_keys($this->options);
}
/**
* Does integration have the given UI element?
*
* @param string $element
* @return bool
*/
public function has_ui_element($element)
{
$elements = $this->get_ui_elements();
return in_array($element, $elements, true);
}
/**
* Return a string to the admin settings page for this object (if any)
*
* @param int $object_id
* @return string
*/
public function get_object_link($object_id)
{
return '';
}
/**
* Get the data for this integration request
*
* By default, this will return a combination of all $_GET and $_POST parameters.
* Override this method if you need data from somewhere else.
*
* This data should contain the value of the checkbox (required)
* and the lists to which should be subscribed (optional)
*
* @see MC4WP_Integration::$checkbox_name
* @see MC4WP_Integration::get_lists
* @see MC4WP_Integration::checkbox_was_checked
*
* @return array
*/
public function get_data()
{
return array_merge((array) $_GET, (array) $_POST);
}
/**
* Converts an array to an attribute string (foo="bar" bar="foo") with escaped values.
*
* @param array $attrs
* @return string
*/
protected function array_to_attr_string(array $attrs)
{
$str = '';
foreach ($attrs as $key => $value) {
$str .= sprintf('%s="%s" ', $key, esc_attr($value));
}
return $str;
}
/**
* @return MC4WP_Debug_Log
*/
protected function get_log()
{
return mc4wp('log');
}
/**
* @return MC4WP_API_V3
*/
protected function get_api()
{
return mc4wp('api');
}
}