PluginProbe ʕ •ᴥ•ʔ
Atarim – AI Agency for WordPress: Edit Pages, Fix Code, Update Plugins, SEO & Client Feedback / trunk
Atarim – AI Agency for WordPress: Edit Pages, Fix Code, Update Plugins, SEO & Client Feedback vtrunk
5.1.3 5.1.2 5.1.1 5.1 5.0 trunk 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 3.2.0 3.2.1 3.22 3.22.1 3.22.2 3.22.3 3.22.4 3.22.5 3.22.6 3.3.0 3.3.1 3.3.2 3.3.2.1 3.3.2.2 3.3.3 3.30 3.31 3.32 3.4 3.4.1 3.4.3 3.4.4 3.5 3.5.1 3.6 3.6.1 3.7 3.8 3.9 3.9.1 3.9.2 3.9.3 3.9.4 3.9.6 3.9.6.1 4.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.2 4.1.3 4.2 4.2.1 4.2.2 4.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.4
atarim-visual-collaboration / third-party / forms / formidable / class-avcf-formidable-helpers.php
atarim-visual-collaboration / third-party / forms / formidable Last commit date
class-avcf-abilities-formidable-pro.php 3 weeks ago class-avcf-abilities-formidable.php 3 weeks ago class-avcf-formidable-detector.php 1 month ago class-avcf-formidable-helpers.php 3 weeks ago
class-avcf-formidable-helpers.php
182 lines
1 <?php
2 /**
3 * Formidable Forms — shared helpers for the standalone Formidable ability cluster.
4 *
5 * Uses Formidable's stable PHP API for forms/fields/notifications/entries
6 * (FrmForm, FrmField, FrmFormAction, FrmEntry) and direct $wpdb on frm_items
7 * for stats/counts. Entry status lives in the is_draft column: 0 = published,
8 * 1 = draft, 2 = spam. Entries are stored by Formidable core (free), so reads
9 * are not Pro-gated. Built on Formidable's API; not runtime-tested here.
10 *
11 * @package atarim-visual-collaboration
12 */
13
14 if ( ! defined('ABSPATH') ) {
15 exit;
16 }
17
18 class AVCF_Formidable_Helpers {
19
20 const PLUGIN_SLUG = 'formidable';
21 const PLUGIN_LABEL = 'Formidable Forms';
22
23 public static function items_table() { global $wpdb; return $wpdb->prefix . 'frm_items'; }
24
25 public static function map_form_summary( $f ) {
26 $form_id = isset( $f->id ) ? (int) $f->id : 0;
27 return [
28 'id' => $form_id,
29 'plugin' => self::PLUGIN_SLUG,
30 'title' => isset( $f->name ) ? (string) $f->name : '',
31 'status' => isset( $f->status ) ? (string) $f->status : 'published',
32 'entries_total' => $form_id > 0 ? self::count_entries( $form_id, false ) : 0,
33 'last_submission' => $form_id > 0 ? self::last_submission_at( $form_id ) : null,
34 'created_at' => isset( $f->created_at ) ? (string) $f->created_at : null,
35 ];
36 }
37
38 public static function map_fields( $form_id ) {
39 $fields = [];
40 if ( ! class_exists( 'FrmField' ) ) { return $fields; }
41 $form_fields = FrmField::get_all_for_form( (int) $form_id );
42 foreach ( (array) $form_fields as $field ) {
43 if ( ! isset( $field->id ) ) { continue; }
44 $type = isset( $field->type ) ? (string) $field->type : 'unknown';
45 if ( in_array( $type, [ 'end_divider', 'divider', 'break', 'captcha', 'html' ], true ) ) { continue; }
46 $options = [];
47 if ( isset( $field->options ) ) {
48 $choices = is_string( $field->options ) ? maybe_unserialize( $field->options ) : $field->options;
49 if ( is_array( $choices ) ) {
50 foreach ( $choices as $choice ) {
51 if ( is_array( $choice ) && isset( $choice['label'] ) ) { $options[] = (string) $choice['label']; }
52 elseif ( is_string( $choice ) ) { $options[] = $choice; }
53 }
54 }
55 }
56 $fields[] = [
57 'id' => (string) $field->id,
58 'key' => isset( $field->field_key ) ? (string) $field->field_key : '',
59 'type' => $type,
60 'label' => isset( $field->name ) ? (string) $field->name : '',
61 'required' => ! empty( $field->required ),
62 'options' => $options,
63 ];
64 }
65 return $fields;
66 }
67
68 public static function map_notifications( $form_id ) {
69 $notifications = [];
70 if ( class_exists( 'FrmFormAction' ) && method_exists( 'FrmFormAction', 'get_action_for_form' ) ) {
71 $actions = FrmFormAction::get_action_for_form( (int) $form_id, 'email' );
72 if ( is_array( $actions ) ) {
73 foreach ( $actions as $action ) {
74 if ( ! is_object( $action ) ) { continue; }
75 $aid = isset( $action->ID ) ? (string) $action->ID : ( isset( $action->id ) ? (string) $action->id : '' );
76 $settings = isset( $action->post_content ) && is_array( $action->post_content ) ? $action->post_content : [];
77 $notifications[] = [
78 'id' => $aid,
79 'name' => isset( $action->post_title ) ? (string) $action->post_title : ( 'Email ' . $aid ),
80 'recipients' => self::parse_recipients( isset( $settings['email_to'] ) ? (string) $settings['email_to'] : '' ),
81 'subject' => isset( $settings['email_subject'] ) ? (string) $settings['email_subject'] : '',
82 'enabled' => ! ( isset( $action->post_status ) && $action->post_status === 'draft' ),
83 ];
84 }
85 }
86 }
87 return $notifications;
88 }
89
90 public static function map_form_full( $form, $include_raw = false ) {
91 $form_id = (int) $form->id;
92 $fields = self::map_fields( $form_id );
93 $options = isset( $form->options ) && is_array( $form->options ) ? $form->options : ( is_string( $form->options ) ? maybe_unserialize( $form->options ) : [] );
94 return [
95 'id' => $form_id,
96 'plugin' => self::PLUGIN_SLUG,
97 'title' => isset( $form->name ) ? (string) $form->name : '',
98 'status' => isset( $form->status ) ? (string) $form->status : 'published',
99 'field_count' => count( $fields ),
100 'fields' => $fields,
101 'notifications' => self::map_notifications( $form_id ),
102 'created_at' => isset( $form->created_at ) ? (string) $form->created_at : null,
103 'shortcode' => sprintf( '[formidable id=%d]', $form_id ),
104 'raw' => $include_raw ? $options : null,
105 ];
106 }
107
108 public static function build_label_map( $fields ) {
109 $map = [];
110 foreach ( (array) $fields as $f ) {
111 if ( isset( $f['id'] ) ) { $map[ (string) $f['id'] ] = isset( $f['label'] ) ? (string) $f['label'] : (string) $f['id']; }
112 }
113 return $map;
114 }
115
116 public static function normalize_entry( $raw_entry, $form_id, $label_map, $include_raw = true ) {
117 $entry_id = isset( $raw_entry->id ) ? (int) $raw_entry->id : 0;
118 $form_id = (int) $form_id;
119 $fields = [];
120 $metas = isset( $raw_entry->metas ) && is_array( $raw_entry->metas ) ? $raw_entry->metas : [];
121 foreach ( $metas as $field_id => $value ) {
122 $fields[] = [ 'id' => (string) $field_id, 'label' => isset( $label_map[ (string) $field_id ] ) ? $label_map[ (string) $field_id ] : (string) $field_id, 'type' => '', 'value' => $value ];
123 }
124 $is_draft = isset( $raw_entry->is_draft ) ? (int) $raw_entry->is_draft : 0;
125 $status = $is_draft === 2 ? 'spam' : ( $is_draft === 1 ? 'draft' : 'published' );
126 return [
127 'id' => $entry_id,
128 'plugin' => self::PLUGIN_SLUG,
129 'form_id' => $form_id,
130 'submitted_at' => isset( $raw_entry->created_at ) ? (string) $raw_entry->created_at : '',
131 'source_url' => isset( $raw_entry->source_url ) ? (string) $raw_entry->source_url : null,
132 'ip_address' => isset( $raw_entry->ip ) ? (string) $raw_entry->ip : null,
133 'user_id' => isset( $raw_entry->user_id ) ? (int) $raw_entry->user_id : 0,
134 'item_key' => isset( $raw_entry->item_key ) ? (string) $raw_entry->item_key : '',
135 'status' => $status,
136 'fields' => $fields,
137 'raw' => $include_raw ? $raw_entry : null,
138 ];
139 }
140
141 public static function count_entries( $form_id, $include_spam ) {
142 global $wpdb;
143 $table = self::items_table();
144 $where = $include_spam ? 'form_id = %d' : 'form_id = %d AND (is_draft != 2 OR is_draft IS NULL)';
145 return (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$table}` WHERE {$where}", (int) $form_id ) );
146 }
147
148 public static function last_submission_at( $form_id ) {
149 global $wpdb;
150 $table = self::items_table();
151 $row = $wpdb->get_var( $wpdb->prepare( "SELECT MAX(created_at) FROM `{$table}` WHERE form_id = %d", (int) $form_id ) );
152 return $row ? (string) $row : null;
153 }
154
155 public static function stats( $form_id, $args = [] ) {
156 global $wpdb;
157 $table = self::items_table();
158 $where = [ 'form_id = %d', '(is_draft != 2 OR is_draft IS NULL)' ]; $params = [ (int) $form_id ];
159 if ( ! empty( $args['date_from'] ) ) { $where[] = 'created_at >= %s'; $params[] = (string) $args['date_from']; }
160 if ( ! empty( $args['date_to'] ) ) { $where[] = 'created_at <= %s'; $params[] = (string) $args['date_to']; }
161 $where_sql = implode( ' AND ', $where );
162 $by_day = $wpdb->get_results( $wpdb->prepare( "SELECT DATE(created_at) as day, COUNT(*) as count FROM `{$table}` WHERE {$where_sql} GROUP BY DATE(created_at) ORDER BY day ASC", $params ), ARRAY_A );
163 $ext = $wpdb->get_row( $wpdb->prepare( "SELECT MIN(created_at) as first_date, MAX(created_at) as last_date, COUNT(*) as total FROM `{$table}` WHERE {$where_sql}", $params ), ARRAY_A );
164 return [
165 'total' => isset( $ext['total'] ) ? (int) $ext['total'] : 0,
166 'first_date' => isset( $ext['first_date'] ) && $ext['first_date'] ? (string) $ext['first_date'] : null,
167 'last_date' => isset( $ext['last_date'] ) && $ext['last_date'] ? (string) $ext['last_date'] : null,
168 'by_day' => is_array( $by_day ) ? $by_day : [],
169 ];
170 }
171
172 public static function parse_recipients( $str ) {
173 if ( (string) $str === '' ) { return []; }
174 $out = [];
175 foreach ( (array) preg_split( '/[,\n;]+/', (string) $str ) as $part ) {
176 $clean = trim( (string) $part );
177 if ( $clean !== '' ) { $out[] = $clean; }
178 }
179 return $out;
180 }
181 }
182