|
1 | 1 | <?php |
2 | 2 | /** |
3 | | - * Gravity Wiz // Gravity Forms // Progress Meter |
4 | | - * |
5 | | - * Display a meter indicating your progression towards a set goal based on your Gravity Forms entries. |
6 | | - * |
7 | | - * Plugin Name: GF Progress Meter |
8 | | - * Plugin URI: https://gravitywiz.com/gravity-forms-progress-meter/ |
9 | | - * Description: Display a meter indicating your progression towards a set goal based on your Gravity Forms entries. |
10 | | - * Author: Gravity Wiz |
11 | | - * Version: 1.3 |
12 | | - * Author URI: https://gravitywiz.com |
13 | | - * |
14 | | - * @todo |
15 | | - * - Add support for different colors and themes. |
16 | | - * - Add support for live updates as new entries are submitted. |
17 | | - * - Add support for calculating by true form total rather than captured payments. |
| 3 | + * This snippet is now available as a free plugin with Spellbook. ✨ |
| 4 | + * Instructions for installing this plugin can be found here: |
| 5 | + * https://gravitywiz.com/gravity-forms-progress-meter/ |
18 | 6 | */ |
19 | | -class GW_Progress_Meter { |
20 | | - |
21 | | - private static $instance = null; |
22 | | - |
23 | | - public static function get_instance() { |
24 | | - if ( self::$instance === null ) { |
25 | | - self::$instance = new self; |
26 | | - } |
27 | | - return self::$instance; |
28 | | - } |
29 | | - |
30 | | - private function __construct() { |
31 | | - |
32 | | - add_filter( 'gform_shortcode_meter', array( $this, 'do_meter_shortcode' ), 10, 2 ); |
33 | | - |
34 | | - } |
35 | | - |
36 | | - public function do_meter_shortcode( $output, $atts ) { |
37 | | - |
38 | | - $atts = shortcode_atts( array( |
39 | | - 'id' => false, |
40 | | - 'status' => 'total', // accepts 'total', 'unread', 'starred', 'trash', 'spam' |
41 | | - 'goal' => false, |
42 | | - 'start' => false, |
43 | | - 'field' => false, |
44 | | - 'count_label' => '%s submissions', |
45 | | - 'goal_label' => '%s goal', |
46 | | - 'name' => false, // Accepts a string; used via the `shortcode_atts_gf_progress_meter` filter to conditionally filter the $atts. |
47 | | - ), $atts, 'gf_progress_meter' ); |
48 | | - |
49 | | - $count = $this->get_count( $atts ); |
50 | | - if ( $atts['start'] && $count < $atts['start'] ) { |
51 | | - $count = $atts['start']; |
52 | | - } |
53 | | - |
54 | | - $goal = (int) $this->get_goal( $count, $atts['goal'] ); |
55 | | - |
56 | | - $percent_complete = $count <= 0 ? 0 : round( ( $count / $goal ) * 100 ); |
57 | | - $classes = array( 'gwpm-container' ); |
58 | | - |
59 | | - if ( $percent_complete >= 100 ) { |
60 | | - $classes[] = 'gwpm-goal-reached'; |
61 | | - } |
62 | | - |
63 | | - if ( $percent_complete > 100 ) { |
64 | | - $classes[] = 'gwpm-goal-exceeded'; |
65 | | - $percent_complete = 100; |
66 | | - } |
67 | | - |
68 | | - $output = '<div class="' . implode( ' ', $classes ) . '"> |
69 | | - <div class="gwpm-meter"> |
70 | | - <div class="gwpm-fill" style="width:' . $percent_complete . '%;"></div> |
71 | | - </div> |
72 | | - <div class="gwpm-count"> |
73 | | - ' . $this->prepare_label( $atts['count_label'], 'count', $count ) . ' |
74 | | - </div> |
75 | | - <div class="gwpm-goal"> |
76 | | - ' . $this->prepare_label( $atts['goal_label'], 'goal', $goal ) . ' |
77 | | - </div> |
78 | | - </div>'; |
79 | | - |
80 | | - $this->enqueue_styles(); |
81 | | - |
82 | | - return $output; |
83 | | - } |
84 | | - |
85 | | - public function get_count( $atts ) { |
86 | | - |
87 | | - if ( isset( $atts['count'] ) && ! rgblank( $atts['count'] ) ) { |
88 | | - return $atts['count']; |
89 | | - } |
90 | | - |
91 | | - if ( $atts['field'] ) { |
92 | | - |
93 | | - global $wpdb; |
94 | | - |
95 | | - if ( in_array( $atts['field'], array( 'payment_amount' ), true ) ) { |
96 | | - |
97 | | - $query = array( |
98 | | - 'select' => "SELECT sum( e.`{$atts['field']}` )", |
99 | | - 'from' => "FROM {$wpdb->prefix}gf_entry e", |
100 | | - 'join' => '', |
101 | | - 'where' => $wpdb->prepare( " |
102 | | - WHERE e.form_id = %d |
103 | | - AND e.status = 'active' |
104 | | - AND e.payment_status = 'Paid'\n", |
105 | | - $atts['id'] |
106 | | - ), |
107 | | - ); |
108 | | - |
109 | | - } else { |
110 | | - |
111 | | - $query = array( |
112 | | - 'select' => 'SELECT sum( em.meta_value )', |
113 | | - 'from' => "FROM {$wpdb->prefix}gf_entry_meta em", |
114 | | - 'join' => "INNER JOIN {$wpdb->prefix}gf_entry e ON e.id = em.entry_id", |
115 | | - 'where' => $wpdb->prepare( " |
116 | | - WHERE em.form_id = %d |
117 | | - AND em.meta_key = %s |
118 | | - AND e.status = 'active'\n", |
119 | | - $atts['id'], $atts['field'] |
120 | | - ), |
121 | | - ); |
122 | | - |
123 | | - if ( class_exists( 'GF_Partial_Entries' ) ) { |
124 | | - $query['where'] .= "and em.entry_id NOT IN( SELECT entry_id FROM {$wpdb->prefix}gf_entry_meta WHERE meta_key = 'partial_entry_id' )"; |
125 | | - } |
126 | | - } |
127 | | - |
128 | | - $sql = implode( "\n", $query ); |
129 | | - |
130 | | - // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
131 | | - $count = intval( $wpdb->get_var( $sql ) ); |
132 | | - |
133 | | - } else { |
134 | | - |
135 | | - $valid_statuses = array( 'total', 'unread', 'starred', 'trash', 'spam' ); |
136 | | - if ( ! $atts['id'] || ! in_array( $atts['status'], $valid_statuses, true ) ) { |
137 | | - return current_user_can( 'update_core' ) ? __( 'Invalid "id" (the form ID) or "status" (i.e. "total", "trash", etc.) parameter passed.' ) : ''; |
138 | | - } |
139 | | - |
140 | | - $counts = GFFormsModel::get_form_counts( $atts['id'] ); |
141 | | - $count = rgar( $counts, $atts['status'] ); |
142 | | - |
143 | | - } |
144 | | - |
145 | | - return $count; |
146 | | - } |
147 | | - |
148 | | - public function get_goal( $count, $goal ) { |
149 | | - |
150 | | - if ( strpos( $goal, ';' ) === false ) { |
151 | | - return $goal; |
152 | | - } |
153 | | - |
154 | | - $goals = explode( ';', $goal ); |
155 | | - foreach ( $goals as $goal ) { |
156 | | - if ( $count < $goal ) { |
157 | | - return $goal; |
158 | | - } |
159 | | - } |
160 | | - |
161 | | - return end( $goals ); |
162 | | - } |
163 | | - |
164 | | - public function enqueue_styles() { |
165 | | - if ( ! has_action( 'wp_footer', array( $this, 'output_styles' ) ) ) { |
166 | | - add_action( 'wp_footer', array( $this, 'output_styles' ) ); |
167 | | - add_action( 'gform_footer', array( $this, 'output_styles' ) ); |
168 | | - } |
169 | | - } |
170 | | - |
171 | | - public function output_styles() { |
172 | | - ?> |
173 | | - <style> |
174 | | - .gwpm-container { |
175 | | - display: flex; |
176 | | - flex-wrap: wrap; |
177 | | - margin-bottom: 1.5rem; |
178 | | - } |
179 | | - .gwpm-meter { |
180 | | - width: 100%; |
181 | | - height: 2rem; |
182 | | - border-radius: 1rem; |
183 | | - vertical-align: middle; |
184 | | - background: #D2D6DC; |
185 | | - font-size: 1rem; |
186 | | - line-height: 1rem; |
187 | | - } |
188 | | - .gwpm-fill { |
189 | | - background-color: #1E7AC4; |
190 | | - height: 100%; |
191 | | - border-radius: 1rem; |
192 | | - } |
193 | | - .gwpm-goal-reached .gwpm-fill { |
194 | | - background-color: #42C414; |
195 | | - } |
196 | | - .gwpm-count, .gwpm-goal { |
197 | | - line-height: 2; |
198 | | - } |
199 | | - .gwpm-count { |
200 | | - width: 50%; |
201 | | - } |
202 | | - .gwpm-goal { |
203 | | - width: 50%; |
204 | | - text-align: right; |
205 | | - } |
206 | | - .gwpm-count-number, .gwpm-goal-number { |
207 | | - font-weight: bold; |
208 | | - } |
209 | | - </style> |
210 | | - <?php |
211 | | - } |
212 | | - |
213 | | - public function prepare_label( $label, $type, $number ) { |
214 | | - |
215 | | - $bits = explode( ' ', $label ); |
216 | | - |
217 | | - foreach ( $bits as &$bit ) { |
218 | | - // In order to support formatted numbers we needed to move away from use the `%d` placeholder. This code |
219 | | - // automatically updates existing uses of the `%d` to `%s`. |
220 | | - if ( strpos( $bit, '%d' ) !== false ) { |
221 | | - $bit = str_replace( '%d', '%s', $bit ); |
222 | | - } |
223 | | - if ( strpos( $bit, '%s' ) !== false ) { |
224 | | - $currency = new RGCurrency( GFCommon::get_currency() ); |
225 | | - $number_format = rgar( $currency, 'thousand_separator' ) === '.' ? 'decimal_comma' : ''; |
226 | | - $bit = sprintf( '<span class="gwpm-%s-number">' . $bit . '</span>', $type, GFCommon::format_number( $number, $number_format, '', true ) ); |
227 | | - } |
228 | | - } |
229 | | - |
230 | | - return implode( ' ', $bits ); |
231 | | - } |
232 | | - |
233 | | -} |
234 | | - |
235 | | -function gw_progress_meter() { |
236 | | - return GW_Progress_Meter::get_instance(); |
237 | | -} |
238 | | - |
239 | | -gw_progress_meter(); |
0 commit comments