class-avcf-abilities-gravity-pro.php
1 month ago
class-avcf-abilities-gravity.php
1 month ago
class-avcf-gravity-detector.php
1 month ago
class-avcf-gravity-helpers.php
1 month ago
class-avcf-gravity-helpers.php
203 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Gravity Forms — shared helpers for the standalone GF ability cluster. |
| 4 | * |
| 5 | * Lifts the proven GFAPI mapping/stats logic out of the old unified adapter so |
| 6 | * the GF cluster is fully self-contained (no shared forms base). Public API used: |
| 7 | * GFAPI::get_forms / get_form / get_entries / get_entry / count_entries |
| 8 | * GFAPI::update_entry / update_form / add_form / add_entry / delete_* (writers in -pro) |
| 9 | * {prefix}gf_entry table for stats / last-submission. |
| 10 | * |
| 11 | * Built on Gravity's public API; not runtime-tested here. |
| 12 | * |
| 13 | * @package atarim-visual-collaboration |
| 14 | */ |
| 15 | |
| 16 | if ( ! defined('ABSPATH') ) { |
| 17 | exit; |
| 18 | } |
| 19 | |
| 20 | class AVCF_Gravity_Helpers { |
| 21 | |
| 22 | const PLUGIN_SLUG = 'gravity'; |
| 23 | const PLUGIN_LABEL = 'Gravity Forms'; |
| 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['title'] ) ? (string) $f['title'] : '', |
| 31 | 'status' => empty( $f['is_active'] ) ? 'inactive' : 'active', |
| 32 | 'entries_total' => $form_id > 0 ? (int) GFAPI::count_entries( $form_id ) : 0, |
| 33 | 'last_submission' => $form_id > 0 ? self::last_submission_at( $form_id ) : null, |
| 34 | 'created_at' => isset( $f['date_created'] ) ? (string) $f['date_created'] : null, |
| 35 | ]; |
| 36 | } |
| 37 | |
| 38 | public static function map_field( $f ) { |
| 39 | $fid = is_object( $f ) ? (string) $f->id : ( isset( $f['id'] ) ? (string) $f['id'] : '' ); |
| 40 | $type = is_object( $f ) ? (string) $f->type : ( isset( $f['type'] ) ? (string) $f['type'] : 'unknown' ); |
| 41 | $label = is_object( $f ) ? (string) $f->label : ( isset( $f['label'] ) ? (string) $f['label'] : '' ); |
| 42 | $required = is_object( $f ) ? ! empty( $f->isRequired ) : ! empty( $f['isRequired'] ); |
| 43 | $admin = is_object( $f ) ? ( property_exists( $f, 'adminLabel' ) ? (string) $f->adminLabel : '' ) : ( isset( $f['adminLabel'] ) ? (string) $f['adminLabel'] : '' ); |
| 44 | $choices = is_object( $f ) ? ( property_exists( $f, 'choices' ) ? $f->choices : null ) : ( isset( $f['choices'] ) ? $f['choices'] : null ); |
| 45 | $options = []; |
| 46 | if ( is_array( $choices ) ) { |
| 47 | foreach ( $choices as $choice ) { |
| 48 | if ( isset( $choice['text'] ) ) { $options[] = (string) $choice['text']; } |
| 49 | } |
| 50 | } |
| 51 | $cond = is_object( $f ) ? ( property_exists( $f, 'conditionalLogic' ) ? $f->conditionalLogic : null ) : ( isset( $f['conditionalLogic'] ) ? $f['conditionalLogic'] : null ); |
| 52 | return [ |
| 53 | 'id' => $fid, |
| 54 | 'type' => $type, |
| 55 | 'label' => $label, |
| 56 | 'admin_label' => $admin, |
| 57 | 'required' => (bool) $required, |
| 58 | 'options' => $options, |
| 59 | 'has_conditional' => ! empty( $cond ), |
| 60 | ]; |
| 61 | } |
| 62 | |
| 63 | public static function map_form_full( $form, $include_raw = false ) { |
| 64 | if ( ! is_array( $form ) ) { return null; } |
| 65 | $form_id = isset( $form['id'] ) ? (int) $form['id'] : 0; |
| 66 | |
| 67 | $fields = []; |
| 68 | if ( isset( $form['fields'] ) && is_array( $form['fields'] ) ) { |
| 69 | foreach ( $form['fields'] as $f ) { $fields[] = self::map_field( $f ); } |
| 70 | } |
| 71 | |
| 72 | $notifications = []; |
| 73 | if ( isset( $form['notifications'] ) && is_array( $form['notifications'] ) ) { |
| 74 | foreach ( $form['notifications'] as $nid => $n ) { |
| 75 | if ( ! is_array( $n ) ) { continue; } |
| 76 | $notifications[] = [ |
| 77 | 'id' => (string) $nid, |
| 78 | 'name' => isset( $n['name'] ) ? (string) $n['name'] : ( 'Notification ' . $nid ), |
| 79 | 'event' => isset( $n['event'] ) ? (string) $n['event'] : 'form_submission', |
| 80 | 'to_type' => isset( $n['toType'] ) ? (string) $n['toType'] : '', |
| 81 | 'recipients' => self::parse_recipients( isset( $n['to'] ) ? (string) $n['to'] : '' ), |
| 82 | 'subject' => isset( $n['subject'] ) ? (string) $n['subject'] : '', |
| 83 | 'enabled' => ! isset( $n['isActive'] ) || ! empty( $n['isActive'] ), |
| 84 | ]; |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | $confirmations = []; |
| 89 | if ( isset( $form['confirmations'] ) && is_array( $form['confirmations'] ) ) { |
| 90 | foreach ( $form['confirmations'] as $cid => $c ) { |
| 91 | if ( ! is_array( $c ) ) { continue; } |
| 92 | $confirmations[] = [ |
| 93 | 'id' => (string) $cid, |
| 94 | 'name' => isset( $c['name'] ) ? (string) $c['name'] : '', |
| 95 | 'type' => isset( $c['type'] ) ? (string) $c['type'] : 'message', |
| 96 | 'is_default' => ! empty( $c['isDefault'] ), |
| 97 | ]; |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | return [ |
| 102 | 'id' => $form_id, |
| 103 | 'plugin' => self::PLUGIN_SLUG, |
| 104 | 'title' => isset( $form['title'] ) ? (string) $form['title'] : '', |
| 105 | 'description' => isset( $form['description'] ) ? (string) $form['description'] : '', |
| 106 | 'status' => empty( $form['is_active'] ) ? 'inactive' : 'active', |
| 107 | 'field_count' => count( $fields ), |
| 108 | 'fields' => $fields, |
| 109 | 'notifications' => $notifications, |
| 110 | 'confirmations' => $confirmations, |
| 111 | 'created_at' => isset( $form['date_created'] ) ? (string) $form['date_created'] : null, |
| 112 | 'shortcode' => sprintf( '[gravityform id="%d" title="false" description="false"]', $form_id ), |
| 113 | 'raw' => $include_raw ? $form : null, |
| 114 | ]; |
| 115 | } |
| 116 | |
| 117 | public static function normalize_entry( $raw_entry, $form_id, $form = null, $include_raw = true ) { |
| 118 | $entry_id = isset( $raw_entry['id'] ) ? (int) $raw_entry['id'] : 0; |
| 119 | $form_id = (int) $form_id; |
| 120 | |
| 121 | $field_meta = []; |
| 122 | if ( is_array( $form ) && isset( $form['fields'] ) && is_array( $form['fields'] ) ) { |
| 123 | foreach ( $form['fields'] as $f ) { |
| 124 | $fid = is_object( $f ) ? (string) $f->id : ( isset( $f['id'] ) ? (string) $f['id'] : '' ); |
| 125 | if ( $fid === '' ) { continue; } |
| 126 | $field_meta[ $fid ] = [ |
| 127 | 'type' => is_object( $f ) ? (string) $f->type : ( isset( $f['type'] ) ? (string) $f['type'] : '' ), |
| 128 | 'label' => is_object( $f ) ? (string) $f->label : ( isset( $f['label'] ) ? (string) $f['label'] : '' ), |
| 129 | ]; |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | $reserved = [ |
| 134 | 'id','form_id','date_created','date_updated','is_starred','is_read', |
| 135 | 'ip','source_url','post_id','currency','payment_status','payment_date', |
| 136 | 'payment_amount','payment_method','transaction_id','is_fulfilled', |
| 137 | 'created_by','transaction_type','user_agent','status', |
| 138 | ]; |
| 139 | $fields = []; |
| 140 | foreach ( (array) $raw_entry as $key => $value ) { |
| 141 | if ( in_array( $key, $reserved, true ) ) { continue; } |
| 142 | if ( ! is_numeric( $key ) && ! preg_match( '/^\d+\.\d+$/', (string) $key ) ) { continue; } |
| 143 | $major = (string) (int) $key; |
| 144 | $meta = isset( $field_meta[ $major ] ) ? $field_meta[ $major ] : [ 'type' => '', 'label' => '' ]; |
| 145 | $fields[] = [ 'id' => (string) $key, 'label' => $meta['label'], 'type' => $meta['type'], 'value' => $value ]; |
| 146 | } |
| 147 | |
| 148 | $status = isset( $raw_entry['status'] ) ? (string) $raw_entry['status'] : 'active'; |
| 149 | $norm = $status === 'spam' ? 'spam' : ( $status === 'trash' ? 'trash' : 'published' ); |
| 150 | |
| 151 | return [ |
| 152 | 'id' => $entry_id, |
| 153 | 'plugin' => self::PLUGIN_SLUG, |
| 154 | 'form_id' => $form_id, |
| 155 | 'submitted_at' => isset( $raw_entry['date_created'] ) ? (string) $raw_entry['date_created'] : '', |
| 156 | 'source_url' => isset( $raw_entry['source_url'] ) ? (string) $raw_entry['source_url'] : null, |
| 157 | 'ip_address' => isset( $raw_entry['ip'] ) ? (string) $raw_entry['ip'] : null, |
| 158 | 'user_id' => isset( $raw_entry['created_by'] ) ? (int) $raw_entry['created_by'] : 0, |
| 159 | 'payment_status'=> isset( $raw_entry['payment_status'] ) ? (string) $raw_entry['payment_status'] : null, |
| 160 | 'status' => $norm, |
| 161 | 'fields' => $fields, |
| 162 | 'raw' => $include_raw ? $raw_entry : null, |
| 163 | ]; |
| 164 | } |
| 165 | |
| 166 | public static function parse_recipients( $str ) { |
| 167 | if ( (string) $str === '' ) { return []; } |
| 168 | $out = []; |
| 169 | foreach ( (array) preg_split( '/[,\n;]+/', (string) $str ) as $part ) { |
| 170 | $clean = trim( (string) $part ); |
| 171 | if ( $clean !== '' ) { $out[] = $clean; } |
| 172 | } |
| 173 | return $out; |
| 174 | } |
| 175 | |
| 176 | public static function last_submission_at( $form_id ) { |
| 177 | global $wpdb; |
| 178 | $form_id = (int) $form_id; |
| 179 | $table = $wpdb->prefix . 'gf_entry'; |
| 180 | $row = $wpdb->get_var( $wpdb->prepare( "SELECT MAX(date_created) FROM `{$table}` WHERE form_id = %d", $form_id ) ); |
| 181 | return $row ? (string) $row : null; |
| 182 | } |
| 183 | |
| 184 | /** Per-day counts + extremes for a form, optional date window. */ |
| 185 | public static function stats( $form_id, $args = [] ) { |
| 186 | global $wpdb; |
| 187 | $form_id = (int) $form_id; |
| 188 | $table = $wpdb->prefix . 'gf_entry'; |
| 189 | $where = [ 'form_id = %d' ]; $params = [ $form_id ]; |
| 190 | if ( ! empty( $args['date_from'] ) ) { $where[] = 'date_created >= %s'; $params[] = (string) $args['date_from']; } |
| 191 | if ( ! empty( $args['date_to'] ) ) { $where[] = 'date_created <= %s'; $params[] = (string) $args['date_to']; } |
| 192 | $where_sql = implode( ' AND ', $where ); |
| 193 | $by_day = $wpdb->get_results( $wpdb->prepare( "SELECT DATE(date_created) AS day, COUNT(*) AS count FROM `{$table}` WHERE {$where_sql} GROUP BY DATE(date_created) ORDER BY day ASC", $params ), 'ARRAY_A' ); |
| 194 | $ext = $wpdb->get_row( $wpdb->prepare( "SELECT MIN(date_created) AS first_date, MAX(date_created) AS last_date, COUNT(*) AS total FROM `{$table}` WHERE {$where_sql}", $params ), 'ARRAY_A' ); |
| 195 | return [ |
| 196 | 'total' => $ext && isset( $ext['total'] ) ? (int) $ext['total'] : 0, |
| 197 | 'first_date' => $ext && isset( $ext['first_date'] ) ? $ext['first_date'] : null, |
| 198 | 'last_date' => $ext && isset( $ext['last_date'] ) ? $ext['last_date'] : null, |
| 199 | 'by_day' => is_array( $by_day ) ? $by_day : [], |
| 200 | ]; |
| 201 | } |
| 202 | } |
| 203 |