site_host = domain_mapping_siteurl( get_current_blog_id() ); } else { $this->site_host = site_url(); } // Load the plugin textdomain. add_action( 'init', array( $this, 'set_locale' ) ); // Set admin requirements on init, will check for is_admin so the upsell will be contained only in admin. // We need init because class=modula-speedup-settings.php has methods applied to admin_init add_action( 'init', array( $this, 'set_admin_requirements' ), 25 ); add_filter( 'modula_lite_default_settings', array( $this, 'speedup_defaults' ) ); if ( Modula_PRO::check_for_license() ) { add_filter( 'modula_shortcode_item_data', array( $this, 'generate_optimized_image_links' ), 5, 3 ); add_action( 'modula_shortcode_after_items', array( $this, 'after_gallery' ) ); } $this->settings = get_option( 'modula_speedup', array( 'enable_optimization' => 'disabled', 'thumbnail_optimization' => 'lossy', 'lightbox_optimization' => 'lossless', ) ); add_filter( 'modula_uninstall_db_options', array( $this, 'speedup_uninstall' ), 18, 1 ); // Add debug information add_filter( 'modula_debug_information', array( $this, 'debug_information' ), 40 ); register_activation_hook( MODULA_SPEEDUP_FILE, array( $this, 'plugin_activation' ) ); // Filter for the srcset and sizes on template image add_filter( 'modula_template_image_srcset', array( $this, 'modula_speedup_srcset' ), 30, 3 ); if ( is_admin() ) { add_action( 'modula_pro_updater', array( $this, 'addon_updater' ), 15, 2 ); } } /** * Set admin requirements and check for license. * * @return void * @since 1.0.12 */ public function set_admin_requirements() { if ( is_admin() ) { if ( class_exists( 'WPChill_Upsells' ) ) { $args = apply_filters( 'modula_upsells_args', array( 'shop_url' => 'https://wp-modula.com', 'slug' => 'modula' ) ); $wpchill_upsell = WPChill_Upsells::get_instance( $args ); if ( $wpchill_upsell && ! $wpchill_upsell->is_upgradable_addon( 'modula-speedup' ) ) { add_filter( 'modula_gallery_tabs', array( $this, 'modula_speedup_tab' ), 99 ); $this->require_admin(); } } } } /** * Prevent plugin activation if Modula Pro is not installed and activated * * @since 1.0.2 */ public function plugin_activation() { if ( ! class_exists( 'Modula_PRO' ) ) { deactivate_plugins( plugin_basename( MODULA_SPEEDUP_FILE ) ); wp_die( __( 'Please install and activate Modula Pro before using Modula Speed Up add-on.', 'modula-speedup' ) ); } } /** * Loads the plugin textdomain for translation. * * @since 1.0.0 */ public function set_locale() { load_plugin_textdomain( $this->plugin_slug, false, MODULA_SPEEDUP_PATH . '/languages' ); } public function addon_updater( $license_key, $store_url ) { if ( class_exists( 'Modula_Pro_Base_Updater' ) ) { $modula_addon_updater = new Modula_Pro_Base_Updater( $store_url, MODULA_SPEEDUP_FILE, array( 'version' => MODULA_SPEEDUP_VERSION, // current version number 'license' => $license_key, // license key (used get_option above to retrieve from DB) 'item_id' => 268582, // ID of the product 'author' => 'MachoThemes', // author of this plugin 'beta' => false, ) ); } } /** * Loads all admin related files into scope. * * @since 1.0.0 */ public function require_admin() { require_once MODULA_SPEEDUP_PATH . 'includes/admin/class-modula-speedup-settings.php'; } /** * Returns the singleton instance of the class. * * @return object The Modula_Video object. * @since 1.0.0 * */ public static function get_instance() { if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Modula_SpeedUp ) ) { self::$instance = new Modula_SpeedUp(); } return self::$instance; } public function generate_optimized_image_links( $item_data, $item, $settings ) { if ( 'disabled' == $settings['enable_optimization'] ) { return $item_data; } if ( 'default' == $settings['enable_optimization'] && 'disabled' == $this->settings['enable_optimization'] ) { return $item_data; } $image_compresion = ( 'default' == $settings['thumbnail_optimization'] ) ? $this->settings['thumbnail_optimization'] : $settings['thumbnail_optimization']; $lightbox_compresion = ( 'default' == $settings['lightbox_optimization'] ) ? $this->settings['lightbox_optimization'] : $settings['lightbox_optimization']; if ( 'disabled' == $image_compresion && 'disabled' == $lightbox_compresion ) { return $item_data; } add_filter( 'modula_resize_images', '__return_false', 10 ); $gallery_type = isset( $settings['type'] ) ? $settings['type'] : 'creative-gallery'; $grid_sizes = false; $crop = false; if ( in_array( $gallery_type, array( 'creative-gallery', 'custom-grid', 'grid' ) ) ) { if ( 'custom' != $settings['grid_image_size'] ) { $grid_sizes = $settings['grid_image_size']; } else { if ( 'custom-grid' == $settings['type'] ) { $grid_sizes = array( 'width' => absint( $settings['img_size'] ) * absint( $item['width'] ), 'height' => absint( $settings['img_size'] ) * absint( $item['height'] ) ); } else { $grid_sizes = $settings['grid_image_dimensions']; } } if ( 'custom' == $settings['grid_image_size'] ) { if ( 'custom-grid' == $settings['type'] ) { $settings['img_crop'] = isset( $settings['img_crop'] ) ? $settings['img_crop'] : 1; $crop = boolval( $settings['img_crop'] ); } else { $crop = boolval( $settings['grid_image_crop'] ); } } } elseif ( 'slider' == $gallery_type ) { $grid_sizes = $settings['slider_image_size']; if ( 'custom' == $grid_sizes ) { $grid_sizes = $settings['slider_image_dimensions']; $crop = boolval( $settings['slider_image_crop'] ); } } $sizes = $this->get_image_size( $item['id'], $gallery_type, $grid_sizes, $crop ); $image_full = $sizes['url']; $thumb_url = false; if ( 'disabled' != $image_compresion ) { if ( 0 !== strpos( $sizes['url'], $this->site_host ) ) { $image_url = $image_full; } else { $image_url = $this->build_imgopt_url( $image_full, $sizes['width'], $sizes['height'], $image_compresion ); $thumb = wp_get_attachment_image_src( $item['id'], 'thumbnail' ); $thumb_url = $this->build_imgopt_url( $thumb[0], $thumb[1], $thumb[2], $image_compresion ); } } else { $image_url = $image_full; } if ( 'disabled' != $lightbox_compresion ) { if ( 0 === strpos( $sizes['url'], $this->site_host ) ) { $image_full = $this->build_imgopt_url( $image_full, 0, 0, $lightbox_compresion ); } } $item_data['image_full'] = $image_full; $item_data['image_url'] = $image_url; // Add src/data-src attributes to img tag $item_data['img_attributes']['src'] = $image_url; $item_data['img_attributes']['data-src'] = $image_url; if ( $thumb_url ) { $item_data['link_attributes']['data-thumb'] = $thumb_url; } $item_data['img_attributes']['width'] = (int) $sizes['width']; $item_data['img_attributes']['height'] = (int) $sizes['height']; $item_data['compression'] = $image_compresion; return $item_data; } public function after_gallery( $settings ){ if ( 'disabled' == $settings['enable_optimization'] ) { return; } if ( 'default' == $settings['enable_optimization'] && 'disabled' == $this->settings['enable_optimization'] ) { return; } add_filter( 'modula_resize_images', '__return_true', 10 ); } public function get_image_size( $id, $type = 'creative-gallery', $sizes = array(), $crop = false ) { $image_full = wp_get_attachment_image_src( $id, 'full' ); if ( $image_full ) { $return = array( 'url' => $image_full[0], ); $gallery_types = array( 'creative-gallery', 'custom-grid', 'grid' ); if ( in_array( $type, $gallery_types ) ) { if ( is_array( $sizes ) && ! empty( $sizes ) ) { if ( ! $crop ) { $ratio = (float) ( (int) $image_full[1] / (int) $image_full[2] ); $width = $sizes['width']; $height = $sizes['height']; if ( 0 == $sizes['width'] || 0 == $sizes['height'] ) { if ( 0 == $sizes['width'] ) { $width = $sizes['height'] * $ratio; } else { $height = $sizes['width'] / $ratio; } } elseif ( $sizes['width'] / $sizes['height'] != $image_full[1] / $image_full[2] ) { if ( $sizes['width'] <= $sizes['height'] ) { $height = $sizes['width'] / $ratio; } else { $width = $sizes['height'] * $ratio; } } $return['width'] = (int) $width; $return['height'] = (int) $height; } else { $return['width'] = $sizes['width']; $return['height'] = $sizes['height']; } } else { $image_sizes = wp_get_attachment_image_src( $id, $sizes ); if ( $image_sizes ) { $return['width'] = $image_sizes[1]; $return['height'] = $image_sizes[2]; $return['thumb_url'] = $image_sizes[0]; } } } else { $return = apply_filters( "modula_resize_image_{$type}", $return, $id, $sizes, $crop ); } return $return; } else { return new WP_Error( 'modula-gallery-error-no-url', esc_html__( 'No image with this ID.', 'modula-speedup' ) ); } } private function build_imgopt_url( $orig_url, $width = 0, $height = 0, $compression = 'lossless' ) { // sanitize width and height. if ( strpos( $width, '%' ) !== false ) { $width = 0; } if ( strpos( $height, '%' ) !== false ) { $height = 0; } $width = (int) $width; $height = (int) $height; $imgopt_base_url = $this->get_imgopt_base_url( $compression ); $imgopt_size = ''; if ( $width && 0 !== $width ) { $imgopt_size = ',w_' . $width; } if ( $height && 0 !== $height ) { $imgopt_size .= ',h_' . $height; } $url = $imgopt_base_url . $imgopt_size . '/' . $orig_url; return $url; } private function get_imgopt_base_url( $compression ) { $imgopt_host = $this->imgopt_host; $imgopt_base_url = $imgopt_host . 'client/q_' . $compression . ',ret_img'; return $imgopt_base_url; } public function speedup_defaults( $defaults ) { $defaults['enable_optimization'] = 'default'; $defaults['thumbnail_optimization'] = 'default'; $defaults['lightbox_optimization'] = 'default'; return $defaults; } /** * Speedup uninstall * * @param $db_options * * @return mixed * * @since 1.0.3 */ public function speedup_uninstall( $db_options ) { $db_options[] = 'modula_speedup'; return $db_options; } /** * Add debug information * * @param $info * * @return mixed * @since 1.0.7 */ public function debug_information( $info ) { $speedup_otps = get_option( 'modula_speedup' ); $info['modula_speedup_version'] = array( 'label' => __( 'Modula Speedup Version', 'modula-best-grid-gallery' ), 'value' => esc_html( MODULA_SPEEDUP_VERSION ), 'debug' => esc_html( 'Modula Speedup version ' . MODULA_LITE_VERSION ), ); $info['compression'] = array( 'label' => __( 'Modula compression', 'modula-best-grid-gallery' ), 'value' => ( isset( $speedup_otps['enable_optimization'] ) && 'enabled' == $speedup_otps['enable_optimization'] ) ? esc_html__( 'Enabled', 'modula-speedup' ) : esc_html__( 'Disabled', 'modula-speedup' ), 'debug' => ( isset( $speedup_otps['enable_optimization'] ) && 'enabled' == $speedup_otps['enable_optimization'] ) ? 'Enabled compression' : 'Disabled compression', ); $info['thumb_compression'] = array( 'label' => __( 'Modula thumbnail compression', 'modula-best-grid-gallery' ), 'value' => ( isset( $speedup_otps['thumbnail_optimization'] ) ) ? esc_html( $speedup_otps['thumbnail_optimization'] ) : esc_html__( 'Disabled', 'modula-speedup' ), 'debug' => ( isset( $speedup_otps['thumbnail_optimization'] ) ) ? esc_html( $speedup_otps['thumbnail_optimization'] ) : 'Disabled thumbnail compression', ); $info['lightbox_compression'] = array( 'label' => __( 'Modula lightbox compression', 'modula-best-grid-gallery' ), 'value' => ( isset( $speedup_otps['lightbox_optimization'] ) ) ? esc_html( $speedup_otps['lightbox_optimization'] ) : esc_html__( 'Disabled', 'modula-speedup' ), 'debug' => ( isset( $speedup_otps['lightbox_optimization'] ) ) ? esc_html( $speedup_otps['lightbox_optimization'] ) : 'Disabled lightbox compression', ); return $info; } /** * Add CDN to the srcset of the images * * @param $srcset * @param $data * @param $image_meta * * @return array|string|string[] * * @since 1.0.10 */ public function modula_speedup_srcset( $srcset, $data, $image_meta ) { if ( ! isset( $data->compression ) || ! $data->compression ) { return $srcset; } $srcset = ''; $src_matched = false; $upload_dir = wp_get_upload_dir(); $image_src = $upload_dir['baseurl'] . $image_meta['file']; $dirname = _wp_get_attachment_relative_path( $image_meta['file'] ); if ( $dirname ) { $dirname = trailingslashit( $dirname ); } $upload_dir = wp_get_upload_dir(); $image_baseurl = trailingslashit( $upload_dir['baseurl'] ) . $dirname; /* * If currently on HTTPS, prefer HTTPS URLs when we know they're supported by the domain * (which is to say, when they share the domain name of the current request). */ if ( is_ssl() && 'https' !== substr( $image_baseurl, 0, 5 ) && parse_url( $image_baseurl, PHP_URL_HOST ) === $_SERVER['HTTP_HOST'] ) { $image_baseurl = set_url_scheme( $image_baseurl, 'https' ); } $image_width = $image_meta['width']; $image_height = $image_meta['height']; $image_edited = preg_match( '/-e[0-9]{13}/', wp_basename( $image_src ), $image_edit_hash ); $sources = array(); // As said in WP, the 'src' image has to be the first in the 'srcset', because of a bug in iOS8. See #35030. $sizes['full'] = array( 'file' => basename($image_meta['file']), 'width' => $image_width, 'height' => $image_height ); $sizes = array_merge( $sizes, $image_meta['sizes'] ); foreach ( $sizes as $size => $values ) { $is_src = false; // Check if image meta isn't corrupted. if ( ! is_array( $values ) ) { continue; } // If the file name is part of the `src`, we've confirmed a match. if ( ! $src_matched && false !== strpos( $image_src, $dirname . $values['file'] ) ) { $src_matched = true; $is_src = true; } // Filter out images that are from previous edits. if ( $image_edited && ! strpos( $values['file'], $image_edit_hash[0] ) ) { continue; } // If the image dimensions are within 1px of the expected size, use it. if ( wp_image_matches_ratio( $image_width, $image_height, $values['width'], $values['height'] ) ) { // Add the URL, descriptor, and value to the sources array to be returned. $source = array( 'url' => $this->build_imgopt_url( $image_baseurl . $values['file'], $values['width'], $values['height'], $data->compression ), 'descriptor' => 'w', 'value' => $values['width'], ); // The 'src' image has to be the first in the 'srcset', because of a bug in iOS8. See #35030. if ( $is_src ) { $sources = array( $values['width'] => $source ) + $sources; } else { $sources[ $values['width'] ] = $source; } } } foreach ( $sources as $key => $source ) { $srcset .= str_replace( ' ', '%20', $source['url'] ) . ' ' . $source['value'] . $source['descriptor'] . ', '; } return rtrim( $srcset, ', ' ); } /** * Unset badge * * @param [type] $tabs * @return void * @since 1.0.12 */ public function modula_speedup_tab( $tabs ) { unset( $tabs['speedup']['badge'] ); return $tabs; } }