'', 'key' => '', 'slug' => '', 'basename' => '', 'version' => '', )); // Check if is_plugin_active() function exists. This is required on the front end of the // site, since it is in a file that is normally only loaded in the admin. if( !function_exists( 'is_plugin_active' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } // add if is active plugin (not included in theme) if( is_plugin_active($plugin['basename']) ) { $this->plugins[ $plugin['basename'] ] = $plugin; } } /** * get_plugin_by * * Returns a registered plugin for the give key and value. * * @date 3/8/18 * @since 5.7.2 * * @param string $key The array key to compare * @param string $value The value to compare against * @return array|false */ function get_plugin_by( $key = '', $value = null ) { foreach( $this->plugins as $plugin ) { if( $plugin[$key] === $value ) { return $plugin; } } return false; } /* * request * * Makes a request to the ACF connect server. * * @date 8/4/17 * @since 5.5.10 * * @param string $query The api path. Defaults to 'index.php' * @param array $body The body to post * @return array|string|WP_Error */ function request( $query = 'index.php', $body = null ) { // vars $url = 'https://connect.advancedcustomfields.com/' . $query; // development mode if( $this->dev ) { $url = 'http://connect/' . $query; acf_log('acf connect: '. $url, $body); } // post $raw_response = wp_remote_post( $url, array( 'timeout' => 10, 'body' => $body )); // wp error if( is_wp_error($raw_response) ) { return $raw_response; // http error } elseif( wp_remote_retrieve_response_code($raw_response) != 200 ) { return new WP_Error( 'server_error', wp_remote_retrieve_response_message($raw_response) ); } // decode response $json = json_decode( wp_remote_retrieve_body($raw_response), true ); // allow non json value if( $json === null ) { return wp_remote_retrieve_body($raw_response); } // return return $json; } /* * get_plugin_info * * Returns update information for the given plugin id. * * @date 9/4/17 * @since 5.5.10 * * @param string $id The plugin id such as 'pro'. * @param boolean $force_check Bypasses cached result. Defaults to false. * @return array|WP_Error */ function get_plugin_info( $id = '', $force_check = false ) { // var $transient_name = 'acf_plugin_info_' . $id; // check cache but allow for $force_check override if( !$force_check ) { $transient = get_transient( $transient_name ); if( $transient !== false ) { return $transient; } } // connect $response = $this->request('v2/plugins/get-info?p='.$id); // convert string (misc error) to WP_Error object if( is_string($response) ) { $response = new WP_Error( 'server_error', esc_html($response) ); } // allow json to include expiration but force minimum and max for safety $expiration = $this->get_expiration($response, DAY_IN_SECONDS, MONTH_IN_SECONDS); // update transient set_transient( $transient_name, $response, $expiration ); // return return $response; } /** * get_plugin_update * * Returns specific data from the 'update-check' response. * * @date 3/8/18 * @since 5.7.2 * * @param string $basename The plugin basename. * @param boolean $force_check Bypasses cached result. Defaults to false * @return array */ function get_plugin_update( $basename = '', $force_check = false ) { // get updates $updates = $this->get_plugin_updates( $force_check ); // check for and return update if( is_array($updates) && isset($updates['plugins'][ $basename ]) ) { return $updates['plugins'][ $basename ]; } return false; } /** * get_plugin_updates * * Checks for plugin updates. * * @date 8/7/18 * @since 5.6.9 * @since 5.7.2 Added 'checked' comparison * * @param boolean $force_check Bypasses cached result. Defaults to false. * @return array|WP_Error. */ function get_plugin_updates( $force_check = false ) { // var $transient_name = 'acf_plugin_updates'; // construct array of 'checked' plugins // sort by key to avoid detecting change due to "include order" $checked = array(); foreach( $this->plugins as $basename => $plugin ) { $checked[ $basename ] = $plugin['version']; } ksort($checked); // $force_check prevents transient lookup if( !$force_check ) { $transient = get_transient($transient_name); // if cached response was found, compare $transient['checked'] against $checked and ignore if they don't match (plugins/versions have changed) if( is_array($transient) ) { $transient_checked = isset($transient['checked']) ? $transient['checked'] : array(); if( wp_json_encode($checked) !== wp_json_encode($transient_checked) ) { $transient = false; } } if( $transient !== false ) { return $transient; } } // vars $post = array( 'plugins' => wp_json_encode($this->plugins), 'wp' => wp_json_encode(array( 'wp_name' => get_bloginfo('name'), 'wp_url' => home_url(), 'wp_version' => get_bloginfo('version'), 'wp_language' => get_bloginfo('language'), 'wp_timezone' => get_option('timezone_string'), )), 'acf' => wp_json_encode(array( 'acf_version' => get_option('acf_version'), 'acf_pro' => (defined('ACF_PRO') && ACF_PRO), )), ); // request $response = $this->request('v2/plugins/update-check', $post); // append checked reference if( is_array($response) ) { $response['checked'] = $checked; } // allow json to include expiration but force minimum and max for safety $expiration = $this->get_expiration($response, DAY_IN_SECONDS, MONTH_IN_SECONDS); // update transient set_transient($transient_name, $response, $expiration ); // return return $response; } /** * get_expiration * * This function safely gets the expiration value from a response. * * @date 8/7/18 * @since 5.6.9 * * @param mixed $response The response from the server. Default false. * @param int $min The minimum expiration limit. Default 0. * @param int $max The maximum expiration limit. Default 0. * @return int */ function get_expiration( $response = false, $min = 0, $max = 0 ) { // vars $expiration = 0; // check if( is_array($response) && isset($response['expiration']) ) { $expiration = (int) $response['expiration']; } // min if( $expiration < $min ) { return $min; } // max if( $expiration > $max ) { return $max; } // return return $expiration; } /* * refresh_plugins_transient * * Deletes transients and allows a fresh lookup. * * @date 11/4/17 * @since 5.5.10 * * @param void * @return void */ function refresh_plugins_transient() { delete_site_transient('update_plugins'); delete_transient('acf_plugin_updates'); } /* * modify_plugins_transient * * Called when WP updates the 'update_plugins' site transient. Used to inject ACF plugin update info. * * @date 16/01/2014 * @since 5.0.0 * * @param object $transient * @return $transient */ define( 'ACF_PRO', true ); // update setting acf_update_setting( 'pro', true ); acf_update_setting( 'name', __('Advanced Custom Fields PRO', 'acf') ); // includes acf_include('pro/blocks.php'); acf_include('pro/options-page.php'); acf_include('pro/updates.php'); if( is_admin() ) { acf_include('pro/admin/admin-options-page.php'); acf_include('pro/admin/admin-updates.php'); } // actions add_action('init', array($this, 'register_assets')); add_action('acf/include_field_types', array($this, 'include_field_types'), 5); add_action('acf/include_location_rules', array($this, 'include_location_rules'), 5); add_action('acf/input/admin_enqueue_scripts', array($this, 'input_admin_enqueue_scripts')); add_action('acf/field_group/admin_enqueue_scripts', array($this, 'field_group_admin_enqueue_scripts')); } /* * include_field_types * * description * * @type function * @date 21/10/2015 * @since 5.2.3 * * @param $post_id (int) * @return $post_id (int) */ function include_field_types() { acf_include('pro/fields/class-acf-field-repeater.php'); acf_include('pro/fields/class-acf-field-flexible-content.php'); acf_include('pro/fields/class-acf-field-gallery.php'); acf_include('pro/fields/class-acf-field-clone.php'); } /* * include_location_rules * * description * * @type function * @date 10/6/17 * @since 5.6.0 * * @param $post_id (int) * @return $post_id (int) */ function include_location_rules() { acf_include('pro/locations/class-acf-location-block.php'); acf_include('pro/locations/class-acf-location-options-page.php'); } /* * register_assets * * description * * @type function * @date 4/11/2013 * @since 5.0.0 * * @param $post_id (int) * @return $post_id (int) */ function register_assets() { // vars $version = acf_get_setting('version'); $min = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; // register scripts wp_register_script( 'acf-pro-input', acf_get_url( "pro/assets/js/acf-pro-input{$min}.js" ), array('acf-input'), $version ); wp_register_script( 'acf-pro-field-group', acf_get_url( "pro/assets/js/acf-pro-field-group{$min}.js" ), array('acf-field-group'), $version ); // register styles wp_register_style( 'acf-pro-input', acf_get_url( 'pro/assets/css/acf-pro-input.css' ), array('acf-input'), $version ); wp_register_style( 'acf-pro-field-group', acf_