627 lines
15 KiB
PHP
627 lines
15 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Get a service by its name
|
|
*
|
|
* _Example:_
|
|
*
|
|
* $forms = mc4wp('forms');
|
|
* $api = mc4wp('api');
|
|
*
|
|
* When no service parameter is given, the entire container will be returned.
|
|
*
|
|
* @ignore
|
|
* @access private
|
|
*
|
|
* @param null|string $service (optional)
|
|
* @return mixed
|
|
*
|
|
* @throws Exception when service is not found
|
|
*/
|
|
function mc4wp($service = null)
|
|
{
|
|
static $mc4wp = null;
|
|
if (null === $mc4wp) {
|
|
$mc4wp = new MC4WP_Container();
|
|
}
|
|
|
|
if (null !== $service) {
|
|
return $mc4wp->get($service);
|
|
}
|
|
|
|
return $mc4wp;
|
|
}
|
|
|
|
/**
|
|
* Gets the Mailchimp for WP options from the database
|
|
* Uses default values to prevent undefined index notices.
|
|
*
|
|
* @since 1.0
|
|
* @access public
|
|
* @static array $options
|
|
* @return array
|
|
*/
|
|
function mc4wp_get_options()
|
|
{
|
|
$defaults = require MC4WP_PLUGIN_DIR . '/config/default-settings.php';
|
|
$options = (array) get_option('mc4wp', array());
|
|
$options = array_merge($defaults, $options);
|
|
|
|
/**
|
|
* Filters the Mailchimp for WordPress settings (general).
|
|
*
|
|
* @param array $options
|
|
*/
|
|
return apply_filters('mc4wp_settings', $options);
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
function mc4wp_get_settings()
|
|
{
|
|
return mc4wp_get_options();
|
|
}
|
|
|
|
/**
|
|
* @since 4.2.6
|
|
* @return string
|
|
*/
|
|
function mc4wp_get_api_key()
|
|
{
|
|
// try to get from constant
|
|
if (defined('MC4WP_API_KEY') && constant('MC4WP_API_KEY') !== '') {
|
|
return MC4WP_API_KEY;
|
|
}
|
|
|
|
// get from options
|
|
$opts = mc4wp_get_options();
|
|
return $opts['api_key'];
|
|
}
|
|
|
|
/**
|
|
* Gets the Mailchimp for WP API class (v3) and injects it with the API key
|
|
*
|
|
* @since 4.0
|
|
* @access public
|
|
*
|
|
* @return MC4WP_API_V3
|
|
*/
|
|
function mc4wp_get_api_v3()
|
|
{
|
|
$api_key = mc4wp_get_api_key();
|
|
return new MC4WP_API_V3($api_key);
|
|
}
|
|
|
|
/**
|
|
* Creates a new instance of the Debug Log
|
|
*
|
|
* @return MC4WP_Debug_Log
|
|
*/
|
|
function mc4wp_get_debug_log()
|
|
{
|
|
$opts = mc4wp_get_options();
|
|
|
|
// get default log file location
|
|
$upload_dir = wp_upload_dir(null, false);
|
|
$file = $upload_dir['basedir'] . '/mailchimp-for-wp/debug-log.php';
|
|
$default_file = $file;
|
|
|
|
/**
|
|
* Filters the log file to write to.
|
|
*
|
|
* @param string $file The log file location. Default: /wp-content/uploads/mailchimp-for-wp/mc4wp-debug.log
|
|
*/
|
|
$file = apply_filters('mc4wp_debug_log_file', $file);
|
|
|
|
if ($file === $default_file) {
|
|
$dir = dirname($file);
|
|
if (! is_dir($dir)) {
|
|
mkdir($dir, 0755, true);
|
|
}
|
|
|
|
if (! is_file($dir . '/.htaccess')) {
|
|
$lines = array(
|
|
'<IfModule !authz_core_module>',
|
|
'Order deny,allow',
|
|
'Deny from all',
|
|
'</IfModule>',
|
|
'<IfModule authz_core_module>',
|
|
'Require all denied',
|
|
'</IfModule>',
|
|
);
|
|
file_put_contents($dir . '/.htaccess', join(PHP_EOL, $lines));
|
|
}
|
|
|
|
if (! is_file($dir . '/index.html')) {
|
|
file_put_contents($dir . '/index.html', '');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Filters the minimum level to log messages.
|
|
*
|
|
* @see MC4WP_Debug_Log
|
|
*
|
|
* @param string|int $level The minimum level of messages which should be logged.
|
|
*/
|
|
$level = apply_filters('mc4wp_debug_log_level', $opts['debug_log_level']);
|
|
|
|
return new MC4WP_Debug_Log($file, $level);
|
|
}
|
|
|
|
/**
|
|
* Get URL to a file inside the plugin directory
|
|
*
|
|
* @since 4.8.3
|
|
* @param string $path
|
|
* @return string
|
|
*/
|
|
function mc4wp_plugin_url($path)
|
|
{
|
|
static $base = null;
|
|
if ($base === null) {
|
|
$base = plugins_url('/', MC4WP_PLUGIN_FILE);
|
|
}
|
|
|
|
return $base . $path;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get current URL (full)
|
|
*
|
|
* @return string
|
|
*/
|
|
function mc4wp_get_request_url()
|
|
{
|
|
global $wp;
|
|
|
|
// get requested url from global $wp object
|
|
$site_request_uri = $wp->request;
|
|
|
|
// fix for IIS servers using index.php in the URL
|
|
if (false !== stripos($_SERVER['REQUEST_URI'], '/index.php/' . $site_request_uri)) {
|
|
$site_request_uri = 'index.php/' . $site_request_uri;
|
|
}
|
|
|
|
// concatenate request url to home url
|
|
$url = home_url($site_request_uri);
|
|
$url = trailingslashit($url);
|
|
|
|
return esc_url($url);
|
|
}
|
|
|
|
/**
|
|
* Get current URL path.
|
|
*
|
|
* @return string
|
|
*/
|
|
function mc4wp_get_request_path()
|
|
{
|
|
return $_SERVER['REQUEST_URI'];
|
|
}
|
|
|
|
/**
|
|
* Get IP address for client making current request
|
|
*
|
|
* @return string|null
|
|
*/
|
|
function mc4wp_get_request_ip_address()
|
|
{
|
|
if (isset($_SERVER['X-Forwarded-For'])) {
|
|
$ip_address = $_SERVER['X-Forwarded-For'];
|
|
} elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
|
$ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
|
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
|
|
$ip_address = $_SERVER['REMOTE_ADDR'];
|
|
}
|
|
|
|
if (isset($ip_address)) {
|
|
if (! is_array($ip_address)) {
|
|
$ip_address = explode(',', $ip_address);
|
|
}
|
|
|
|
// use first IP in list
|
|
$ip_address = trim($ip_address[0]);
|
|
|
|
// if IP address is not valid, simply return null
|
|
if (! filter_var($ip_address, FILTER_VALIDATE_IP)) {
|
|
return null;
|
|
}
|
|
|
|
return $ip_address;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Strips all HTML tags from all values in a mixed variable, then trims the result.
|
|
*
|
|
* @access public
|
|
* @param mixed $value
|
|
*
|
|
* @return mixed
|
|
*/
|
|
function mc4wp_sanitize_deep($value)
|
|
{
|
|
if (is_scalar($value)) {
|
|
// strip all HTML tags & whitespace
|
|
$value = trim(strip_tags($value));
|
|
|
|
// convert & back to &
|
|
$value = html_entity_decode($value, ENT_NOQUOTES);
|
|
} elseif (is_array($value)) {
|
|
$value = array_map('mc4wp_sanitize_deep', $value);
|
|
} elseif (is_object($value)) {
|
|
$vars = get_object_vars($value);
|
|
foreach ($vars as $key => $data) {
|
|
$value->{$key} = mc4wp_sanitize_deep($data);
|
|
}
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @since 4.0
|
|
* @ignore
|
|
*
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
function _mc4wp_update_groupings_data($data = array())
|
|
{
|
|
|
|
// data still has old "GROUPINGS" key?
|
|
if (empty($data['GROUPINGS'])) {
|
|
return $data;
|
|
}
|
|
|
|
// prepare new key
|
|
if (! isset($data['INTERESTS'])) {
|
|
$data['INTERESTS'] = array();
|
|
}
|
|
|
|
$map = get_option('mc4wp_groupings_map', array());
|
|
|
|
foreach ($data['GROUPINGS'] as $grouping_id => $groups) {
|
|
// for compatibility with expanded grouping arrays
|
|
$grouping_key = $grouping_id;
|
|
if (is_array($groups) && isset($groups['id']) && isset($groups['groups'])) {
|
|
$grouping_id = $groups['id'];
|
|
$groups = $groups['groups'];
|
|
}
|
|
|
|
// do we have transfer data for this grouping id?
|
|
if (! isset($map[ $grouping_id ])) {
|
|
continue;
|
|
}
|
|
|
|
// if we get a string, explode on delimiter(s)
|
|
if (is_string($groups)) {
|
|
// for BC with 3.x: explode on comma's
|
|
$groups = join('|', explode(',', $groups));
|
|
|
|
// explode on current delimiter
|
|
$groups = explode('|', $groups);
|
|
}
|
|
|
|
// loop through groups and find interest ID
|
|
$migrated = 0;
|
|
foreach ($groups as $key => $group_name_or_id) {
|
|
// do we know the new interest ID?
|
|
if (empty($map[ $grouping_id ]['groups'][ $group_name_or_id ])) {
|
|
continue;
|
|
}
|
|
|
|
$interest_id = $map[ $grouping_id ]['groups'][ $group_name_or_id ];
|
|
|
|
// add to interests data
|
|
if (! in_array($interest_id, $data['INTERESTS'], false)) {
|
|
++$migrated;
|
|
$data['INTERESTS'][] = $interest_id;
|
|
}
|
|
}
|
|
|
|
// remove old grouping ID if we migrated all groups.
|
|
if ($migrated === count($groups)) {
|
|
unset($data['GROUPINGS'][ $grouping_key ]);
|
|
}
|
|
}
|
|
|
|
// if everything went well, this is now empty & moved to new INTERESTS key.
|
|
if (empty($data['GROUPINGS'])) {
|
|
unset($data['GROUPINGS']);
|
|
}
|
|
|
|
// is this empty? just unset it then.
|
|
if (empty($data['INTERESTS'])) {
|
|
unset($data['INTERESTS']);
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Guesses merge vars based on given data & current request.
|
|
*
|
|
* @since 3.0
|
|
* @access public
|
|
*
|
|
* @param array $data
|
|
*
|
|
* @return array
|
|
*/
|
|
function mc4wp_add_name_data($data)
|
|
{
|
|
|
|
// Guess first and last name
|
|
if (! empty($data['NAME']) && empty($data['FNAME']) && empty($data['LNAME'])) {
|
|
$data['NAME'] = trim($data['NAME']);
|
|
$strpos = strpos($data['NAME'], ' ');
|
|
|
|
if ($strpos !== false) {
|
|
$data['FNAME'] = trim(substr($data['NAME'], 0, $strpos));
|
|
$data['LNAME'] = trim(substr($data['NAME'], $strpos));
|
|
} else {
|
|
$data['FNAME'] = $data['NAME'];
|
|
}
|
|
}
|
|
|
|
// Set name value
|
|
if (empty($data['NAME']) && ! empty($data['FNAME']) && ! empty($data['LNAME'])) {
|
|
$data['NAME'] = sprintf('%s %s', $data['FNAME'], $data['LNAME']);
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Gets the "email type" for new subscribers.
|
|
*
|
|
* Possible return values are either "html" or "text"
|
|
*
|
|
* @access public
|
|
* @since 3.0
|
|
*
|
|
* @return string
|
|
*/
|
|
function mc4wp_get_email_type()
|
|
{
|
|
$email_type = 'html';
|
|
|
|
/**
|
|
* Filters the email type preference for this new subscriber.
|
|
*
|
|
* @param string $email_type
|
|
*/
|
|
$email_type = (string) apply_filters('mc4wp_email_type', $email_type);
|
|
|
|
return $email_type;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @ignore
|
|
* @return bool
|
|
*/
|
|
function _mc4wp_use_sslverify()
|
|
{
|
|
|
|
// Disable for all transports other than CURL
|
|
if (! function_exists('curl_version')) {
|
|
return false;
|
|
}
|
|
|
|
$curl = curl_version();
|
|
|
|
// Disable if OpenSSL is not installed
|
|
if (empty($curl['ssl_version'])) {
|
|
return false;
|
|
}
|
|
|
|
// Disable if on WP 4.4, see https://core.trac.wordpress.org/ticket/34935
|
|
if ($GLOBALS['wp_version'] === '4.4') {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* This will replace the first half of a string with "*" characters.
|
|
*
|
|
* @param string $string
|
|
* @return string
|
|
*/
|
|
function mc4wp_obfuscate_string($string)
|
|
{
|
|
$length = strlen($string);
|
|
$obfuscated_length = ceil($length / 2);
|
|
$string = str_repeat('*', $obfuscated_length) . substr($string, $obfuscated_length);
|
|
return $string;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
* @ignore
|
|
*/
|
|
function _mc4wp_obfuscate_email_addresses_callback($m)
|
|
{
|
|
$one = $m[1] . str_repeat('*', strlen($m[2]));
|
|
$two = $m[3] . str_repeat('*', strlen($m[4]));
|
|
$three = $m[5];
|
|
return sprintf('%s@%s.%s', $one, $two, $three);
|
|
}
|
|
|
|
/**
|
|
* Obfuscates email addresses in a string.
|
|
*
|
|
* @param $string String possibly containing email address
|
|
* @return string
|
|
*/
|
|
function mc4wp_obfuscate_email_addresses($string)
|
|
{
|
|
return preg_replace_callback('/([\w\.]{1,4})([\w\.]*)\@(\w{1,2})(\w*)\.(\w+)/', '_mc4wp_obfuscate_email_addresses_callback', $string);
|
|
}
|
|
|
|
/**
|
|
* Refreshes Mailchimp lists. This can take a while if the connected Mailchimp account has many lists.
|
|
*
|
|
* @return void
|
|
*/
|
|
function mc4wp_refresh_mailchimp_lists()
|
|
{
|
|
$mailchimp = new MC4WP_MailChimp();
|
|
$mailchimp->refresh_lists();
|
|
}
|
|
|
|
/**
|
|
* Get element from array, allows for dot notation eg: "foo.bar"
|
|
*
|
|
* @param array $array
|
|
* @param string $key
|
|
* @param mixed $default
|
|
* @return mixed
|
|
*/
|
|
function mc4wp_array_get($array, $key, $default = null)
|
|
{
|
|
if (is_null($key)) {
|
|
return $array;
|
|
}
|
|
|
|
if (isset($array[ $key ])) {
|
|
return $array[ $key ];
|
|
}
|
|
|
|
foreach (explode('.', $key) as $segment) {
|
|
if (! is_array($array) || ! array_key_exists($segment, $array)) {
|
|
return $default;
|
|
}
|
|
|
|
$array = $array[ $segment ];
|
|
}
|
|
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* Filters string and strips out all HTML tags and attributes, except what's in our whitelist.
|
|
*
|
|
* @param string $string The string to apply KSES whitelist on
|
|
* @return string
|
|
* @since 4.8.8
|
|
*/
|
|
function mc4wp_kses($string)
|
|
{
|
|
$always_allowed_attr = array_fill_keys(
|
|
array(
|
|
'aria-describedby',
|
|
'aria-details',
|
|
'aria-label',
|
|
'aria-labelledby',
|
|
'aria-hidden',
|
|
'class',
|
|
'id',
|
|
'style',
|
|
'title',
|
|
'role',
|
|
'data-*',
|
|
'tabindex',
|
|
),
|
|
true
|
|
);
|
|
$input_allowed_attr = array_merge(
|
|
$always_allowed_attr,
|
|
array_fill_keys(
|
|
array(
|
|
'type',
|
|
'required',
|
|
'placeholder',
|
|
'value',
|
|
'name',
|
|
'step',
|
|
'min',
|
|
'max',
|
|
'checked',
|
|
'width',
|
|
'autocomplete',
|
|
'autofocus',
|
|
'minlength',
|
|
'maxlength',
|
|
'size',
|
|
'pattern',
|
|
'disabled',
|
|
'readonly',
|
|
),
|
|
true
|
|
)
|
|
);
|
|
|
|
$allowed = array(
|
|
'p' => $always_allowed_attr,
|
|
'label' => array_merge($always_allowed_attr, array( 'for' => true )),
|
|
'input' => $input_allowed_attr,
|
|
'button' => $input_allowed_attr,
|
|
'fieldset' => $always_allowed_attr,
|
|
'legend' => $always_allowed_attr,
|
|
'ul' => $always_allowed_attr,
|
|
'ol' => $always_allowed_attr,
|
|
'li' => $always_allowed_attr,
|
|
'select' => array_merge($input_allowed_attr, array( 'multiple' => true )),
|
|
'option' => array_merge($input_allowed_attr, array( 'selected' => true )),
|
|
'optgroup' => array(
|
|
'disabled' => true,
|
|
'label' => true,
|
|
),
|
|
'textarea' => array_merge(
|
|
$input_allowed_attr,
|
|
array(
|
|
'rows' => true,
|
|
'cols' => true,
|
|
)
|
|
),
|
|
'div' => $always_allowed_attr,
|
|
'strong' => $always_allowed_attr,
|
|
'b' => $always_allowed_attr,
|
|
'i' => $always_allowed_attr,
|
|
'br' => array(),
|
|
'em' => $always_allowed_attr,
|
|
'span' => $always_allowed_attr,
|
|
'a' => array_merge($always_allowed_attr, array( 'href' => true )),
|
|
'img' => array_merge(
|
|
$always_allowed_attr,
|
|
array(
|
|
'src' => true,
|
|
'alt' => true,
|
|
'width' => true,
|
|
'height' => true,
|
|
'srcset' => true,
|
|
'sizes' => true,
|
|
'referrerpolicy' => true,
|
|
)
|
|
),
|
|
'u' => $always_allowed_attr,
|
|
);
|
|
|
|
return wp_kses($string, $allowed);
|
|
}
|
|
|
|
/**
|
|
* Helper function for safely deprecating a changed filter hook.
|
|
*
|
|
* @param string $old_hook
|
|
* @param string $new_hook
|
|
*
|
|
* @return void
|
|
*/
|
|
function mc4wp_apply_deprecated_filters($old_hook, $new_hook)
|
|
{
|
|
add_filter($new_hook, function ($value, $a = null, $b = null, $c = null) use ($new_hook, $old_hook) {
|
|
return apply_filters_deprecated($old_hook, array( $value, $a, $b, $c ), '4.9.0', $new_hook);
|
|
}, 10, 3);
|
|
}
|