Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
2d27bbc
Blaze: add new dashboard menu
jeherve Apr 14, 2023
bf75d2c
Add some basic tests
jeherve Apr 14, 2023
896ef8f
[not verified] Merge remote-tracking branch 'origin/trunk' into add/b…
jeherve May 5, 2023
5e37310
Add local setup for testing
sbarbosa May 5, 2023
22e9ae6
Rename dashboard classes and remove unneeded config parameters
sbarbosa May 5, 2023
148fd7b
Adds JS dependencies when loading the Blaze dashboard from the CDN
sbarbosa May 10, 2023
3b39aea
Merge branch 'trunk' into add/blaze-dashboard-menu
sbarbosa May 24, 2023
d5cf234
Merge remote-tracking branch 'origin/trunk' into add/blaze-dashboard-…
jeherve May 29, 2023
1cf5231
Move menu to Tools core menu
jeherve May 29, 2023
19d4660
Update tests following menu location change
jeherve May 29, 2023
538b16b
Changes Blaze entry points
sbarbosa May 29, 2023
f75f845
Merge remote-tracking branch 'origin/trunk' into add/blaze-dashboard-…
jeherve May 31, 2023
5fe6693
Fix linting error
jeherve May 31, 2023
08cda61
Add Status package dependency
jeherve May 31, 2023
6888c0e
Update dashboard page path
jeherve May 31, 2023
7a865b9
Switch to Plans package to avoid dependency to the Jetpack plugin
jeherve May 31, 2023
e3e1fd7
Add safeguards around endpoints
jeherve May 31, 2023
86f260c
Switch to extracted method to check for wpcom simple
jeherve May 31, 2023
dbc779d
Only load admin scripts when necessary
jeherve May 31, 2023
a1857c4
Change dashboard link interceptor to new path
sbarbosa May 31, 2023
6db420e
Update tests following dbc779d2c38c11b19381746dd112be149601f04a
jeherve Jun 1, 2023
4f2d68e
Gate access to the new dashboard.
jeherve Jun 1, 2023
f91e4c4
Simplify the script enqueue test
jeherve Jun 1, 2023
b62ed16
Simplify how scripts and styles are enqueued
jeherve Jun 1, 2023
c2214e1
Extract filter into its own method and add test for it
jeherve Jun 1, 2023
16e6bab
Pass filter status and site values from PHP to JS
jeherve Jun 1, 2023
86c94c0
Introduce new method to display links to the Blaze dashboard
jeherve Jun 1, 2023
014f8d7
Start using new method to display links in the Posts list
jeherve Jun 1, 2023
b547bfd
Introduce conditional Blaze links to the block editor panel
jeherve Jun 1, 2023
9795e0a
Remove extra changelog entries
jeherve Jun 1, 2023
bf58c8d
Merge remote-tracking branch 'origin/trunk' into add/blaze-dashboard-…
jeherve Jun 1, 2023
276c33c
Simplify fetching post title
jeherve Jun 1, 2023
3fa2099
Remove unnecessary argument
jeherve Jun 1, 2023
de17d88
[not verified] Merge remote-tracking branch 'origin/trunk' into add/b…
jeherve Jun 2, 2023
a20893c
Added query strings to the DSP redirect calls
sbarbosa Jun 2, 2023
3ba3264
Add validation to the query params
sbarbosa Jun 5, 2023
77aea5f
Merge remote-tracking branch 'origin/trunk' into add/blaze-dashboard-…
jeherve Jun 6, 2023
769f72e
Merge remote-tracking branch 'origin/trunk' into add/blaze-dashboard-…
jeherve Jun 6, 2023
626f3cf
[not verified] Merge remote-tracking branch 'origin/trunk' into add/b…
jeherve Jun 7, 2023
80c7c8e
Merge remote-tracking branch 'origin/trunk' into add/blaze-dashboard-…
jeherve Jun 15, 2023
a4638d5
Fixes error HTTP 414 on POST/PUT endpoints
sbarbosa Jun 15, 2023
ed25519
[not verified] Merge remote-tracking branch 'origin/trunk' into add/b…
jeherve Jun 16, 2023
29dedd3
Separate generic rest into root controllers
sbarbosa Jun 19, 2023
75f85bd
Improves get_data logic by reusing a variable
sbarbosa Jun 20, 2023
724c172
[not verified] Merge remote-tracking branch 'origin/trunk' into add/b…
jeherve Jun 20, 2023
d428a3f
Bump versions
jeherve Jun 20, 2023
7b3631e
Filter parameters to the WP endpoint call
sbarbosa Jun 20, 2023
5ff108d
Fixes the register_rest_route to support queryparams if plain permali…
sbarbosa Jun 20, 2023
7b1b445
[not verified] Merge remote-tracking branch 'origin/trunk' into add/b…
jeherve Jun 21, 2023
f51d02a
Fix copy/paste miss
jeherve Jun 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions projects/packages/blaze/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
vendor/
wordpress/
node_modules/
dist/
build/
.cache/
4 changes: 4 additions & 0 deletions projects/packages/blaze/changelog/add-blaze-dashboard-menu
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Add new Blaze Dashboard menu item.
9 changes: 6 additions & 3 deletions projects/packages/blaze/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
"type": "jetpack-library",
"license": "GPL-2.0-or-later",
"require": {
"automattic/jetpack-assets": "@dev",
"automattic/jetpack-connection": "@dev",
"automattic/jetpack-plans": "@dev",
"automattic/jetpack-redirect": "@dev",
"automattic/jetpack-status": "@dev",
"automattic/jetpack-sync": "@dev"
},
"require-dev": {
"yoast/phpunit-polyfills": "1.0.4",
"automattic/jetpack-assets": "@dev",
"automattic/jetpack-changelogger": "@dev",
"automattic/wordbless": "@dev"
},
Expand Down Expand Up @@ -59,11 +62,11 @@
"link-template": "https://github.com/automattic/jetpack-blaze/compare/v${old}...v${new}"
},
"branch-alias": {
"dev-trunk": "0.6.x-dev"
"dev-trunk": "0.7.x-dev"
},
"textdomain": "jetpack-blaze",
"version-constants": {
"::PACKAGE_VERSION": "src/class-blaze.php"
"::PACKAGE_VERSION": "src/class-dashboard.php"
}
},
"config": {
Expand Down
2 changes: 1 addition & 1 deletion projects/packages/blaze/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@automattic/jetpack-blaze",
"version": "0.6.1-alpha",
"version": "0.7.0-alpha",
"description": "Attract high-quality traffic to your site using Blaze. Using this service, you can advertise a post or page on some of the millions of pages across WordPress.com and Tumblr from just $5 per day.",
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/packages/blaze/#readme",
"bugs": {
Expand Down
130 changes: 112 additions & 18 deletions projects/packages/blaze/src/class-blaze.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@

namespace Automattic\Jetpack;

use Automattic\Jetpack\Blaze\Dashboard as Blaze_Dashboard;
use Automattic\Jetpack\Blaze\Dashboard_REST_Controller as Blaze_Dashboard_REST_Controller;
use Automattic\Jetpack\Connection\Client;
use Automattic\Jetpack\Connection\Initial_State as Connection_Initial_State;
use Automattic\Jetpack\Connection\Manager as Jetpack_Connection;
use Automattic\Jetpack\Status as Jetpack_Status;
use Automattic\Jetpack\Sync\Settings as Sync_Settings;

/**
* Class for promoting posts.
*/
class Blaze {

const PACKAGE_VERSION = '0.6.1-alpha';

/**
* Script handle for the JS file we enqueue in the post editor.
*
Expand All @@ -34,7 +34,8 @@ class Blaze {
public static $script_path = '../build/editor.js';

/**
* The configuration method that is called from the jetpack-config package.
* Initializer.
* Used to configure the blaze package, eg when called via the Config package.
*
* @return void
*/
Expand All @@ -43,6 +44,10 @@ public static function init() {
add_action( 'load-edit.php', array( __CLASS__, 'add_post_links_actions' ) );
// In the post editor, add a post-publish panel to allow promoting the post.
add_action( 'enqueue_block_editor_assets', array( __CLASS__, 'enqueue_block_editor_assets' ) );
// Add a Blaze Menu.
add_action( 'admin_menu', array( __CLASS__, 'enable_blaze_menu' ), 999 );
// Adds Blaze rest API
add_action( 'rest_api_init', array( new Blaze_Dashboard_REST_Controller(), 'register_rest_routes' ) );
}

/**
Expand All @@ -57,6 +62,46 @@ public static function add_post_links_actions() {
}
}

/**
* Is the wp-admin Dashboard enabled?
*
* @return bool
*/
public static function is_dashboard_enabled() {
/**
* Enable a wp-admin dashboard for Blaze campaign management.
*
* @since $$next-version$$
*
* @param bool $should_enable Should the dashboard be enabled? False by default for now.
*/
return apply_filters( 'jetpack_blaze_dashboard_enable', false );
}

/**
* Enable the Blaze menu.
*
* @return void
*/
public static function enable_blaze_menu() {
if (
self::should_initialize()
&& self::is_dashboard_enabled()
) {
$blaze_dashboard = new Blaze_Dashboard();
$page_suffix = add_submenu_page(
'tools.php',
esc_attr__( 'Advertising', 'jetpack-blaze' ),
__( 'Advertising', 'jetpack-blaze' ),
'manage_options',
'advertising',
array( $blaze_dashboard, 'render' ),
100
);
add_action( 'load-' . $page_suffix, array( $blaze_dashboard, 'admin_init' ) );
}
}

/**
* Check the WordPress.com REST API
* to ensure that the site supports the Blaze feature.
Expand Down Expand Up @@ -161,6 +206,47 @@ public static function should_initialize() {
return apply_filters( 'jetpack_blaze_enabled', $should_initialize );
}

/**
* Get URL to create a Blaze campaign for a specific post.
*
* This can return 2 different types of URL:
* - Calypso Links
* - wp-admin Links if access to the wp-admin Blaze Dashboard is enabled.
*
* @param int $post_id Post ID.
*
* @return array An array with the link, and whether this is a Calypso or a wp-admin link.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a huge fan of returning an array here just to get the info on whether we should link outside of wp-admin or not, I would rather return just the URL. That said, this seemed cleaner than having to check the string returned by this method later on just to find out if it was an external link or not.

*/
public static function get_campaign_management_url( $post_id ) {
if ( self::is_dashboard_enabled() ) {
$admin_url = admin_url( 'tools.php?page=advertising' );
$hostname = wp_parse_url( get_site_url(), PHP_URL_HOST );
$blaze_url = sprintf(
'%1$s#!/advertising/%2$s/posts/promote/post-%3$s',
$admin_url,
$hostname,
esc_attr( $post_id )
);

return array(
'link' => $blaze_url,
'external' => false,
);
}

// Default Calypso link.
$blaze_url = Redirect::get_url(
'jetpack-blaze',
array(
'query' => 'blazepress-widget=post-' . esc_attr( $post_id ),
)
);
return array(
'link' => $blaze_url,
'external' => true,
);
}

/**
* Adds the Promote link to the posts list row action.
*
Expand All @@ -187,24 +273,21 @@ public static function jetpack_blaze_row_action( $post_actions, $post ) {
return $post_actions;
}

// Might be useful to wrap in a method call for general use without post_id.
$blaze_url = Redirect::get_url(
'jetpack-blaze',
array(
'query' => 'blazepress-widget=post-' . esc_attr( $post_id ),
)
$blaze_url = self::get_campaign_management_url( $post_id );
$text = _x( 'Blaze', 'Verb', 'jetpack-blaze' );
$title = get_the_title( $post );
$label = sprintf(
/* translators: post title */
__( 'Blaze “%s” to Tumblr and WordPress.com audiences.', 'jetpack-blaze' ),
$title
);

// Add the link, make sure to tooltip hover.
$text = _x( 'Blaze', 'Verb', 'jetpack-blaze' );
$title = _draft_or_post_title( $post );
/* translators: post title */
$label = sprintf( __( 'Blaze “%s” to Tumblr and WordPress.com audiences.', 'jetpack-blaze' ), $title );
$post_actions['blaze'] = sprintf(
'<a href="%1$s" target="_blank" title="%2$s" aria-label="%2$s" rel="noopener noreferrer">%3$s</a>',
esc_url( $blaze_url ),
'<a href="%1$s" title="%2$s" aria-label="%2$s" %4$s>%3$s</a>',
esc_url( $blaze_url['link'] ),
esc_attr( $label ),
esc_html( $text )
esc_html( $text ),
( true === $blaze_url['external'] ? 'target="_blank" rel="noopener noreferrer"' : '' )
);

return $post_actions;
Expand Down Expand Up @@ -249,5 +332,16 @@ public static function enqueue_block_editor_assets() {

// Adds Connection package initial state.
wp_add_inline_script( self::SCRIPT_HANDLE, Connection_Initial_State::render(), 'before' );

// Pass additional data to our script.
wp_localize_script(
self::SCRIPT_HANDLE,
'blazeInitialState',
array(
'adminUrl' => esc_url( admin_url() ),
'isDashboardEnabled' => self::is_dashboard_enabled(),
'siteFragment' => ( new Jetpack_Status() )->get_site_suffix(),
)
);
}
}
145 changes: 145 additions & 0 deletions projects/packages/blaze/src/class-dashboard-config-data.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php
/**
* Blaze dashboard Initial State
*
* @package automattic/jetpack-blaze
*/

namespace Automattic\Jetpack\Blaze;

use Automattic\Jetpack\Current_Plan;
use Jetpack_Options;

/**
* Class Dashboard_Config_Data
*/
class Dashboard_Config_Data {
/**
* Set configData to window.configData.
*
* @param array $config_data The config data.
*/
public function get_js_config_data( $config_data = null ) {
return 'window.configData = ' . wp_json_encode(
$config_data === null ? $this->get_data() : $config_data
) . ';';
}

/**
* Return the config for the app.
*/
public function get_data() {
$blog_id = Jetpack_Options::get_option( 'id' );
$empty_object = json_decode( '{}' );
return array(
'admin_page_base' => $this->get_admin_path(),
'api_root' => esc_url_raw( rest_url() ),
'blog_id' => $blog_id,
'enable_all_sections' => false,
'env_id' => 'production',
'google_analytics_key' => 'UA-10673494-15',
'hostname' => wp_parse_url( get_site_url(), PHP_URL_HOST ),
'i18n_default_locale_slug' => 'en',
'mc_analytics_enabled' => false,
'meta' => array(),
'nonce' => wp_create_nonce( 'wp_rest' ),
'site_name' => \get_bloginfo( 'name' ),
'sections' => array(),
// Features are inlined in Calypso Blaze app (wp-calypso/apps/blaze-dashboard)
'features' => array(),
'intial_state' => array(
'currentUser' => array(
'id' => 1000,
'user' => array(
'ID' => 1000,
'username' => 'no-user',
'localeSlug' => $this->get_site_locale(),
),
'capabilities' => array(
"$blog_id" => $this->get_current_user_capabilities(),
),
),
'sites' => array(
'items' => array(
"$blog_id" => array(
'ID' => $blog_id,
'URL' => site_url(),
'jetpack' => true,
'visible' => true,
'capabilities' => $empty_object,
'products' => array(),
'plan' => $empty_object, // we need this empty object, otherwise the front end would crash on insight page.
'options' => array(
'admin_url' => admin_url(),
'gmt_offset' => $this->get_gmt_offset(),
),
),
),
'features' => array( "$blog_id" => array( 'data' => $this->get_plan_features() ) ),
),
),
);
}

/**
* Get the current site GMT Offset.
*
* @return float The current site GMT Offset by hours.
*/
protected function get_gmt_offset() {
return (float) get_option( 'gmt_offset' );
}

/**
* Page base for the Calypso admin page.
*/
protected function get_admin_path() {
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
if ( ! isset( $_SERVER['PHP_SELF'] ) || ! isset( $_SERVER['QUERY_STRING'] ) ) {
$parsed = wp_parse_url( admin_url( 'tools.php?page=advertising' ) );
return $parsed['path'] . '?' . $parsed['query'];
}
// We do this because page.js requires the exactly page base to be set otherwise it will not work properly.
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
return wp_unslash( $_SERVER['PHP_SELF'] ) . '?' . wp_unslash( $_SERVER['QUERY_STRING'] );
}

/**
* Get locale acceptable by Calypso.
*/
protected function get_site_locale() {
/**
* In WP, locales are formatted as LANGUAGE_REGION, for example `en`, `en_US`, `es_AR`,
* but Calypso expects language-region, e.g. `en-us`, `en`, `es-ar`. So we need to convert
* them to lower case and replace the underscore with a dash.
*/
$locale = strtolower( get_locale() );
$locale = str_replace( '_', '-', $locale );

return $locale;
}

/**
* Get the features of the current plan.
*/
protected function get_plan_features() {
$plan = Current_Plan::get();
if ( empty( $plan['features'] ) ) {
return array();
}
return $plan['features'];
}
Comment on lines +107 to +131
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Down the road (not in this PR), I think it may be nice to extract those instead of copying them from the Stats Admin class.


/**
* Get the capabilities of the current user.
*
* @return array An array of capabilities.
*/
protected function get_current_user_capabilities() {
$user = wp_get_current_user();
if ( ! $user || is_wp_error( $user ) ) {
return array();
}
return $user->allcaps;
}
}
Loading