PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / helpers / FrmFormsListHelper.php

FrmFormsListHelper.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More trunk, at classes/helpers/FrmFormsListHelper.php

830 lines 22.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 class FrmFormsListHelper extends FrmListHelper {
7
8 /**
9 * @var string
10 */
11 public $status = '';
12
13 public $total_items = 0;
14
15 /**
16 * @param array $args
17 */
18 public function __construct( $args ) {
19 $this->status = self::get_param( array( 'param' => 'form_type' ) );
20
21 parent::__construct( $args );
22 $this->screen->set_screen_reader_content(
23 array(
24 'heading_list' => esc_html__( 'Forms list', 'formidable' ),
25 )
26 );
27 }
28
29 /**
30 * @return void
31 */
32 public function prepare_items() {
33 global $per_page, $mode;
34
35 $page = $this->get_pagenum();
36 $per_page = $this->get_items_per_page( 'formidable_page_formidable_per_page' );
37
38 $mode = self::get_param(
39 array(
40 'param' => 'mode',
41 'default' => 'list',
42 )
43 );
44
45 $orderby = self::get_param(
46 array(
47 'param' => 'orderby',
48 'default' => 'name',
49 )
50 );
51 $order = self::get_param(
52 array(
53 'param' => 'order',
54 'default' => 'ASC',
55 )
56 );
57
58 FrmAppController::apply_saved_sort_preference( $orderby, $order );
59
60 $start = self::get_param(
61 array(
62 'param' => 'start',
63 'default' => ( $page - 1 ) * $per_page,
64 )
65 );
66
67 $s_query = array(
68 array(
69 'or' => 1,
70 'parent_form_id' => null,
71 'parent_form_id <' => 1,
72 ),
73 );
74 switch ( $this->status ) {
75 case 'draft':
76 $s_query['is_template'] = 0;
77 $s_query['status'] = 'draft';
78 break;
79 case 'trash':
80 $s_query['status'] = 'trash';
81 break;
82 default:
83 $s_query['is_template'] = 0;
84 $s_query['status !'] = 'trash';
85 break;
86 }
87
88 $s = self::get_param(
89 array(
90 'param' => 's',
91 'sanitize' => 'sanitize_text_field',
92 )
93 );
94
95 if ( $s !== '' ) {
96 preg_match_all( '/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $s, $matches );
97 $search_terms = array_map( 'trim', $matches[0] );
98
99 foreach ( $search_terms as $term ) {
100 $s_query[] = array(
101 'or' => true,
102 'name LIKE' => $term,
103 'description LIKE' => $term,
104 'created_at LIKE' => $term,
105 'form_key LIKE' => $term,
106 'id' => $term,
107 );
108 unset( $term );
109 }
110 }
111
112 $this->items = FrmForm::getAll( $s_query, $orderby . ' ' . $order, $start . ',' . $per_page );
113 $total_items = FrmDb::get_count( 'frm_forms', $s_query );
114 $this->total_items = $total_items;
115
116 $this->set_pagination_args(
117 array(
118 'total_items' => $total_items,
119 'per_page' => $per_page,
120 )
121 );
122 }
123
124 /**
125 * @return void
126 */
127 public function no_items() {
128 $s = self::get_param(
129 array(
130 'param' => 's',
131 'sanitize' => 'sanitize_text_field',
132 )
133 );
134
135 if ( $s !== '' ) {
136 $current_url = set_url_scheme(
137 'http://' . FrmAppHelper::get_server_value( 'HTTP_HOST' ) . FrmAppHelper::get_server_value( 'REQUEST_URI' )
138 );
139 $clear_url = remove_query_arg( 's', $current_url );
140
141 echo '<p>';
142 printf(
143 /* translators: %1$s: Start link HTML, %2$s: End link HTML */
144 esc_html__( 'No forms match your search. %1$sClear search%2$s', 'formidable' ),
145 '<a href="' . esc_url( $clear_url ) . '">',
146 '</a>'
147 );
148 echo '</p>';
149 return;
150 }
151
152 if ( $this->status === 'trash' ) {
153 echo '<p>';
154 esc_html_e( 'No forms found in the trash.', 'formidable' );
155 // phpcs:disable Generic.WhiteSpace.ScopeIndent
156 ?>
157 <a href="<?php echo esc_url( admin_url( 'admin.php?page=formidable' ) ); ?>">
158 <?php esc_html_e( 'See all forms.', 'formidable' ); ?>
159 </a>
160 <?php
161 // phpcs:enable Generic.WhiteSpace.ScopeIndent
162 echo '</p>';
163 } else {
164 $title = __( 'No Forms Found', 'formidable' );
165 include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/_no_forms.php';
166 }
167 }
168
169 public function get_bulk_actions() {
170 $actions = array();
171
172 if ( 'trash' === $this->status ) {
173 if ( current_user_can( 'frm_edit_forms' ) ) {
174 $actions['bulk_untrash'] = __( 'Restore', 'formidable' );
175 }
176
177 if ( current_user_can( 'frm_delete_forms' ) ) {
178 $actions['bulk_delete'] = __( 'Delete Permanently', 'formidable' );
179 }
180 } elseif ( EMPTY_TRASH_DAYS && current_user_can( 'frm_delete_forms' ) ) {
181 $actions['bulk_trash'] = __( 'Move to Trash', 'formidable' );
182 } elseif ( current_user_can( 'frm_delete_forms' ) ) {
183 $actions['bulk_delete'] = __( 'Delete', 'formidable' );
184 }
185
186 return $actions;
187 }
188
189 /**
190 * @param string $which
191 *
192 * @return void
193 */
194 public function extra_tablenav( $which ) {
195 if ( 'top' !== $which ) {
196 return;
197 }
198
199 if ( 'trash' !== $this->status || ! current_user_can( 'frm_delete_forms' ) ) {
200 return;
201 }
202
203 // phpcs:disable Generic.WhiteSpace.ScopeIndent
204 ?>
205 <div class="alignleft actions frm_visible_overflow">
206 <?php submit_button( __( 'Empty Trash', 'formidable' ), 'apply', 'delete_all', false ); ?>
207 </div>
208 <?php
209 // phpcs:enable Generic.WhiteSpace.ScopeIndent
210 }
211
212 /**
213 * @return array
214 */
215 public function get_views() {
216 $statuses = array(
217 'published' => __( 'My Forms', 'formidable' ),
218 'draft' => __( 'Drafts', 'formidable' ),
219 'trash' => __( 'Trash', 'formidable' ),
220 );
221
222 $links = array();
223 $counts = FrmForm::get_count();
224 $form_type = FrmAppHelper::simple_get( 'form_type', 'sanitize_title', 'published' );
225
226 if ( isset( $statuses[ $form_type ] ) ) {
227 $counts->$form_type = $this->total_items;
228 }
229
230 $form_type = self::get_param(
231 array(
232 'param' => 'form_type',
233 'default' => 'published',
234 )
235 );
236
237 foreach ( $statuses as $status => $name ) {
238 $class = $status == $form_type ? ' class="current"' : ''; // phpcs:ignore Universal.Operators.StrictComparisons
239
240 if ( $counts->{$status} || 'draft' !== $status ) {
241 /* translators: %1$s: Status, %2$s: Number of items */
242 $links[ $status ] = '<a href="' . esc_url( '?page=formidable&form_type=' . $status ) . '" ' . $class . '>' . sprintf( __( '%1$s <span class="count">(%2$s)</span>', 'formidable' ), $name, number_format_i18n( $counts->{$status} ) ) . '</a>'; // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
243 }
244
245 unset( $status, $name );
246 }
247
248 return $links;
249 }
250
251 /**
252 * @param stdClass $item
253 * @param string $style
254 *
255 * @return string
256 */
257 public function single_row( $item, $style = '' ) {
258 global $mode;
259
260 // Set up the hover actions for this user
261 $actions = array();
262 $edit_link = FrmForm::get_edit_link( $item->id );
263
264 $this->get_actions( $actions, $item, $edit_link );
265
266 $action_links = $this->row_actions( $actions );
267 $checkbox = $this->get_row_checkbox( $item );
268 $r = '<tr id="item-action-' . absint( $item->id ) . '"' . $style . '>';
269
270 list( $columns, $hidden ) = $this->get_column_info();
271
272 $format = 'Y/m/d';
273
274 if ( 'list' !== $mode ) {
275 $format .= ' \<\b\r \/\> g:i:s a';
276 }
277
278 foreach ( $columns as $column_name => $column_display_name ) {
279 $class = $column_name . ' column-' . $column_name . ( 'name' === $column_name ? ' post-title page-title column-title' : '' );
280 $style = '';
281
282 if ( in_array( $column_name, $hidden, true ) ) {
283 $class .= ' hidden';
284 }
285
286 if ( $column_name === 'name' ) {
287 $class .= ' column-primary';
288 }
289
290 $class = 'class="' . esc_attr( $class ) . '"';
291 $attributes = $class . $style . $this->get_column_data_attr( $column_name, $column_display_name );
292
293 switch ( $column_name ) {
294 case 'cb':
295 $r .= '<th scope="row" class="check-column">' . $checkbox . '</th>';
296 break;
297 case 'id':
298 case 'form_key':
299 $val = $item->{$column_name};
300 break;
301 case 'name':
302 $val = $this->get_form_name( $item, $actions, $edit_link, $mode );
303 $val .= $action_links;
304 break;
305 case 'created_at':
306 $date = gmdate( $format, strtotime( $item->created_at ) );
307 $val = '<abbr title="' . esc_attr( gmdate( 'Y/m/d g:i:s A', strtotime( $item->created_at ) ) ) . '">' . $date . '</abbr>';
308 break;
309 case 'entries':
310 $val = $this->get_entries_column_value( $item );
311 break;
312 default:
313 if ( method_exists( $this, 'column_' . $column_name ) ) {
314 $val = call_user_func( array( $this, 'column_' . $column_name ), $item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
315 }
316 break;
317 }//end switch
318
319 if ( isset( $val ) ) {
320 $r .= "<td $attributes>";
321 $r .= $val;
322 $r .= '</td>';
323 }
324 unset( $val );
325 }//end foreach
326 return $r . '</tr>';
327 }
328
329 /**
330 * @param string $column_name
331 * @param string $column_display_name
332 *
333 * @return string
334 */
335 private function get_column_data_attr( $column_name, $column_display_name ) {
336 if ( 'settings' === $column_name ) {
337 return ' data-colname="' . esc_attr( trim( strip_tags( $column_display_name ) ) ) . '"';
338 }
339 return ' data-colname="' . esc_attr( $column_display_name ) . '"';
340 }
341
342 /**
343 * @param object $item
344 *
345 * @return string
346 */
347 private function get_entries_column_value( $item ) {
348 if ( ! empty( $item->options['no_save'] ) ) {
349 return (string) FrmAppHelper::icon_by_class(
350 'frmfont frm_forbid_icon frm_bstooltip',
351 array(
352 'title' => __( 'Saving entries is disabled for this form', 'formidable' ),
353 'echo' => false,
354 )
355 );
356 }
357
358 $text = intval( FrmEntry::getRecordCount( $item->id ) );
359 return current_user_can( 'frm_view_entries' ) ? '<a href="' . esc_url( admin_url( 'admin.php?page=formidable-entries&form=' . $item->id ) ) . '">' . $text . '</a>' : (string) $text; // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
360 }
361
362 /**
363 * @param object $item
364 *
365 * @return string
366 */
367 private function get_row_checkbox( $item ) {
368 // Set up the checkbox (because the user is editable, otherwise it's empty).
369 $checkbox = '<input type="checkbox" name="item-action[]" id="cb-item-action-' . absint( $item->id ) . '" value="' . esc_attr( $item->id ) . '" />';
370 $checkbox_label_text = sprintf(
371 // translators: Form title
372 __( 'Select %s', 'formidable' ),
373 ! empty( $item->name ) ? $item->name : FrmFormsHelper::get_no_title_text()
374 );
375
376 return $checkbox . '<label for="cb-item-action-' . absint( $item->id ) . '"><span class="screen-reader-text">' . esc_html( $checkbox_label_text ) . '</span></label>';
377 }
378
379 /**
380 * Get the HTML for the Actions column in the form list.
381 * This includes multiple icons for triggering the embed modal, the visual styler, and an active landing page.
382 *
383 * @since 6.0
384 * @deprecated 6.32 We moved these actions to other places. This column will show if there is a filter added to the hook.
385 *
386 * @param stdClass $form
387 *
388 * @return string
389 */
390 protected function column_shortcode( $form ) {
391 $val = '<a href="#" class="frm-embed-form" role="button" aria-label="' . esc_attr__( 'Embed Form', 'formidable' ) . '">' . FrmAppHelper::icon_by_class( 'frmfont frm_code_icon', array( 'echo' => false ) ) . '</a>'; // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
392 $val .= $this->column_style( $form );
393 $val .= $this->column_views( $form );
394 $val = apply_filters( 'frm_form_list_actions', $val, array( 'form' => $form ) );
395 // Remove the space hard coded in Landing pages.
396 $val = str_replace( '&nbsp;', '', $val );
397 return '<div>' . $val . '</div>';
398 }
399
400 /**
401 * Get the HTML for the Style column in the form list.
402 *
403 * @since 6.0
404 *
405 * @param stdClass $form
406 *
407 * @return string
408 */
409 protected function column_style( $form ) {
410 $style_setting = $form->options['custom_style'] ?? '';
411 $frm_settings = FrmAppHelper::get_settings();
412
413 if ( $style_setting === '0' || 'none' === $frm_settings->load_style ) {
414 // Don't show a link if styling is off.
415 return '';
416 }
417
418 $style = FrmStylesController::get_form_style( $form );
419
420 if ( ! $style ) {
421 // Do a second pass to avoid null values.
422 $frm_style = new FrmStyle( 'default' );
423 $style = $frm_style->get_one();
424 }
425
426 $href = FrmStylesHelper::get_edit_url( $style, $form->id );
427 return '<a href="' . esc_url( $href ) . '" title="' . esc_attr( $style->post_title ) . '">' . FrmAppHelper::icon_by_class( 'frmfont frm_pallet_icon', array( 'echo' => false ) ) . '</a>'; // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
428 }
429
430 /**
431 * Generate the HTML for the form Views page.
432 *
433 * @since 6.19
434 *
435 * @param stdClass $form Form object.
436 *
437 * @return string
438 */
439 protected function column_views( $form ) {
440 $attributes = array(
441 'href' => admin_url( 'admin.php?page=formidable-views&form=' . absint( $form->id ) . '&show_nav=1' ),
442 'title' => __( 'Link to list of all views for this form.', 'formidable' ),
443 'target' => '_blank',
444 );
445
446 if ( class_exists( 'FrmViewsDisplay' ) ) {
447 $view_ids = FrmViewsDisplay::get_display_ids_by_form( $form->id );
448 $view_count = $view_ids ? count( $view_ids ) : 0;
449 } else {
450 $view_count = 0;
451 }
452
453 // phpcs:disable Generic.WhiteSpace.ScopeIndent
454 return '<a ' . FrmAppHelper::array_to_html_params( $attributes ) . '>
455 ' . intval( $view_count ) .
456 '</a>';
457 // phpcs:enable Generic.WhiteSpace.ScopeIndent
458 }
459
460 /**
461 * Get the HTML for the Settings column in the form list.
462 *
463 * @since 6.32
464 *
465 * @return string
466 */
467 protected function column_settings() {
468 return '&nbsp;';
469 }
470
471 /**
472 * @param array $actions
473 * @param object $item
474 * @param string $edit_link
475 *
476 * @return void
477 */
478 private function get_actions( &$actions, $item, $edit_link ) {
479 $new_actions = FrmFormsHelper::get_action_links( $item->id, $item );
480
481 foreach ( $new_actions as $link => $action ) {
482 $new_actions[ $link ] = FrmFormsHelper::format_link_html( $action, 'short' );
483 }
484
485 if ( 'trash' === $this->status ) {
486 $actions = $new_actions;
487 return;
488 }
489
490 if ( current_user_can( 'frm_edit_forms' ) ) {
491 $actions['frm_edit'] = '<a href="' . esc_url( $edit_link ) . '">' . esc_html__( 'Edit', 'formidable' ) . '</a>';
492 $actions['frm_settings'] = '<a href="' . esc_url( '?page=formidable&frm_action=settings&id=' . $item->id ) . '">' . esc_html__( 'Settings', 'formidable' ) . '</a>';
493 }
494
495 $actions = array_merge( $actions, $new_actions );
496 $actions['embed'] = '<a href="#" class="frm-embed-form" role="button" aria-label="' . esc_attr__( 'Embed Form', 'formidable' ) . '">' . esc_html__( 'Embed', 'formidable' ) . '</a>'; // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
497 $actions['view'] = '<a href="' . esc_url( FrmFormsHelper::get_direct_link( $item->form_key, $item ) ) . '" target="_blank">' . esc_html__( 'Preview', 'formidable' ) . '</a>'; // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
498 }
499
500 /**
501 * @param object $item
502 * @param array $actions
503 * @param string $edit_link
504 * @param string $mode
505 *
506 * @return string
507 */
508 private function get_form_name( $item, $actions, $edit_link, $mode = 'list' ) {
509 $form_name = $item->name;
510
511 if ( is_null( $form_name ) || trim( $form_name ) === '' ) {
512 $form_name = FrmFormsHelper::get_no_title_text();
513 }
514
515 $form_name = FrmAppHelper::kses( $form_name );
516
517 if ( 'excerpt' !== $mode ) {
518 $form_name = FrmAppHelper::truncate( $form_name, 50 );
519 }
520
521 $val = '<strong>';
522
523 if ( 'trash' === $this->status ) {
524 $val .= $form_name;
525 } else {
526 $val .= '<a href="' . esc_url( isset( $actions['frm_edit'] ) ? $edit_link : FrmFormsHelper::get_direct_link( $item->form_key, $item ) ) . '" class="row-title">' . FrmAppHelper::kses( $form_name ) . '</a> '; // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
527 }
528
529 $this->add_draft_label( $item, $val );
530 $val .= '</strong>';
531
532 $this->add_form_description( $item, $val );
533
534 return $val;
535 }
536
537 /**
538 * @param object $item
539 * @param string $val
540 *
541 * @return void
542 */
543 private function add_draft_label( $item, &$val ) {
544 if ( 'draft' === $item->status && 'draft' !== $this->status ) {
545 $val .= ' - <span class="post-state">' . esc_html__( 'Draft', 'formidable' ) . '</span>';
546 }
547 }
548
549 /**
550 * @param object $item
551 * @param string $val
552 *
553 * @return void
554 */
555 private function add_form_description( $item, &$val ) {
556 global $mode;
557
558 if ( 'excerpt' === $mode && ! is_null( $item->description ) ) {
559 $val .= FrmAppHelper::truncate( strip_tags( $item->description ), 50 );
560 }
561 }
562
563 /**
564 * @return string
565 */
566 protected function confirm_bulk_delete() {
567 return __( 'ALL selected forms and their entries will be permanently deleted. Want to proceed?', 'formidable' );
568 }
569
570 /**
571 * @param stdClass $form
572 *
573 * @return string
574 */
575 public function column_embeds( $form ) {
576 if ( $this->column_is_hidden( 'embeds' ) ) {
577 // Locating embeds means scanning post_content, so skip it when the column is hidden.
578 return '';
579 }
580
581 $posts = $this->get_posts_contain_form( $form );
582
583 if ( ! $posts ) {
584 return '<span class="frm-forms-list-embeds-zero">0</span>';
585 }
586
587 return FrmAppHelper::clip(
588 function () use ( $posts ) {
589 ?>
590 <a href="#" class="frm-forms-list-embeds-btn" data-posts="<?php echo esc_attr( wp_json_encode( $posts ) ); ?>">
591 <?php
592 FrmAppHelper::icon_by_class( 'frmfont frm_arrowdown6_icon' );
593 echo intval( count( $posts ) );
594 ?>
595 </a>
596 <?php
597 }
598 );
599 }
600
601 /**
602 * Checks if a column is hidden with Screen Options.
603 *
604 * @since 6.35
605 *
606 * @param string $column_name Column name.
607 *
608 * @return bool
609 */
610 private function column_is_hidden( $column_name ) {
611 $column_info = $this->get_column_info();
612
613 if ( ! isset( $column_info[1] ) || ! is_array( $column_info[1] ) ) {
614 return false;
615 }
616
617 return in_array( $column_name, $column_info[1], true );
618 }
619
620 /**
621 * Gets posts or pages that contain the form shortcode.
622 *
623 * @since 6.32
624 *
625 * @param stdClass $form Form object.
626 *
627 * @return array
628 */
629 private function get_posts_contain_form( $form ) {
630 $cached_posts = FrmFormEmbedsHelper::get_cached_posts();
631
632 if ( ! isset( $cached_posts[ $form->id ] ) || ! is_array( $cached_posts[ $form->id ] ) ) {
633 // A single scan covers every form listed on this page, not just this one.
634 $cached_posts = $this->fill_embed_posts_cache( $form );
635 }
636
637 if ( ! isset( $cached_posts[ $form->id ] ) || ! is_array( $cached_posts[ $form->id ] ) ) {
638 return array();
639 }
640
641 // Links and title fallbacks are derived at render time, not stored. get_edit_post_link()
642 // depends on the current user, so caching it in a shared transient would hand one user's
643 // edit link to another, and a permalink cached now goes stale on any slug change.
644 return FrmFormEmbedsHelper::prepare_posts( $cached_posts[ $form->id ] );
645 }
646
647 /**
648 * Scans for embeds once and caches the result for every form listed on the current page.
649 *
650 * @since 6.35
651 *
652 * @param stdClass $form The form whose column is currently rendering.
653 *
654 * @return array Embed posts keyed by form ID.
655 */
656 private function fill_embed_posts_cache( $form ) {
657 $cached_posts = FrmFormEmbedsHelper::get_cached_posts();
658 $search_map = array();
659 $forms = array();
660
661 foreach ( $this->get_forms_to_scan( $form ) as $form_id => $form_to_scan ) {
662 if ( isset( $cached_posts[ $form_id ] ) && is_array( $cached_posts[ $form_id ] ) ) {
663 continue;
664 }
665
666 $search_map[ $form_id ] = $this->get_search_strings_for_form( $form_id );
667 $forms[ $form_id ] = $form_to_scan;
668 }
669
670 if ( ! $forms ) {
671 return $cached_posts;
672 }
673
674 $matched = FrmFormEmbedsHelper::match_candidate_posts( $search_map );
675
676 foreach ( $forms as $form_id => $form_to_scan ) {
677 $posts = $this->filter_embed_posts( $matched[ $form_id ], $form_to_scan );
678 $cached_posts[ $form_id ] = FrmFormEmbedsHelper::slim_posts( $posts );
679 }
680
681 FrmFormEmbedsHelper::save_cached_posts( $cached_posts );
682
683 return $cached_posts;
684 }
685
686 /**
687 * Gets every form rendered on the current list page, keyed by form ID.
688 *
689 * @since 6.35
690 *
691 * @param stdClass $form The form whose column is currently rendering.
692 *
693 * @return array
694 */
695 private function get_forms_to_scan( $form ) {
696 $forms = array( $form->id => $form );
697
698 if ( ! is_array( $this->items ) ) {
699 return $forms;
700 }
701
702 foreach ( $this->items as $item ) {
703 if ( is_object( $item ) && isset( $item->id ) ) {
704 $forms[ $item->id ] = $item;
705 }
706 }
707
708 return $forms;
709 }
710
711 /**
712 * Applies the frm_get_posts_contain_form filter to a form's embed posts.
713 *
714 * @since 6.35
715 *
716 * @param array $posts Posts that embed the form.
717 * @param stdClass $form Form object.
718 *
719 * @return array
720 */
721 private function filter_embed_posts( $posts, $form ) {
722 /**
723 * @since 6.32
724 *
725 * @param stdClass[] $posts
726 * @param array $args
727 */
728 $filtered_posts = apply_filters( 'frm_get_posts_contain_form', $posts, compact( 'form' ) );
729
730 if ( ! is_array( $filtered_posts ) ) {
731 _doing_it_wrong( 'frm_get_posts_contain_form', 'Filter should return an array.', '6.32' );
732 return $posts;
733 }
734
735 return $filtered_posts;
736 }
737
738 /**
739 * Gets search strings for a form inside a post.
740 *
741 * @since 6.32
742 *
743 * @param int $form_id Form ID.
744 *
745 * @return string[]
746 */
747 protected function get_search_strings_for_form( $form_id ) {
748 return $this->get_base_search_strings_for_form( $form_id );
749 }
750
751 /**
752 * Gets the base search strings for a form inside a post.
753 *
754 * @since 6.32
755 *
756 * @param int $form_id Form ID.
757 *
758 * @return string[]
759 */
760 protected function get_base_search_strings_for_form( $form_id ) {
761 $strings = array(
762 '<!-- wp:formidable/simple-form {"formId":"' . $form_id . '"',
763 );
764
765 // The shortcode renders a form from its key just as happily as from its ID, in either
766 // attribute, so all four spellings have to be searched or those pages never count.
767 $identifiers = array( $form_id );
768 $form_key = FrmForm::get_key_by_id( $form_id );
769
770 if ( $form_key && $form_key !== (string) $form_id ) {
771 $identifiers[] = $form_key;
772 }
773
774 foreach ( $identifiers as $identifier ) {
775 foreach ( array( 'id', 'key' ) as $att ) {
776 $strings[] = '[formidable ' . $att . '=' . $identifier . ']';
777 $strings[] = '[formidable ' . $att . '=' . $identifier . ' ';
778 $strings[] = '[formidable ' . $att . '="' . $identifier . '"';
779 $strings[] = '[formidable ' . $att . "='" . $identifier . "'";
780 }
781 }
782
783 return $strings;
784 }
785
786 /**
787 * Maybe clear the embed posts transient when a post is inserted.
788 *
789 * @since 6.32
790 *
791 * @param int $post_id Post ID.
792 * @param WP_Post $post Post object.
793 * @param bool $update True when an existing post was updated rather than created.
794 *
795 * @return void
796 */
797 public static function maybe_clear_embed_posts_transient( $post_id, $post, $update = false ) {
798 FrmFormEmbedsHelper::maybe_clear_on_insert( $post_id, $post, $update );
799 }
800
801 /**
802 * Maybe clear the embed posts transient when a post is updated.
803 *
804 * @since 6.35
805 *
806 * @param int $post_id Post ID.
807 * @param WP_Post $post_after Post object after the update.
808 * @param WP_Post $post_before Post object before the update.
809 *
810 * @return void
811 */
812 public static function maybe_clear_embed_posts_transient_on_update( $post_id, $post_after, $post_before ) {
813 FrmFormEmbedsHelper::maybe_clear_on_update( $post_id, $post_after, $post_before );
814 }
815
816 /**
817 * Maybe clear the embed posts transient when a post is trashed, untrashed or deleted.
818 *
819 * @since 6.35
820 *
821 * @param int $post_id Post ID.
822 * @param WP_Post|null $post Post object, when the hook provides one.
823 *
824 * @return void
825 */
826 public static function clear_embed_posts_transient_for_post( $post_id, $post = null ) {
827 FrmFormEmbedsHelper::maybe_clear_for_post( $post_id, $post );
828 }
829 }
830