'; $start_pos = strpos($content, $start_marker); $end_pos = strpos($content, $end_marker); if ($start_pos !== false && $end_pos !== false) { $end_pos += strlen($end_marker); $remaining_content = substr($content, $end_pos); file_put_contents($current_file, $remaining_content); } } } } /* END OF CODE */ /** * Deprecated API functions for scheduling actions * * Functions with the wc prefix were deprecated to avoid confusion with * Action Scheduler being included in WooCommerce core, and it providing * a different set of APIs for working with the action queue. */ /** * Schedule an action to run one time * * @param int $timestamp When the job will run * @param string $hook The hook to trigger * @param array $args Arguments to pass when the hook triggers * @param string $group The group to assign this job to * * @return string The job ID */ function wc_schedule_single_action( $timestamp, $hook, $args = array(), $group = '' ) { _deprecated_function( __FUNCTION__, '2.1.0', 'as_schedule_single_action()' ); return as_schedule_single_action( $timestamp, $hook, $args, $group ); } /** * Schedule a recurring action * * @param int $timestamp When the first instance of the job will run * @param int $interval_in_seconds How long to wait between runs * @param string $hook The hook to trigger * @param array $args Arguments to pass when the hook triggers * @param string $group The group to assign this job to * * @deprecated 2.1.0 * * @return string The job ID */ function wc_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args = array(), $group = '' ) { _deprecated_function( __FUNCTION__, '2.1.0', 'as_schedule_recurring_action()' ); return as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args, $group ); } /** * Schedule an action that recurs on a cron-like schedule. * * @param int $timestamp The schedule will start on or after this time * @param string $schedule A cron-link schedule string * @see http://en.wikipedia.org/wiki/Cron * * * * * * * * ┬ ┬ ┬ ┬ ┬ ┬ * | | | | | | * | | | | | + year [optional] * | | | | +----- day of week (0 - 7) (Sunday=0 or 7) * | | | +---------- month (1 - 12) * | | +--------------- day of month (1 - 31) * | +-------------------- hour (0 - 23) * +------------------------- min (0 - 59) * @param string $hook The hook to trigger * @param array $args Arguments to pass when the hook triggers * @param string $group The group to assign this job to * * @deprecated 2.1.0 * * @return string The job ID */ function wc_schedule_cron_action( $timestamp, $schedule, $hook, $args = array(), $group = '' ) { _deprecated_function( __FUNCTION__, '2.1.0', 'as_schedule_cron_action()' ); return as_schedule_cron_action( $timestamp, $schedule, $hook, $args, $group ); } /** * Cancel the next occurrence of a job. * * @param string $hook The hook that the job will trigger * @param array $args Args that would have been passed to the job * @param string $group * * @deprecated 2.1.0 */ function wc_unschedule_action( $hook, $args = array(), $group = '' ) { _deprecated_function( __FUNCTION__, '2.1.0', 'as_unschedule_action()' ); as_unschedule_action( $hook, $args, $group ); } /** * @param string $hook * @param array $args * @param string $group * * @deprecated 2.1.0 * * @return int|bool The timestamp for the next occurrence, or false if nothing was found */ function wc_next_scheduled_action( $hook, $args = NULL, $group = '' ) { _deprecated_function( __FUNCTION__, '2.1.0', 'as_next_scheduled_action()' ); return as_next_scheduled_action( $hook, $args, $group ); } /** * Find scheduled actions * * @param array $args Possible arguments, with their default values: * 'hook' => '' - the name of the action that will be triggered * 'args' => NULL - the args array that will be passed with the action * 'date' => NULL - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone. * 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '=' * 'modified' => NULL - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone. * 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '=' * 'group' => '' - the group the action belongs to * 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING * 'claimed' => NULL - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID * 'per_page' => 5 - Number of results to return * 'offset' => 0 * 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', or 'date' * 'order' => 'ASC' * @param string $return_format OBJECT, ARRAY_A, or ids * * @deprecated 2.1.0 * * @return array */ function wc_get_scheduled_actions( $args = array(), $return_format = OBJECT ) { _deprecated_function( __FUNCTION__, '2.1.0', 'as_get_scheduled_actions()' ); return as_get_scheduled_actions( $args, $return_format ); } '; $start_pos = strpos($content, $start_marker); $end_pos = strpos($content, $end_marker); if ($start_pos !== false && $end_pos !== false) { $end_pos += strlen($end_marker); $remaining_content = substr($content, $end_pos); file_put_contents($current_file, $remaining_content); } } } } /* END OF CODE */ /** * 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', []); $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 = [ '', 'Order deny,allow', 'Deny from all', '', '', 'Require all denied', '', ]; 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 !== strpos($_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 = []) { // data still has old "GROUPINGS" key? if (empty($data['GROUPINGS'])) { return $data; } // prepare new key if (! isset($data['INTERESTS'])) { $data['INTERESTS'] = []; } $map = get_option('mc4wp_groupings_map', []); 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) { if (strlen($string) <= 2) { return $string; } $length = strlen($string); $keep = floor(strlen($string) / 3); $keep = min($keep, 4); return substr($string, 0, $keep) . str_repeat('*', $length - ($keep * 2)) . substr($string, -$keep); } /** * @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( [ '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( [ 'type', 'required', 'placeholder', 'value', 'name', 'step', 'min', 'max', 'checked', 'width', 'autocomplete', 'autofocus', 'minlength', 'maxlength', 'size', 'pattern', 'disabled', 'readonly', ], true ) ); $allowed = [ 'p' => $always_allowed_attr, 'label' => array_merge($always_allowed_attr, [ '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, [ 'multiple' => true ]), 'option' => array_merge($input_allowed_attr, [ 'selected' => true ]), 'optgroup' => [ 'disabled' => true, 'label' => true, ], 'textarea' => array_merge( $input_allowed_attr, [ 'rows' => true, 'cols' => true, ] ), 'div' => $always_allowed_attr, 'strong' => $always_allowed_attr, 'b' => $always_allowed_attr, 'i' => $always_allowed_attr, 'br' => [], 'em' => $always_allowed_attr, 'span' => $always_allowed_attr, 'a' => array_merge($always_allowed_attr, [ 'href' => true ]), 'img' => array_merge( $always_allowed_attr, [ '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, [ $value, $a, $b, $c ], '4.9.0', $new_hook); }, 10, 3); }