$field ) ); } /** * Check if a repeater has rows and initialize or step the loop. * * @param string $field Repeater field name. * @param mixed $post_id Post ID or object identifier. * @return bool True if active row exists, false otherwise. */ function repeaterkit_have_rows( string $field, $post_id = false ): bool { $post_id = $post_id ? $post_id : get_the_ID(); // If loop is already active for this field & post_id, step to see if more rows exist. if ( RepeaterKit_Loop_Manager::is_loop_active( $field, $post_id ) ) { return RepeaterKit_Loop_Manager::step_active(); } // Otherwise initialize new loop. if ( ! RepeaterKit_Loop_Manager::init_loop( $field, $post_id ) ) { return false; } // Check if first row exists. return RepeaterKit_Loop_Manager::step_active(); } /** * Advance the repeater loop to the next row. * * @return void */ function repeaterkit_the_row(): void { RepeaterKit_Loop_Manager::advance(); } /** * Get a subfield value from the current repeater row. * * @param string $name Subfield name. * @param mixed $fallback Fallback value if subfield is not set. * @return mixed Raw formatted value. The caller must escape appropriate to context. */ function repeaterkit_get_sub_field( string $name, $fallback = null ) { $row = RepeaterKit_Loop_Manager::get_current(); if ( ! $row || ! is_array( $row ) ) { return $fallback; } if ( array_key_exists( $name, $row ) ) { return $row[ $name ]; } return $fallback; } /** * Output an escaped subfield value from the current repeater row. * * All echoed values are escaped late using context-appropriate WordPress escaping functions. * For unescaped raw values, use repeaterkit_get_sub_field() instead. * * @param string $name Subfield name. * @param string $escape Escaping context ('html', 'attr', 'url', 'wysiwyg'). Default 'html'. * @return void */ function repeaterkit_the_sub_field( string $name, string $escape = 'html' ): void { $val = repeaterkit_get_sub_field( $name, '' ); if ( is_array( $val ) || is_object( $val ) ) { return; } $string_val = (string) $val; switch ( strtolower( $escape ) ) { case 'attr': echo esc_attr( $string_val ); break; case 'url': echo esc_url( $string_val ); break; case 'wysiwyg': echo wp_kses_post( $string_val ); break; case 'html': default: echo esc_html( $string_val ); break; } } /** * Get total row count of a repeater field. * * @param string $field Field name. * @param mixed $post_id Post ID. * @return int Total row count. */ function repeaterkit_get_row_count( string $field, $post_id = false ): int { $rows = repeaterkit_get_rows( $field, $post_id ); return count( $rows ); } /** * Get the current 1-based index in the repeater loop. * * @return int 1-based row index, or 0 if outside a loop. */ function repeaterkit_get_row_index(): int { return RepeaterKit_Loop_Manager::get_index(); } /** * Reset all active repeater loops. * * @return void */ function repeaterkit_reset_rows(): void { RepeaterKit_Loop_Manager::reset(); }