-
-
Save cvstudios/2cae789bcf0063343aa4c980e3a1b5cf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
application/x-httpd-php mailchimp.php ( PHP script text ) | |
<?php | |
/* | |
Plugin Name: MailChimp | |
Plugin URI: http://www.mailchimp.com/plugins/mailchimp-wordpress-plugin/ | |
Description: The MailChimp plugin allows you to quickly and easily add a signup form for your MailChimp list. | |
Version: 1.5.7 | |
Author: MailChimp | |
Author URI: https://mailchimp.com/ | |
*/ | |
/* Copyright 2008-2012 MailChimp.com (email : api@mailchimp.com) | |
This program is free software; you can redistribute it and/or modify | |
it under the terms of the GNU General Public License as published by | |
the Free Software Foundation; either version 2 of the License, or | |
(at your option) any later version. | |
This program 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 this program; if not, write to the Free Software | |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
*/ | |
// Version constant for easy CSS refreshes | |
define('MCSF_VER', '1.5.7'); | |
// What's our permission (capability) threshold | |
define('MCSF_CAP_THRESHOLD', 'manage_options'); | |
// Define our location constants, both MCSF_DIR and MCSF_URL | |
mailchimpSF_where_am_i(); | |
// Get our MailChimp API class in scope | |
if (!class_exists('MailChimp_API')) { | |
$path = plugin_dir_path(__FILE__); | |
require_once($path . 'lib/mailchimp/mailchimp.php'); | |
} | |
// includes the widget code so it can be easily called either normally or via ajax | |
include_once('mailchimp_widget.php'); | |
// includes the backwards compatibility functions | |
include_once('mailchimp_compat.php'); | |
/** | |
* Do the following plugin setup steps here | |
* | |
* Internationalization | |
* Resource (JS & CSS) enqueuing | |
* | |
* @return void | |
*/ | |
function mailchimpSF_plugin_init() { | |
// Internationalize the plugin | |
$textdomain = 'mailchimp_i18n'; | |
$locale = apply_filters( 'plugin_locale', get_locale(), $textdomain); | |
load_textdomain('mailchimp_i18n', MCSF_LANG_DIR.$textdomain.'-'.$locale.'.mo'); | |
// Remove Sopresto check. If user does not have API key, make them authenticate. | |
if (get_option('mc_list_id') && get_option('mc_merge_field_migrate') != true && mailchimpSF_get_api() !== false) { | |
mailchimpSF_update_merge_fields(get_option('mc_list_id')); | |
} | |
// Bring in our appropriate JS and CSS resources | |
mailchimpSF_load_resources(); | |
} | |
add_action( 'init', 'mailchimpSF_plugin_init' ); | |
/** | |
* Add the settings link to the MailChimp plugin row | |
* | |
* @param array $links - Links for the plugin | |
* @return array - Links | |
*/ | |
function mailchimpSD_plugin_action_links($links) { | |
$settings_page = add_query_arg(array('page' => 'mailchimpSF_options'), admin_url('options-general.php')); | |
$settings_link = '<a href="'.esc_url($settings_page).'">'.__('Settings', 'mailchimp_i18n' ).'</a>'; | |
array_unshift($links, $settings_link); | |
return $links; | |
} | |
add_filter('plugin_action_links_'.plugin_basename(__FILE__), 'mailchimpSD_plugin_action_links', 10, 1); | |
/** | |
* Loads the appropriate JS and CSS resources depending on | |
* settings and context (admin or not) | |
* | |
* @return void | |
*/ | |
function mailchimpSF_load_resources() { | |
// JS | |
if (get_option('mc_use_javascript') == 'on') { | |
if (!is_admin()) { | |
wp_enqueue_script('jquery_scrollto', MCSF_URL.'/js/scrollTo.js', array('jquery'), MCSF_VER); | |
wp_enqueue_script('mailchimpSF_main_js', MCSF_URL.'/js/mailchimp.js', array('jquery', 'jquery-form'), MCSF_VER); | |
// some javascript to get ajax version submitting to the proper location | |
global $wp_scripts; | |
$wp_scripts->localize('mailchimpSF_main_js', 'mailchimpSF', array( | |
'ajax_url' => trailingslashit(home_url()), | |
)); | |
} | |
} | |
if (get_option('mc_use_datepicker') == 'on' && !is_admin()) { | |
// Datepicker theme | |
wp_enqueue_style('flick', MCSF_URL.'/css/flick/flick.css' | |
); | |
// Datepicker JS | |
wp_enqueue_script('datepicker', MCSF_URL.'/js/datepicker.js', array('jquery','jquery-ui-core')); | |
} | |
if(get_option('mc_nuke_all_styles') != true) { | |
wp_enqueue_style('mailchimpSF_main_css', home_url('?mcsf_action=main_css&ver='.MCSF_VER, 'relative')); | |
wp_enqueue_style('mailchimpSF_ie_css', MCSF_URL.'css/ie.css'); | |
global $wp_styles; | |
$wp_styles->add_data( 'mailchimpSF_ie_css', 'conditional', 'IE' ); | |
} | |
} | |
/** | |
* Loads resources for the MailChimp admin page | |
* | |
* @return void | |
*/ | |
function mc_admin_page_load_resources() { | |
wp_enqueue_style('mailchimpSF_admin_css', MCSF_URL.'css/admin.css'); | |
} | |
add_action('load-settings_page_mailchimpSF_options', 'mc_admin_page_load_resources'); | |
/** | |
* Loads jQuery Datepicker for the date-pick class | |
**/ | |
function mc_datepicker_load() { | |
require_once(MCSF_DIR . '/views/datepicker.php'); | |
} | |
if (get_option('mc_use_datepicker') == 'on' && !is_admin()) { | |
add_action('wp_head', 'mc_datepicker_load'); | |
} | |
/** | |
* Handles requests that as light-weight a load as possible. | |
* typically, JS or CSS | |
**/ | |
function mailchimpSF_early_request_handler() { | |
if (isset($_GET['mcsf_action'])) { | |
switch ($_GET['mcsf_action']) { | |
case 'main_css': | |
header("Content-type: text/css"); | |
mailchimpSF_main_css(); | |
exit; | |
} | |
} | |
} | |
add_action('init', 'mailchimpSF_early_request_handler', 0); | |
/** | |
* Outputs the front-end CSS. This checks several options, so it | |
* was best to put it in a Request-handled script, as opposed to | |
* a static file. | |
*/ | |
function mailchimpSF_main_css() { | |
require_once(MCSF_DIR . '/views/css/frontend.php'); | |
} | |
/** | |
* Add our settings page to the admin menu | |
* | |
* @return void | |
*/ | |
function mailchimpSF_add_pages(){ | |
// Add settings page for users who can edit plugins | |
add_options_page( __( 'MailChimp Setup', 'mailchimp_i18n' ), __( 'MailChimp Setup', 'mailchimp_i18n' ), MCSF_CAP_THRESHOLD, 'mailchimpSF_options', 'mailchimpSF_setup_page'); | |
} | |
add_action('admin_menu', 'mailchimpSF_add_pages'); | |
function mailchimpSF_request_handler() { | |
if (isset($_POST['mcsf_action'])) { | |
switch ($_POST['mcsf_action']) { | |
case 'login': | |
$key = trim($_POST['mailchimpSF_api_key']); | |
try { | |
$api = new MailChimp_API($key); | |
} catch (Exception $e) { | |
$msg = "<strong class='mc_error_msg'>" . $e->getMessage() . "</strong>"; | |
mailchimpSF_global_msg($msg); | |
break; | |
} | |
$key = mailchimpSF_verify_key($api); | |
if(is_wp_error($key)) { | |
$msg = "<strong class='mc_error_msg'>" . $key->get_error_message() . "</strong>"; | |
mailchimpSF_global_msg($msg); | |
} | |
break; | |
case 'logout': | |
// Check capability & Verify nonce | |
if (!current_user_can(MCSF_CAP_THRESHOLD) || !wp_verify_nonce($_POST['_mcsf_nonce_action'], 'mc_logout')) { | |
wp_die('Cheatin’ huh?'); | |
} | |
// erase auth information | |
$options = array('mc_api_key', 'mc_sopresto_user', 'mc_sopresto_public_key', 'mc_sopresto_secret_key'); | |
mailchimpSF_delete_options($options); | |
break; | |
case 'change_form_settings': | |
if (!current_user_can(MCSF_CAP_THRESHOLD) || !wp_verify_nonce($_POST['_mcsf_nonce_action'], 'update_general_form_settings')) { | |
wp_die('Cheatin’ huh?'); | |
} | |
// Update the form settings | |
mailchimpSF_save_general_form_settings(); | |
break; | |
case 'mc_submit_signup_form': | |
// Validate nonce | |
if (!wp_verify_nonce($_POST['_mc_submit_signup_form_nonce'], 'mc_submit_signup_form')) { | |
wp_die('Cheatin’ huh?'); | |
} | |
// Attempt the signup | |
mailchimpSF_signup_submit(); | |
// Do a different action for html vs. js | |
switch ($_POST['mc_submit_type']) { | |
case 'html': | |
/* This gets set elsewhere! */ | |
break; | |
case 'js': | |
if (!headers_sent()){ //just in case... | |
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT', true, 200); | |
} | |
echo mailchimpSF_global_msg(); // Don't esc_html this, b/c we've already escaped it | |
exit; | |
} | |
} | |
} | |
} | |
add_action('init', 'mailchimpSF_request_handler'); | |
function mailchimpSF_migrate_sopresto() { | |
$sopresto = get_option('mc_sopresto_secret_key'); | |
if(!$sopresto) { | |
return; | |
} | |
// Talk to Sopresto, make exchange, delete old sopresto things. | |
$body = array( | |
'public_key' => get_option('mc_sopresto_public_key'), | |
'hash' => sha1(get_option('mc_sopresto_public_key').get_option('mc_sopresto_secret_key')) | |
); | |
$url = 'https://sopresto.socialize-this.com/mailchimp/exchange'; | |
$args = array( | |
'method' => 'POST', | |
'timeout' => 500, | |
'redirection' => 5, | |
'httpversion' => '1.0', | |
'user-agent' => 'MailChimp WordPress Plugin/' . get_bloginfo( 'url' ), | |
'body' => $body | |
); | |
//post to sopresto | |
$key = wp_remote_post($url, $args); | |
if(!is_wp_error($key) && $key['response']['code'] == 200) { | |
$key = json_decode($key['body']); | |
try { | |
$api = new MailChimp_API($key->response); | |
} catch (Exception $e) { | |
$msg = "<strong class='mc_error_msg'>" . $e->getMessage() . "</strong>"; | |
mailchimpSF_global_msg($msg); | |
return; | |
} | |
$verify = mailchimpSF_verify_key($api); | |
//something went wrong with the key that we had | |
if(is_wp_error($verify)) { | |
return; | |
} | |
delete_option('mc_sopresto_public_key'); | |
delete_option('mc_sopresto_secret_key'); | |
delete_option('mc_sopresto_user'); | |
return; | |
} | |
// Nothing to do here. | |
return; | |
} | |
function mailchimpSF_update_merge_fields($list_id) | |
{ | |
mailchimpSF_get_merge_vars(get_option('mc_list_id'), true); | |
mailchimpSF_get_interest_categories(get_option('mc_list_id'), true); | |
update_option('mc_merge_field_migrate', true); | |
} | |
function mailchimpSF_auth_nonce_key($salt = null) { | |
if (is_null($salt)) { | |
$salt = mailchimpSF_auth_nonce_salt(); | |
} | |
return 'social_authentication' . md5( AUTH_KEY . $salt ); | |
} | |
function mailchimpSF_auth_nonce_salt() { | |
return md5(microtime().$_SERVER['SERVER_ADDR']); | |
} | |
/** | |
* Creates new MailChimp API v3 object | |
* | |
* @return MailChimp_API | false | |
*/ | |
function mailchimpSF_get_api($force = false) { | |
$key = get_option('mc_api_key'); | |
if($key) { | |
return new MailChimp_API($key); | |
} | |
return false; | |
} | |
/** | |
* Checks to see if we're storing a password, if so, we need | |
* to upgrade to the API key | |
* | |
* @return bool | |
**/ | |
function mailchimpSF_needs_upgrade() { | |
$igs = get_option('mc_interest_groups'); | |
if ($igs !== false // we have an option | |
&& ( | |
empty($igs) || // it can be an empty array (no interest groups) | |
(is_array($igs) && isset($igs[0]['id'])) // OR it should be a populated array that's well-formed | |
)) { | |
return false; // no need to upgrade | |
} | |
else { | |
return true; // yeah, let's do it | |
} | |
} | |
/** | |
* Deletes all mailchimp options | |
**/ | |
function mailchimpSF_delete_setup() { | |
$options = array('mc_user_id', 'mc_sopresto_user', 'mc_sopresto_public_key', 'mc_sopresto_secret_key', 'mc_rewards', 'mc_use_javascript', 'mc_use_datepicker', 'mc_use_unsub_link', 'mc_list_id', 'mc_list_name', 'mc_interest_groups', 'mc_merge_vars'); | |
$igs = get_option('mc_interest_groups'); | |
if (is_array($igs)) { | |
foreach ($igs as $ig) { | |
$opt = 'mc_show_interest_groups_'.$ig['id']; | |
$options[] = $opt; | |
} | |
} | |
$mv = get_option('mc_merge_vars'); | |
if (is_array($mv)){ | |
foreach($mv as $var){ | |
$opt = 'mc_mv_'.$var['tag']; | |
$options[] = $opt; | |
} | |
} | |
mailchimpSF_delete_options($options); | |
} | |
/** | |
* Gets or sets a global message based on parameter passed to it | |
* | |
* @return string/bool depending on get/set | |
**/ | |
function mailchimpSF_global_msg($msg = null) { | |
global $mcsf_msgs; | |
// Make sure we're formed properly | |
if (!is_array($mcsf_msgs)) { | |
$mcsf_msgs = array(); | |
} | |
// See if we're getting | |
if (is_null($msg)) { | |
return implode('', $mcsf_msgs); | |
} | |
// Must be setting | |
$mcsf_msgs[] = $msg; | |
return true; | |
} | |
/** | |
* Sets the default options for the option form | |
**/ | |
function mailchimpSF_set_form_defaults($list_name = '') { | |
update_option('mc_header_content',__( 'Sign up for', 'mailchimp_i18n' ).' '.$list_name); | |
update_option('mc_submit_text',__( 'Subscribe', 'mailchimp_i18n' )); | |
update_option('mc_use_datepicker', 'on'); | |
update_option('mc_custom_style','off'); | |
update_option('mc_use_javascript','on'); | |
update_option('mc_double_optin', true); | |
update_option('mc_use_unsub_link','off'); | |
update_option('mc_header_border_width','1'); | |
update_option('mc_header_border_color','E3E3E3'); | |
update_option('mc_header_background','FFFFFF'); | |
update_option('mc_header_text_color','CC6600'); | |
update_option('mc_form_border_width','1'); | |
update_option('mc_form_border_color','E0E0E0'); | |
update_option('mc_form_background','FFFFFF'); | |
update_option('mc_form_text_color','3F3F3f'); | |
} | |
/** | |
* Saves the General Form settings on the options page | |
* | |
* @return void | |
**/ | |
function mailchimpSF_save_general_form_settings() { | |
// IF NOT DEV MODE | |
if (isset($_POST['mc_rewards'])){ | |
update_option('mc_rewards', 'on'); | |
$msg = '<p class="success_msg">'.__('Monkey Rewards turned On!', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
} else if (get_option('mc_rewards')!='off') { | |
update_option('mc_rewards', 'off'); | |
$msg = '<p class="success_msg">'.__('Monkey Rewards turned Off!', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
} | |
if (isset($_POST['mc_use_javascript'])){ | |
update_option('mc_use_javascript', 'on'); | |
$msg = '<p class="success_msg">'.__('Fancy Javascript submission turned On!', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
} else if (get_option('mc_use_javascript')!='off') { | |
update_option('mc_use_javascript', 'off'); | |
$msg = '<p class="success_msg">'.__('Fancy Javascript submission turned Off!', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
} | |
if (isset($_POST['mc_use_datepicker'])){ | |
update_option('mc_use_datepicker', 'on'); | |
$msg = '<p class="success_msg">'.__('Datepicker turned On!', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
} else if (get_option('mc_use_datepicker')!='off') { | |
update_option('mc_use_datepicker', 'off'); | |
$msg = '<p class="success_msg">'.__('Datepicker turned Off!', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
} | |
/*Enable double optin toggle*/ | |
if(isset($_POST['mc_double_optin'])) { | |
update_option('mc_double_optin', true); | |
$msg = '<p class="success_msg">'.__('Double opt-in turned On!', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
} else if (get_option('mc_double_optin') != false) { | |
update_option('mc_double_optin', false); | |
$msg = '<p class="success_msg">'.__('Double opt-in turned Off!', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
} | |
/* NUKE the CSS! */ | |
if(isset($_POST['mc_nuke_all_styles'])) { | |
update_option('mc_nuke_all_styles', true); | |
$msg = '<p class="success_msg">'.__('MailChimp CSS turned Off!', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
}elseif (get_option('mc_nuke_all_styles') !== false) { | |
update_option('mc_nuke_all_styles', false); | |
$msg = '<p class="success_msg">'.__('MailChimp CSS turned On!', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
} | |
/* Update existing */ | |
if (isset($_POST['mc_update_existing'])) { | |
update_option('mc_update_existing', true); | |
$msg = '<p class="success_msg">' . __('Update existing subscribers turned On!') . '</p>'; | |
mailchimpSF_global_msg($msg); | |
} elseif (get_option('mc_update_existing') ==! false) { | |
update_option('mc_update_existing', false); | |
$msg = '<p class="success_msg">' . __('Update existing subscribers turned Off!') . '</p>'; | |
mailchimpSF_global_msg($msg); | |
} | |
if (isset($_POST['mc_use_unsub_link'])){ | |
update_option('mc_use_unsub_link', 'on'); | |
$msg = '<p class="success_msg">'.__('Unsubscribe link turned On!', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
} | |
elseif (get_option('mc_use_unsub_link')!='off') { | |
update_option('mc_use_unsub_link', 'off'); | |
$msg = '<p class="success_msg">'.__('Unsubscribe link turned Off!', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
} | |
$content = stripslashes($_POST['mc_header_content']); | |
$content = str_replace("\r\n","<br/>", $content); | |
update_option('mc_header_content', $content ); | |
$content = stripslashes($_POST['mc_subheader_content']); | |
$content = str_replace("\r\n","<br/>", $content); | |
update_option('mc_subheader_content', $content ); | |
$submit_text = stripslashes($_POST['mc_submit_text']); | |
$submit_text = str_replace("\r\n","", $submit_text); | |
update_option('mc_submit_text', $submit_text); | |
// Set Custom Style option | |
update_option('mc_custom_style', isset($_POST['mc_custom_style']) ? 'on' : 'off'); | |
//we told them not to put these things we are replacing in, but let's just make sure they are listening... | |
if(isset($_POST['mc_form_border_width'])) { | |
update_option('mc_form_border_width',str_replace('px', '', $_POST['mc_form_border_width']) ); | |
} | |
if(isset($_POST['mc_form_border_color'])) { | |
update_option('mc_form_border_color', str_replace('#', '', $_POST['mc_form_border_color'])); | |
} | |
if(isset($_POST['mc_form_background'])){ | |
update_option('mc_form_background',str_replace('#', '', $_POST['mc_form_background'])); | |
} | |
if(isset($_POST['mc_form_text_color'])) { | |
update_option('mc_form_text_color', str_replace('#', '', $_POST['mc_form_text_color'])); | |
} | |
// IF NOT DEV MODE | |
$igs = get_option('mc_interest_groups'); | |
if (is_array($igs)) { | |
foreach($igs as $var){ | |
$opt = 'mc_show_interest_groups_'.$var['id']; | |
if (isset($_POST[$opt])){ | |
update_option($opt,'on'); | |
} else { | |
update_option($opt,'off'); | |
} | |
} | |
} | |
$mv = get_option('mc_merge_vars'); | |
if (is_array($mv)) { | |
foreach($mv as $var){ | |
$opt = 'mc_mv_'.$var['tag']; | |
if (isset($_POST[$opt]) || $var['required']=='Y'){ | |
update_option($opt,'on'); | |
} else { | |
update_option($opt,'off'); | |
} | |
} | |
} | |
$msg = '<p class="success_msg">'.esc_html(__('Successfully Updated your List Subscribe Form Settings!', 'mailchimp_i18n')).'</p>'; | |
mailchimpSF_global_msg($msg); | |
} | |
/** | |
* Sees if the user changed the list, and updates options accordingly | |
**/ | |
function mailchimpSF_change_list_if_necessary() { | |
// Simple permission check before going through all this | |
if (!current_user_can(MCSF_CAP_THRESHOLD)) { return; } | |
$api = mailchimpSF_get_api(); | |
if (!$api) { return; } | |
//we *could* support paging, but few users have that many lists (and shouldn't) | |
$lists = $api->get('lists',100, array('fields' => 'lists.id,lists.name,lists.email_type_option')); | |
$lists = $lists['lists']; | |
if (is_array($lists) && !empty($lists) && isset($_POST['mc_list_id'])) { | |
/* If our incoming list ID (the one chosen in the select dropdown) | |
is in our array of lists, the set it to be the active list */ | |
foreach($lists as $key => $list) { | |
if ($list['id'] == $_POST['mc_list_id']) { | |
$list_id = $_POST['mc_list_id']; | |
$list_name = $list['name']; | |
$list_key = $key; | |
} | |
} | |
$orig_list = get_option('mc_list_id'); | |
if ($list_id != '') { | |
update_option('mc_list_id', $list_id); | |
update_option('mc_list_name', $list_name); | |
update_option('mc_email_type_option', $lists[$list_key]['email_type_option']); | |
// See if the user changed the list | |
$new_list = false; | |
if ($orig_list != $list_id){ | |
// The user changed the list, Reset the Form Defaults | |
mailchimpSF_set_form_defaults($list_name); | |
$new_list = true; | |
} | |
// email_type_option | |
// Grab the merge vars and interest groups | |
$mv = mailchimpSF_get_merge_vars($list_id, $new_list); | |
$igs = mailchimpSF_get_interest_categories($list_id, $new_list); | |
$igs_text = ' '; | |
if (is_array($igs)) { | |
$igs_text .= sprintf(__('and %s Sets of Interest Groups', 'mailchimp_i18n'), count($igs)); | |
} | |
$msg = '<p class="success_msg">'. | |
sprintf( | |
__('<b>Success!</b> Loaded and saved the info for %d Merge Variables', 'mailchimp_i18n').$igs_text, | |
count($mv) | |
).' '. | |
__('from your list').' "'.$list_name.'"<br/><br/>'. | |
__('Now you should either Turn On the MailChimp Widget or change your options below, then turn it on.', 'mailchimp_i18n').'</p>'; | |
mailchimpSF_global_msg($msg); | |
} | |
} | |
} | |
function mailchimpSF_get_merge_vars($list_id, $new_list) { | |
$api = mailchimpSF_get_api(); | |
$mv = $api->get('lists/' . $list_id . '/merge-fields', 80); | |
//if we get an error back from the api, exit this process. | |
if(is_wp_error($mv)) { | |
return; | |
} | |
$mv['merge_fields'] = mailchimpSF_add_email_field($mv['merge_fields']); | |
update_option('mc_merge_vars', $mv['merge_fields']); | |
foreach($mv['merge_fields'] as $var){ | |
$opt = 'mc_mv_'.$var['tag']; | |
//turn them all on by default | |
if ($new_list) { | |
update_option($opt, 'on' ); | |
} | |
} | |
return $mv['merge_fields']; | |
} | |
function mailchimpSF_add_email_field($merge) { | |
$email = array( | |
'tag' => 'EMAIL', | |
'name' => __('Email Address', 'mailchimp_i18n'), | |
'type' => 'email', | |
'required' => true, | |
'public' => true, | |
'display_order' => 1, | |
'default_value' => null | |
); | |
array_unshift($merge, $email); | |
return $merge; | |
} | |
function mailchimpSF_get_interest_categories($list_id, $new_list) { | |
$api = mailchimpSF_get_api(); | |
$igs = $api->get('lists/' . $list_id . '/interest-categories', 60); | |
//if we get an error back from the api, exis | |
if(is_wp_error($igs)) { | |
return; | |
} | |
if (is_array($igs)) { | |
$key = 0; | |
foreach($igs['categories'] as $ig) { | |
$groups = $api->get('lists/' . $list_id . '/interest-categories/' . $ig['id'] . '/interests', 60); | |
$igs['categories'][$key]['groups'] = $groups['interests']; | |
$opt = 'mc_show_interest_groups_'.$ig['id']; | |
//turn them all on by default | |
if ($new_list) { | |
update_option($opt, 'on' ); | |
} | |
$key++; | |
} | |
} | |
update_option('mc_interest_groups', $igs['categories']); | |
return $igs['categories']; | |
} | |
/** | |
* Outputs the Settings/Options page | |
*/ | |
function mailchimpSF_setup_page() { | |
$path = plugin_dir_path(__FILE__); | |
wp_enqueue_script('showMe', MCSF_URL.'js/hidecss.js', array('jquery'), MCSF_VER); | |
require_once($path.'/views/setup_page.php'); | |
}//mailchimpSF_setup_page() | |
function mailchimpSF_register_widgets() { | |
if (mailchimpSF_get_api()) { | |
register_widget('mailchimpSF_Widget'); | |
} | |
} | |
add_action('widgets_init', 'mailchimpSF_register_widgets'); | |
function mailchimpSF_shortcode($atts){ | |
ob_start(); | |
mailchimpSF_signup_form(); | |
return ob_get_clean(); | |
} | |
add_shortcode('mailchimpsf_form', 'mailchimpSF_shortcode'); | |
/** | |
* Attempts to signup a user, per the $_POST args. | |
* | |
* This sets a global message, that is then used in the widget | |
* output to retrieve and display that message. | |
* | |
* @return bool | |
*/ | |
function mailchimpSF_signup_submit() { | |
$mv = get_option('mc_merge_vars', array()); | |
$mv_tag_keys = array(); | |
$igs = get_option('mc_interest_groups', array()); | |
$listId = get_option('mc_list_id'); | |
$email = isset($_POST['mc_mv_EMAIL']) ? strip_tags(stripslashes($_POST['mc_mv_EMAIL'])) : ''; | |
$merge = $errs = $html_errs = array(); // Set up some vars | |
$merge = mailchimpSF_merge_submit($mv); | |
//Catch errors and fail early. | |
if(is_wp_error($merge)) { | |
$msg = "<strong class='mc_error_msg'>" . $merge->get_error_message() . "</strong>"; | |
mailchimpSF_global_msg($msg); | |
return false; | |
} | |
// Head back to the beginning of the merge vars array | |
reset($mv); | |
// Ensure we have an array | |
$igs = !is_array($igs) ? array() : $igs; | |
$igs = mailchimpSF_groups_submit($igs); | |
// Clear out empty merge vars | |
$merge = mailchimpSF_merge_remove_empty($merge); | |
if (isset($_POST['email_type']) && in_array($_POST['email_type'], array('text', 'html', 'mobile'))) { | |
$email_type = $_POST['email_type']; | |
} | |
else { | |
$email_type = 'html'; | |
} | |
$api = mailchimpSF_get_api(); | |
if (!$api) { | |
$url = mailchimpSF_signup_form_url(); | |
$error = '<strong class="mc_error_msg">'. __('We encountered a problem adding ' . $email . ' to the list. Please <a href="' . $url . '">sign up here.</a>') . '</strong>'; | |
mailchimpSF_global_msg($error); | |
return false; | |
} | |
$url = 'lists/'. $listId . '/members/' . md5(strtolower($email)); | |
$status = mailchimpSF_check_status($url); | |
// If update existing is turned off and the subscriber exists, error out. | |
if (get_option('mc_update_existing') == false && $status === 'subscribed') { | |
$msg = 'This email address is already subscribed to the list.'; | |
$error = new WP_Error('mailchimp-update-existing', $msg); | |
mailchimpSF_global_msg('<strong class="mc_error_msg">' . $msg . '</strong>'); | |
return false; | |
} | |
$body = mailchimpSF_subscribe_body($merge, $igs, $email_type, $email, $status, get_option('mc_double_optin')); | |
$retval = $api->post($url, $body, 'PUT'); | |
// If we have errors, then show them | |
if(is_wp_error($retval)) { | |
$msg = "<strong class='mc_error_msg'>" . $retval->get_error_message() . "</strong>"; | |
mailchimpSF_global_msg($msg); | |
return false; | |
} | |
if($retval['status'] == 'subscribed') { | |
$esc = __("Success, you've been signed up.", 'mailchimp_i18n'); | |
$msg = "<strong class='mc_success_msg'>{$esc}</strong>"; | |
} else { | |
$esc = __("Success, you've been signed up! Please look for our confirmation email.", 'mailchimp_i18n'); | |
$msg = "<strong class='mc_success_msg'>{$esc}</strong>"; | |
} | |
// Set our global message | |
mailchimpSF_global_msg($msg); | |
return true; | |
} | |
/* | |
Cleans up merge fields and interests to make them | |
API 3.0-friendly. | |
*/ | |
function mailchimpSF_subscribe_body($merge, $igs, $email_type, $email, $status, $double_optin) | |
{ | |
$body = new stdClass(); | |
$body->email_address = $email; | |
$body->email_type = $email_type; | |
$body->merge_fields = $merge; | |
if (!empty($igs)) { | |
$body->interests = $igs; | |
} | |
if($status !== 'subscribed') { | |
// single opt-in that covers new subscribers | |
if (!$status && $double_optin == false) { | |
$body->status = 'subscribed'; | |
} else { | |
// anyone else | |
$body->status = 'pending'; | |
} | |
} | |
return $body; | |
} | |
function mailchimpSF_check_status($endpoint) { | |
$endpoint .= '?fields=status'; | |
$api = mailchimpSF_get_api(); | |
$subscriber = $api->get($endpoint, null); | |
if(is_wp_error($subscriber)) { | |
return false; | |
} | |
return $subscriber['status']; | |
} | |
function mailchimpSF_merge_submit($mv) { | |
// Loop through our Merge Vars, and if they're empty, but required, then print an error, and mark as failed | |
$merge = new stdClass(); | |
foreach($mv as $var) { | |
// We also want to create an array where the keys are the tags for easier validation later | |
$tag = $var['tag']; | |
$mv_tag_keys[$tag] = $var; | |
$opt = 'mc_mv_' . $tag; | |
$opt_val = isset($_POST[$opt]) ? stripslashes_deep($_POST[$opt]) : ''; | |
// Handle phone number logic | |
if ($var['type'] === 'phone' && $var['options']['phone_format'] === 'US') { | |
$opt_val = mailchimpSF_merge_validate_phone($opt_val, $var); | |
if(is_wp_error($opt_val)) { | |
return $opt_val; | |
} | |
} | |
// Handle address logic | |
else if (is_array($opt_val) && $var['type'] == 'address') { | |
$validate = mailchimpSF_merge_validate_address($opt_val, $var); | |
if(is_wp_error($validate)) { | |
return $validate; | |
} | |
if($validate) { | |
$merge->$tag = $validate; | |
} | |
continue; | |
} | |
else if (is_array($opt_val)) { | |
$keys = array_keys($opt_val); | |
$val = new stdClass(); | |
foreach($keys as $key) { | |
$val->$key = $opt_val[$key]; | |
} | |
$opt_val = $val; | |
} | |
if ($var['required'] == 'Y' && trim($opt_val) == '') { | |
$message = sprintf(__("You must fill in %s.", 'mailchimp_i18n'), esc_html($var['name'])); | |
$error = new WP_Error('missing_required_field', $message); | |
return $error; | |
} | |
else { | |
if ($tag != 'EMAIL') { | |
$merge->$tag = $opt_val; | |
} | |
} | |
} | |
return $merge; | |
} | |
function mailchimpSF_merge_validate_phone($opt_val, $var) { | |
// This filters out all 'falsey' elements | |
$opt_val = array_filter($opt_val); | |
// If they weren't all empty | |
if (!$opt_val) { | |
return; | |
} | |
$opt_val = implode('-', $opt_val); | |
if (strlen($opt_val) < 12) { | |
$opt_val = ''; | |
} | |
if (!preg_match('/[0-9]{0,3}-[0-9]{0,3}-[0-9]{0,4}/A', $opt_val)) { | |
$message = sprintf(__("%s must consist of only numbers", 'mailchimp_i18n'), esc_html($var['name'])); | |
$error = new WP_Error('mc_phone_validation', $message); | |
return $error; | |
} | |
return $opt_val; | |
} | |
function mailchimpSF_merge_validate_address($opt_val, $var) { | |
if ($var['required'] == 'Y') { | |
if (empty($opt_val['addr1']) || empty($opt_val['city'])) { | |
$message = sprintf(__("You must fill in %s.", 'mailchimp_i18n'), esc_html($var['name'])); | |
$error = new WP_Error('invalid_address_merge', $message); | |
return $error; | |
} | |
} else { | |
if (empty($opt_val['addr1']) || empty($opt_val['city'])) { | |
return false; | |
} | |
} | |
$merge = new stdClass(); | |
$merge->addr1 = $opt_val['addr1']; | |
$merge->addr2 = $opt_val['addr2']; | |
$merge->city = $opt_val['city']; | |
$merge->state = $opt_val['state']; | |
$merge->zip = $opt_val['zip']; | |
$merge->country = $opt_val['country']; | |
return $merge; | |
} | |
function mailchimpSF_merge_remove_empty($merge) | |
{ | |
foreach ($merge as $k => $v) { | |
if (is_object($v) && empty($v)) { | |
unset($merge->$k); | |
} elseif ((is_string($v) && trim($v) === '') || is_null($v)) { | |
unset($merge->$k); | |
} | |
} | |
// If we have an empty $merge, then assign empty string. | |
if (count($merge) == 0 || $merge == '') { | |
$merge = ''; | |
} | |
return $merge; | |
} | |
function mailchimpSF_groups_submit($igs) { | |
$groups = mailchimpSF_set_all_groups_to_false(); | |
if(empty($igs)) { | |
return new StdClass(); | |
} | |
//get groups and ids | |
//set all to false | |
foreach ($igs as $ig) { | |
$ig_id = $ig['id']; | |
if (get_option('mc_show_interest_groups_'.$ig_id) == 'on' && $ig['type'] !== 'hidden') { | |
switch ($ig['type']) { | |
case 'dropdown': | |
case 'radio': | |
// there can only be one value submitted for radio/dropdowns, so use that at the group id. | |
if (isset($_POST['group'][$ig_id]) && !empty($_POST['group'][$ig_id])) { | |
$value = $_POST['group'][$ig_id]; | |
$groups->$value = true; | |
} | |
break; | |
case 'checkboxes': | |
if (isset($_POST['group'][$ig_id])) { | |
foreach ($_POST['group'][$ig_id] as $id => $value) { | |
$groups->$id = true; | |
} | |
} | |
break; | |
default: | |
// Nothing | |
break; | |
} | |
} | |
} | |
return $groups; | |
} | |
function mailchimpSF_set_all_groups_to_false() { | |
$toreturn = new StdClass(); | |
foreach (get_option('mc_interest_groups') as $grouping) { | |
if($grouping['type'] !== 'hidden') { | |
foreach ($grouping['groups'] as $group) { | |
$id = $group['id']; | |
$toreturn->$id = false; | |
} | |
} | |
} | |
return $toreturn; | |
} | |
function mailchimpSF_verify_key($api) { | |
$user = $api->get(''); | |
if (is_wp_error($user)) { | |
return $user; | |
} | |
//Might as well set this data if we have it already. | |
$valid_roles = array('owner', 'admin', 'manager'); | |
if(in_array($user['role'], $valid_roles)) { | |
update_option('mc_api_key', $api->key); | |
update_option('mc_user', $user); | |
update_option('mc_datacenter', $api->datacenter); | |
} else { | |
$msg = __('API Key must belong to "Owner", "Admin", or "Manager."', 'mailchimp_i18n'); | |
return new WP_Error('mc-invalid-role', $msg); | |
} | |
return; | |
} | |
function mailchimpSF_update_profile_url($email) { | |
$dc = get_option('mc_datacenter'); | |
$eid = base64_encode($email); | |
$user = get_option('mc_user'); | |
$list_id = get_option('mc_list_id'); | |
$url = 'http://' . $dc . '.list-manage.com/subscribe/send-email?u=' . $user['account_id'] . '&id=' . $list_id . '&e=' . $eid; | |
return $url; | |
} | |
function mailchimpSF_signup_form_url() { | |
$dc = get_option('mc_datacenter'); | |
$user = get_option('mc_user'); | |
$list_id = get_option('mc_list_id'); | |
$url = 'http://' . $dc . '.list-manage.com/subscribe?u=' . $user['account_id'] . '&id=' . $list_id; | |
return $url; | |
} | |
function mailchimpSF_delete_options($options = array()) { | |
foreach($options as $option) { | |
delete_option($option); | |
} | |
} | |
/********************** | |
* Utility Functions * | |
**********************/ | |
/** | |
* Utility function to allow placement of plugin in plugins, mu-plugins, child or parent theme's plugins folders | |
* | |
* This function must be ran _very early_ in the load process, as it sets up important constants for the rest of the plugin | |
*/ | |
function mailchimpSF_where_am_i() { | |
$locations = array( | |
'plugins' => array( | |
'dir' => plugin_dir_path(__FILE__), | |
'url' => plugins_url() | |
), | |
'mu_plugins' => array( | |
'dir' => plugin_dir_path(__FILE__), | |
'url' => plugins_url(), | |
), | |
'template' => array( | |
'dir' => trailingslashit(get_template_directory()).'plugins/', | |
'url' => trailingslashit(get_template_directory_uri()).'plugins/', | |
), | |
'stylesheet' => array( | |
'dir' => trailingslashit(get_stylesheet_directory()).'plugins/', | |
'url' => trailingslashit(get_stylesheet_directory_uri()).'plugins/', | |
), | |
); | |
// Set defaults | |
$mscf_dirbase = trailingslashit(basename(dirname(__FILE__))); // Typically wp-mailchimp/ or mailchimp/ | |
$mscf_dir = trailingslashit(plugin_dir_path(__FILE__)); | |
$mscf_url = trailingslashit(plugins_url(null, __FILE__)); | |
// Try our hands at finding the real location | |
foreach ($locations as $key => $loc) { | |
$dir = trailingslashit($loc['dir']).$mscf_dirbase; | |
$url = trailingslashit($loc['url']).$mscf_dirbase; | |
if (is_file($dir.basename(__FILE__))) { | |
$mscf_dir = $dir; | |
$mscf_url = $url; | |
break; | |
} | |
} | |
// Define our complete filesystem path | |
define('MCSF_DIR', $mscf_dir); | |
/* Lang location needs to be relative *from* ABSPATH, | |
so strip it out of our language dir location */ | |
define('MCSF_LANG_DIR', trailingslashit(MCSF_DIR).'po/'); | |
// Define our complete URL to the plugin folder | |
define('MCSF_URL', $mscf_url); | |
} | |
/** | |
* MODIFIED VERSION of wp_verify_nonce from WP Core. Core was not overridden to prevent problems when replacing | |
* something universally. | |
* | |
* Verify that correct nonce was used with time limit. | |
* | |
* The user is given an amount of time to use the token, so therefore, since the | |
* UID and $action remain the same, the independent variable is the time. | |
* | |
* @param string $nonce Nonce that was used in the form to verify | |
* @param string|int $action Should give context to what is taking place and be the same when nonce was created. | |
* @return bool Whether the nonce check passed or failed. | |
*/ | |
function mailchimpSF_verify_nonce($nonce, $action = -1) { | |
$user = wp_get_current_user(); | |
$uid = (int) $user->ID; | |
if ( ! $uid ) { | |
$uid = apply_filters( 'nonce_user_logged_out', $uid, $action ); | |
} | |
if ( empty( $nonce ) ) { | |
return false; | |
} | |
$token = 'MAILCHIMP'; | |
$i = wp_nonce_tick(); | |
// Nonce generated 0-12 hours ago | |
$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce'), -12, 10 ); | |
if ( hash_equals( $expected, $nonce ) ) { | |
return 1; | |
} | |
// Nonce generated 12-24 hours ago | |
$expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 ); | |
if ( hash_equals( $expected, $nonce ) ) { | |
return 2; | |
} | |
// Invalid nonce | |
return false; | |
} | |
/** | |
* MODIFIED VERSION of wp_create_nonce from WP Core. Core was not overridden to prevent problems when replacing | |
* something universally. | |
* | |
* Creates a cryptographic token tied to a specific action, user, and window of time. | |
* | |
* @param string $action Scalar value to add context to the nonce. | |
* @return string The token. | |
*/ | |
function mailchimpSF_create_nonce($action = -1) { | |
$user = wp_get_current_user(); | |
$uid = (int) $user->ID; | |
if ( ! $uid ) { | |
/** This filter is documented in wp-includes/pluggable.php */ | |
$uid = apply_filters( 'nonce_user_logged_out', $uid, $action ); | |
} | |
$token = 'MAILCHIMP'; | |
$i = wp_nonce_tick(); | |
return substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Code errors in mailchimp.php add an extra slash to the following file paths (noticed when running a link checker):
.../wp-content/plugins/mailchimp//js/scrollTo.js?ver=1.5.7
.../wp-content/plugins/mailchimp//js/mailchimp.js?ver=1.5.7
.../wp-content/plugins/mailchimp//css/flick/flick.css?ver=4.9.6
.../wp-content/plugins/mailchimp//js/datepicker.js?ver=4.9.6
Error Line 102:
MCSF_URL.'/js/scrollTo.js'
correct to:
MCSF_URL.'js/scrollTo.js'
Error Line 103:
MCSF_URL.'/js/mailchimp.js'
correct to:
MCSF_URL.'js/mailchimp.js'
Error Line 114:
MCSF_URL.'/css/flick/flick.css'
correct to:
MCSF_URL.'css/flick/flick.css'
Error Line 117:
MCSF_URL.'/js/datepicker.js'
correct to:
MCSF_URL.'js/datepicker.js'