PluginProbe
ActivityPub / 1.0.3
ActivityPub v1.0.3
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
activitypub / includes / class-blocks.php

class-blocks.php in ActivityPub 1.0.3, at includes/class-blocks.php

152 lines 5.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Activitypub;
3
4 use Activitypub\Collection\Followers;
5 use Activitypub\Collection\Users as User_Collection;
6 use Activitypub\is_user_type_disabled;
7
8 class Blocks {
9 public static function init() {
10 // this is already being called on the init hook, so just add it.
11 self::register_blocks();
12 \add_action( 'wp_enqueue_scripts', array( self::class, 'add_data' ) );
13 \add_action( 'enqueue_block_editor_assets', array( self::class, 'add_data' ) );
14 }
15
16 public static function add_data() {
17 $context = is_admin() ? 'editor' : 'view';
18 $followers_handle = 'activitypub-followers-' . $context . '-script';
19 $follow_me_handle = 'activitypub-follow-me-' . $context . '-script';
20 $data = array(
21 'namespace' => ACTIVITYPUB_REST_NAMESPACE,
22 'enabled' => array(
23 'site' => ! is_user_type_disabled( 'blog' ),
24 'users' => ! is_user_type_disabled( 'user' ),
25 ),
26 );
27 $js = sprintf( 'var _activityPubOptions = %s;', wp_json_encode( $data ) );
28 \wp_add_inline_script( $followers_handle, $js, 'before' );
29 \wp_add_inline_script( $follow_me_handle, $js, 'before' );
30 }
31
32 public static function register_blocks() {
33 \register_block_type_from_metadata(
34 ACTIVITYPUB_PLUGIN_DIR . '/build/followers',
35 array(
36 'render_callback' => array( self::class, 'render_follower_block' ),
37 )
38 );
39 \register_block_type_from_metadata(
40 ACTIVITYPUB_PLUGIN_DIR . '/build/follow-me',
41 array(
42 'render_callback' => array( self::class, 'render_follow_me_block' ),
43 )
44 );
45 }
46
47 private static function get_user_id( $user_string ) {
48 if ( is_numeric( $user_string ) ) {
49 return absint( $user_string );
50 }
51 // any other non-numeric falls back to 0, including the `site` string used in the UI
52 return 0;
53 }
54
55 /**
56 * Filter an array by a list of keys.
57 * @param array $array The array to filter.
58 * @param array $keys The keys to keep.
59 * @return array The filtered array.
60 */
61 protected static function filter_array_by_keys( $array, $keys ) {
62 return array_intersect_key( $array, array_flip( $keys ) );
63 }
64
65 /**
66 * Render the follow me block.
67 * @param array $attrs The block attributes.
68 * @return string The HTML to render.
69 */
70 public static function render_follow_me_block( $attrs ) {
71 $user_id = self::get_user_id( $attrs['selectedUser'] );
72 $user = User_Collection::get_by_id( $user_id );
73 if ( ! is_wp_error( $user ) ) {
74 $attrs['profileData'] = self::filter_array_by_keys(
75 $user->to_array(),
76 array( 'icon', 'name', 'resource' )
77 );
78 }
79 $wrapper_attributes = get_block_wrapper_attributes(
80 array(
81 'aria-label' => __( 'Follow me on the Fediverse', 'activitypub' ),
82 'class' => 'activitypub-follow-me-block-wrapper',
83 'data-attrs' => wp_json_encode( $attrs ),
84 )
85 );
86 // todo: render more than an empty div?
87 return '<div ' . $wrapper_attributes . '></div>';
88 }
89
90 public static function render_follower_block( $attrs ) {
91 $followee_user_id = self::get_user_id( $attrs['selectedUser'] );
92 $per_page = absint( $attrs['per_page'] );
93 $follower_data = Followers::get_followers_with_count( $followee_user_id, $per_page );
94
95 $attrs['followerData']['total'] = $follower_data['total'];
96 $attrs['followerData']['followers'] = array_map(
97 function( $follower ) {
98 return self::filter_array_by_keys(
99 $follower->to_array(),
100 array( 'icon', 'name', 'preferredUsername', 'url' )
101 );
102 },
103 $follower_data['followers']
104 );
105 $wrapper_attributes = get_block_wrapper_attributes(
106 array(
107 'aria-label' => __( 'Fediverse Followers', 'activitypub' ),
108 'class' => 'activitypub-follower-block',
109 'data-attrs' => wp_json_encode( $attrs ),
110 )
111 );
112
113 $html = '<div ' . $wrapper_attributes . '>';
114 if ( $attrs['title'] ) {
115 $html .= '<h3>' . esc_html( $attrs['title'] ) . '</h3>';
116 }
117 $html .= '<ul>';
118 foreach ( $follower_data['followers'] as $follower ) {
119 $html .= '<li>' . self::render_follower( $follower ) . '</li>';
120 }
121 // We are only pagination on the JS side. Could be revisited but we gotta ship!
122 $html .= '</ul></div>';
123 return $html;
124 }
125
126 public static function render_follower( $follower ) {
127 $external_svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" class="components-external-link__icon css-rvs7bx esh4a730" aria-hidden="true" focusable="false"><path d="M18.2 17c0 .7-.6 1.2-1.2 1.2H7c-.7 0-1.2-.6-1.2-1.2V7c0-.7.6-1.2 1.2-1.2h3.2V4.2H7C5.5 4.2 4.2 5.5 4.2 7v10c0 1.5 1.2 2.8 2.8 2.8h10c1.5 0 2.8-1.2 2.8-2.8v-3.6h-1.5V17zM14.9 3v1.5h3.7l-6.4 6.4 1.1 1.1 6.4-6.4v3.7h1.5V3h-6.3z"></path></svg>';
128 $template =
129 '<a href="%s" title="%s" class="components-external-link activitypub-link" target="_blank" rel="external noreferrer noopener">
130 <img width="40" height="40" src="%s" class="avatar activitypub-avatar" />
131 <span class="activitypub-actor">
132 <strong class="activitypub-name">%s</strong>
133 <span class="sep">/</span>
134 <span class="activitypub-handle">@%s</span>
135 </span>
136 %s
137 </a>';
138
139 $data = $follower->to_array();
140
141 return sprintf(
142 $template,
143 esc_url( $data['url'] ),
144 esc_attr( $data['name'] ),
145 esc_attr( $data['icon']['url'] ),
146 esc_html( $data['name'] ),
147 esc_html( $data['preferredUsername'] ),
148 $external_svg
149 );
150 }
151 }
152