| 1 |
<?php |
| 2 |
/** |
| 3 |
* Admin class. |
| 4 |
* |
| 5 |
* Author: Andrei Baicus <andrei@themeisle.com> |
| 6 |
* Created on: 19/07/2018 |
| 7 |
* |
| 8 |
* @soundtrack Somewhere Else - Marillion |
| 9 |
* @package \Optimole\Inc |
| 10 |
* @author Optimole <friends@optimole.com> |
| 11 |
*/ |
| 12 |
|
| 13 |
/** |
| 14 |
* Class Optml_Admin |
| 15 |
*/ |
| 16 |
class Optml_Admin { |
| 17 |
|
| 18 |
/** |
| 19 |
* Hold the settings object. |
| 20 |
* |
| 21 |
* @var Optml_Settings Settings object. |
| 22 |
*/ |
| 23 |
public $settings; |
| 24 |
|
| 25 |
/** |
| 26 |
* Optml_Admin constructor. |
| 27 |
*/ |
| 28 |
public function __construct() { |
| 29 |
$this->settings = new Optml_Settings(); |
| 30 |
|
| 31 |
add_action( 'admin_menu', array( $this, 'add_dashboard_page' ) ); |
| 32 |
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) ); |
| 33 |
add_action( 'admin_bar_menu', array( $this, 'add_traffic_node' ), 9999 ); |
| 34 |
add_filter( 'wp_resource_hints', array( $this, 'add_dns_prefetch' ), 10, 2 ); |
| 35 |
add_action( 'optml_daily_sync', array( $this, 'daily_sync' ) ); |
| 36 |
add_action( 'wp_head', array( $this, 'generator' ) ); |
| 37 |
add_action( 'admin_init', array( $this, 'maybe_redirect' ) ); |
| 38 |
if ( ! is_admin() && $this->settings->is_connected() ) { |
| 39 |
if ( ! wp_next_scheduled( 'optml_daily_sync' ) ) { |
| 40 |
wp_schedule_event( time() + 10, 'daily', 'optml_daily_sync', array() ); |
| 41 |
} |
| 42 |
} |
| 43 |
} |
| 44 |
|
| 45 |
/** |
| 46 |
* Maybe redirect to dashboard page. |
| 47 |
*/ |
| 48 |
public function maybe_redirect() { |
| 49 |
if ( ! get_transient( 'optml_fresh_install' ) ) { |
| 50 |
return; |
| 51 |
} |
| 52 |
|
| 53 |
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { |
| 54 |
return; |
| 55 |
} |
| 56 |
|
| 57 |
delete_transient( 'optml_fresh_install' ); |
| 58 |
|
| 59 |
if ( is_network_admin() || isset( $_GET['activate-multi'] ) ) { |
| 60 |
return; |
| 61 |
} |
| 62 |
|
| 63 |
if ( $this->settings->is_connected() ) { |
| 64 |
return; |
| 65 |
} |
| 66 |
wp_safe_redirect( admin_url( 'upload.php?page=optimole' ) ); |
| 67 |
exit; |
| 68 |
} |
| 69 |
|
| 70 |
/** |
| 71 |
* Output Generator tag. |
| 72 |
*/ |
| 73 |
public function generator() { |
| 74 |
if ( ! $this->settings->is_connected() ) { |
| 75 |
return; |
| 76 |
} |
| 77 |
if ( ! $this->settings->is_enabled() ) { |
| 78 |
return; |
| 79 |
} |
| 80 |
echo '<meta name="generator" content="Optimole ' . esc_attr( OPTML_VERSION ) . '">'; |
| 81 |
} |
| 82 |
|
| 83 |
/** |
| 84 |
* Update daily the quota routine. |
| 85 |
*/ |
| 86 |
function daily_sync() { |
| 87 |
|
| 88 |
$api_key = $this->settings->get( 'api_key' ); |
| 89 |
if ( empty( $api_key ) ) { |
| 90 |
return; |
| 91 |
} |
| 92 |
|
| 93 |
$request = new Optml_Api(); |
| 94 |
$data = $request->get_user_data( $api_key ); |
| 95 |
if ( $data === false ) { |
| 96 |
return; |
| 97 |
} |
| 98 |
|
| 99 |
$this->settings->update( 'service_data', $data ); |
| 100 |
|
| 101 |
} |
| 102 |
|
| 103 |
/** |
| 104 |
* Adds cdn url for prefetch. |
| 105 |
* |
| 106 |
* @param array $hints Hints array. |
| 107 |
* @param string $relation_type Type of relation. |
| 108 |
* |
| 109 |
* @return array Altered hints array. |
| 110 |
*/ |
| 111 |
public function add_dns_prefetch( $hints, $relation_type ) { |
| 112 |
if ( 'dns-prefetch' !== $relation_type ) { |
| 113 |
return $hints; |
| 114 |
} |
| 115 |
if ( ! $this->settings->is_connected() ) { |
| 116 |
return $hints; |
| 117 |
} |
| 118 |
if ( ! $this->settings->is_enabled() ) { |
| 119 |
return $hints; |
| 120 |
} |
| 121 |
$hints[] = sprintf( '//%s', $this->settings->get_cdn_url() ); |
| 122 |
|
| 123 |
return $hints; |
| 124 |
} |
| 125 |
|
| 126 |
/** |
| 127 |
* Add the dashboard page. |
| 128 |
*/ |
| 129 |
public function add_dashboard_page() { |
| 130 |
add_media_page( 'Optimole', 'Optimole', 'manage_options', 'optimole', array( $this, 'render_dashboard_page' ) ); |
| 131 |
} |
| 132 |
|
| 133 |
/** |
| 134 |
* Render dashboard page. |
| 135 |
*/ |
| 136 |
public function render_dashboard_page() { |
| 137 |
?> |
| 138 |
<div id="optimole-app"> |
| 139 |
<app></app> |
| 140 |
</div> |
| 141 |
<?php |
| 142 |
} |
| 143 |
|
| 144 |
/** |
| 145 |
* Enqueue scripts needed for admin functionality. |
| 146 |
*/ |
| 147 |
public function enqueue() { |
| 148 |
$current_screen = get_current_screen(); |
| 149 |
if ( ! isset( $current_screen->id ) ) { |
| 150 |
return; |
| 151 |
} |
| 152 |
if ( $current_screen->id != 'media_page_optimole' ) { |
| 153 |
return; |
| 154 |
} |
| 155 |
wp_register_script( OPTML_NAMESPACE . '-admin', OPTML_URL . 'assets/js/bundle' . ( ! OPTML_DEBUG ? '.min' : '' ) . '.js', array(), OPTML_VERSION ); |
| 156 |
wp_localize_script( OPTML_NAMESPACE . '-admin', 'optimoleDashboardApp', $this->localize_dashboard_app() ); |
| 157 |
wp_enqueue_script( OPTML_NAMESPACE . '-admin' ); |
| 158 |
} |
| 159 |
|
| 160 |
/** |
| 161 |
* Localize the dashboard app. |
| 162 |
* |
| 163 |
* @return array |
| 164 |
*/ |
| 165 |
private function localize_dashboard_app() { |
| 166 |
$api_key = $this->settings->get( 'api_key' ); |
| 167 |
$service_data = $this->settings->get( 'service_data' ); |
| 168 |
$admin_bar_item = $this->settings->get( 'admin_bar_item' ); |
| 169 |
$image_replacer = $this->settings->get( 'image_replacer' ); |
| 170 |
$user = get_userdata( get_current_user_id() ); |
| 171 |
$args = array( |
| 172 |
'strings' => $this->get_dashboard_strings(), |
| 173 |
'assets_url' => OPTML_URL . 'assets/', |
| 174 |
'connection_status' => empty( $service_data ) ? 'no' : 'yes', |
| 175 |
'api_key' => $api_key, |
| 176 |
'root' => rest_url( OPTML_NAMESPACE . '/v1' ), |
| 177 |
'nonce' => wp_create_nonce( 'wp_rest' ), |
| 178 |
'user_data' => $service_data, |
| 179 |
'quality' => $this->settings->get( 'quality' ), |
| 180 |
'current_user' => array( |
| 181 |
'email' => $user->user_email |
| 182 |
), |
| 183 |
'admin_bar_item' => $admin_bar_item, |
| 184 |
'image_replacer' => $image_replacer, |
| 185 |
'home_url' => home_url(), |
| 186 |
); |
| 187 |
|
| 188 |
return $args; |
| 189 |
} |
| 190 |
|
| 191 |
/** |
| 192 |
* Get all dashboard strings. |
| 193 |
* |
| 194 |
* @return array |
| 195 |
*/ |
| 196 |
private function get_dashboard_strings() { |
| 197 |
return array( |
| 198 |
'optimole' => 'Optimole', |
| 199 |
'version' => OPTML_VERSION, |
| 200 |
'terms_menu' => __( 'Terms', 'optimole-wp' ), |
| 201 |
'privacy_menu' => __( 'Privacy', 'optimole-wp' ), |
| 202 |
'testdrive_menu' => __( 'Test Optimole', 'optimole-wp' ), |
| 203 |
'service_details' => __( 'Image optimization service', 'optimole-wp' ), |
| 204 |
'connect_btn' => __( 'Connect to OptiMole Service', 'optimole-wp' ), |
| 205 |
'disconnect_btn' => __( 'Disconnect', 'optimole-wp' ), |
| 206 |
'api_key_placeholder' => __( 'API Key', 'optimole-wp' ), |
| 207 |
'account_needed_heading' => __( 'Sign-up for API key', 'optimole-wp' ), |
| 208 |
'invalid_key' => __( 'Invalid API Key', 'optimole-wp' ), |
| 209 |
'status' => __( 'Status', 'optimole-wp' ), |
| 210 |
'email_address_label' => __( 'Your email address', 'optimole-wp' ), |
| 211 |
'register_btn' => __( 'Register & Email API key', 'optimole-wp' ), |
| 212 |
'step_one_api_title' => __( 'Enter your API key.', 'optimole-wp' ), |
| 213 |
'step_one_api_desc' => sprintf( __( 'Copy the API key you have received via email or you can get it from %s Optimole dashboard%s. <br/>', 'optimole-wp' ), '<a href="https://dashboard.optimole.com/" target="_blank"> ', '</a>' ), |
| 214 |
'step_two_api_title' => __( 'Connect to Optimole.', 'optimole-wp' ), |
| 215 |
'step_two_api_desc' => __( ' Fill in the upper API key field and connect to Optimole service.', 'optimole-wp' ), |
| 216 |
'api_exists' => __( 'I already have an API key.', 'optimole-wp' ), |
| 217 |
'back_to_register' => __( 'Register account', 'optimole-wp' ), |
| 218 |
'back_to_connect' => __( 'Connect account', 'optimole-wp' ), |
| 219 |
'error_register' => sprintf( __( 'Error registering account. You can try again %shere%s ', 'optimole-wp' ), '<a href="https://dashboard.optimole.com/register" target="_blank"> ', '</a>' ), |
| 220 |
'connected' => __( 'Connected', 'optimole-wp' ), |
| 221 |
'not_connected' => __( 'Not connected', 'optimole-wp' ), |
| 222 |
'usage' => __( 'Monthly Usage', 'optimole-wp' ), |
| 223 |
'quota' => __( 'Monthly Quota', 'optimole-wp' ), |
| 224 |
'logged_in_as' => __( 'Logged in as', 'optimole-wp' ), |
| 225 |
'private_cdn_url' => __( 'Private CDN url', 'optimole-wp' ), |
| 226 |
'options' => __( 'Options', 'optimole-wp' ), |
| 227 |
'notification_message_register' => __( 'We have sent you an email with the API key. Please copy and paste the key in the field below.', 'optimole-wp' ), |
| 228 |
'account_needed_title' => sprintf( |
| 229 |
__( 'In order to get access to free image optimization service you will need an API key from %s.', 'optimole-wp' ), |
| 230 |
' <a href="https://dashboard.optimole.com/register" target="_blank">optimole.com</a>' |
| 231 |
), |
| 232 |
'account_needed_subtitle_1' => sprintf( |
| 233 |
__( 'You will get access to our image optimization service for free in the limit of 1GB traffic per month. ', 'optimole-wp' ) |
| 234 |
), |
| 235 |
'account_needed_subtitle_2' => sprintf( |
| 236 |
__( 'Bonus, if you dont use a CDN, we got you covered, we will serve the images using our default CDN.', 'optimole-wp' ) |
| 237 |
), |
| 238 |
'dashboard_menu_item' => __( 'Dashboard', 'optimole-wp' ), |
| 239 |
'settings_menu_item' => __( 'Settings', 'optimole-wp' ), |
| 240 |
'options_strings' => array( |
| 241 |
'toggle_ab_item' => __( 'Admin bar status', 'optimole-wp' ), |
| 242 |
'enable_image_replace' => __( 'Enable image replacement', 'optimole-wp' ), |
| 243 |
'show' => __( 'Show', 'optimole-wp' ), |
| 244 |
'hide' => __( 'Hide', 'optimole-wp' ), |
| 245 |
'high_q_title' => __( 'High', 'optimole-wp' ), |
| 246 |
'medium_q_title' => __( 'Medium', 'optimole-wp' ), |
| 247 |
'low_q_title' => __( 'Low', 'optimole-wp' ), |
| 248 |
'auto_q_title' => __( 'Auto', 'optimole-wp' ), |
| 249 |
'quality_title' => __( 'Compression quality', 'optimole-wp' ), |
| 250 |
'quality_desc' => __( 'Select how much would like to compress the images.', 'optimole-wp' ), |
| 251 |
'enabled' => __( 'Enabled', 'optimole-wp' ), |
| 252 |
'option_saved' => __( 'Option saved.', 'optimole-wp' ), |
| 253 |
'disabled' => __( 'Disabled', 'optimole-wp' ), |
| 254 |
'image_1_label' => __( 'Original', 'optimole-wp' ), |
| 255 |
'image_2_label' => __( 'Optimized', 'optimole-wp' ), |
| 256 |
'save_quality_btn' => __( 'Save', 'optimole-wp' ), |
| 257 |
'sample_image_loading' => __( ' Loading a sample image. ', 'optimole-wp' ), |
| 258 |
'no_images_found' => __( 'You dont have any images in your Media Library. Add one and check how the Optimole will perform.', 'optimole-wp' ), |
| 259 |
'quality_slider_desc' => __( ' See one sample image which will help you choose the right quality of the compression.', 'optimole-wp' ), |
| 260 |
'replacer_desc' => __( 'Replace all the image urls from your website with the ones optimized by Optimole.', 'optimole-wp' ), |
| 261 |
'admin_bar_desc' => __( 'Show in the WordPress admin bar the available quota from Optimole service.', 'optimole-wp' ), |
| 262 |
), |
| 263 |
'latest_images' => array( |
| 264 |
'image' => __( 'Image', 'optimole-wp' ), |
| 265 |
'no_images_found' => sprintf( __( 'We might have a delay finding optimized images. Meanwhile you can visit your %shomepage%s and check how our plugin performs. ', 'optimole-wp' ), '<a href="' . esc_url( home_url() ) . '" target="_blank" >', '</a>' ), |
| 266 |
'compression' => __( 'Optimization', 'optimole-wp' ), |
| 267 |
'loading_latest_images' => __( 'Loading your optimized images...', 'optimole-wp' ), |
| 268 |
'last' => __( 'Last', 'optimole-wp' ), |
| 269 |
'optimized_images' => __( 'optimized images', 'optimole-wp' ), |
| 270 |
'same_size' => __( '🙉 We couldn\'t do better, this image is already optimized at maximum. ', 'optimole-wp' ), |
| 271 |
'small_optimization' => __( '😬 Not that much, just <strong>{ratio}</strong> smaller.', 'optimole-wp' ), |
| 272 |
'medium_optimization' => __( '🤓 We are on the right track, <strong>{ratio}</strong> squeezed.', 'optimole-wp' ), |
| 273 |
'big_optimization' => __( '❤️❤️❤️ Our moles just nailed it, this one is <strong>{ratio}</strong> smaller. ', 'optimole-wp' ), |
| 274 |
) |
| 275 |
); |
| 276 |
} |
| 277 |
|
| 278 |
/** |
| 279 |
* Add top admin bar notice of traffic quota/usage. |
| 280 |
* |
| 281 |
* @param WP_Admin_Bar $wp_admin_bar Admin bar resource. |
| 282 |
*/ |
| 283 |
public function add_traffic_node( $wp_admin_bar ) { |
| 284 |
if ( ! is_user_logged_in() ) { |
| 285 |
return; |
| 286 |
} |
| 287 |
$settings = new Optml_Settings(); |
| 288 |
if ( ! $settings->is_connected() ) { |
| 289 |
return; |
| 290 |
} |
| 291 |
$should_load = $settings->get( 'admin_bar_item' ); |
| 292 |
|
| 293 |
$service_data = $this->settings->get( 'service_data' ); |
| 294 |
if ( empty( $service_data ) ) { |
| 295 |
return; |
| 296 |
} |
| 297 |
$args = array( |
| 298 |
'id' => 'optml_image_quota', |
| 299 |
'title' => 'Optimole' . __( ' Image Traffic', 'optimole-wp' ) . ': ' . number_format( floatval( ( $service_data['usage'] / 1000 ) ), 3 ) . ' / ' . number_format( floatval( ( $service_data['quota'] / 1000 ) ), 0 ) . 'GB', |
| 300 |
'href' => 'https://dashboard.optimole.com/', |
| 301 |
'meta' => array( |
| 302 |
'target' => '_blank', |
| 303 |
'class' => $should_load !== 'enabled' ? 'hidden' : '' |
| 304 |
) |
| 305 |
); |
| 306 |
$wp_admin_bar->add_node( $args ); |
| 307 |
} |
| 308 |
} |
| 309 |
|