Skip to content

Commit fa80ac0

Browse files
authored
Support Queries Discussed at the Micropub Popups (#229)
* Change category search to filter per proposal * Turn filter into a function and test that function * Pass input to syndicate target filter to allow for additional queries * Add additional query filters to source query * Add offset query argument to media endpoint source * Fix permissions for Indieauth change on media endpoint * Bump version
1 parent 5063d46 commit fa80ac0

File tree

8 files changed

+113
-56
lines changed

8 files changed

+113
-56
lines changed

includes/class-micropub-endpoint.php

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,8 @@ public static function post_handler( $request ) {
316316
return $response;
317317
}
318318

319-
private static function get_syndicate_targets( $user_id ) {
320-
return apply_filters( 'micropub_syndicate-to', array(), $user_id );
319+
private static function get_syndicate_targets( $user_id, $input = null ) {
320+
return apply_filters( 'micropub_syndicate-to', array(), $user_id, $input );
321321
}
322322

323323
/**
@@ -332,7 +332,7 @@ public static function query_handler( $request ) {
332332
switch ( static::$input['q'] ) {
333333
case 'config':
334334
$resp = array(
335-
'syndicate-to' => static::get_syndicate_targets( $user_id ),
335+
'syndicate-to' => static::get_syndicate_targets( $user_id, static::$input ),
336336
'media-endpoint' => rest_url( static::get_namespace() . '/media' ),
337337
'mp' => array(
338338
'slug',
@@ -351,7 +351,7 @@ public static function query_handler( $request ) {
351351
break;
352352
case 'syndicate-to':
353353
// return syndication targets with filter
354-
$resp = array( 'syndicate-to' => static::get_syndicate_targets( $user_id ) );
354+
$resp = array( 'syndicate-to' => static::get_syndicate_targets( $user_id, static::$input ) );
355355
break;
356356
case 'category':
357357
// https://github.com/indieweb/micropub-extensions/issues/5
@@ -364,18 +364,10 @@ public static function query_handler( $request ) {
364364
)
365365
)
366366
);
367-
if ( array_key_exists( 'search', static::$input ) ) {
368-
$search = static::$input['search'];
369-
$resp = array_values(
370-
array_filter(
371-
$resp,
372-
function( $value ) use ( $search ) {
373-
return ( false !== stripos( $value, $search ) );
374-
}
375-
)
376-
);
367+
if ( array_key_exists( 'filter', static::$input ) ) {
368+
$filter = static::$input['filter'];
369+
$resp = mp_filter( $resp, $filter );
377370
}
378-
379371
$resp = array( 'categories' => $resp );
380372
break;
381373
case 'source':
@@ -386,14 +378,40 @@ function( $value ) use ( $search ) {
386378
}
387379
$resp = self::query( $post_id );
388380
} else {
389-
$numberposts = mp_get( static::$input, 'limit', 10 );
390-
$posts = get_posts(
391-
array(
392-
'posts_per_page' => $numberposts,
393-
'fields' => 'ids',
394-
)
381+
$args = array(
382+
'posts_per_page' => mp_get( static::$input, 'limit', 10 ),
383+
'fields' => 'ids',
395384
);
396-
$resp = array();
385+
if ( array_key_exists( 'offset', static::$input ) ) {
386+
$args['offset'] = mp_get( static::$input, 'offset' );
387+
}
388+
389+
if ( array_key_exists( 'visibility', static::$input ) ) {
390+
$visibilitylist = array( array( 'private' ), array( 'public' ) );
391+
if ( ! in_array( $props['visibility'], $visibilitylist, true ) ) {
392+
// Returning null will cause the server to return a 400 error
393+
return null;
394+
}
395+
if ( array( 'private' ) === $props['visibility'] ) {
396+
if ( user_can( $user_id, 'read_private_posts' ) ) {
397+
$args['post-status'] = 'private';
398+
}
399+
}
400+
} elseif ( array_key_exists( 'post-status', static::$input ) ) {
401+
// According to the proposed specification these are the only two properties supported.
402+
// https://indieweb.org/Micropub-extensions#Post_Status
403+
// For now these are the only two we will support even though WordPress defaults to 8 and allows custom
404+
// But makes it easy to change
405+
406+
// Map published to the WordPress property publish.
407+
if ( 'published' === mp_get( static::$input, 'post-status' ) ) {
408+
$args['post-status'] = 'publish';
409+
} elseif ( 'draft' === mp_get( static::$input, 'post-status' ) ) {
410+
$args['post-status'] = 'draft';
411+
}
412+
}
413+
$posts = get_posts( $args );
414+
$resp = array();
397415
foreach ( $posts as $post ) {
398416
$resp[] = self::query( $post );
399417
}

includes/class-micropub-media.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,10 @@ protected static function permissions_check( $request ) {
203203
static::$micropub_auth_response = apply_filters( 'indieauth_response', static::$micropub_auth_response );
204204
if ( 'POST' === $request->get_method() ) {
205205
if ( ! current_user_can( 'upload_files' ) ) {
206-
return new WP_Micropub_Error( 'forbidden', 'User is not permitted to upload files', 403 );
206+
return new WP_Micropub_Error( 'insufficient_scope', 'You do not have permission to create or upload media', 401 );
207207
}
208-
}
209-
$intersect = array_intersect( array( 'create', 'media' ), static::$scopes );
210-
if ( empty( $intersect ) ) {
211-
return new WP_Micropub_Error( 'insufficient_scope', 'You do not have permission to create or upload media', 401 );
208+
} else if ( ! current_user_can( 'read' ) ) {
209+
return new WP_Micropub_Error( 'forbidden', 'Unauthorized', 403 );
212210
}
213211

214212
return true;
@@ -365,14 +363,16 @@ public static function query_handler( $request ) {
365363
$resp = self::return_media_data( $attachment_id );
366364
} else {
367365
$numberposts = mp_get( $params, 'limit', 10 );
368-
$attachments = get_posts(
369-
array(
370-
'posts_per_page' => $numberposts,
371-
'post_type' => 'attachment',
372-
'fields' => 'ids',
373-
'order' => 'DESC',
374-
)
366+
$args = array(
367+
'posts_per_page' => $numberposts,
368+
'post_type' => 'attachment',
369+
'fields' => 'ids',
370+
'order' => 'DESC',
375371
);
372+
if ( array_key_exists( 'offset', $params ) ) {
373+
$args['offset'] = mp_get( $params, 'offset' );
374+
}
375+
$attachments = get_posts( $args );
376376
$resp = array();
377377
foreach ( $attachments as $attachment ) {
378378
$resp[] = self::return_media_data( $attachment );

includes/functions.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,17 @@ function mp_get( $array, $key, $default = array(), $index = false ) {
3434
return $return;
3535
}
3636
}
37+
38+
if ( ! function_exists( 'mp_filter' ) ) {
39+
// Searches for partial matches in an array of strings
40+
function mp_filter( $array, $filter ) {
41+
return array_values(
42+
array_filter(
43+
$array,
44+
function( $value ) use ( $filter ) {
45+
return ( false !== stripos( $value, $filter ) );
46+
}
47+
)
48+
);
49+
}
50+
}

micropub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Author: IndieWeb WordPress Outreach Club
88
* Author URI: https://indieweb.org/WordPress_Outreach_Club
99
* Text Domain: micropub
10-
* Version: 2.2.0
10+
* Version: 2.2.1
1111
*/
1212

1313
/* See README for supported filters and actions.

readme.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Called during the creation of a Micropub post. This defaults to post, but allows
5656
Called during the creation of a Micropub post. This defaults to nothing but allows for a Micropub post to set a custom taxonomy.
5757

5858

59-
`micropub_syndicate-to( $synd_urls, $user_id )`
59+
`micropub_syndicate-to( $synd_urls, $user_id, $input )`
6060

6161
Called to generate the list of `syndicate-to` targets to return in response to a query. Returns `$synd_urls`, an array, possibly modified. This filter is empty by default
6262

@@ -214,6 +214,12 @@ into markdown and saved to readme.md.
214214
## Changelog
215215
216216
217+
### 2.2.1 (2020-07-31 )
218+
* Change category query parameter from search to filter per decision at Micropub Popup Session
219+
* Fix permissions for Media Endpoint to match Endpoint
220+
* For source query on both media and micropub endpoint support offset parameter
221+
222+
217223
### 2.2.0 (2020-07-25 )
218224
* Deprecate MICROPUB_LOCAL_AUTH, MICROPUB_AUTHENTICATION_ENDPOINT and MICROPUB_TOKEN_ENDPOINT constants.
219225
* Remove IndieAuth Client code, will now require the IndieAuth or other plugin that does not yet exist.

readme.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Tags: micropub, publish, indieweb, microformats
44
Requires at least: 4.9.9
55
Requires PHP: 5.6
66
Tested up to: 5.4.2
7-
Stable tag: 2.2.0
7+
Stable tag: 2.2.1
88
License: CC0
99
License URI: http://creativecommons.org/publicdomain/zero/1.0/
1010
Donate link: -
@@ -62,7 +62,7 @@ Called during the creation of a Micropub post. This defaults to post, but allows
6262
Called during the creation of a Micropub post. This defaults to nothing but allows for a Micropub post to set a custom taxonomy.
6363

6464

65-
`micropub_syndicate-to( $synd_urls, $user_id )`
65+
`micropub_syndicate-to( $synd_urls, $user_id, $input )`
6666

6767
Called to generate the list of `syndicate-to` targets to return in response to a query. Returns `$synd_urls`, an array, possibly modified. This filter is empty by default
6868

@@ -207,6 +207,11 @@ into markdown and saved to readme.md.
207207

208208
== Changelog ==
209209

210+
= 2.2.1 (2020-07-31 ) =
211+
* Change category query parameter from search to filter per decision at Micropub Popup Session
212+
* Fix permissions for Media Endpoint to match Endpoint
213+
* For source query on both media and micropub endpoint support offset parameter
214+
210215
= 2.2.0 (2020-07-25 ) =
211216
* Deprecate MICROPUB_LOCAL_AUTH, MICROPUB_AUTHENTICATION_ENDPOINT and MICROPUB_TOKEN_ENDPOINT constants.
212217
* Remove IndieAuth Client code, will now require the IndieAuth or other plugin that does not yet exist.

tests/test_functions.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
/** Unit tests for the Micropub Global Functions.
4+
*/
5+
6+
class MicropubFunctionsTest extends WP_UnitTestCase {
7+
function test_mp_filter() {
8+
$input = array(
9+
'webmention',
10+
'jsonfeed',
11+
'micropub',
12+
'author',
13+
'foo',
14+
'bar',
15+
'indieweb',
16+
'indieweb-goals',
17+
'indienews'
18+
);
19+
$return = mp_filter( $input, 'indie' );
20+
$this->assertEquals(
21+
$return,
22+
array(
23+
'indieweb',
24+
'indieweb-goals',
25+
'indienews'
26+
)
27+
);
28+
}
29+
30+
}

tests/test_media.php

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,7 @@ public function test_media_handle_upload() {
7272
$this->assertInternalType( "int", $id );
7373
}
7474

75-
public function test_upload_file_with_scope() {
76-
static::$scopes = array( 'create' );
77-
add_filter( 'indieauth_scopes', array( get_called_class(), 'scopes' ), 12 );
75+
public function test_upload_file() {
7876
wp_set_current_user( self::$author_id );
7977
$response = rest_get_server()->dispatch( self::upload_request() );
8078
$data = $response->get_data();
@@ -89,8 +87,6 @@ public function test_upload_file_with_scope() {
8987
}
9088

9189
public function test_empty_upload() {
92-
static::$scopes = array( 'create' );
93-
add_filter( 'indieauth_scopes', array( get_called_class(), 'scopes' ), 12 );
9490
wp_set_current_user( self::$author_id );
9591
$request = new WP_REST_Request( 'POST', Micropub_Media::get_rest_route( true ) );
9692
$response = rest_get_server()->dispatch( $request );
@@ -99,22 +95,10 @@ public function test_empty_upload() {
9995
}
10096

10197
public function test_upload_file_without_scope() {
102-
static::$scopes = array();
103-
add_filter( 'indieauth_scopes', array( get_called_class(), 'scopes' ), 12 );
104-
wp_set_current_user( self::$author_id );
105-
$response = rest_get_server()->dispatch( self::upload_request() );
106-
$data = $response->get_data();
107-
$this->assertEquals( 401, $response->get_status(), wp_json_encode( $data ) );
108-
}
109-
110-
public function test_upload_file_with_scope_but_insufficient_permissions() {
111-
static::$scopes = array( 'create' );
112-
add_filter( 'indieauth_scopes', array( get_called_class(), 'scopes' ), 12 );
11398
wp_set_current_user( self::$subscriber_id );
11499
$response = rest_get_server()->dispatch( self::upload_request() );
115100
$data = $response->get_data();
116-
$this->assertEquals( 403, $response->get_status(), wp_json_encode( $data ) );
101+
$this->assertEquals( 401, $response->get_status(), wp_json_encode( $data ) );
117102
}
118103

119-
120104
}

0 commit comments

Comments
 (0)