From 63b291a90e76e24e4a0bd2aa173e17a89688364d Mon Sep 17 00:00:00 2001 From: Lauri Kallioniemi Date: Fri, 22 Oct 2021 13:11:52 +0300 Subject: [PATCH] Remove AWS plugin requirement, use AWS SDK for PHP 3.0 instead --- README.md | 2 - .../wp-amazon-c3-cloudfront-clear-cache.php | 240 +++++- classes/wp-aws-plugin-base.php | 694 ++++++++++++++++++ composer.json | 10 +- view/footer.php | 1 + view/header.php | 3 + wordpress-c3.php | 25 +- 7 files changed, 926 insertions(+), 49 deletions(-) create mode 100644 classes/wp-aws-plugin-base.php create mode 100644 view/footer.php create mode 100644 view/header.php diff --git a/README.md b/README.md index 3d009df..71f6933 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,6 @@ Cloudfront cache management based on C3 Cloudfront Cache Controller by AMIMOTO and WP Offload S3 Lite by Delicious Brains -Needs Amazon Web Services 1.0.7 to work - set `define('DISTRIBUTION_ID', 'XXXX')` in wp-config.php Otherwise install just like any other plugin diff --git a/classes/wp-amazon-c3-cloudfront-clear-cache.php b/classes/wp-amazon-c3-cloudfront-clear-cache.php index afd640e..8f5b05c 100644 --- a/classes/wp-amazon-c3-cloudfront-clear-cache.php +++ b/classes/wp-amazon-c3-cloudfront-clear-cache.php @@ -6,7 +6,13 @@ * Date: 23/01/2017 * Time: 20.45 */ -class C3_CloudFront_Clear_Cache extends AWS_Plugin_Base { + + +use Aws\CloudFront\CloudFrontClient; +use Aws\Exception\AwsException; + + +class C3_CloudFront_Clear_Cache extends AC3_Plugin_Base { /** * @var Amazon_Web_Services @@ -48,6 +54,7 @@ class C3_CloudFront_Clear_Cache extends AWS_Plugin_Base { */ protected $default_tab = ''; + /** * @var string */ @@ -81,7 +88,9 @@ function init( $plugin_file_path ) { $this->plugin_menu_title = __( 'CloudFront Cache Controller', 'wp-amazon-c3-cloudfront-clear-cache' ); // Plugin setup - add_action( 'aws_admin_menu', [ $this, 'admin_menu' ] ); + add_action( 'admin_menu', array( $this, 'admin_menu' ) ); + add_action( 'network_admin_menu', array( $this, 'admin_menu' ) ); + add_action( 'aws_admin_menu', [ $this, 'aws_admin_menu' ] ); add_filter( 'plugin_action_links', [ $this, 'plugin_actions_settings_link' ], 10, 2 ); //cron hook @@ -248,7 +257,6 @@ function get_setting( $key, $default = '', $lang = null ) { * @return string|false */ public function get_setting_distribution_id( $key, $value, $constant = 'DISTRIBUTION_ID' ) { - if ( 'distribution_id' === $key && defined( $constant ) ) { $distribution_id = constant( $constant ); @@ -313,9 +321,9 @@ function get_c3client( $force = false ) { $args = []; - $client = $this->aws->get_client()->get( 'CloudFront', $args ); + $c3client = $this->get_client(); - $this->set_client( $client ); + $this->set_client( $c3client ); } @@ -368,13 +376,17 @@ public function list_distribution_invalidations($distribution_id) { 'MaxItems' => apply_filters( 'c3_max_invalidation_logs', 25 ), ] ); - if ( $items->get( 'Quantity' ) ) { - foreach ( $items->get( 'Items' ) as $item ) { - $item['DistributionId'] = $distribution_id; - array_push( $invalidations, $item ); + if (isset($items['InvalidationList'])) + { + if ($items['InvalidationList']['Quantity'] > 0) + { + foreach ($items['InvalidationList']['Items'] as $item) + { + $item['DistributionId'] = $distribution_id; + array_push( $invalidations, $item ); + } } } - } catch ( Exception $e ) { error_log( print_r( '==========', true ) ); @@ -459,6 +471,48 @@ function limitWild($wild) { return $wild; } + /** + * Allows the AWS client factory to use the IAM role for EC2 instances + * instead of key/secret for credentials + * http://docs.aws.amazon.com/aws-sdk-php/guide/latest/credentials.html#instance-profile-credentials + * + * @return bool + */ + function use_ec2_iam_roles() { + if ( defined( 'AWS_USE_EC2_IAM_ROLE' ) && AWS_USE_EC2_IAM_ROLE ) { + return true; + } + + return false; + } + + function get_client() { + if ( $this->needs_access_keys() ) { + throw new Exception( sprintf( __( 'You must first set your AWS access keys to use this addon.', 'amazon-web-services' ), 'admin.php?page=' . $this->plugin_slug ) ); + } + + if ( is_null( $this->c3client ) ) { + $args = array(); + + if ( ! $this->use_ec2_iam_roles() ) { + $credentials = array( + 'key' => $this->get_access_key_id(), + 'secret' => $this->get_secret_access_key(), + ); + } + $credentials = apply_filters( 'aws_get_client_args', $credentials ); + $this->client = new CloudFrontClient([ + 'profile' => 'default', + 'version' => 'latest', + 'region' => 'us-east-1', + 'debug' => false, + 'credentials' => $credentials + ]); + + } + return $this->client; + } + function limitItems($items) { if (is_array($items) && count($items)) { $items = $this->order($items); @@ -583,6 +637,7 @@ function combineCommon($items) { public function create_invalidation_array( $items, $lang = null ) { + if ( ! $this->get_setting( 'distribution_id', false, $lang ) ) { return false; } @@ -599,11 +654,13 @@ public function create_invalidation_array( $items, $lang = null ) { return [ 'DistributionId' => esc_attr( $this->get_setting( 'distribution_id', false, $lang ) ), - 'Paths' => [ - 'Quantity' => count( $items ), - 'Items' => $items, + 'InvalidationBatch' => [ + 'CallerReference' => uniqid(), + 'Paths' => [ + 'Items' => $items, + 'Quantity' => count( $items ), + ], ], - 'CallerReference' => uniqid(), ]; } @@ -995,23 +1052,56 @@ function create_cron_invalidation( $items, $lang = null ) { } /** - * Add the settings menu item + * Add the settings page to the top-level AWS menu item for backwards compatibility. * - * @param Amazon_Web_Services $aws + * @param \Amazon_Web_Services $aws Plugin class instance from the amazon-web-services plugin. */ - function admin_menu( $aws ) { - $hook_suffix = $aws->add_page( $this->get_plugin_page_title(), $this->plugin_menu_title, 'manage_options', $this->plugin_slug, [ - $this, - 'render_page' - ] ); + public function aws_admin_menu( $aws ) { + $aws->add_page( + $this->get_plugin_page_title(), + $this->get_plugin_menu_title(), + 'manage_options', + $this->plugin_slug, + array( $this, 'render_page' ) + ); + } - if ( false !== $hook_suffix ) { - $this->hook_suffix = $hook_suffix; - add_action( 'load-' . $this->hook_suffix, [ $this, 'plugin_load' ] ); - } + + /** + * Add the settings page to the top-level Settings menu item. + */ + public function admin_menu() { + $this->hook_suffix = add_submenu_page( + $this->get_plugin_pagenow(), + $this->get_plugin_page_title(), + $this->get_plugin_menu_title(), + 'manage_options', + $this->plugin_slug, + array( $this, 'render_page' ) + ); + + do_action( 'as3cf_hook_suffix', $this->hook_suffix ); + + add_action( 'load-' . $this->hook_suffix, array( $this, 'plugin_load' ) ); + } + + /** + * Get the plugin title to be used in admin menu + * + * @return string + */ + function get_plugin_menu_title() { + return apply_filters( 'as3cf_settings_menu_title', $this->plugin_menu_title ); } + function plugin_load() { + + if ( $this->get_plugin_pagenow() !== $GLOBALS['pagenow'] ) { + wp_redirect( $this->get_plugin_page_url() ); + exit; + } + $version = $this->get_asset_version(); $suffix = $this->get_asset_suffix(); @@ -1061,19 +1151,14 @@ function handle_post_request() { * Display the main settings page for the plugin */ function render_page() { - $this->aws->render_view( 'header', [ 'page_title' => $this->get_plugin_page_title(), 'page' => 'c3cf' ] ); - $aws_client = $this->aws->get_client(); + $this->render_view( 'header', [ 'page_title' => $this->get_plugin_page_title(), 'page' => 'c3cf' ] ); - if ( is_wp_error( $aws_client ) ) { - $this->render_view( 'error-fatal', [ 'message' => $aws_client->get_error_message() ] ); - } else { - do_action( 'c3cf_pre_settings_render' ); - $this->render_view( 'settings' ); - do_action( 'c3cf_post_settings_render' ); - } + do_action( 'c3cf_pre_settings_render' ); + $this->render_view( 'settings' ); + do_action( 'c3cf_post_settings_render' ); - $this->aws->render_view( 'footer' ); + $this->render_view( 'footer' ); } /** @@ -1166,4 +1251,89 @@ public function the_guid( $guid ) { return $guid; } + /** + * Whether or not IAM access keys are needed. + * + * Keys are needed if we are not using EC2 roles or not defined/set yet. + * + * @return bool + */ + public function needs_access_keys() { + if ( $this->use_ec2_iam_roles() ) { + return false; + } + + return ! $this->are_access_keys_set(); + } + + /** + * Check if access keys are defined either by constants or database + * + * @return bool + */ + function are_access_keys_set() { + return $this->get_access_key_id() && $this->get_secret_access_key(); + } + + /** + * Get the AWS key from a constant or the settings + * + * Falls back to settings only if neither constant is defined. + * + * @return string + */ + function get_access_key_id() { + if ( $this->are_prefixed_key_constants_set() || $this->are_key_constants_set() ) { + if ( defined( 'DBI_AWS_ACCESS_KEY_ID' ) ) { + return DBI_AWS_ACCESS_KEY_ID; + } elseif ( defined( 'AWS_ACCESS_KEY_ID' ) ) { + return AWS_ACCESS_KEY_ID; // Deprecated + } + } else { + return $this->get_setting( 'access_key_id' ); + } + + return ''; + } + + /** + * Check if we are using the prefixed constants for the AWS access credentials + * + * @return bool + */ + function are_prefixed_key_constants_set() { + return defined( 'DBI_AWS_ACCESS_KEY_ID' ) || defined( 'DBI_AWS_SECRET_ACCESS_KEY' ); + } + + /** + * Check if we are using constants for the AWS access credentials + * + * @return bool + */ + function are_key_constants_set() { + return defined( 'AWS_ACCESS_KEY_ID' ) || defined( 'AWS_SECRET_ACCESS_KEY' ); + } + + /** + * Get the AWS secret from a constant or the settings + * + * Falls back to settings only if neither constant is defined. + * + * @return string + */ + function get_secret_access_key() { + if ( $this->are_prefixed_key_constants_set() || $this->are_key_constants_set() ) { + if ( defined( 'DBI_AWS_SECRET_ACCESS_KEY' ) ) { + return DBI_AWS_SECRET_ACCESS_KEY; + } elseif ( defined( 'AWS_SECRET_ACCESS_KEY' ) ) { + return AWS_SECRET_ACCESS_KEY; // Deprecated + } + } else { + return $this->get_setting( 'secret_access_key' ); + } + + return ''; + } + + } diff --git a/classes/wp-aws-plugin-base.php b/classes/wp-aws-plugin-base.php new file mode 100644 index 0000000..232823a --- /dev/null +++ b/classes/wp-aws-plugin-base.php @@ -0,0 +1,694 @@ +plugin_file_path = $plugin_file_path; + $this->plugin_dir_path = rtrim( plugin_dir_path( $plugin_file_path ), '/' ); + $this->plugin_basename = plugin_basename( $plugin_file_path ); + $this->plugin_pagenow = is_multisite() ? 'settings.php' : 'options-general.php'; + + if ( $this->plugin_slug && isset( $GLOBALS['aws_meta'][ $this->plugin_slug ]['version'] ) ) { + $this->plugin_version = $GLOBALS['aws_meta'][ $this->plugin_slug ]['version']; + } + } + + /** + * Accessor for plugin version + * + * @return mixed + */ + public function get_plugin_version() { + return $this->plugin_version; + } + + /** + * Accessor for plugin slug + * + * @return string + */ + public function get_plugin_slug() { + return $this->plugin_slug; + } + + /** + * Accessor for plugin basename + * + * @return string + */ + public function get_plugin_basename() { + return $this->plugin_basename; + } + + /** + * Accessor for plugin file path + * + * @return string + */ + public function get_plugin_file_path() { + return $this->plugin_file_path; + } + + /** + * Accessor for plugin dir path + * + * @return string + */ + public function get_plugin_dir_path() { + return $this->plugin_dir_path; + } + + /** + * Accessor for plugin sdks dir path + * + * @return string + */ + public function get_plugin_sdks_dir_path() { + return $this->get_plugin_dir_path() . '/vendor'; + } + + /** + * Accessor for plugin_pagenow + * + * @return string + */ + public function get_plugin_pagenow() { + return $this->plugin_pagenow; + } + + /** + * Get the plugin's settings array + * + * @param bool $force + * + * @return array + */ + function get_settings( $force = false ) { + if ( is_null( $this->settings ) || $force ) { + $saved_settings = get_site_option( static::SETTINGS_KEY ); + $this->settings = $this->filter_settings( $saved_settings ); + + // Now that we have merged database and defined settings, sanitize them before use. + if ( ! empty( $this->settings ) ) { + foreach ( $this->settings as $key => $val ) { + $this->settings[ $key ] = $this->sanitize_setting( $key, $val ); + } + } + + // If defined settings keys have changed since last time settings were saved to database, re-save to remove the new keys. + if ( ! empty( $saved_settings ) && ! empty( $this->defined_settings ) && ! empty( array_intersect_key( $saved_settings, $this->defined_settings ) ) ) { + $this->save_settings(); + } + } + + return $this->settings; + } + + /** + * Returns first (preferred) settings constant that can be defined, otherwise blank. + * + * @return string + */ + public static function preferred_settings_constant() { + if ( ! empty( static::$settings_constants ) ) { + return static::$settings_constants[0]; + } else { + return ''; + } + } + + /** + * Get the constant used to define the settings. + * + * @return string|false Constant name if defined, otherwise false + */ + public static function settings_constant() { + return AS3CF_Utils::get_first_defined_constant( static::$settings_constants ); + } + + /** + * Get all settings that have been defined via constant for the plugin + * + * @param bool $force + * + * @return array + */ + function get_defined_settings( $force = false ) { + if ( ! static::settings_constant() ) { + $this->defined_settings = array(); + + return $this->defined_settings; + } + + if ( is_null( $this->defined_settings ) || $force ) { + $this->defined_settings = array(); + $unserialized = maybe_unserialize( constant( static::settings_constant() ) ); + $unserialized = is_array( $unserialized ) ? $unserialized : array(); + + foreach ( $unserialized as $key => $value ) { + if ( ! in_array( $key, $this->get_settings_whitelist() ) ) { + continue; + } + + if ( is_bool( $value ) || is_null( $value ) ) { + $value = (int) $value; + } + + if ( is_numeric( $value ) ) { + $value = strval( $value ); + } else { + $value = $this->sanitize_setting( $key, $value ); + } + + $this->defined_settings[ $key ] = $value; + } + + $this->listen_for_settings_constant_changes(); + + // Normalize the defined settings before saving, so we can detect when a real change happens. + ksort( $this->defined_settings ); + update_site_option( 'as3cf_constant_' . static::settings_constant(), array_diff_key( $this->defined_settings, array_flip( $this->get_monitored_settings_blacklist() ) ) ); + } + + return $this->defined_settings; + } + + /** + * Subscribe to changes of the site option used to store the constant-defined settings. + */ + protected function listen_for_settings_constant_changes() { + if ( false !== static::settings_constant() && ! has_action( 'update_site_option_' . 'as3cf_constant_' . static::settings_constant(), array( + $this, + 'settings_constant_changed', + ) ) ) { + add_action( 'add_site_option_' . 'as3cf_constant_' . static::settings_constant(), array( + $this, + 'settings_constant_added', + ), 10, 3 ); + add_action( 'update_site_option_' . 'as3cf_constant_' . static::settings_constant(), array( + $this, + 'settings_constant_changed', + ), 10, 4 ); + } + } + + /** + * Translate a settings constant option addition into a change. + * + * @param string $option Name of the option. + * @param mixed $value Value the option is being initialized with. + * @param int $network_id ID of the network. + */ + public function settings_constant_added( $option, $value, $network_id ) { + $db_settings = get_site_option( static::SETTINGS_KEY, array() ); + $this->settings_constant_changed( $option, $value, $db_settings, $network_id ); + } + + /** + * Callback for announcing when settings-defined values change. + * + * @param string $option Name of the option. + * @param mixed $new_settings Current value of the option. + * @param mixed $old_settings Old value of the option. + * @param int $network_id ID of the network. + */ + public function settings_constant_changed( $option, $new_settings, $old_settings, $network_id ) { + if ( ! static::settings_constant() ) { + return; + } + + $old_settings = $old_settings ?: array(); + + foreach ( $this->get_settings_whitelist() as $setting ) { + $old_value = isset( $old_settings[ $setting ] ) ? $old_settings[ $setting ] : null; + $new_value = isset( $new_settings[ $setting ] ) ? $new_settings[ $setting ] : null; + + if ( $old_value !== $new_value ) { + /** + * Setting-specific hook for setting change. + * + * @param mixed $new_value + * @param mixed $old_value + * @param string $setting + */ + do_action( 'as3cf_constant_' . static::settings_constant() . '_changed_' . $setting, $new_value, $old_value, $setting ); + + /** + * Generic hook for setting change. + * + * @param mixed $new_value + * @param mixed $old_value + * @param string $setting + */ + do_action( 'as3cf_constant_' . static::settings_constant() . '_changed', $new_value, $old_value, $setting ); + } + } + } + + /** + * Filter the plugin settings array + * + * @param array $settings + * + * @return array $settings + */ + function filter_settings( $settings ) { + $defined_settings = $this->get_defined_settings(); + + // Bail early if there are no defined settings + if ( empty( $defined_settings ) ) { + return $settings; + } + + foreach ( $defined_settings as $key => $value ) { + $settings[ $key ] = $value; + } + + return $settings; + } + + /** + * Get the whitelisted settings for the plugin. + * Meant to be overridden in child classes. + * + * @return array + */ + function get_settings_whitelist() { + return array(); + } + + /** + * Get the blacklisted settings for monitoring changes in defines. + * These settings will not be saved in the database. + * Meant to be overridden in child classes. + * + * @return array + */ + function get_monitored_settings_blacklist() { + return array(); + } + + /** + * List of settings that should skip full sanitize. + * + * @return array + */ + function get_skip_sanitize_settings() { + return array(); + } + + /** + * List of settings that should be treated as paths. + * + * @return array + */ + function get_path_format_settings() { + return array(); + } + + /** + * List of settings that should be treated as directory paths. + * + * @return array + */ + function get_prefix_format_settings() { + return array(); + } + + /** + * Sanitize a setting value, maybe. + * + * @param string $key + * @param mixed $value + * + * @return mixed + */ + function sanitize_setting( $key, $value ) { + $skip_sanitize = $this->get_skip_sanitize_settings(); + + if ( in_array( $key, $skip_sanitize ) ) { + if ( is_array( $value ) ) { + $result = array(); + foreach ( $value as $k => $v ) { + $result[ $k ] = wp_strip_all_tags( $v ); + } + $value = $result; + } else { + $value = wp_strip_all_tags( $value ); + } + } else { + $value = sanitize_text_field( $value ); + + // Make sure path setting is absolute and not just "/". + // But not on Windows as it can have various forms of path, e.g. C:\Sites and \\shared\sites. + if ( '/' === DIRECTORY_SEPARATOR && in_array( $key, $this->get_path_format_settings() ) ) { + $value = trim( AS3CF_Utils::unleadingslashit( $value ) ); + $value = empty( $value ) ? '' : AS3CF_Utils::leadingslashit( $value ); + } + + // Make sure prefix setting is relative with trailing slash for visibility. + if ( in_array( $key, $this->get_prefix_format_settings() ) ) { + $value = trim( untrailingslashit( $value ) ); + $value = empty( $value ) ? '' : AS3CF_Utils::trailingslash_prefix( $value ); + } + } + + return $value; + } + + /** + * Get a specific setting + * + * @param $key + * @param string $default + * + * @return string + */ + function get_setting( $key, $default = '' ) { + $this->get_settings(); + + if ( isset( $this->settings[ $key ] ) ) { + $setting = $this->settings[ $key ]; + } else { + $setting = $default; + } + + return apply_filters( 'as3cf_get_setting', $setting, $key ); + } + + /** + * Get a specific setting from the core plugin. + * + * @param $key + * @param string $default + * + * @return string + */ + public function get_core_setting( $key, $default = '' ) { + return $this->get_setting( $key, $default ); + } + + /** + * Gets a single setting that has been defined in the plugin settings constant + * + * @param string $key + * @param mixed $default + * + * @return mixed + */ + function get_defined_setting( $key, $default = '' ) { + $defined_settings = $this->get_defined_settings(); + $setting = isset( $defined_settings[ $key ] ) ? $defined_settings[ $key ] : $default; + + return $setting; + } + + /** + * Delete a setting + * + * @param $key + */ + function remove_setting( $key ) { + $this->get_settings(); + + if ( isset( $this->settings[ $key ] ) ) { + unset( $this->settings[ $key ] ); + } + } + + /** + * Removes a defined setting from the defined_settings array. + * + * Does not unset the actual constant. + * + * @param $key + */ + function remove_defined_setting( $key ) { + $this->get_defined_settings(); + + if ( isset( $this->defined_settings[ $key ] ) ) { + unset( $this->defined_settings[ $key ] ); + } + } + + /** + * Render a view template file + * + * @param string $view View filename without the extension + * @param array $args Arguments to pass to the view + */ + function render_view( $view, $args = array() ) { + extract( $args ); + include $this->plugin_dir_path . '/view/' . $view . '.php'; + } + + /** + * Set a setting + * + * @param $key + * @param $value + */ + function set_setting( $key, $value ) { + $this->get_settings(); + + $this->settings[ $key ] = $value; + } + + /** + * Bulk set the settings array + * + * @param array $settings + */ + function set_settings( $settings ) { + $this->settings = $settings; + } + + /** + * Save the settings to the database + */ + public function save_settings() { + if ( is_array( $this->settings ) ) { + ksort( $this->settings ); + } + + $this->update_site_option( static::SETTINGS_KEY, array_diff_key( $this->settings, $this->defined_settings ) ); + } + + /** + * Update site option. + * + * @param string $option + * @param mixed $value + * @param bool $autoload + * + * @return bool + */ + public function update_site_option( $option, $value, $autoload = true ) { + if ( is_multisite() ) { + return update_site_option( $option, $value ); + } + + return update_option( $option, $value, $autoload ); + } + + /** + * Helper method to return the settings page URL for the plugin + * + * @param array $args + * @param string $url_method To prepend to admin_url() + * @param bool $escape Should we escape the URL + * + * @return string + */ + public function get_plugin_page_url( $args = array(), $url_method = 'network', $escape = true ) { + $default_args = array( + 'page' => static::$plugin_page, + ); + + $args = array_merge( $default_args, $args ); + + switch ( $url_method ) { + case 'self': + $base_url = self_admin_url( $this->get_plugin_pagenow() ); + break; + default: + $base_url = network_admin_url( $this->get_plugin_pagenow() ); + } + + // Add a hash to the URL + $hash = false; + if ( isset( $args['hash'] ) ) { + $hash = $args['hash']; + unset( $args['hash'] ); + } else if ( $this->default_tab ) { + $hash = $this->default_tab; + } + + $url = add_query_arg( $args, $base_url ); + + if ( $hash ) { + $url .= '#' . $hash; + } + + if ( $escape ) { + $url = esc_url_raw( $url ); + } + + return $url; + } + + /** + * The text for the plugin action link for the plugin on the plugins page. + * + * @return string + */ + function get_plugin_action_settings_text() { + return __( 'Settings', 'amazon-s3-and-cloudfront' ); + } + + /** + * Add a link to the plugin row for the plugin on the plugins page. + * Needs to be implemented for an extending class using - + * add_filter( 'plugin_action_links', array( $this, 'plugin_actions_settings_link' ), 10, 2 ); + * + * @param array $links + * @param string $file + * + * @return array + */ + function plugin_actions_settings_link( $links, $file ) { + $url = $this->get_plugin_page_url(); + $text = $this->get_plugin_action_settings_text(); + + $settings_link = '' . esc_html( $text ) . ''; + + if ( $file == $this->plugin_basename ) { + array_unshift( $links, $settings_link ); + } + + return $links; + } + + /** + * Enqueue script. + * + * @param string $handle + * @param string $path + * @param array $deps + * @param bool $footer + */ + public function enqueue_script( $handle, $path, $deps = array(), $footer = true ) { + $version = $this->get_asset_version(); + $suffix = $this->get_asset_suffix(); + + $src = plugins_url( $path . $suffix . '.js', $this->plugin_file_path ); + wp_enqueue_script( $handle, $src, $deps, $version, $footer ); + } + + /** + * Enqueue style. + * + * @param string $handle + * @param string $path + * @param array $deps + */ + public function enqueue_style( $handle, $path, $deps = array() ) { + $version = $this->get_asset_version(); + + $src = plugins_url( $path . '.css', $this->plugin_file_path ); + wp_enqueue_style( $handle, $src, $deps, $version ); + } + + /** + * Get the version used for script enqueuing + * + * @return mixed + */ + public function get_asset_version() { + return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? time() : $this->plugin_version; + } + + /** + * Get the filename suffix used for script enqueuing + * + * @return mixed + */ + public function get_asset_suffix() { + return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; + } + + /** + * Generate site URL with correct UTM tags. + * + * @param string $path + * @param array $args + * @param string $hash + * + * @return string + */ + public function dbrains_url( $path, $args = array(), $hash = '' ) { + $args = wp_parse_args( $args, array( + 'utm_medium' => 'insideplugin', + 'utm_source' => $this->get_utm_source(), + ) ); + $args = array_map( 'urlencode', $args ); + $url = trailingslashit( self::DBRAINS_URL ) . ltrim( $path, '/' ); + $url = add_query_arg( $args, $url ); + + if ( $hash ) { + $url .= '#' . $hash; + } + + return $url; + } + + /** + * Get UTM source for plugin. + * + * @return string + */ + protected function get_utm_source() { + return 'AWS'; + } + + /** + * Get the My Account URL + * + * @param array $args + * @param string $hash + * + * @return string + */ + public function get_my_account_url( $args = array(), $hash = '' ) { + return $this->dbrains_url( '/my-account/', $args, $hash ); + } +} diff --git a/composer.json b/composer.json index ac7e72a..963a534 100644 --- a/composer.json +++ b/composer.json @@ -4,6 +4,14 @@ { "name": "Janne Aalto", "email": "janne.aalto@frantic.com" + }, + { + "name": "Sanna Nygård", + "email": "sanna.nygard@frantic.com" + }, + { + "name": "Lauri Kallioniemi", + "email": "lauri.kallioniemi@frantic.com" } ], "license": "MIT", @@ -16,6 +24,6 @@ } ], "require": { - "frc/amazon-web-services": "1.0.7" + "aws/aws-sdk-php": "^3.199" } } diff --git a/view/footer.php b/view/footer.php new file mode 100644 index 0000000..7f5eaa3 --- /dev/null +++ b/view/footer.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/view/header.php b/view/header.php new file mode 100644 index 0000000..16e8ba7 --- /dev/null +++ b/view/header.php @@ -0,0 +1,3 @@ +
+ +

\ No newline at end of file diff --git a/wordpress-c3.php b/wordpress-c3.php index 85d0500..f2cfa21 100644 --- a/wordpress-c3.php +++ b/wordpress-c3.php @@ -1,17 +1,16 @@ is_plugin_active('amazon-s3-and-cloudfront-pro/amazon-s3-and-cloudfront-pro.php')) { @@ -50,4 +50,7 @@ function c3cf_init( $aws ){ $c3cf = new C3_CloudFront_Clear_Cache(__FILE__, $aws); } -add_action('aws_init', 'c3cf_init'); +add_action( 'init', 'c3cf_init' ); + +// If AWS still active need to be around to satisfy addon version checks until upgraded. +add_action( 'aws_init', 'c3cf_init', 11 );