-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathctlt-rss-block.php
241 lines (210 loc) · 6.69 KB
/
ctlt-rss-block.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
<?php
/**
* Plugin Name: WP RSS Block
* Description: Allow users to display external RSS feed on a page.
* Requires at least: 6.5
* Requires PHP: 8.2
* Version: 1.0.2
* Author: Kelvin Xu
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: ctlt-rss-block
* Requires Plugins: ubc-wp-api-innerblocks
*
* @package ctlt-rss-block
*/
namespace UBC\CTLT\Block\RSS;
/**
* Registers the block using the metadata loaded from the `block.json` file.
* Behind the scenes, it registers also all assets so they can be enqueued
* through the block editor in the corresponding context.
*
* @see https://developer.wordpress.org/reference/functions/register_block_type/
*/
function register_block() {
/**
* Register the blocks within the plugin based on the directory structure.
* WordPress will search the blocks/build folder to locate the blocks.
*/
$blocks = array(
'core' => array(
'rss' => array(
'skip_inner_blocks' => true,
),
),
'inner' => array(
// Custom Inner Blocks belongs to the plugin.
),
);
foreach ( $blocks as $block_type_dir => $block_type ) {
foreach ( $block_type as $dir => $args ) {
register_block_type_from_metadata( __DIR__ . '/blocks/build/' . $block_type_dir . '/' . $dir, $args );
}
}
}
/**
* This function does couple of things.
*
* 1. Adds 'ubc/api-template' as an ancestor block to the innerblocks that you would like to activate.
* 2. Adds 'ubc/ctlt-rss' as a parent block of the pagination block and template block.
*
* @param array $metadata The metadata of the block.
* @return array The updated metadata with added ancestor block.
*/
function add_support_ubc_inner_blocks( $metadata ) {
if ( 'ubc/api-pagination' === $metadata['name'] || 'ubc/api-template' === $metadata['name'] || 'ubc/api-no-results' === $metadata['name'] ) {
$metadata['parent'][] = 'ubc/ctlt-rss';
}
$supported_inner_blocks = apply_filters(
'wpapi_filter_supported_inner_blocks',
array(
'ubc/api-title',
'ubc/api-terms',
'ubc/api-excerpt',
'ubc/api-content',
'ubc/api-datetime',
'ubc/api-image',
),
'ubc/ctlt-rss'
);
if ( in_array( $metadata['name'], $supported_inner_blocks ) ) {
if ( ! array_key_exists( 'ancestor', $metadata ) ) {
$metadata['ancestor'] = array();
}
$metadata['ancestor'][] = 'ubc/api-template';
}
return $metadata;
}
/**
* Ajax handler to fetch RSS feed.
*/
function ajax_fetch_rss() {
if ( ! isset( $_POST['source'] ) || ! isset( $_POST['per_page'] ) || ! isset( $_POST['current_page'] ) || ! isset( $_POST['offset'] ) ) {
wp_send_json_error();
}
$source = json_decode( wp_unslash( $_POST['source'] ), true );
$per_page = absint( $_POST['per_page'] );
$current_page = absint( $_POST['current_page'] );
$offset = absint( $_POST['offset'] );
$content = fetch_rss( $source, $per_page, $current_page, $offset );
wp_send_json_success( $content );
}
/**
* Ajax handler to clear transient cache generated by fetch_feed method.
*/
function ajax_reset_rss_caches() {
if ( ! isset( $_POST['source'] ) ) {
wp_send_json_error();
}
$source = esc_url( $_POST['source'] );
$md5_of_feed_url = md5( $source );
delete_transient( 'feed_' . $md5_of_feed_url );
delete_transient( 'feed_mod_' . $md5_of_feed_url );
wp_send_json_success();
}//end ajax_reset_rss_caches()
/**
* Initiate API request. Fetch and format RSS feed content for context needs.
*
* @param string $source The URL of the RSS feed.
* @param int $per_page The number of items to fetch per page.
* @param int $current_page The current page number.
* @param int $offset The number of items to skip.
* @return array An array containing the maximum number of items and an array of items.
*/
function fetch_rss( $source, $per_page, $current_page, $offset ) {
include_once ABSPATH . WPINC . '/feed.php';
$feed = fetch_feed( $source );
if ( is_wp_error( $feed ) ) {
return array();
}
// Figure out how many total items there are.
$maxitems = $feed->get_item_quantity() - $offset;
// Build an array of all the items.
$rss_items = $feed->get_items( ( $current_page - 1 ) * $per_page + $offset, $per_page );
$rss_items = array_map(
function ( $rss_item ) {
return apply_filters(
'wpapi_filter_item_context',
array(
'id' => $rss_item->get_id(),
'name' => $rss_item->get_title(),
'author' => $rss_item->get_author(),
'link' => $rss_item->get_permalink(),
'excerpt' => $rss_item->get_description(),
'description' => $rss_item->get_content(),
'terms' => format_terms( $rss_item->get_categories(), 'type' ),
'datetimes' => array(
array(
'label' => 'published_date',
'value' => $rss_item->get_gmdate( 'Y-m-d H:i:s' ),
),
),
'images' => $rss_item->get_enclosure() ? array(
array(
'label' => 'feed_item_image',
'src' => $rss_item->get_enclosure()->get_link(),
),
) : array(),
),
'ubc/ctlt-rss',
$rss_item,
);
},
$rss_items
);
return array(
'maxitems' => $maxitems,
'items' => $rss_items,
);
}
/**
* Group terms based on taxonomy type. Format the terms based on context needs.
*
* @param array $terms The array of terms to be formatted.
* @param string $field The field to group the terms by.
* @return array The formatted array of terms.
*/
function format_terms( $terms, $field ) {
// Group items by field.
$grouped_items = array();
foreach ( $terms as $term ) {
$term = (array) $term;
$field_key = $term[ $field ];
if ( ! isset( $grouped_items[ $field_key ] ) ) {
$grouped_items[ $field_key ] = array();
}
$grouped_items[ $field_key ][] = $term;
}
// Convert the grouped items to an array of objects.
$result = array();
foreach ( $grouped_items as $field_key => $terms_array ) {
$result[] = array(
'taxonomy' => $field_key,
'terms' => $terms_array,
);
}
// Map over the result to format the terms.
$result = array_map(
function ( $group ) {
$group['terms'] = array_map(
function ( $term, $index ) {
return array(
'id' => $index,
'name' => $term['term'],
'link' => '',
);
},
$group['terms'],
array_keys( $group['terms'] )
);
return $group;
},
$result
);
return $result;
}
/*-----------------------------------------------------------------------------------*/
add_action( 'wp_ajax_fetch_rss', __NAMESPACE__ . '\\ajax_fetch_rss' );
add_action( 'wp_ajax_reset_rss_caches', __NAMESPACE__ . '\\ajax_reset_rss_caches' );
add_filter( 'block_type_metadata', __NAMESPACE__ . '\\add_support_ubc_inner_blocks' );
add_action( 'init', __NAMESPACE__ . '\\register_block' );