Skip to content
This repository has been archived by the owner on Nov 6, 2022. It is now read-only.

Repeater row count and row index function. #429

Merged
merged 14 commits into from
Sep 17, 2019
Merged
Show file tree
Hide file tree
Changes from 4 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
24 changes: 24 additions & 0 deletions php/blocks/class-field.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,18 @@ public function cast_value( $value ) {
break;
}

if ( 'repeater' === $this->control ) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could the logic in this class be in the Repeater class, in a validate() method?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done in a1bb136.

/**
* Repeaters contain a blank row, to prevent them from being hidden when empty.
* This removes that row.
*/
if ( isset( $value['rows'] ) ) {
foreach ( $value['rows'] as $key => $row ) {
unset( $value['rows'][ $key ][''] );
}
}
}

return $value;
}

Expand All @@ -194,6 +206,18 @@ public function cast_value( $value ) {
* @return string $value The value to echo.
*/
public function cast_value_to_string( $value ) {
if ( 'repeater' === $this->control ) {
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
return sprintf(
// translators: Placeholders are the opening and closing anchor tags of a link.
__( '⚠️ Please use Block Lab\'s %1$srepeater functions%2$s to display repeater fields in your template.', 'block-lab' ),
'<a href="https://getblocklab.com/docs/fields/repeater/">',
'</a>'
);
}
return '';
}

if ( is_array( $value ) ) {
return implode( ', ', $value );
}
Expand Down
7 changes: 4 additions & 3 deletions php/blocks/controls/class-repeater.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ class Repeater extends Control_Abstract {
/**
* Field variable type.
*
* The Repeater control is an array of objects, with each row being an object.
* For example, a repeater with one row might be [ { 'example-text': 'Foo', 'example-image': 4232 } ].
* The Repeater control is an array of arrays, with each row being its own array.
* For example, a repeater with two rows might be:
* [ 'rows': [ 0: [ 'example-text': 'Foo', 'example-image': 42 ], 1: [ 'example-text': 'Bar', 'example-image': 32 ] ] ].
*
* @var string
*/
public $type = 'object';
public $type = 'array';
Copy link
Collaborator

Choose a reason for hiding this comment

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

Good thing to bring up. In PHP, this would be an array(), and in JS it'd be an object. I don't see many examples of array or object attributes in Core blocks.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah – makes much more sense for $type to represent the Javascript type, rather than the PHP type. Addressed in 2b61b64.


/**
* Repeater constructor.
Expand Down
41 changes: 41 additions & 0 deletions php/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,47 @@ function reset_block_rows( $name ) {
block_lab()->loop()->reset( $name );
}

/**
* Return the total amount of rows in a repeater.
*
* @param string $name The name of the repeater field.
* @return int|bool The total amount of rows. False if the repeater isn't found.
*/
function block_row_count( $name ) {
global $block_lab_attributes;

if ( ! isset( $block_lab_attributes[ $name ] ) ) {
Copy link
Collaborator

@kienstra kienstra Sep 13, 2019

Choose a reason for hiding this comment

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

This function looks good overall.

Is this conditional necessary?

It seems that if it's not set, the block below will return false:

if ( ! isset( $block_lab_attributes[ $name ]['rows'] ) ) {
	return false;
}

Copy link
Member Author

Choose a reason for hiding this comment

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

That's a really good point.

The thinking here is:

  1. Check if a row even exists
  2. Check if it's a repeater (has rows)

Given this, do you still think it's worth only doing the single (second) condition? I'm more than happy to make that change. Just wanted to explain my approach.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sure, it's kind of a nitpick 😄

My guess is that there's not much performance difference between the existing approach, and an approach with only one isset() check.

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed in 6300f33.

return false;
}

if ( ! isset( $block_lab_attributes[ $name ]['rows'] ) ) {
return false;
}

return count( $block_lab_attributes[ $name ]['rows'] );
}

/**
* Return the index of the current repeater row.
*
* Note: The index is zero-based, which means that the first row in a repeater has
* an index of 0, the second row has an index of 1, and so on.
*
* @param string $name (Optional) The name of the repeater field.
* @return int|bool The index of the row. False if the repeater isn't found.
*/
function block_row_index( $name = '' ) {
if ( '' === $name ) {
$name = block_lab()->loop()->active;
}

if ( ! isset( block_lab()->loop()->loops[ $name ] ) ) {
return false;
}

return block_lab()->loop()->loops[ $name ];
}

/**
* Return the value of a sub-field.
*
Expand Down
2 changes: 1 addition & 1 deletion tests/php/unit/blocks/controls/test-class-repeater.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function setUp() {
public function test_construct() {
$this->assertEquals( 'Repeater', $this->instance->label );
$this->assertEquals( 'repeater', $this->instance->name );
$this->assertEquals( 'object', $this->instance->type );
$this->assertEquals( 'array', $this->instance->type );
}

/**
Expand Down