Skip to content

gwpc-post-image-subfields.php: Added snippet to enable word count for Post Image subfields. #1148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 213 additions & 0 deletions gp-word-count/gwpc-post-image-subfields.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
<?php
/**
* Gravity Wiz // Gravity Forms // Word Count for Post Image Subfields (Caption, Description, Alt, Title)
*
* Instruction Video: https://www.loom.com/share/005eda834a6348f9a874a5e6cdd85461
*
* Set min/max word counts for any Post Image subfield (caption, description, alt, title) per field.
* Supports multiple subfields per field.
*
* @version 1.0.0
* @author David Smith <[email protected]>
* @license GPL-2.0+
* @link https://gravitywiz.com/
*/
class GW_Post_Image_Word_Count {

private static $_instance = null;
private $_configs = array();

Check warning on line 18 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

Equals sign not aligned with surrounding assignments; expected 9 spaces but found 1 space

public static function get_instance() {
if ( self::$_instance === null ) {
self::$_instance = new self();
}
return self::$_instance;
}

public function __construct( $config = array() ) {

$this->_configs[] = array_merge( array(
'form_id' => false,
'field_id' => false,
'limits' => array()

Check failure on line 32 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

Each array item in a multi-line array declaration must end in a comma
), $config );

add_action( 'init', array( $this, 'init' ) );

}

public function init() {

if ( ! $this->is_applicable() ) {
return;
}

add_action( 'gform_enqueue_scripts', array( $this, 'enqueue_scripts' ), 20 );
add_action( 'gform_register_init_scripts', array( $this, 'enqueue_textarea_counter' ), 20 );
add_filter( 'gform_validation', array( $this, 'validate_word_count' ) );

}

public function is_applicable() {
return ! empty( $this->_configs );
}

// Map subfield keys to their input suffixes and labels.
public function get_subfields() {
return array(
'caption' => array( 'suffix' => '4', 'label' => __( 'Caption', 'gravityforms' ) ),

Check failure on line 58 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

When a multi-item array uses associative keys, each value should start on a new line.
'description' => array( 'suffix' => '7', 'label' => __( 'Description', 'gravityforms' ) ),

Check failure on line 59 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

When a multi-item array uses associative keys, each value should start on a new line.
'alt' => array( 'suffix' => '2', 'label' => __( 'Alt Text', 'gravityforms' ) ),

Check failure on line 60 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

When a multi-item array uses associative keys, each value should start on a new line.
'title' => array( 'suffix' => '1', 'label' => __( 'Title', 'gravityforms' ) ),

Check failure on line 61 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

When a multi-item array uses associative keys, each value should start on a new line.
);
}

public function enqueue_scripts( $form ) {
// Check if any Post Image field is configured for word count.
foreach ( $this->_configs as $config ) {
if ( ( ! $config['form_id'] || $form['id'] == $config['form_id'] ) && $config['field_id'] ) {
foreach ( $form['fields'] as $field ) {
if ( $field->id == $config['field_id'] && $field->type === 'post_image' ) {
// Force enqueue the GP Word Count JS.
wp_enqueue_script( 'gp-word-count', plugins_url( 'scripts/jquery.textareaCounter.js', 'gwwordcount/gwwordcount.php' ), array( 'jquery' ), null, true );
return;
}
}
}
}
}

public function enqueue_textarea_counter( $form ) {

foreach ( $this->_configs as $config ) {
if ( ! $this->is_config_applicable_to_form( $config, $form ) ) {
continue;
}

$field = GFAPI::get_field( $form, $config['field_id'] );
if ( ! $field || $field->type !== 'post_image' || empty( $config['limits'] ) ) {
continue;
}

$form_id = $form['id'];
$field_id = $field->id;

foreach ( $config['limits'] as $subfield => $limits ) {
$subfields = $this->get_subfields();
if ( empty( $subfields[ $subfield ] ) ) {
continue;
}

$suffix = $subfields[ $subfield ]['suffix'];
$min = isset( $limits['min'] ) ? intval( $limits['min'] ) : 0;
$max = isset( $limits['max'] ) ? intval( $limits['max'] ) : 0;

$args = array(
'formId' => $form_id,

Check warning on line 106 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

Array double arrow not aligned correctly; expected 18 space(s) between &quot;'formId'&quot; and double arrow, but found 17.
'limit' => $max,
'min' => $min,
'truncate' => true,
'defaultLabel' => sprintf( __( 'Max: %s words', 'gp-word-count' ), '{limit}' ),

Check warning on line 110 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

A gettext call containing placeholders was found, but was not accompanied by a &quot;translators:&quot; comment on the line above to clarify the meaning of the placeholders.
'defaultLabelSingular' => sprintf( __( 'Max: %s word', 'gp-word-count' ), '{limit}' ),

Check warning on line 111 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

A gettext call containing placeholders was found, but was not accompanied by a &quot;translators:&quot; comment on the line above to clarify the meaning of the placeholders.
'counterLabel' => sprintf( __( '%s words left', 'gp-word-count' ), '{remaining}' ),

Check warning on line 112 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

A gettext call containing placeholders was found, but was not accompanied by a &quot;translators:&quot; comment on the line above to clarify the meaning of the placeholders.
'counterLabelSingular' => sprintf( __( '%s word left', 'gp-word-count' ), '{remaining}' ),

Check warning on line 113 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

A gettext call containing placeholders was found, but was not accompanied by a &quot;translators:&quot; comment on the line above to clarify the meaning of the placeholders.
'limitReachedLabel' => '<span class="gwwc-max-reached" style="font-weight:bold;">' . sprintf( __( '%s words left', 'gp-word-count' ), '{remaining}' ) . '</span>',

Check warning on line 114 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

A gettext call containing placeholders was found, but was not accompanied by a &quot;translators:&quot; comment on the line above to clarify the meaning of the placeholders.
'limitExceededLabel' => '<span class="gwwc-max-exceeded" style="font-weight:bold;color:#c0392b;">' . sprintf( __( 'Limit exceeded!', 'gp-word-count' ), '{remaining}' ) . '</span>',
'minCounterLabel' => sprintf( __( '%s more words required', 'gp-word-count' ), '{remaining}' ),

Check warning on line 116 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

A gettext call containing placeholders was found, but was not accompanied by a &quot;translators:&quot; comment on the line above to clarify the meaning of the placeholders.
'minCounterLabelSingular' => sprintf( __( '%s more word required', 'gp-word-count' ), '{remaining}' ),

Check warning on line 117 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

A gettext call containing placeholders was found, but was not accompanied by a &quot;translators:&quot; comment on the line above to clarify the meaning of the placeholders.
'minReachedLabel' => '<span class="gwwc-min-reached" style="font-weight:bold;color:#27ae60">' . __( 'Minimum word count met.', 'gp-word-count' ) . '</span>',
'minDefaultLabel' => sprintf( __( 'Min: %s words', 'gp-word-count' ), '{min}' ),

Check warning on line 119 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

A gettext call containing placeholders was found, but was not accompanied by a &quot;translators:&quot; comment on the line above to clarify the meaning of the placeholders.
'minDefaultLabelSingular' => sprintf( __( 'Min: %s word', 'gp-word-count' ), '{min}' ),
);

$args_json = json_encode( $args );
$input_id = "input_{$form_id}_{$field_id}_{$suffix}";
$script = "jQuery('#{$input_id}').textareaCounter({$args_json});";

GFFormDisplay::add_init_script( $form_id, "gwwc_post_image_{$subfield}_wc_{$field_id}", GFFormDisplay::ON_PAGE_RENDER, $script );
}
}

}

public function validate_word_count( $result ) {

$form = $result['form'];

foreach ( $this->_configs as $config ) {
if ( ! $this->is_config_applicable_to_form( $config, $form ) ) {
continue;
}

foreach ( $form['fields'] as &$field ) {
if ( $field->id != $config['field_id'] || $field->type !== 'post_image' || empty( $config['limits'] ) ) {
continue;
}

foreach ( $config['limits'] as $subfield => $limits ) {
$subfields = $this->get_subfields();
if ( empty( $subfields[ $subfield ] ) ) {
continue;
}

$suffix = $subfields[ $subfield ]['suffix'];
$label = $subfields[ $subfield ]['label'];
$input_name = "input_{$field->id}_{$suffix}";
$value = rgpost( $input_name );
$word_count = preg_match_all( '/\S+/', trim( $value ) );

Comment on lines +153 to +158
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid PHP 8.1+ deprecation/warnings: ensure trim() gets a string

If the subfield isn’t present, rgpost() may return null. trim(null) is deprecated. Cast before trimming and handle the empty case.

Apply this diff:

-					$input_name = "input_{$field->id}_{$suffix}";
-					$value      = rgpost( $input_name );
-					$word_count = preg_match_all( '/\S+/', trim( $value ) );
+					$input_name = "input_{$field->id}_{$suffix}";
+					$value      = trim( (string) rgpost( $input_name ) );
+					$word_count = $value === '' ? 0 : preg_match_all( '/\S+/', $value );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$suffix = $subfields[ $subfield ]['suffix'];
$label = $subfields[ $subfield ]['label'];
$input_name = "input_{$field->id}_{$suffix}";
$value = rgpost( $input_name );
$word_count = preg_match_all( '/\S+/', trim( $value ) );
$suffix = $subfields[ $subfield ]['suffix'];
$label = $subfields[ $subfield ]['label'];
$input_name = "input_{$field->id}_{$suffix}";
$value = trim( (string) rgpost( $input_name ) );
$word_count = $value === '' ? 0 : preg_match_all( '/\S+/', $value );
🤖 Prompt for AI Agents
In gp-word-count/gwpc-post-image-subfields.php around lines 153 to 158, rgpost()
can return null so calling trim() directly can trigger PHP 8.1+ deprecation
warnings; ensure you coerce the value to a string or default to an empty string
before trimming and then only call preg_match_all if the trimmed string is
non-empty (otherwise set word_count to 0). Replace the direct trim($value) usage
with a safe string cast or null coalescing to '' and handle the empty case to
avoid warnings and produce a correct 0 word count.

$min = isset( $limits['min'] ) ? intval( $limits['min'] ) : 0;
$max = isset( $limits['max'] ) ? intval( $limits['max'] ) : 0;

if ( $min && $word_count < $min ) {
$field->failed_validation = true;
$field->validation_message = sprintf(
_n( '%s must be at least %s word.', '%s must be at least %s words.', $min, 'gp-word-count' ),

Check failure on line 165 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

Multiple placeholders should be ordered. Expected '%1$s, %2$s', but got %s, %s.

Check failure on line 165 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

Multiple placeholders should be ordered. Expected '%1$s, %2$s', but got %s, %s.
$label, $min
);
$result['is_valid'] = false;
}

if ( $max && $word_count > $max ) {
$field->failed_validation = true;
$field->validation_message = sprintf(
_n( '%s may only be %s word.', '%s may only be %s words.', $max, 'gp-word-count' ),

Check failure on line 174 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

Multiple placeholders should be ordered. Expected '%1$s, %2$s', but got %s, %s.

Check failure on line 174 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

Multiple placeholders should be ordered. Expected '%1$s, %2$s', but got %s, %s.
$label, $max
);
$result['is_valid'] = false;
}
}
}
}

$result['form'] = $form;
return $result;

}

private function is_config_applicable_to_form( $config, $form ) {
return ( ! $config['form_id'] || $form['id'] == $config['form_id'] ) && $config['field_id'];
}

}

// CONFIGURATION: Set your field IDs and subfield limits here.
new GW_Post_Image_Word_Count( array(
'form_id' => 1, // Form ID (optional, can be false to apply to all forms)
'field_id' => 3, // Post Image field ID
'limits' => array(
'caption' => array( 'min' => 3, 'max' => 10 ),

Check failure on line 199 in gp-word-count/gwpc-post-image-subfields.php

View workflow job for this annotation

GitHub Actions / PHPCS (Files Changed)

Spaces must be used for mid-line alignment; tabs are not allowed
'description' => array( 'min' => 2, 'max' => 20 ),
// 'alt' => array( 'min' => 1, 'max' => 5 ),
// 'title' => array( 'min' => 1, 'max' => 5 ),
),
) );

// Add more configurations as needed...
// new GW_Post_Image_Word_Count( array(
// 'form_id' => 2,
// 'field_id' => 8,
// 'limits' => array(
// 'caption' => array( 'min' => 5, 'max' => 15 ),
// ),
// ) );