Skip to content

Commit 13b296e

Browse files
committed
Add hashtag follow support.
1 parent d9b2960 commit 13b296e

File tree

1 file changed

+181
-1
lines changed

1 file changed

+181
-1
lines changed

includes/class-mastodon-api.php

Lines changed: 181 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class Mastodon_API {
3939
const REMOTE_USER_TAXONOMY = 'mastodon-api-remote-user';
4040
const CPT = 'enable-mastodon-apps';
4141

42+
const FOLLOW_HASHTAG_USER_META_KEY = 'enable-mastodon-apps-tags-followed';
43+
4244
/**
4345
* Constructor
4446
*/
@@ -161,6 +163,9 @@ public function rewrite_rules() {
161163
'api/v1/timelines/(home|public)' => 'api/v1/timelines/$matches[1]',
162164
'api/v1/timelines/tag/([^/|$]+)' => 'api/v1/timelines/tag/$matches[1]',
163165
'api/v2/search' => 'api/v1/search',
166+
'api/v1/tags/(.+)' => 'api/v1/tags/$matches[1]',
167+
'api/v1/tags/([^/]+)/follow' => 'api/v1/tags/$matches[1]/follow',
168+
'api/v1/tags/([^/]+)/unfollow' => 'api/v1/tags/$matches[1]/unfollow',
164169
);
165170

166171
foreach ( $generic as $rule ) {
@@ -254,7 +259,7 @@ public function add_rest_routes() {
254259
'api/v1/followed_tags',
255260
array(
256261
'methods' => 'GET',
257-
'callback' => '__return_empty_array',
262+
'callback' => array( $this, 'api_followed_tags' ),
258263
'permission_callback' => array( $this, 'logged_in_permission' ),
259264
)
260265
);
@@ -660,6 +665,36 @@ public function add_rest_routes() {
660665
'permission_callback' => array( $this, 'logged_in_permission' ),
661666
)
662667
);
668+
669+
register_rest_route(
670+
self::PREFIX,
671+
'api/v1/tags/(?P<id>[^/]+)',
672+
array(
673+
'methods' => array( 'GET', 'OPTIONS' ),
674+
'callback' => array( $this, 'api_tags' ),
675+
'permission_callback' => array( $this, 'logged_in_permission' ),
676+
)
677+
);
678+
679+
register_rest_route(
680+
self::PREFIX,
681+
'api/v1/tags/(?P<id>[^/]+)/follow',
682+
array(
683+
'methods' => array( 'POST', 'OPTIONS' ),
684+
'callback' => array( $this, 'api_tags_follow' ),
685+
'permission_callback' => array( $this, 'logged_in_permission' ),
686+
)
687+
);
688+
689+
register_rest_route(
690+
self::PREFIX,
691+
'api/v1/tags/(?P<id>[^/]+)/unfollow',
692+
array(
693+
'methods' => array( 'POST', 'OPTIONS' ),
694+
'callback' => array( $this, 'api_tags_unfollow' ),
695+
'permission_callback' => array( $this, 'logged_in_permission' ),
696+
)
697+
);
663698
}
664699

