| 1 |
<?php |
| 2 |
/** |
| 3 |
* A class that adds a search customization interface to wp-admin. |
| 4 |
* |
| 5 |
* @package automattic/jetpack-search |
| 6 |
*/ |
| 7 |
|
| 8 |
namespace Automattic\Jetpack\Search; |
| 9 |
|
| 10 |
use Automattic\Jetpack\Assets; |
| 11 |
use Automattic\Jetpack\Connection\Manager as Connection_Manager; |
| 12 |
use Automattic\Jetpack\Status; |
| 13 |
use Automattic\Jetpack\Tracking; |
| 14 |
|
| 15 |
/** |
| 16 |
* Responsible for adding a search customization interface to wp-admin. |
| 17 |
* |
| 18 |
* @package Automattic\Jetpack\Search |
| 19 |
*/ |
| 20 |
class Customberg { |
| 21 |
/** |
| 22 |
* The singleton instance of this class. |
| 23 |
* |
| 24 |
* @var Customberg |
| 25 |
*/ |
| 26 |
protected static $instance; |
| 27 |
|
| 28 |
/** |
| 29 |
* Search Plan class. |
| 30 |
* |
| 31 |
* @var Plan |
| 32 |
*/ |
| 33 |
public $plan; |
| 34 |
|
| 35 |
/** |
| 36 |
* Get the singleton instance of the class. |
| 37 |
* |
| 38 |
* @return Customberg |
| 39 |
*/ |
| 40 |
public static function instance() { |
| 41 |
if ( ! isset( self::$instance ) ) { |
| 42 |
self::$instance = new static(); |
| 43 |
self::$instance->init_hooks(); |
| 44 |
} |
| 45 |
|
| 46 |
return self::$instance; |
| 47 |
} |
| 48 |
|
| 49 |
/** |
| 50 |
* Adds action hooks. |
| 51 |
*/ |
| 52 |
public function init_hooks() { |
| 53 |
add_action( 'admin_menu', array( $this, 'add_wp_admin_page' ), 999 ); |
| 54 |
add_filter( 'pre_option_jetpack_search_show_powered_by', array( $this, 'get_show_powered_by' ) ); |
| 55 |
$this->plan = new Plan(); |
| 56 |
} |
| 57 |
|
| 58 |
/** |
| 59 |
* Adds a wp-admin page without adding a sidebar submenu item. |
| 60 |
*/ |
| 61 |
public function add_wp_admin_page() { |
| 62 |
if ( ! $this->should_add_page() ) { |
| 63 |
return; |
| 64 |
} |
| 65 |
|
| 66 |
// Intentionally omits adding a submenu via the first empty argument. |
| 67 |
$hook = add_submenu_page( |
| 68 |
'', |
| 69 |
/** "Search" is a product name, do not translate. */ |
| 70 |
'Jetpack Search', |
| 71 |
'Search', |
| 72 |
'manage_options', // Must be an admin. |
| 73 |
'jetpack-search-configure', |
| 74 |
array( $this, 'jetpack_search_admin_page' ) |
| 75 |
); |
| 76 |
|
| 77 |
add_action( "admin_print_scripts-$hook", array( $this, 'load_assets' ) ); |
| 78 |
add_action( 'admin_footer', array( 'Automattic\Jetpack\Search\Helper', 'print_instant_search_sidebar' ) ); |
| 79 |
} |
| 80 |
|
| 81 |
/** |
| 82 |
* Force option value to be true if in free plan. |
| 83 |
* |
| 84 |
* @param string $value The incoming value to be replaced. |
| 85 |
*/ |
| 86 |
public function get_show_powered_by( $value ) { |
| 87 |
if ( $this->plan->is_free_plan() ) { |
| 88 |
return true; |
| 89 |
} |
| 90 |
return $value; |
| 91 |
} |
| 92 |
|
| 93 |
/** |
| 94 |
* Prints the dashboard container. |
| 95 |
*/ |
| 96 |
public function jetpack_search_admin_page() { |
| 97 |
// TODO: Spin this function off into a static helper function in a helper class for code reuse. |
| 98 |
$static_url = apply_filters( 'jetpack_static_url', '//en.wordpress.com/i/loading/loading-64.gif' ); |
| 99 |
?> |
| 100 |
<div id="jp-search-configure" class="jp-search-configure-dashboard" style="height: calc(100vh - 100px);"> |
| 101 |
<div class="hide-if-no-js" style="height: 100%;"> |
| 102 |
<img class="jp-search-loader" width="32" height="32" alt="<?php esc_attr_e( 'Loading…', 'jetpack-search-pkg' ); ?>" src="<?php echo esc_url( $static_url ); ?>" style=" |
| 103 |
position: absolute; |
| 104 |
left: 50%; |
| 105 |
top: 50%; |
| 106 |
"/> |
| 107 |
</div> |
| 108 |
<div class="hide-if-js"><?php esc_html_e( 'Your Jetpack Search customization page requires JavaScript to function properly.', 'jetpack-search-pkg' ); ?></div> |
| 109 |
</div> |
| 110 |
<?php |
| 111 |
} |
| 112 |
|
| 113 |
/** |
| 114 |
* Loads assets for the customization experience. |
| 115 |
*/ |
| 116 |
public function load_assets() { |
| 117 |
$this->load_assets_with_parameters( Package::get_installed_path() ); |
| 118 |
} |
| 119 |
|
| 120 |
/** |
| 121 |
* Loads script and style assets according to parameters provided. |
| 122 |
* |
| 123 |
* @param string $package_base_path - Base path for the search package. |
| 124 |
*/ |
| 125 |
public function load_assets_with_parameters( $package_base_path ) { |
| 126 |
Tracking::register_tracks_functions_scripts( true ); |
| 127 |
|
| 128 |
Assets::register_script( |
| 129 |
'jp-search-configure', |
| 130 |
'build/customberg/jp-search-configure.js', |
| 131 |
$package_base_path . '/src', // A full path to a file or a directory inside a plugin. |
| 132 |
array( |
| 133 |
'css_dependencies' => array( |
| 134 |
'wp-components', |
| 135 |
'wp-block-editor', |
| 136 |
), |
| 137 |
'in_footer' => true, |
| 138 |
'textdomain' => 'jetpack-search-pkg', |
| 139 |
) |
| 140 |
); |
| 141 |
Assets::enqueue_script( 'jp-search-configure' ); |
| 142 |
|
| 143 |
// Use wp_add_inline_script instead of wp_localize_script, see https://core.trac.wordpress.org/ticket/25280. |
| 144 |
wp_add_inline_script( 'jp-search-configure', 'var JetpackInstantSearchOptions=' . wp_json_encode( Helper::generate_initial_javascript_state(), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . ';', 'before' ); |
| 145 |
wp_add_inline_script( |
| 146 |
'jp-search-configure', |
| 147 |
"window.jetpackSearchConfigureInit( 'jp-search-configure' )" |
| 148 |
); |
| 149 |
} |
| 150 |
|
| 151 |
/** |
| 152 |
* Determine if the requisite page should be added to wp-admin. |
| 153 |
* |
| 154 |
* @return boolean |
| 155 |
*/ |
| 156 |
protected function should_add_page() { |
| 157 |
$is_offline_mode = ( new Status() )->is_offline_mode(); |
| 158 |
$is_connected = ( new Connection_Manager( Package::SLUG ) )->is_connected(); |
| 159 |
$supports_search = ( new Plan() )->supports_instant_search(); |
| 160 |
|
| 161 |
return ( |
| 162 |
! $is_offline_mode && // Must be online. |
| 163 |
$is_connected && // Must be connected. |
| 164 |
$supports_search // Must have plan supporting Jetpack (Instant) Search. |
| 165 |
); |
| 166 |
} |
| 167 |
} |
| 168 |
|