-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add user preference api #1948
Closed
Closed
Add user preference api #1948
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
38a6970
User preferences API
notnownikki 16f32af
Add missing preferences.php
notnownikki 226e221
docstring fix
notnownikki deb859a
Merge preferences class and API route methods, fix lint issues
notnownikki 0a41626
Lint cleanups, tests for API
notnownikki 9c63d3c
PHP 5.3 fix
notnownikki 2e1259e
Docstring fix
notnownikki File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
/** | ||
* API Endpoints. | ||
* | ||
* @package gutenberg | ||
*/ | ||
|
||
if ( ! defined( 'ABSPATH' ) ) { | ||
die( 'Silence is golden.' ); | ||
} | ||
|
||
/** | ||
* Callback for registering gutenberg API routes. | ||
* | ||
* @return void | ||
*/ | ||
function gutenberg_register_routes() { | ||
Gutenberg_User_Preferences::register_routes(); | ||
} | ||
|
||
add_action( 'rest_api_init', 'gutenberg_register_routes' ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
<?php | ||
/** | ||
* Preference handling. | ||
* | ||
* @package gutenberg | ||
*/ | ||
|
||
if ( ! defined( 'ABSPATH' ) ) { | ||
die( 'Silence is golden.' ); | ||
} | ||
|
||
/** | ||
* User preference management. | ||
*/ | ||
class Gutenberg_User_Preferences { | ||
/** | ||
* Used to validate preference names are correct. | ||
* | ||
* @var Array $valid_preferences List of valid preference names. | ||
*/ | ||
public static $valid_preferences = array( | ||
'block_usage', | ||
'layout_config', | ||
); | ||
|
||
/** | ||
* Validates that a preference name is valid, as part of a REST API request. | ||
* | ||
* @param string $preference_name Preference name. | ||
* @return bool If the preference name is valid preference. | ||
*/ | ||
public static function is_valid_preference_name( $preference_name ) { | ||
return in_array( $preference_name, self::$valid_preferences ); | ||
} | ||
|
||
/** | ||
* Validates that all preference names in the request are valid. | ||
* | ||
* @param String $param Preference name. | ||
* @param WP_REST_Request $request The REST request. | ||
* @param String $key The parameter key for the value being validated. | ||
* @return Bool If all keys are valid preference names. | ||
*/ | ||
public static function validate_preferences( $param, $request, $key ) { | ||
foreach ( $param as $preference_name => $value ) { | ||
if ( ! self::is_valid_preference_name( $preference_name ) ) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Checks that the user has the needd permissions to store and read preferences. | ||
* | ||
* @return bool | ||
*/ | ||
public static function check_permissions() { | ||
$user_id = get_current_user_id(); | ||
return user_can( $user_id, 'edit_posts' ); | ||
} | ||
|
||
/** | ||
* Gets all preferences for a user. | ||
* | ||
* @param WP_REST_Request $request The REST request. | ||
* @return mixed Stored preference values indexed by preference name. | ||
*/ | ||
public static function get_preferences( $request ) { | ||
$user_id = get_current_user_id(); | ||
$preferences = array(); | ||
foreach ( self::$valid_preferences as $preference_name ) { | ||
$preferences[ $preference_name ] = get_user_meta( $user_id, 'gutenberg_' . $preference_name ); | ||
} | ||
return $preferences; | ||
} | ||
|
||
/** | ||
* Sets preferences for a user. | ||
* | ||
* Expects an array of preferences to store, indexed by the preference name. | ||
* | ||
* @param WP_REST_Request $request The REST request. | ||
* @return bool If the store was successful. | ||
*/ | ||
public static function set_preferences( $request ) { | ||
$params = $request->get_params(); | ||
$user_id = get_current_user_id(); | ||
|
||
foreach ( $params['preferences'] as $preference_name => $value ) { | ||
if ( ! self::is_valid_preference_name( $preference_name ) ) { | ||
return false; | ||
} | ||
} | ||
|
||
foreach ( $params['preferences'] as $preference_name => $value ) { | ||
update_user_meta( $user_id, 'gutenberg_' . $preference_name, $value ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If |
||
} | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* Registers preferences API routes. | ||
* | ||
* @return void | ||
*/ | ||
public static function register_routes() { | ||
register_rest_route( 'gutenberg/v1', '/user-preferences', array( | ||
array( | ||
'methods' => WP_REST_Server::READABLE, | ||
'callback' => 'Gutenberg_User_Preferences::get_preferences', | ||
'permission_callback' => 'Gutenberg_User_Preferences::check_permissions', | ||
), | ||
array( | ||
'methods' => WP_REST_Server::EDITABLE, | ||
'callback' => 'Gutenberg_User_Preferences::set_preferences', | ||
'permission_callback' => 'Gutenberg_User_Preferences::check_permissions', | ||
'args' => array( | ||
'preferences' => array( | ||
'required' => true, | ||
'validate_callback' => 'Gutenberg_User_Preferences::validate_preferences', | ||
), | ||
), | ||
), | ||
) ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
<?php | ||
/** | ||
* User preferences API Tests | ||
* | ||
* @package Gutenberg | ||
*/ | ||
|
||
/** | ||
* Test Gutenberg_User_Preferences | ||
*/ | ||
class User_Preferences_API_Test extends WP_Test_REST_Controller_Testcase { | ||
protected static $user; | ||
protected static $editor; | ||
public static function wpSetUpBeforeClass( $factory ) { | ||
self::$editor = $factory->user->create( array( | ||
'role' => 'editor', | ||
'user_email' => '[email protected]', | ||
) ); | ||
self::$user = $factory->user->create( array( | ||
'role' => 'subscriber', | ||
'user_email' => '[email protected]', | ||
) ); | ||
} | ||
|
||
public static function wpTearDownAfterClass() { | ||
self::delete_user( self::$user ); | ||
self::delete_user( self::$editor ); | ||
} | ||
|
||
public function test_register_routes() { | ||
$routes = $this->server->get_routes(); | ||
$this->assertArrayHasKey( '/gutenberg/v1/user-preferences', $routes ); | ||
$this->assertCount( 2, $routes['/gutenberg/v1/user-preferences'] ); | ||
} | ||
|
||
public function test_get_item() { | ||
wp_set_current_user( self::$editor ); | ||
|
||
$request = new WP_REST_Request( 'GET', '/gutenberg/v1/user-preferences' ); | ||
$response = $this->server->dispatch( $request ); | ||
|
||
$this->assertEquals( 200, $response->get_status() ); | ||
|
||
// Each valid preference should be present. | ||
foreach ( Gutenberg_User_Preferences::$valid_preferences as $preference ) { | ||
$this->assertArrayHasKey( $preference, $response->data ); | ||
} | ||
} | ||
|
||
public function test_get_item_without_permission() { | ||
wp_set_current_user( self::$user ); | ||
|
||
$request = new WP_REST_Request( 'GET', '/gutenberg/v1/user-preferences' ); | ||
$response = $this->server->dispatch( $request ); | ||
|
||
$this->assertEquals( 403, $response->get_status() ); | ||
} | ||
|
||
/** | ||
* Should fail with invalid preferences | ||
*/ | ||
function test_set_item_with_invalid_preferences() { | ||
wp_set_current_user( self::$editor ); | ||
|
||
$params = array( | ||
'preferences' => array( | ||
'bad_pref_name' => 42, | ||
), | ||
); | ||
|
||
$request = new WP_REST_Request( 'POST', '/gutenberg/v1/user-preferences' ); | ||
$request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); | ||
$request->set_body_params( $params ); | ||
|
||
$response = $this->server->dispatch( $request ); | ||
$this->assertEquals( 'rest_invalid_param', $response->data['code'] ); | ||
$this->assertEquals( 400, $response->get_status() ); | ||
} | ||
|
||
/** | ||
* Should set an individual preference | ||
*/ | ||
function test_update_item() { | ||
wp_set_current_user( self::$editor ); | ||
|
||
$params = array( | ||
'preferences' => array( | ||
'block_usage' => array( 'core/text' ), | ||
), | ||
); | ||
|
||
$request = new WP_REST_Request( 'POST', '/gutenberg/v1/user-preferences' ); | ||
$request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); | ||
$request->set_body_params( $params ); | ||
$response = $this->server->dispatch( $request ); | ||
|
||
$this->assertEquals( 200, $response->get_status() ); | ||
|
||
$request = new WP_REST_Request( 'GET', '/gutenberg/v1/user-preferences' ); | ||
$response = $this->server->dispatch( $request ); | ||
|
||
$this->assertEquals( array( 'core/text' ), $response->data['block_usage'][0] ); | ||
|
||
} | ||
|
||
/** | ||
* Should set multiple preferences | ||
*/ | ||
function test_update_item_multiple_preferences() { | ||
wp_set_current_user( self::$editor ); | ||
|
||
$params = array( | ||
'preferences' => array( | ||
'block_usage' => array( 'core/text' ), | ||
'layout_config' => array( | ||
'things' => 'awesome', | ||
), | ||
), | ||
); | ||
|
||
$request = new WP_REST_Request( 'POST', '/gutenberg/v1/user-preferences' ); | ||
$request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); | ||
$request->set_body_params( $params ); | ||
$response = $this->server->dispatch( $request ); | ||
|
||
$this->assertEquals( 200, $response->get_status() ); | ||
|
||
$request = new WP_REST_Request( 'GET', '/gutenberg/v1/user-preferences' ); | ||
$response = $this->server->dispatch( $request ); | ||
|
||
$this->assertEquals( array( 'core/text' ), $response->data['block_usage'][0] ); | ||
$this->assertEquals( array( | ||
'things' => 'awesome', | ||
), $response->data['layout_config'][0] ); | ||
|
||
} | ||
|
||
/** API does not implement these. */ | ||
public function test_get_items() {} | ||
public function test_create_item() {} | ||
public function test_delete_item() {} | ||
public function test_prepare_item() {} | ||
public function test_context_param() {} | ||
public function test_get_item_schema() {} | ||
|
||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when a preference is unset? It should be excluded from this array.