PluginProbe ʕ •ᴥ•ʔ
FrontBlocks for Gutenberg/GeneratePress / ci-artifacts
FrontBlocks for Gutenberg/GeneratePress vci-artifacts
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 1 month ago BackButton.php 7 months ago BeforeAfter.php 1 month ago BlockPatterns.php 4 months ago Carousel.php 1 month ago ContainerEdgeAlignment.php 1 month ago Counter.php 1 month ago Events.php 6 months ago FaqSchema.php 1 month ago FluidTypography.php 4 months ago Gallery.php 8 months ago GravityFormsInline.php 1 month ago Headline.php 1 month ago InsertPost.php 1 month ago ProductCategories.php 8 months ago ReadingProgress.php 7 months ago ReadingTime.php 8 months ago ShapeAnimations.php 1 month ago StackedImages.php 4 months ago StickyColumn.php 1 month ago Testimonials.php 8 months ago TextAnimation.php 1 month ago
InsertPost.php
326 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( 'init', array( $this, 'register_scripts' ) );
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 * Register frontend scripts and styles for conditional enqueueing.
46 *
47 * @return void
48 */
49 public function register_scripts() {
50 wp_register_style(
51 'frontblocks-insert-post',
52 FRBL_PLUGIN_URL . 'assets/insert-post/frontblocks-insert-post.css',
53 array(),
54 FRBL_VERSION
55 );
56 }
57
58 /**
59 * Enqueue block editor assets.
60 *
61 * @return void
62 */
63 public function enqueue_block_editor_assets() {
64 // Enqueue jQuery UI for autocomplete.
65 wp_enqueue_script( 'jquery-ui-autocomplete' );
66 wp_enqueue_style( 'jquery-ui', FRBL_PLUGIN_URL . 'assets/insert-post/jquery-ui.css', array(), '1.13.2' );
67
68 wp_enqueue_script(
69 'frontblocks-insert-post-option',
70 FRBL_PLUGIN_URL . 'assets/insert-post/frontblocks-insert-post-option.js',
71 array( 'wp-blocks', 'wp-element', 'wp-components', 'wp-data', 'wp-edit-post', 'wp-api-fetch', 'jquery', 'jquery-ui-autocomplete' ),
72 FRBL_VERSION,
73 true
74 );
75
76 // Set script translations for JavaScript.
77 wp_set_script_translations(
78 'frontblocks-insert-post-option',
79 'frontblocks'
80 );
81
82 // Localize script with AJAX URL and nonce.
83 wp_localize_script(
84 'frontblocks-insert-post-option',
85 'frblInsertPost',
86 array(
87 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
88 'nonce' => wp_create_nonce( 'frbl_insert_post_nonce' ),
89 )
90 );
91 }
92
93 /**
94 * AJAX callback for searching posts.
95 *
96 * @return void
97 */
98 public function search_posts_callback() {
99 // Verify nonce.
100 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
101 if ( ! wp_verify_nonce( $nonce, 'frbl_insert_post_nonce' ) ) {
102 wp_die( 'Security check failed' );
103 }
104
105 $search_term = sanitize_text_field( wp_unslash( $_POST['search'] ?? '' ) );
106 $post_type = sanitize_text_field( wp_unslash( $_POST['post_type'] ?? 'post' ) );
107
108 if ( empty( $search_term ) ) {
109 wp_send_json_error( 'Search term is required' );
110 }
111
112 $args = array(
113 'post_type' => $post_type,
114 'post_status' => 'publish',
115 'posts_per_page' => 10,
116 's' => $search_term,
117 'orderby' => 'title',
118 'order' => 'ASC',
119 );
120
121 $query = new \WP_Query( $args );
122 $posts = array();
123
124 if ( $query->have_posts() ) {
125 while ( $query->have_posts() ) {
126 $query->the_post();
127 $posts[] = array(
128 'id' => get_the_ID(),
129 'title' => get_the_title(),
130 'type' => get_post_type(),
131 );
132 }
133 wp_reset_postdata();
134 }
135
136 wp_send_json_success( $posts );
137 }
138
139 /**
140 * Register the Insert Post block.
141 *
142 * @return void
143 */
144 public function register_insert_post_block() {
145 register_block_type(
146 'frontblocks/insert-post',
147 array(
148 'editor_script' => 'frontblocks-insert-post-option',
149 'render_callback' => array( $this, 'render_insert_post_block' ),
150 'attributes' => array(
151 'selectedPostId' => array(
152 'type' => 'number',
153 'default' => 0,
154 ),
155 'selectedPostType' => array(
156 'type' => 'string',
157 'default' => 'post',
158 ),
159 'selectedPostTitle' => array(
160 'type' => 'string',
161 'default' => '',
162 ),
163 'selectedPostContent' => array(
164 'type' => 'string',
165 'default' => '',
166 ),
167 'className' => array(
168 'type' => 'string',
169 'default' => '',
170 ),
171 ),
172 )
173 );
174 }
175
176 /**
177 * Render the Insert Post block on frontend.
178 *
179 * @param array $attributes Block attributes.
180 * @return string HTML output.
181 */
182 public function render_insert_post_block( $attributes ) {
183 // Enqueue frontend styles only when this block is rendered.
184 if ( ! wp_style_is( 'frontblocks-insert-post', 'enqueued' ) ) {
185 wp_enqueue_style( 'frontblocks-insert-post' );
186 }
187
188 $post_id = $attributes['selectedPostId'] ?? 0;
189
190 if ( ! $post_id ) {
191 return '<div class="frbl-insert-post-empty">' . __( 'No post selected', 'frontblocks' ) . '</div>';
192 }
193
194 $post = get_post( $post_id );
195
196 if ( ! $post || 'publish' !== $post->post_status ) {
197 return '<div class="frbl-insert-post-error">' . __( 'Selected post not found or not published', 'frontblocks' ) . '</div>';
198 }
199
200 $title = get_the_title( $post_id );
201 $content = $post->post_content;
202
203 if ( empty( $content ) ) {
204 return '';
205 }
206
207 $wrapper_class = 'frbl-insert-post';
208 if ( ! empty( $attributes['className'] ) ) {
209 $wrapper_class .= ' ' . esc_attr( $attributes['className'] );
210 }
211
212 ob_start();
213 ?>
214 <div class="<?php echo esc_attr( $wrapper_class ); ?>">
215 <?php if ( ! empty( $title ) ) : ?>
216 <h2 class="frbl-insert-post-title"><?php echo esc_html( $title ); ?></h2>
217 <?php endif; ?>
218
219 <div class="frbl-insert-post-content">
220 <?php echo wp_kses_post( apply_filters( 'the_content', $content ) ); ?>
221 </div>
222 </div>
223 <?php
224 return ob_get_clean();
225 }
226
227 /**
228 * Add insert post attributes to grid block.
229 *
230 * @param string $block_content Block content.
231 * @param array $block Block attributes.
232 * @return string
233 */
234 public function add_insert_post_attributes_to_grid_block( $block_content, $block ) {
235 $attrs = $block['attrs'] ?? array();
236 $insert_post_enabled = isset( $attrs['frblInsertPostEnabled'] ) ? (bool) $attrs['frblInsertPostEnabled'] : false;
237
238 if ( $insert_post_enabled ) {
239 // Add data attribute to indicate insert post functionality.
240 $block_content = preg_replace(
241 '/<div([^>]*)class="([^"]*gb-grid-wrapper[^"]*)"([^>]*)>/',
242 '<div$1class="$2 frbl-insert-post-grid"$3 data-insert-post="true">',
243 $block_content,
244 1
245 );
246 }
247
248 return $block_content;
249 }
250
251 /**
252 * Register custom attributes for blocks.
253 *
254 * @return void
255 */
256 public function register_custom_attributes() {
257 add_filter(
258 'generateblocks_blocks_registered_block',
259 array( $this, 'register_insert_post_attributes_for_grid_block' ),
260 9,
261 2
262 );
263
264 add_action(
265 'enqueue_block_editor_assets',
266 array( $this, 'add_inline_script_for_attributes' )
267 );
268 }
269
270 /**
271 * Register insert post attributes for GenerateBlocks Grid block.
272 *
273 * @param array $block_args The block arguments.
274 * @param string $block_type The name of the block.
275 * @return array Modified block arguments.
276 */
277 public function register_insert_post_attributes_for_grid_block( $block_args, $block_type ) {
278 if ( 'generateblocks/grid' !== $block_type ) {
279 return $block_args;
280 }
281
282 if ( ! isset( $block_args['attributes'] ) ) {
283 $block_args['attributes'] = array();
284 }
285
286 $block_args['attributes']['frblInsertPostEnabled'] = array(
287 'type' => 'boolean',
288 'default' => false,
289 );
290
291 return $block_args;
292 }
293
294 /**
295 * Add inline script for block attributes.
296 *
297 * @return void
298 */
299 public function add_inline_script_for_attributes() {
300 wp_add_inline_script(
301 'wp-blocks',
302 "
303 wp.hooks.addFilter(
304 'blocks.registerBlockType',
305 'frontblocks/insert-post-grid-attributes',
306 function( settings, name ) {
307 if ( name !== 'generateblocks/grid' ) {
308 return settings;
309 }
310
311 settings.attributes = {
312 ...settings.attributes,
313 frblInsertPostEnabled: {
314 type: 'boolean',
315 default: false
316 }
317 };
318
319 return settings;
320 }
321 );
322 "
323 );
324 }
325 }
326