slug = $slug;
$this->settings = Settings::get_instance();
if ( ! $parent ) {
$this->page_id = add_menu_page(
$title,
$title,
'manage_options',
$this->slug,
null,
$this->get_menu_icon()
);
} else {
$this->page_id = add_submenu_page(
$parent,
$title,
$title,
$nextgen ? 'NextGEN Manage gallery' : 'manage_options',
$this->slug,
array( $this, 'render' )
);
}
// No need to load these action on parent pages, as they are just placeholders for sub pages.
if ( $parent ) {
add_filter( 'load-' . $this->page_id, array( $this, 'on_load' ) );
add_action( 'load-' . $this->page_id, array( $this, 'register_meta_boxes' ) );
add_filter( 'load-' . $this->page_id, array( $this, 'add_action_hooks' ) );
}
}
/**
* Common hooks for all screens
*
* @since 2.9.0
*/
public function add_action_hooks() {
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
// Notices.
add_action( 'admin_notices', array( $this, 'smush_deactivated' ) );
add_action( 'network_admin_notices', array( $this, 'smush_deactivated' ) );
add_action( 'wp_smush_header_notices', array( $this, 'settings_updated' ) );
// Check for any stored API message and show it.
add_action( 'wp_smush_header_notices', array( $this, 'show_api_message' ) );
add_action( 'admin_notices', array( $this, 'smush_dash_required' ) );
add_action( 'network_admin_notices', array( $this, 'smush_dash_required' ) );
add_action( 'wp_smush_render_setting_row', array( $this, 'render_row' ), 10, 4 );
add_filter( 'admin_body_class', array( $this, 'smush_body_classes' ) );
// Filter query args to remove from the URL.
add_filter( 'removable_query_args', array( $this, 'add_removable_query_args' ) );
}
/**
* Enqueue scripts.
*
* @since 3.8.8
*
* @param string $hook Hook from where the call is made.
*/
public function enqueue_scripts( $hook ) {}
/**
* Return the admin menu slug
*
* @return string
*/
public function get_slug() {
return $this->slug;
}
/**
* Load an admin view.
*
* @param string $name View name = file name.
* @param array $args Arguments.
* @param string $dir Directory for the views. Default: views.
*/
public function view( $name, $args = array(), $dir = 'views' ) {
$file = WP_SMUSH_DIR . "app/{$dir}/{$name}.php";
$content = '';
if ( is_file( $file ) ) {
ob_start();
if ( isset( $args['id'] ) ) {
$args['orig_id'] = $args['id'];
$args['id'] = str_replace( '/', '-', $args['id'] );
}
extract( $args );
include $file;
$content = ob_get_clean();
}
// Everything escaped in all template files.
echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/**
* Display an admin notice about plugin deactivation.
*/
public function smush_deactivated() {
// Display only in backend for administrators.
if ( ! is_admin() || ! is_super_admin() || ! get_site_option( 'smush_deactivated' ) ) {
return;
}
?>
has_key() ) ) {
return;
}
// Do not show on free versions of the plugin.
if ( false !== strpos( WP_SMUSH_DIR, 'wp-smushit' ) ) {
return;
}
$function = is_multisite() ? 'network_admin_url' : 'admin_url';
$url = wp_nonce_url(
$function( 'update.php?action=install-plugin&plugin=install_wpmudev_dash' ),
'install-plugin_install_wpmudev_dash'
);
?>
id, Admin::$plugin_pages, true ) && false === strpos( get_current_screen()->id, 'page_smush' ) ) {
return $classes;
}
// Remove old wpmud class from body of smush page to avoid style conflict.
$classes = str_replace( 'wpmud ', '', $classes );
$classes .= ' ' . WP_SHARED_UI_VERSION;
return $classes;
}
/**
* Filters the query args to remove from the URL.
*
* @since 3.8.0
*
* @param array $args Removable query args.
* @return array
*/
public function add_removable_query_args( $args ) {
$args[] = 'notice';
return $args;
}
/**
* Allows to register meta boxes for the page.
*
* @since 2.9.0
*/
public function register_meta_boxes() {}
/**
* Add meta box.
*
* @param string $id Meta box ID.
* @param string $title Meta box title.
* @param callable $callback Callback for meta box content.
* @param callable $callback_header Callback for meta box header.
* @param callable $callback_footer Callback for meta box footer.
* @param string $context Meta box context.
* @param array $args Arguments.
*/
public function add_meta_box( $id, $title, $callback = null, $callback_header = null, $callback_footer = null, $context = 'main', $args = array() ) {
$default_args = array(
'box_class' => 'sui-box',
'box_header_class' => 'sui-box-header',
'box_content_class' => 'sui-box-body',
'box_footer_class' => 'sui-box-footer',
);
$args = wp_parse_args( $args, $default_args );
if ( ! isset( $this->meta_boxes[ $this->slug ] ) ) {
$this->meta_boxes[ $this->slug ] = array();
}
if ( ! isset( $this->meta_boxes[ $this->slug ][ $context ] ) ) {
$this->meta_boxes[ $this->slug ][ $context ] = array();
}
if ( ! isset( $this->meta_boxes[ $this->slug ][ $context ] ) ) {
$this->meta_boxes[ $this->slug ][ $context ] = array();
}
$meta_box = array(
'id' => $id,
'title' => $title,
'callback' => $callback,
'callback_header' => $callback_header,
'callback_footer' => $callback_footer,
'args' => $args,
);
if ( $meta_box ) {
$this->meta_boxes[ $this->slug ][ $context ][ $id ] = $meta_box;
}
}
/**
* Render the page
*/
public function render() {
// Shared UI wrapper with accessible color option.
$classes = $this->settings->get( 'accessible_colors' ) ? 'sui-wrap sui-color-accessible' : 'sui-wrap';
echo '';
$this->render_page_header();
$this->render_modals();
$this->render_inner_content();
// Nonce field.
wp_nonce_field( 'save_wp_smush_options', 'wp_smush_options_nonce', '' );
// Close shared ui wrapper.
echo '
';
}
/**
* Renders all the modals to be used in the page.
*
* @since 3.7.0
*/
private function render_modals() {
$this->prepare_modals();
// Render all modals.
foreach ( $this->modals as $modal_file => $args ) {
$this->view( $modal_file, $args, 'modals' );
}
}
private function prepare_modals() {
$this->prepare_onboarding_modal();
$this->prepare_upgrade_modal();
}
/**
* Onboarding Modal (show onload).
*
* List bulk smush features, and the related settings.
*
* => Expect to show it for the fresh installation.
* And we will show it when users can access bulk smush page.
* 1. Show it on single site.
* 2. For MU site, it depends on Sub-site Controls:
* 2.1. IF disable bulk smush page for sub-sites
* => Only show it on network side.
* 2.2. IF enable bulk smush page for sub-sites:
* - Show it for sub-sites.
* - Now we do not show it for network side since we do not show bulk smush page there.
* TODO: Maybe show it when we support bulk smush page on network side, @see: SMUSH-369
*/
private function prepare_onboarding_modal() {
$skip_quick_setup = ! empty( get_option( 'skip-smush-setup' ) );
if (
$skip_quick_setup
|| $this->has_onload_modal()
|| ! $this->settings->has_bulk_smush_page()
) {
return;
}
$this->modals['onboarding'] = array(
'cta_url' => Helper::get_recheck_images_link(),
);
}
private function has_onload_modal( $modal = false ) {
if (
empty( $this->modals )
|| ( $modal && ! isset( $this->modals[ $modal ] ) )
) {
return false;
}
$onload_modals = array(
'onboarding',
'updated',
);
$rendered_onload_modals = array_intersect( $onload_modals, array_keys( $this->modals ) );
return ! empty( $rendered_onload_modals );
}
/**
* Upgrade/New Feature modal (show onload).
*
* Show it when users can access bulk smush page, and network admin.
*/
private function prepare_upgrade_modal() {
$whitelabel_hide_doc_link = apply_filters( 'wpmudev_branding_hide_doc_link', false );
$hide_upgrade_modal = empty( get_site_option( 'wp-smush-show_upgrade_modal' ) );
$is_on_subsite_screen = ! is_network_admin();
if (
$this->has_onload_modal()
|| $hide_upgrade_modal
|| $whitelabel_hide_doc_link
|| ( $is_on_subsite_screen && ! $this->settings->has_bulk_smush_page() )
) {
$should_ignore_upgrade_modal = $whitelabel_hide_doc_link || $this->has_onload_modal( 'onboarding' );
if ( $should_ignore_upgrade_modal ) {
delete_site_option( 'wp-smush-show_upgrade_modal' );
}
return;
}
$cta_url = $this->settings->has_bulk_smush_page() ? Helper::get_page_url( 'smush-bulk' ) : '';
$this->modals['updated'] = array(
'cta_url' => $cta_url,
);
}
/**
* Get the current screen tab
*
* @return string
*/
public function get_current_tab() {
$tabs = $this->get_tabs();
$view = filter_input( INPUT_GET, 'view', FILTER_SANITIZE_SPECIAL_CHARS );
if ( $view && array_key_exists( $view, $tabs ) ) {
return $view;
}
if ( empty( $tabs ) ) {
return false;
}
reset( $tabs );
return key( $tabs );
}
/**
* Display tabs navigation
*/
public function show_tabs() {
$this->view(
'tabs',
array(
'tabs' => $this->get_tabs(),
)
);
}
/**
* Get a tab URL
*
* @param string $tab Tab ID.
*
* @return string
*/
public function get_tab_url( $tab ) {
$tabs = $this->get_tabs();
if ( ! isset( $tabs[ $tab ] ) ) {
return '';
}
if ( is_multisite() && is_network_admin() ) {
return network_admin_url( 'admin.php?page=' . $this->slug . '&view=' . $tab );
} else {
return admin_url( 'admin.php?page=' . $this->slug . '&view=' . $tab );
}
}
/**
* Get the list of tabs for this screen
*
* @return array
*/
protected function get_tabs() {
return apply_filters( 'wp_smush_admin_page_tabs_' . $this->slug, $this->tabs );
}
/**
* Render inner content.
*/
protected function render_inner_content() {
$this->view( 'smush-page' );
}
/**
* Render meta box.
*
* @param string $context Meta box context. Default: main.
*/
protected function do_meta_boxes( $context = 'main' ) {
if ( empty( $this->meta_boxes[ $this->slug ][ $context ] ) ) {
return;
}
do_action_ref_array( 'wp_smush_admin_do_meta_boxes_' . $this->slug, array( &$this ) );
foreach ( $this->meta_boxes[ $this->slug ][ $context ] as $id => $box ) {
$args = array(
'title' => $box['title'],
'id' => $id,
'callback' => $box['callback'],
'callback_header' => $box['callback_header'],
'callback_footer' => $box['callback_footer'],
'args' => $box['args'],
);
$this->view( 'meta-box', $args );
}
}
/**
* Check if there is any meta box for a given context.
*
* @param string $context Meta box context.
*
* @return bool
*/
protected function has_meta_boxes( $context ) {
return ! empty( $this->meta_boxes[ $this->slug ][ $context ] );
}
/**
* Check if view exists.
*
* @param string $name View name = file name.
*
* @return bool
*/
protected function view_exists( $name ) {
$file = WP_SMUSH_DIR . "app/views/$name.php";
return is_file( $file );
}
/**
* Smush icon svg image
*
* @return string
*/
private function get_menu_icon() {
ob_start();
?>
get_slug() ) {
case 'smush-bulk':
$doc .= '#bulk-smush';
break;
case 'smush-directory':
$doc .= '#directory-smush';
break;
case 'smush-lazy-load':
$doc .= '#lazy-loading';
break;
case 'smush-cdn':
$doc .= '#cdn';
break;
case 'smush-webp':
$doc .= '#local-webp';
break;
case 'smush-integrations':
$doc .= '#integrations';
break;
case 'smush-tools':
$doc .= '#tools';
break;
case 'smush-settings':
$doc .= '#settings';
break;
}
return $doc;
}
/**
* Prints out the page header for bulk smush page.
*
* @return void
*/
public function render_page_header() {
$current_screen = get_current_screen();
?>
core();
// Default message.
$message = esc_html__( 'Your settings have been updated!', 'wp-smushit' );
// Notice class.
$message_class = 'success';
if ( 'smush-cdn' === $this->get_slug() ) {
$cdn = $this->settings->get_setting( 'wp-smush-cdn_status' );
if ( isset( $cdn->cdn_enabling ) && $cdn->cdn_enabling ) {
$message = esc_html__( 'Your settings have been saved and changes are now propagating to the CDN. Changes can take up to 30 minutes to take effect but your images will continue to be served in the meantime, please be patient.', 'wp-smushit' );
}
}
// Additional message if we got work to do!
$resmush_count = is_array( $core->resmush_ids ) && count( $core->resmush_ids ) > 0;
$smush_count = is_array( $core->remaining_count ) && $core->remaining_count > 0;
if ( $smush_count || $resmush_count ) {
$message_class = 'warning';
// Show link to bulk smush tab from other tabs.
$bulk_smush_link = 'smush-bulk' === $this->get_slug() ? '' : '';
/* translators: %1$s - , %2$s - */
$message .= ' ' . sprintf( esc_html__( 'You have images that need smushing. %1$sBulk smush now!%2$s', 'wp-smushit' ), $bulk_smush_link, '' );
}
?>
settings->delete_setting( 'wp-smush-settings_updated' );
}
/**
* Check if the page should be rendered.
*
* @since 3.2.2
* @since 3.8.0 Added $tab parameter.
*
* @param string $page Page to check for.
*
* @return bool
*/
public static function should_render( $page = '' ) {
// Render all pages on single site installs.
if ( ! is_multisite() ) {
return true;
}
if ( empty( $page ) ) {
return false;
}
$access = get_site_option( 'wp-smush-networkwide' );
if ( ! $access || in_array( $page, array( 'directory', 'webp', 'configs' ), true ) ) {
return is_network_admin();
}
if ( '1' === $access ) {
return ! is_network_admin();
}
if ( is_array( $access ) ) {
if ( is_network_admin() && ! in_array( $page, $access, true ) ) {
return true;
}
if ( ! is_network_admin() && in_array( $page, $access, true ) ) {
return true;
}
}
return false;
}
/**
* Return this menu page URL
*
* @since 3.5.0
*
* @return string
*/
public function get_page_url() {
if ( is_multisite() && is_network_admin() ) {
global $_parent_pages;
if ( isset( $_parent_pages[ $this->slug ] ) ) {
$parent_slug = $_parent_pages[ $this->slug ];
if ( $parent_slug && ! isset( $_parent_pages[ $parent_slug ] ) ) {
$url = network_admin_url( add_query_arg( 'page', $this->slug, $parent_slug ) );
} else {
$url = network_admin_url( 'admin.php?page=' . $this->slug );
}
} else {
$url = '';
}
return esc_url( $url );
} else {
return menu_page_url( $this->slug, false );
}
}
/**
* Get a page URL.
*
* @param string $page Page slug.
*
* @return string
*/
public function get_url( $page = '' ) {
if ( ! $page ) {
$page = $this->get_slug();
}
return Helper::get_page_url( $page );
}
/**
* Render setting row.
*
* @param string $name Setting name.
* @param bool $value Setting value.
* @param bool $disable Disable row/option.
* @param bool $upsell Is the row an upsell.
*/
public function render_row( $name, $value, $disable = false, $upsell = false ) {
$this->view( 'settings-row', compact( 'name', 'value', 'disable', 'upsell' ) );
}
/**
* Enqueue scripts.
* Used by the Tutorials and Dashboard pages.
*/
protected function enqueue_tutorials_scripts() {
wp_enqueue_script(
'smush-tutorials',
WP_SMUSH_URL . 'app/assets/js/smush-tutorials.min.js',
array( 'wp-i18n' ),
WP_SMUSH_VERSION,
true
);
$strings = array(
'tutorials' => esc_html__( 'Tutorials', 'wp-smushit' ),
'tutorials_link' => 'https://wpmudev.com/blog/tutorials/tutorial-category/smush-pro/',
'tutorials_strings' => array(
array(
'loading' => esc_html__( 'Loading tutorials...', 'wp-smushit' ),
'min_read' => esc_html__( 'min read', 'wp-smushit' ),
'read_article' => esc_html__( 'Read article', 'wp-smushit' ),
),
),
);
wp_localize_script( 'smush-tutorials', 'smush_tutorials', $strings );
}
/**
* Enqueue the scripts for configs.
* Used in the Settings and Dashboard pages.
*
* @since 3.9.0
*/
protected function enqueue_configs_scripts() {
// Configs are only used on single installs and on the network admin on MU.
if ( is_multisite() && ! is_network_admin() ) {
return;
}
wp_enqueue_script(
'smush-react-configs',
WP_SMUSH_URL . 'app/assets/js/smush-react-configs.min.js',
array( 'wp-i18n', 'smush-sui' ),
WP_SMUSH_VERSION,
true
);
wp_add_inline_script(
'smush-react-configs',
'wp.i18n.setLocaleData( ' . wp_json_encode( $this->get_locale_data() ) . ', "wp-smushit" );',
'before'
);
// Configs.
wp_localize_script(
'smush-react-configs',
'smushReact',
array(
'hideBranding' => apply_filters( 'wpmudev_branding_hide_branding', false ),
'isPro' => WP_Smush::is_pro(),
'links' => array(
'configsPage' => network_admin_url( 'admin.php?page=smush-settings&view=configs' ),
'accordionImg' => WP_SMUSH_URL . 'app/assets/images/smush-config-icon@2x.png',
'hubConfigs' => 'https://wpmudev.com/hub2/configs/my-configs',
'hubWelcome' => 'https://wpmudev.com/hub-welcome/?utm_source=smush&utm_medium=plugin&utm_campaign=smush_hub_config',
'freeNoticeHub' => 'https://wpmudev.com/hub-welcome/?utm_source=smush&utm_medium=plugin&utm_campaign=smush_hub_config',
),
'requestsData' => array(
'root' => esc_url_raw( rest_url( 'wp-smush/v1/preset_configs' ) ),
'nonce' => wp_create_nonce( 'wp_rest' ),
'apiKey' => Helper::get_wpmudev_apikey(),
'hubBaseURL' => defined( 'WPMUDEV_CUSTOM_API_SERVER' ) && WPMUDEV_CUSTOM_API_SERVER ? trailingslashit( WPMUDEV_CUSTOM_API_SERVER ) . 'api/hub/v1/package-configs' : null,
// Hard-coding these because the Free version doesn't have the WDP ID header in wp-smushit.php.
'pluginData' => array(
'name' => 'Smush' . ( WP_Smush::is_pro() ? ' Pro' : '' ),
'id' => '912164',
),
'pluginRequests' => array(
'nonce' => wp_create_nonce( 'smush_handle_config' ),
'uploadAction' => 'smush_upload_config',
'createAction' => 'smush_save_config',
'applyAction' => 'smush_apply_config',
),
),
)
);
}
/**
* Gets the translated strings for javascript translations.
*
* @since 3.8.5
* @since 3.9.0 Moved from Smush\App\Admin to here.
*
* @return array
*/
protected function get_locale_data() {
$translations = get_translations_for_domain( 'wp-smushit' );
$locale = array(
'' => array(
'domain' => 'wp-smushit',
'lang' => get_user_locale(),
),
);
if ( ! empty( $translations->headers['Plural-Forms'] ) ) {
$locale['']['plural_forms'] = $translations->headers['Plural-Forms'];
}
foreach ( $translations->entries as $msgid => $entry ) {
$locale[ $msgid ] = $entry->translations;
}
return $locale;
}
protected function get_utm_link( $args = array() ) {
$default = array(
'utm_source' => 'smush',
'utm_medium' => 'plugin',
);
$args = wp_parse_args( $args, $default );
return add_query_arg( $args, $this->upgrade_url );
}
public function get_connect_site_link() {
if ( WP_Smush::is_pro() || WP_Smush::is_expired() ) {
// Do not show connect site link for pro or expired users.
return;
}
if ( ! class_exists( '\WPMUDEV_Dashboard' ) ) {
return add_query_arg(
array(
'utm_source' => 'smush',
'utm_medium' => 'plugin',
'utm_campaign' => 'smush_ultra_existing',
),
'https://wpmudev.com/hub2/connect/'
);
}
$dashboard_path = 'admin.php?page=wpmudev';
if ( ! is_multisite() ) {
return admin_url( $dashboard_path );
}
if ( is_super_admin() ) {
return network_admin_url( $dashboard_path );
}
}
}