Skip to content

Commit ba32383

Browse files
authored
gwpc-post-image-subfields.php: Added snippet to enable word count for Post Image subfields.
1 parent 21f4c77 commit ba32383

File tree

1 file changed

+237
-0
lines changed

1 file changed

+237
-0
lines changed
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
<?php
2+
/**
3+
* Gravity Wiz // Gravity Forms // Word Count for Post Image Subfields (Caption, Description, Alt, Title)
4+
*
5+
* Instruction Video: https://www.loom.com/share/005eda834a6348f9a874a5e6cdd85461
6+
*
7+
* Set min/max word counts for any Post Image subfield (caption, description, alt, title) per field.
8+
* Supports multiple subfields per field.
9+
*
10+
* @version 1.0.0
11+
* @author David Smith <[email protected]>
12+
* @license GPL-2.0+
13+
* @link https://gravitywiz.com/
14+
*/
15+
class GW_Post_Image_Word_Count {
16+
17+
private static $_instance = null;
18+
private $_configs = array();
19+
20+
public static function get_instance() {
21+
if ( self::$_instance === null ) {
22+
self::$_instance = new self();
23+
}
24+
return self::$_instance;
25+
}
26+
27+
public function __construct( $config = array() ) {
28+
29+
$this->_configs[] = array_merge( array(
30+
'form_id' => false,
31+
'field_id' => false,
32+
'limits' => array(),
33+
), $config );
34+
35+
add_action( 'init', array( $this, 'init' ) );
36+
37+
}
38+
39+
public function init() {
40+
41+
if ( ! $this->is_applicable() ) {
42+
return;
43+
}
44+
45+
add_action( 'gform_enqueue_scripts', array( $this, 'enqueue_scripts' ), 20 );
46+
add_action( 'gform_register_init_scripts', array( $this, 'enqueue_textarea_counter' ), 20 );
47+
add_filter( 'gform_validation', array( $this, 'validate_word_count' ) );
48+
49+
}
50+
51+
public function is_applicable() {
52+
return ! empty( $this->_configs );
53+
}
54+
55+
// Map subfield keys to their input suffixes and labels.
56+
public function get_subfields() {
57+
return array(
58+
'caption' => array(
59+
'suffix' => '4',
60+
'label' => __( 'Caption', 'gravityforms' ),
61+
),
62+
'description' => array(
63+
'suffix' => '7',
64+
'label' => __( 'Description', 'gravityforms' ),
65+
),
66+
'alt' => array(
67+
'suffix' => '2',
68+
'label' => __( 'Alt Text', 'gravityforms' ),
69+
),
70+
'title' => array(
71+
'suffix' => '1',
72+
'label' => __( 'Title', 'gravityforms' ),
73+
),
74+
);
75+
}
76+
77+
public function enqueue_scripts( $form ) {
78+
// Check if any Post Image field is configured for word count.
79+
foreach ( $this->_configs as $config ) {
80+
if ( ( ! $config['form_id'] || $form['id'] == $config['form_id'] ) && $config['field_id'] ) {
81+
foreach ( $form['fields'] as $field ) {
82+
if ( $field->id == $config['field_id'] && $field->type === 'post_image' ) {
83+
// Force enqueue the GP Word Count JS.
84+
wp_enqueue_script( 'gp-word-count', plugins_url( 'scripts/jquery.textareaCounter.js', 'gwwordcount/gwwordcount.php' ), array( 'jquery' ), null, true );
85+
return;
86+
}
87+
}
88+
}
89+
}
90+
}
91+
92+
public function enqueue_textarea_counter( $form ) {
93+
94+
foreach ( $this->_configs as $config ) {
95+
if ( ! $this->is_config_applicable_to_form( $config, $form ) ) {
96+
continue;
97+
}
98+
99+
$field = GFAPI::get_field( $form, $config['field_id'] );
100+
if ( ! $field || $field->type !== 'post_image' || empty( $config['limits'] ) ) {
101+
continue;
102+
}
103+
104+
$form_id = $form['id'];
105+
$field_id = $field->id;
106+
107+
foreach ( $config['limits'] as $subfield => $limits ) {
108+
$subfields = $this->get_subfields();
109+
if ( empty( $subfields[ $subfield ] ) ) {
110+
continue;
111+
}
112+
113+
$suffix = $subfields[ $subfield ]['suffix'];
114+
$min = isset( $limits['min'] ) ? intval( $limits['min'] ) : 0;
115+
$max = isset( $limits['max'] ) ? intval( $limits['max'] ) : 0;
116+
117+
$args = array(
118+
'formId' => $form_id,
119+
'limit' => $max,
120+
'min' => $min,
121+
'truncate' => true,
122+
'defaultLabel' => sprintf( __( 'Max: %s words', 'gp-word-count' ), '{limit}' ),
123+
'defaultLabelSingular' => sprintf( __( 'Max: %s word', 'gp-word-count' ), '{limit}' ),
124+
'counterLabel' => sprintf( __( '%s words left', 'gp-word-count' ), '{remaining}' ),
125+
'counterLabelSingular' => sprintf( __( '%s word left', 'gp-word-count' ), '{remaining}' ),
126+
'limitReachedLabel' => '<span class="gwwc-max-reached" style="font-weight:bold;">' . sprintf( __( '%s words left', 'gp-word-count' ), '{remaining}' ) . '</span>',
127+
'limitExceededLabel' => '<span class="gwwc-max-exceeded" style="font-weight:bold;color:#c0392b;">' . sprintf( __( 'Limit exceeded!', 'gp-word-count' ), '{remaining}' ) . '</span>',
128+
'minCounterLabel' => sprintf( __( '%s more words required', 'gp-word-count' ), '{remaining}' ),
129+
'minCounterLabelSingular' => sprintf( __( '%s more word required', 'gp-word-count' ), '{remaining}' ),
130+
'minReachedLabel' => '<span class="gwwc-min-reached" style="font-weight:bold;color:#27ae60">' . __( 'Minimum word count met.', 'gp-word-count' ) . '</span>',
131+
'minDefaultLabel' => sprintf( __( 'Min: %s words', 'gp-word-count' ), '{min}' ),
132+
'minDefaultLabelSingular' => sprintf( __( 'Min: %s word', 'gp-word-count' ), '{min}' ),
133+
);
134+
135+
$args_json = json_encode( $args );
136+
$input_id = "input_{$form_id}_{$field_id}_{$suffix}";
137+
$script = "jQuery('#{$input_id}').textareaCounter({$args_json});";
138+
139+
GFFormDisplay::add_init_script( $form_id, "gwwc_post_image_{$subfield}_wc_{$field_id}", GFFormDisplay::ON_PAGE_RENDER, $script );
140+
}
141+
}
142+
143+
}
144+
145+
public function validate_word_count( $result ) {
146+
147+
$form = $result['form'];
148+
149+
foreach ( $this->_configs as $config ) {
150+
if ( ! $this->is_config_applicable_to_form( $config, $form ) ) {
151+
continue;
152+
}
153+
154+
foreach ( $form['fields'] as &$field ) {
155+
if ( $field->id != $config['field_id'] || $field->type !== 'post_image' || empty( $config['limits'] ) ) {
156+
continue;
157+
}
158+
159+
foreach ( $config['limits'] as $subfield => $limits ) {
160+
$subfields = $this->get_subfields();
161+
if ( empty( $subfields[ $subfield ] ) ) {
162+
continue;
163+
}
164+
165+
$suffix = $subfields[ $subfield ]['suffix'];
166+
$label = $subfields[ $subfield ]['label'];
167+
$input_name = "input_{$field->id}_{$suffix}";
168+
$value = rgpost( $input_name );
169+
$word_count = preg_match_all( '/\S+/', trim( $value ) );
170+
171+
$min = isset( $limits['min'] ) ? intval( $limits['min'] ) : 0;
172+
$max = isset( $limits['max'] ) ? intval( $limits['max'] ) : 0;
173+
174+
if ( $min && $word_count < $min ) {
175+
$field->failed_validation = true;
176+
$field->validation_message = sprintf(
177+
_n( '%1$s must be at least %2$s word.', '%1$s must be at least %2$s words.', $min, 'gp-word-count' ),
178+
$label, $min
179+
);
180+
$result['is_valid'] = false;
181+
}
182+
183+
if ( $max && $word_count > $max ) {
184+
$field->failed_validation = true;
185+
$field->validation_message = sprintf(
186+
_n( '%1$s may only be %2$s word.', '%1$s may only be %2$s words.', $max, 'gp-word-count' ),
187+
$label, $max
188+
);
189+
$result['is_valid'] = false;
190+
}
191+
}
192+
}
193+
}
194+
195+
$result['form'] = $form;
196+
return $result;
197+
198+
}
199+
200+
private function is_config_applicable_to_form( $config, $form ) {
201+
return ( ! $config['form_id'] || $form['id'] == $config['form_id'] ) && $config['field_id'];
202+
}
203+
204+
}
205+
206+
// CONFIGURATION: Set your field IDs and subfield limits here.
207+
new GW_Post_Image_Word_Count( array(
208+
'form_id' => 1, // Form ID (optional, can be false to apply to all forms)
209+
'field_id' => 3, // Post Image field ID
210+
'limits' => array(
211+
'caption' => array(
212+
'min' => 3,
213+
'max' => 10,
214+
),
215+
'description' => array(
216+
'min' => 2,
217+
'max' => 20,
218+
),
219+
// 'alt' => array(
220+
// 'min' => 1,
221+
// 'max' => 5
222+
// ),
223+
// 'title' => array(
224+
// 'min' => 1,
225+
// 'max' => 5
226+
// ),
227+
),
228+
) );
229+
230+
// Add more configurations as needed...
231+
// new GW_Post_Image_Word_Count( array(
232+
// 'form_id' => 2,
233+
// 'field_id' => 8,
234+
// 'limits' => array(
235+
// 'caption' => array( 'min' => 5, 'max' => 15 ),
236+
// ),
237+
// ) );

0 commit comments

Comments
 (0)