style(), 'group.php' ), [ 'attributes' => Field::html_attributes( [ 'class' => 'remaily-group', 'data-remaily-group' => $inner ? null : $group, 'hidden' => !$inner && $hidden, 'inert' => !$inner && $hidden, ] ), 'content' => $mark, 'group' => $group, 'inner' => $inner, 'form' => $form, ] ); return false !== strpos( $html, $mark ) ? explode( $mark, $html, 2 ) : [ $html, '' ]; } /** * A repeated group (form/{style}/repeater.php): its rows (repeater-row.php), a template the front script copies for a new * one, and the Add and Remove buttons (repeater-button.php) * * @param Form $form Form * @param string $group Group * @param array $repeater Its settings and fields * @param string $inner Its part of the template * @param array $sent Sent values of its fields by row * @param callable $render A token's HTML * @param bool $hidden Hidden by its conditions * * @return string */ public static function repeater( Form $form, $group, array $repeater, $inner, array $sent, callable $render, $hidden ) { $min = (int) $repeater['min']; $max = (int) $repeater['max'] ?: Repeater::LIMIT; $remove = self::repeater_button( $form, $group, 'remove', $repeater['remove'] ?: __( 'Remove', 'remaily' ) ); $keys = []; // The rows sent back (without the script), else as many as it starts with foreach ( $repeater['fields'] as $name ) { $keys = array_merge( $keys, array_filter( array_keys( $sent[ $name ] ?? [] ), 'is_int' ) ); } $keys = array_unique( $keys ); sort( $keys ); $keys = $keys ?: range( 0, max( $min, 1 ) - 1 ); $row = static fn( $key ) => StyleManager::render_template( StyleManager::form_file( $form->style(), 'repeater-row.php' ), [ 'attributes' => Field::html_attributes( [ 'class' => 'remaily-repeater__row', 'data-remaily-row' => (string) $key, ] ), 'content' => Template::replace( $inner, static fn( $token ) => $render( $token, [ $group, $key ] ) ), 'remove' => $remove, 'key' => $key, 'group' => $group, 'form' => $form, ] ); return StyleManager::render_template( StyleManager::form_file( $form->style(), 'repeater.php' ), [ 'attributes' => Field::html_attributes( [ 'class' => 'remaily-group remaily-repeater', 'data-remaily-group' => $group, 'data-remaily-repeater' => true, 'data-min' => (string) $min, 'data-max' => (string) $max, 'hidden' => $hidden, 'inert' => $hidden, ] ), 'rows' => implode( '', array_map( $row, $keys ) ), 'template' => '', 'add' => self::repeater_button( $form, $group, 'add', $repeater['add'] ?: __( 'Add another', 'remaily' ) ), 'group' => $group, 'settings' => $repeater, 'form' => $form, ] ); } /** * A repeated group's Add or Remove button (form/{style}/repeater-button.php) * * @param Form $form Form * @param string $group Group * @param string $action add or remove * @param string $label Button text * * @return string */ private static function repeater_button( Form $form, $group, $action, $label ) { return StyleManager::render_template( StyleManager::form_file( $form->style(), 'repeater-button.php' ), [ 'action' => $action, 'label' => $label, 'attributes' => Field::html_attributes( [ 'type' => 'button', 'class' => 'remaily-repeater__' . $action, 'data-remaily-' . $action => true, ] ), 'group' => $group, 'form' => $form, ] ); } }