PluginProbe
ActivityPub / 7.7.0
ActivityPub v7.7.0
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 / build / reactions / render.php

render.php in ActivityPub 7.7.0, at build/reactions/render.php

220 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Server-side rendering of the `activitypub/reactions` block.
4 *
5 * @package ActivityPub
6 */
7
8 use Activitypub\Blocks;
9 use Activitypub\Comment;
10
11 use function Activitypub\is_activitypub_request;
12
13 if ( is_activitypub_request() || is_feed() ) {
14 return;
15 }
16
17 /* @var array $attributes Block attributes. */
18 $attributes = wp_parse_args( $attributes, array( 'align' => null ) );
19
20 /* @var \WP_Block $block Current block. */
21 $block = $block ?? '';
22
23 /* @var string $content Block content. */
24 $content = $content ?? '';
25
26 if ( empty( $content ) ) {
27 // Fallback for v1.0.0 blocks.
28 $_title = $attributes['title'] ?? __( 'Fediverse Reactions', 'activitypub' );
29 $content = '<h6 class="wp-block-heading">' . esc_html( $_title ) . '</h6>';
30 unset( $attributes['title'], $attributes['className'] );
31 } else {
32 $content = implode( PHP_EOL, wp_list_pluck( $block->parsed_block['innerBlocks'], 'innerHTML' ) );
33 }
34
35 // Get the Post ID from attributes or use the current post.
36 $_post_id = $attributes['postId'] ?? get_the_ID();
37
38 // Generate a unique ID for the block.
39 $block_id = 'activitypub-reactions-block-' . wp_unique_id();
40
41 $reactions = array();
42
43 foreach ( Comment::get_comment_types() as $_type => $type_object ) {
44 $_comments = get_comments(
45 array(
46 'post_id' => $_post_id,
47 'type' => $_type,
48 'status' => 'approve',
49 'parent' => 0,
50 )
51 );
52
53 if ( empty( $_comments ) ) {
54 continue;
55 }
56
57 $count = count( $_comments );
58 // phpcs:disable WordPress.WP.I18n
59 $label = sprintf(
60 _n(
61 $type_object['count_single'],
62 $type_object['count_plural'],
63 $count,
64 'activitypub'
65 ),
66 number_format_i18n( $count )
67 );
68 // phpcs:enable WordPress.WP.I18n
69
70 $reactions[ $_type ] = array(
71 'label' => $label,
72 'count' => $count,
73 'items' => array_map(
74 function ( $comment ) {
75 return array(
76 'name' => html_entity_decode( $comment->comment_author ),
77 'url' => $comment->comment_author_url,
78 'avatar' => get_avatar_url( $comment ),
79 );
80 },
81 $_comments
82 ),
83 );
84 }
85
86 if ( empty( $reactions ) ) {
87 echo '<!-- Reactions block: No reactions found. -->';
88 return;
89 }
90
91 // Set up the Interactivity API config.
92 wp_interactivity_config(
93 'activitypub/reactions',
94 array(
95 'defaultAvatarUrl' => ACTIVITYPUB_PLUGIN_URL . 'assets/img/mp.jpg',
96 'namespace' => ACTIVITYPUB_REST_NAMESPACE,
97 )
98 );
99
100 // Set up the Interactivity API state.
101 wp_interactivity_state( 'activitypub/reactions', array( 'reactions' => array( $_post_id => $reactions ) ) );
102
103 // Render a subset of the most recent reactions.
104 $reactions = array_map(
105 function ( $reaction ) use ( $attributes ) {
106 $count = 20;
107 if ( 'wide' === $attributes['align'] ) {
108 $count = 40;
109 } elseif ( 'full' === $attributes['align'] ) {
110 $count = 60;
111 }
112
113 $reaction['items'] = array_slice( array_reverse( $reaction['items'] ), 0, $count );
114
115 return $reaction;
116 },
117 $reactions
118 );
119
120 // Initialize the context for the block.
121 $context = array(
122 'blockId' => $block_id,
123 'modal' => array(
124 'isCompact' => true,
125 'isOpen' => false,
126 'items' => array(),
127 ),
128 'postId' => $_post_id,
129 'reactions' => $reactions,
130 );
131
132 // Add the block wrapper attributes.
133 $wrapper_attributes = get_block_wrapper_attributes(
134 array(
135 'id' => $block_id,
136 'data-wp-interactive' => 'activitypub/reactions',
137 'data-wp-context' => wp_json_encode( $context, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ),
138 'data-wp-init' => 'callbacks.initReactions',
139 )
140 );
141
142 ob_start();
143 ?>
144 <ul class="reactions-list">
145 <template data-wp-each="context.modal.items">
146 <li class="reaction-item">
147 <a data-wp-bind--href="context.item.url" target="_blank" rel="noopener noreferrer">
148 <img
149 alt=""
150 data-wp-bind--alt="context.item.name"
151 data-wp-bind--src="context.item.avatar"
152 data-wp-on--error="callbacks.setDefaultAvatar"
153 src=""
154 />
155 <span class="reaction-name" data-wp-text="context.item.name"></span>
156 </a>
157 </li>
158 </template>
159 </ul>
160 <?php
161 $modal_content = ob_get_clean();
162
163 ?>
164
165 <div <?php echo $wrapper_attributes; // phpcs:ignore WordPress.Security.EscapeOutput ?>>
166 <?php echo $content; // phpcs:ignore WordPress.Security.EscapeOutput ?>
167
168 <div class="activitypub-reactions">
169 <?php
170 foreach ( $reactions as $_type => $reaction ) :
171 /* translators: %s: reaction type. */
172 $aria_label = sprintf( __( 'View all %s', 'activitypub' ), Comment::get_comment_type_attr( $_type, 'label' ) );
173 ?>
174 <div class="reaction-group" data-reaction-type="<?php echo esc_attr( $_type ); ?>">
175 <ul class="reaction-avatars">
176 <template data-wp-each="context.reactions.<?php echo esc_attr( $_type ); ?>.items">
177 <li>
178 <a
179 data-wp-bind--href="context.item.url"
180 data-wp-bind--title="context.item.name"
181 target="_blank"
182 rel="noopener noreferrer"
183 >
184 <img
185 data-wp-bind--src="context.item.avatar"
186 data-wp-bind--alt="context.item.name"
187 data-wp-on--error="callbacks.setDefaultAvatar"
188 class="reaction-avatar"
189 height="32"
190 width="32"
191 src=""
192 alt=""
193 />
194 </a>
195 </li>
196 </template>
197 </ul>
198 <button
199 class="reaction-label wp-element-button"
200 data-reaction-type="<?php echo esc_attr( $_type ); ?>"
201 data-wp-on--click="actions.toggleModal"
202 aria-label="<?php echo esc_attr( $aria_label ); ?>"
203 >
204 <?php echo esc_html( $reaction['label'] ); ?>
205 </button>
206 </div>
207 <?php endforeach; ?>
208 </div>
209
210 <?php
211 // Render the modal using the Blocks class.
212 Blocks::render_modal(
213 array(
214 'is_compact' => true,
215 'content' => $modal_content,
216 )
217 );
218 ?>
219 </div>
220