665700
public function query_vars( $query_vars ) {
@@ -2931,4 +2966,149 @@ public function api_instance_v2() {
29312966

29322967
return apply_filters( 'mastodon_api_instance_v2', $ret );
29332968
}
2969+
2970+
public function api_tags( $request ) {
2971+
$token = $this->oauth->get_token();
2972+
$user_id = $token['user_id'];
2973+
$hashtag = $request->get_param( 'id' );
2974+
$followed = $this->check_if_hashtag_followed( $user_id, $hashtag );
2975+
2976+
$term = $this->find_hashtag_term( $hashtag );
2977+
return $this->generate_hashtag_array( $term, array(), $followed );
2978+
}
2979+
2980+
public function api_tags_follow( $request ) {
2981+
$token = $this->oauth->get_token();
2982+
$user_id = $token['user_id'];
2983+
2984+
$tags_followed = get_user_meta( $user_id, self::FOLLOW_HASHTAG_USER_META_KEY, true );
2985+
2986+
if ( false === $tags_followed ) {
2987+
$tags_followed = array();
2988+
} else {
2989+
$tags_followed = unserialize( $tags_followed );
2990+
}
2991+
2992+
$hashtag = $request->get_param( 'id' );
2993+
$term = $this->find_hashtag_term( $hashtag );
2994+
2995+
$tags_followed[ $hashtag ] = true;
2996+
2997+
update_user_meta( $user_id, self::FOLLOW_HASHTAG_USER_META_KEY, serialize( $tags_followed ) );
2998+
2999+
if ( null === $term ) {
3000+
return $this->generate_hashtag_array( '' );
3001+
}
3002+
3003+
return $this->generate_hashtag_array( $term, array(), true );
3004+
}
3005+
3006+
public function api_tags_unfollow( $request ) {
3007+
$token = $this->oauth->get_token();
3008+
$user_id = $token['user_id'];
3009+
3010+
$tags_followed = get_user_meta( $user_id, self::FOLLOW_HASHTAG_USER_META_KEY, true );
3011+
3012+
if ( false === $tags_followed ) {
3013+
$tags_followed = array();
3014+
} else {
3015+
$tags_followed = unserialize( $tags_followed );
3016+
}
3017+
3018+
$hashtag = $request->get_param( 'id' );
3019+
$term = $this->find_hashtag_term( $hashtag );
3020+
3021+
unset( $tags_followed[ $hashtag ] );
3022+
3023+
update_user_meta( $user_id, self::FOLLOW_HASHTAG_USER_META_KEY, serialize( $tags_followed ) );
3024+
3025+
if ( null === $term ) {
3026+
return $this->generate_hashtag_array( '' );
3027+
}
3028+
3029+
return $this->generate_hashtag_array( $term, array() );
3030+
}
3031+
3032+
public function api_followed_tags( $request ) {
3033+
$token = $this->oauth->get_token();
3034+
$user_id = $token['user_id'];
3035+
3036+
$tags_followed = get_user_meta( $user_id, self::FOLLOW_HASHTAG_USER_META_KEY, true );
3037+
3038+
if ( false === $tags_followed ) {
3039+
$tags_followed = array();
3040+
} else {
3041+
$tags_followed = unserialize( $tags_followed );
3042+
}
3043+
3044+
$ret = array();
3045+
foreach ( $tags_followed as $key => $value ) {
3046+
$term = $this->find_hashtag_term( $key );
3047+
$ret[] = $this->generate_hashtag_array( $term, array(), true );
3048+
}
3049+
3050+
return $ret;
3051+
}
3052+
3053+
private function generate_hashtag_array( $term, $history = array(), $following = false ) {
3054+
$ret = array(
3055+
'name' => $term->name,
3056+
'url' => get_term_link( $term ),
3057+
'history' => $history,
3058+
);
3059+
if ( $following ) {
3060+
$ret['following'] = true;
3061+
}
3062+
return $ret;
3063+
}
3064+
3065+
private function get_categories() {
3066+
$args = array(
3067+
'orderby' => 'name',
3068+
'hide_empty' => false,
3069+
);
3070+
return get_categories( $args );
3071+
}
3072+
3073+
private function get_tags() {
3074+
$args = array(
3075+
'orderby' => 'name',
3076+
'hide_empty' => false,
3077+
);
3078+
return get_tags( $args );
3079+
}
3080+
3081+
private function find_hashtag_term( $hashtag ) {
3082+
$tags = $this->get_tags();
3083+
$post_data['tags_input'] = array();
3084+
foreach ( $tags as $tag ) {
3085+
if ( strcmp( $hashtag, $tag->name ) === 0 ) {
3086+
return $tag;
3087+
}
3088+
}
3089+
$categories = $this->get_categories();
3090+
$post_data['post_category'] = array();
3091+
foreach ( $categories as $category ) {
3092+
if ( strcmp( $hashtag, $category->name ) === 0 ) {
3093+
return $category;
3094+
}
3095+
}
3096+
return null;
3097+
}
3098+
3099+
private function check_if_hashtag_followed( $user_id, $hashtag ) {
3100+
$tags_followed = get_user_meta( $user_id, self::FOLLOW_HASHTAG_USER_META_KEY, true );
3101+
3102+
if ( false === $tags_followed ) {
3103+
$tags_followed = array();
3104+
} else {
3105+
$tags_followed = unserialize( $tags_followed );
3106+
}
3107+
3108+
if ( array_key_exists( $hashtag, $tags_followed ) ) {
3109+
return true;
3110+
}
3111+
3112+
return false;
3113+
}
29343114
}

0 commit comments

Comments
 (0)