PluginProbe ʕ •ᴥ•ʔ
FrontBlocks for Gutenberg/GeneratePress / 1.0.3
FrontBlocks for Gutenberg/GeneratePress v1.0.3
trunk 0.2.0 0.2.1 0.2.2 0.2.3 0.2.4 0.2.5 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1.0 1.2.0 1.2.1 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 ci-artifacts
frontblocks / includes / Frontend / InsertPost.php
frontblocks / includes / Frontend Last commit date
Animations.php 9 months ago Carousel.php 9 months ago Gallery.php 9 months ago InsertPost.php 9 months ago StickyColumn.php 9 months ago Testimonials.php 9 months ago
InsertPost.php
316 lines
1 <?php
2 /**
3 * Insert Post module for FrontBlocks.
4 *
5 * @package FrontBlocks
6 * @author David Perez <david@close.technology>
7 * @copyright 2023 Closemarketing
8 * @version 1.0
9 */
10
11 namespace FrontBlocks\Frontend;
12
13 defined( 'ABSPATH' ) || exit;
14
15 /**
16 * InsertPost class.
17 *
18 * @since 1.0.0
19 */
20 class InsertPost {
21
22 /**
23 * Constructor.
24 */
25 public function __construct() {
26 $this->init_hooks();
27 }
28
29 /**
30 * Initialize hooks.
31 *
32 * @return void
33 */
34 private function init_hooks() {
35 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ), 99 );
36 add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) );
37 add_action( 'wp_ajax_frbl_search_posts', array( $this, 'search_posts_callback' ) );
38 add_action( 'wp_ajax_nopriv_frbl_search_posts', array( $this, 'search_posts_callback' ) );
39 add_action( 'init', array( $this, 'register_insert_post_block' ) );
40 add_filter( 'render_block_generateblocks/grid', array( $this, 'add_insert_post_attributes_to_grid_block' ), 10, 2 );
41 add_action( 'init', array( $this, 'register_custom_attributes' ), 5 );
42 }
43
44 /**
45 * Enqueue scripts and styles.
46 *
47 * @return void
48 */
49 public function enqueue_scripts() {
50 $dist_dir = WP_DEBUG ? 'post/' : 'dist/';
51
52 wp_enqueue_style(
53 'frontblocks-insert-post',
54 FRBL_PLUGIN_URL . 'assets/' . $dist_dir . 'frontblocks-insert-post.css',
55 array(),
56 FRBL_VERSION
57 );
58 }
59
60 /**
61 * Enqueue block editor assets.
62 *
63 * @return void
64 */
65 public function enqueue_block_editor_assets() {
66 // Enqueue jQuery UI for autocomplete.
67 wp_enqueue_script( 'jquery-ui-autocomplete' );
68 wp_enqueue_style( 'jquery-ui', 'https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css' );
69
70 wp_enqueue_script(
71 'frontblocks-insert-post-option',
72 FRBL_PLUGIN_URL . 'assets/dist/frontblocks-insert-post-option.js',
73 array( 'wp-blocks', 'wp-element', 'wp-components', 'wp-data', 'wp-edit-post', 'wp-api-fetch', 'jquery', 'jquery-ui-autocomplete' ),
74 FRBL_VERSION,
75 true
76 );
77
78 // Localize script with AJAX URL and nonce.
79 wp_localize_script(
80 'frontblocks-insert-post-option',
81 'frblInsertPost',
82 array(
83 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
84 'nonce' => wp_create_nonce( 'frbl_insert_post_nonce' ),
85 )
86 );
87 }
88
89 /**
90 * AJAX callback for searching posts.
91 *
92 * @return void
93 */
94 public function search_posts_callback() {
95 // Verify nonce.
96 if ( ! wp_verify_nonce( $_POST['nonce'], 'frbl_insert_post_nonce' ) ) {
97 wp_die( 'Security check failed' );
98 }
99
100 $search_term = sanitize_text_field( $_POST['search'] ?? '' );
101 $post_type = sanitize_text_field( $_POST['post_type'] ?? 'post' );
102
103 if ( empty( $search_term ) ) {
104 wp_send_json_error( 'Search term is required' );
105 }
106
107 $args = array(
108 'post_type' => $post_type,
109 'post_status' => 'publish',
110 'posts_per_page' => 10,
111 's' => $search_term,
112 'orderby' => 'title',
113 'order' => 'ASC',
114 );
115
116 $query = new \WP_Query( $args );
117 $posts = array();
118
119 if ( $query->have_posts() ) {
120 while ( $query->have_posts() ) {
121 $query->the_post();
122 $posts[] = array(
123 'id' => get_the_ID(),
124 'title' => get_the_title(),
125 'type' => get_post_type(),
126 );
127 }
128 wp_reset_postdata();
129 }
130
131 wp_send_json_success( $posts );
132 }
133
134 /**
135 * Register the Insert Post block.
136 *
137 * @return void
138 */
139 public function register_insert_post_block() {
140 register_block_type(
141 'frontblocks/insert-post',
142 array(
143 'editor_script' => 'frontblocks-insert-post-option',
144 'render_callback' => array( $this, 'render_insert_post_block' ),
145 'attributes' => array(
146 'selectedPostId' => array(
147 'type' => 'number',
148 'default' => 0,
149 ),
150 'selectedPostType' => array(
151 'type' => 'string',
152 'default' => 'post',
153 ),
154 'selectedPostTitle' => array(
155 'type' => 'string',
156 'default' => '',
157 ),
158 'selectedPostContent' => array(
159 'type' => 'string',
160 'default' => '',
161 ),
162 'className' => array(
163 'type' => 'string',
164 'default' => '',
165 ),
166 ),
167 )
168 );
169 }
170
171 /**
172 * Render the Insert Post block on frontend.
173 *
174 * @param array $attributes Block attributes.
175 * @return string HTML output.
176 */
177 public function render_insert_post_block( $attributes ) {
178 $post_id = $attributes['selectedPostId'] ?? 0;
179
180 if ( ! $post_id ) {
181 return '<div class="frbl-insert-post-empty">' . __( 'No post selected', 'frontblocks' ) . '</div>';
182 }
183
184 $post = get_post( $post_id );
185
186 if ( ! $post || 'publish' !== $post->post_status ) {
187 return '<div class="frbl-insert-post-error">' . __( 'Selected post not found or not published', 'frontblocks' ) . '</div>';
188 }
189
190 $title = get_the_title( $post_id );
191 $content = $post->post_content;
192
193 if ( empty( $content ) ) {
194 return '';
195 }
196
197 $wrapper_class = 'frbl-insert-post';
198 if ( ! empty( $attributes['className'] ) ) {
199 $wrapper_class .= ' ' . esc_attr( $attributes['className'] );
200 }
201
202 ob_start();
203 ?>
204 <div class="<?php echo esc_attr( $wrapper_class ); ?>">
205 <?php if ( ! empty( $title ) ) : ?>
206 <h2 class="frbl-insert-post-title"><?php echo esc_html( $title ); ?></h2>
207 <?php endif; ?>
208
209 <div class="frbl-insert-post-content">
210 <?php echo apply_filters( 'the_content', $content ); ?>
211 </div>
212 </div>
213 <?php
214 return ob_get_clean();
215 }
216
217 /**
218 * Add insert post attributes to grid block.
219 *
220 * @param string $block_content Block content.
221 * @param array $block Block attributes.
222 * @return string
223 */
224 public function add_insert_post_attributes_to_grid_block( $block_content, $block ) {
225 $attrs = $block['attrs'] ?? array();
226 $insert_post_enabled = isset( $attrs['frblInsertPostEnabled'] ) ? (bool) $attrs['frblInsertPostEnabled'] : false;
227
228 if ( $insert_post_enabled ) {
229 // Add data attribute to indicate insert post functionality.
230 $block_content = preg_replace(
231 '/<div([^>]*)class="([^"]*gb-grid-wrapper[^"]*)"([^>]*)>/',
232 '<div$1class="$2 frbl-insert-post-grid"$3 data-insert-post="true">',
233 $block_content,
234 1
235 );
236 }
237
238 return $block_content;
239 }
240
241 /**
242 * Register custom attributes for blocks.
243 *
244 * @return void
245 */
246 public function register_custom_attributes() {
247 add_filter(
248 'generateblocks_blocks_registered_block',
249 array( $this, 'register_insert_post_attributes_for_grid_block' ),
250 9,
251 2
252 );
253
254 add_action(
255 'enqueue_block_editor_assets',
256 array( $this, 'add_inline_script_for_attributes' )
257 );
258 }
259
260 /**
261 * Register insert post attributes for GenerateBlocks Grid block.
262 *
263 * @param array $block_args The block arguments.
264 * @param string $block_type The name of the block.
265 * @return array Modified block arguments.
266 */
267 public function register_insert_post_attributes_for_grid_block( $block_args, $block_type ) {
268 if ( 'generateblocks/grid' !== $block_type ) {
269 return $block_args;
270 }
271
272 if ( ! isset( $block_args['attributes'] ) ) {
273 $block_args['attributes'] = array();
274 }
275
276 $block_args['attributes']['frblInsertPostEnabled'] = array(
277 'type' => 'boolean',
278 'default' => false,
279 );
280
281 return $block_args;
282 }
283
284 /**
285 * Add inline script for block attributes.
286 *
287 * @return void
288 */
289 public function add_inline_script_for_attributes() {
290 wp_add_inline_script(
291 'wp-blocks',
292 "
293 wp.hooks.addFilter(
294 'blocks.registerBlockType',
295 'frontblocks/insert-post-grid-attributes',
296 function( settings, name ) {
297 if ( name !== 'generateblocks/grid' ) {
298 return settings;
299 }
300
301 settings.attributes = {
302 ...settings.attributes,
303 frblInsertPostEnabled: {
304 type: 'boolean',
305 default: false
306 }
307 };
308
309 return settings;
310 }
311 );
312 "
313 );
314 }
315 }
316