How to limit this foreach loop to 10 loops? - php

How can I limit the code below to show 10 loops.
foreach( $entries as $entry ) {
echo '<tr>';
$fields = wpforms_decode( $entry->fields );
foreach( $fields as $field ) {
if ( in_array( $field['id'], $ids)) {
echo '<td>' . apply_filters( 'wpforms_html_field_value', wp_strip_all_tags( $field['value'] ), $field, $form_data, 'entry-frontend-table' );
}
}
echo '</tr>';
}

like this :
$i = 0;
foreach( $entries as $entry ) {
$i++;
if ($i > 9 ) break; // this will stop after the 10th loop and in the beginning of loop 11
echo '<tr>';
$fields = wpforms_decode( $entry->fields );
foreach( $fields as $field ) {
// if you want to stop this loop too use $ii not $i
// but notice stopping this loop will not stop the parent loop !
if ( in_array( $field['id'], $ids)) {
echo '<td>' . apply_filters( 'wpforms_html_field_value', wp_strip_all_tags( $field['value'] ), $field, $form_data, 'entry-frontend-table' );
}
}
echo '</tr>';
}

One possibility where the loop to break is the first one:
foreach( $entries as $key=>$entry )
{
if($key==9) break;
echo '<tr>';
$fields = wpforms_decode( $entry->fields );
foreach( $fields as $field )
{
if ( in_array( $field['id'], $ids))
{
echo '<td>' . apply_filters( 'wpforms_html_field_value', wp_strip_all_tags( $field['value'] ), $field, $form_data, 'entry-frontend-table' );
}
}
echo '</tr>';
}
Another possiblity where the loop to break is the second one:
foreach( $entries as $entry )
{
echo '<tr>';
$fields = wpforms_decode( $entry->fields );
foreach( $fields as $key=>$field )
{
if($key==9) break;
if ( in_array( $field['id'], $ids))
{
echo '<td>' . apply_filters( 'wpforms_html_field_value', wp_strip_all_tags( $field['value'] ), $field, $form_data, 'entry-frontend-table' );
}
}
echo '</tr>';
}
If you want to stop the whole process / method / function you might want to use return instead of break. Break will just stop the current loop process.

Related

Display specific product attribute on Woocommerce cart page

I want to display a specific product attribute on the Woocommerce cart page and checkout page, below the product name in the table. Is this somehow possible with
custom_display_attribute
?
You can use the below filter to display the attributes on the cart page. Reference link: https://isabelcastillo.com/show-woocommerce-product-attributes-on-cart-page
/**
* WooCommerce: show all product attributes, separated by comma, on cart page
*/
function isa_woo_cart_attribute_values( $cart_item, $cart_item_key ) {
$item_data = $cart_item_key['data'];
$attributes = $item_data->get_attributes();
if ( ! $attributes ) {
return $cart_item;
}
$out = $cart_item . '<br />';
$count = count( $attributes );
$i = 0;
foreach ( $attributes as $attribute ) {
// skip variations
if ( $attribute->get_variation() ) {
continue;
}
$name = $attribute->get_name();
if ( $attribute->is_taxonomy() ) {
$product_id = $item_data->get_id();
$terms = wp_get_post_terms( $product_id, $name, 'all' );
// get the taxonomy
$tax = $terms[0]->taxonomy;
// get the tax object
$tax_object = get_taxonomy($tax);
// get tax label
if ( isset ( $tax_object->labels->singular_name ) ) {
$tax_label = $tax_object->labels->singular_name;
} elseif ( isset( $tax_object->label ) ) {
$tax_label = $tax_object->label;
// Trim label prefix since WC 3.0
$label_prefix = 'Product ';
if ( 0 === strpos( $tax_label, $label_prefix ) ) {
$tax_label = substr( $tax_label, strlen( $label_prefix ) );
}
}
$out .= $tax_label . ': ';
$tax_terms = array();
foreach ( $terms as $term ) {
$single_term = esc_html( $term->name );
array_push( $tax_terms, $single_term );
}
$out .= implode(', ', $tax_terms);
if ( $count > 1 && ( $i < ($count - 1) ) ) {
$out .= ', ';
}
$i++;
// end for taxonomies
} else {
// not a taxonomy
$out .= $name . ': ';
$out .= esc_html( implode( ', ', $attribute->get_options() ) );
if ( $count > 1 && ( $i < ($count - 1) ) ) {
$out .= ', ';
}
$i++;
}
}
echo $out;
}
add_filter( 'woocommerce_cart_item_name', isa_woo_cart_attribute_values, 10, 2 );

Add order numbers to children elements, 1,2,3,4,5

I'm trying to output order numbers to elements that are generated from gallery captions.
foreach ( $item['gallery'] as $image ) {
$lines = intval( apply_filters( 'caption_line', 1 ) );
for ( $line = 1; $line <= $lines; $line++ ) {
$attachment_post = get_post( $image['id'] );
$image_caption = $attachment_post->post_excerpt;
echo '<span class="dot1" onclick="currentSlide' . $item['unit_link'] . '(' . esc_attr( $line ) . ')">' . $image_caption . '</span>';
}
}
So I need 1,2,3,4...to be generated for $line, but for what I have tried it only output 1 for all elements, changing 1 $lines = intval( apply_filters( 'caption_line', 1 ) ); to higher number shows the number, but also duplicate them.
Just figured it out, this does exactly what I was looking for!
foreach ( $item['gallery'] as $key => $image ) {
$attachment_post = get_post( $image['id'] );
$image_caption = $attachment_post->post_excerpt;
$keyplus = $key+1;
echo '<span class="dot1" onclick="currentSlide' . $item['unit_link'] . '(' . $keyplus . ')">' . $image_caption . '</span>';
}

PHP - Is it possible to add a string to a variable?

I would like to make a small change in a code for a table of contents.
I want to add a sign in front of each heading. The character should be recognized as text.
I've tried a few things, but unfortunately I have not found the right variable.
The code comes from a plugin for Wordpress
I have already tried the following variables:
$items
$tic
$find
$replace
$post
Here is the code that prints the list:
if ( $tic->is_eligible($custom_toc_position) ) {
extract( $args );
$items = $tic->extract_headings( $find, $replace,wptexturize($post->post_content) );
$title = ( array_key_exists('title', $instance) ) ? apply_filters('widget_title', $instance['title']) : '';
if ( strpos($title, '%PAGE_TITLE%') !== false ) $title = str_replace( '%PAGE_TITLE%', get_the_title(), $title );
if ( strpos($title, '%PAGE_NAME%') !== false ) $title = str_replace( '%PAGE_NAME%', get_the_title(), $title );
$hide_inline = $toc_options['show_toc_in_widget_only'];
$css_classes = '';
// bullets?
if ( $toc_options['bullet_spacing'] )
$css_classes .= ' have_bullets';
else
$css_classes .= ' no_bullets';
if ( $items ) {
// before widget (defined by themes)
echo $before_widget;
// display the widget title if one was input (before and after titles defined by themes)
if ( $title ) echo $before_title . $title . $after_title;
// display the list
echo '<ul class="toc_widget_list' . $css_classes . '">' . $items . '</ul>';
// after widget (defined by themes)
echo $after_widget;
}
This are the full code of function extract_headings:
public function extract_headings( &$find, &$replace, $content = '' )
{
$matches = array();
$anchor = '';
$items = false;
// reset the internal collision collection as the_content may have been triggered elsewhere
// eg by themes or other plugins that need to read in content such as metadata fields in
// the head html tag, or to provide descriptions to twitter/facebook
$this->collision_collector = array();
if ( is_array($find) && is_array($replace) && $content ) {
// get all headings
// the html spec allows for a maximum of 6 heading depths
if ( preg_match_all('/(<h([1-6]{1})[^>]*>).*<\/h\2>/msuU', $content, $matches, PREG_SET_ORDER) ) {
// remove undesired headings (if any) as defined by heading_levels
if ( count($this->options['heading_levels']) != 6 ) {
$new_matches = array();
for ($i = 0; $i < count($matches); $i++) {
if ( in_array($matches[$i][2], $this->options['heading_levels']) )
$new_matches[] = $matches[$i];
}
$matches = $new_matches;
}
// remove specific headings if provided via the 'exclude' property
if ( $this->options['exclude'] ) {
$excluded_headings = explode('|', $this->options['exclude']);
if ( count($excluded_headings) > 0 ) {
for ($j = 0; $j < count($excluded_headings); $j++) {
// escape some regular expression characters
// others: http://www.php.net/manual/en/regexp.reference.meta.php
$excluded_headings[$j] = str_replace(
array('*'),
array('.*'),
trim($excluded_headings[$j])
);
}
$new_matches = array();
for ($i = 0; $i < count($matches); $i++) {
$found = false;
for ($j = 0; $j < count($excluded_headings); $j++) {
if ( #preg_match('/^' . $excluded_headings[$j] . '$/imU', strip_tags($matches[$i][0])) ) {
$found = true;
break;
}
}
if (!$found) $new_matches[] = $matches[$i];
}
if ( count($matches) != count($new_matches) )
$matches = $new_matches;
}
}
// remove empty headings
$new_matches = array();
for ($i = 0; $i < count($matches); $i++) {
if ( trim( strip_tags($matches[$i][0]) ) != false )
$new_matches[] = $matches[$i];
}
if ( count($matches) != count($new_matches) )
$matches = $new_matches;
// check minimum number of headings
if ( count($matches) >= $this->options['start'] ) {
for ($i = 0; $i < count($matches); $i++) {
// get anchor and add to find and replace arrays
$anchor = $this->url_anchor_target( $matches[$i][0] );
$find[] = $matches[$i][0];
$replace[] = str_replace(
array(
$matches[$i][1], // start of heading
'</h' . $matches[$i][2] . '>' // end of heading
),
array(
$matches[$i][1] . '<span id="' . $anchor . '">',
'</span></h' . $matches[$i][2] . '>'
),
$matches[$i][0]
);
// assemble flat list
if ( !$this->options['show_heirarchy'] ) {
$items .= '<li><a href="#' . $anchor . '">';
if ( $this->options['ordered_list'] ) $items .= count($replace) . ' ';
$items .= strip_tags($matches[$i][0]) . '</a></li>';
}
}
// build a hierarchical toc?
// we could have tested for $items but that var can be quite large in some cases
if ( $this->options['show_heirarchy'] ) $items = $this->build_hierarchy( $matches );
}
}
}
return $items;
}
I tried it like this:
$items = '>'.$items
$tic = '>'.$tic
$find = '>'.$find
.
.
.
Unfortunately, nothing has hit the right place
$ items addressed only the entire list
The other Variables had no effect or led to errors
The extract_headings is creating the list items. This section of the function...
// assemble flat list
if ( !$this->options['show_heirarchy'] ) {
$items .= '<li><a href="#' . $anchor . '">';
if ( $this->options['ordered_list'] ) $items .= count($replace) . ' ';
$items .= strip_tags($matches[$i][0]) . '</a></li>';
}
Should look like this:
// assemble flat list
if ( !$this->options['show_heirarchy'] ) {
$items .= '<li><a href="#' . $anchor . '">>';
if ( $this->options['ordered_list'] ) $items .= count($replace) . ' ';
$items .= strip_tags($matches[$i][0]) . '</a></li>';
}
You can see I've added an extra > inside the hyperlink on the third line. If adding an extra > causes any issues, you can also use >.

HTML every 5 iterations on foreach

I´m using extra_user_details.php on wordpress to show user details in a private profile page. As I´m using a lot of extra fields I though about break the query and make the same output every X values in order to show as tabs:
function eud_extract_ExtraFields() {
if ( get_option( 'eud_fields' ) ) {
$all_fields = unserialize( get_option( 'eud_fields' ) );
if ( count( $all_fields ) > 0 ) {
$output = '';
foreach ( $all_fields as $key => $value ) {
if ( isset($value[3]) && ! empty($value[3]) ) {
if ( ($value[3] == 'disable') || ! current_user_can($value[3]) ) {
continue;
}
}
$output .= '<tr>
<th><label for="eud' . esc_attr( $value[1] ) . '">' . esc_attr( $value[0] ) . '</label></th>
<td><input name="eud' . esc_attr( $value[1] ) . '" id="eud' . esc_attr( $value[1] ) . '" type="text" value="' . esc_attr( get_user_meta( get_user_id(), $value[1], true ) ) . '" class="regular-text code" /> <span class="description">' . ( ( isset( $value[2] ) && $value[2] !== '' ) ? esc_attr( stripslashes( $value[2] ) ) : '' ) . '</span></td>
</tr>';
}
}
if ($output != '') {
echo '<div><table class="form-table">';
echo $output;
echo '</table></div>';
}
} }
Thanks!
I´m not sure if this is what I´m looking for. I´m just near...
function eud_extract_ExtraFields() {
if ( get_option( 'eud_fields' ) ) {
$all_fields = unserialize( get_option( 'eud_fields' ) );
if ( count( $all_fields ) > 0 ) {
$output = '';
$i=0;
foreach ($all_fields as $key => $value ) {
if ( isset($value[3]) && ! empty($value[3]) ) {
if ( ($value[3] == 'disable') || ! current_user_can($value[3]) ) {
continue;
}
}
$output .= '<tr>
<th><label for="eud' . esc_attr( $value[1] ) . '">' . esc_attr( $value[0] ) . '</label></th>
<td><input name="eud' . esc_attr( $value[1] ) . '" id="eud' . esc_attr( $value[1] ) . '" type="text" value="' . esc_attr( get_user_meta( get_user_id(), $value[1], true ) ) . '" class="regular-text code" /> <span class="description">' . ( ( isset( $value[2] ) && $value[2] !== '' ) ? esc_attr( stripslashes( $value[2] ) ) : '' ) . '</span></td>
</tr>';
++$i;
if(!($i % 2)) {
echo '<div><table class="form-table">';
echo $output;
echo '</table></div>';
}
}
}
}
}
But I need to split the echo, I mean, now the results are:
first tab echo 1, 2
second tab echo 1,2,3,4
third tab echo 1,2,3,4,5,6
and I need the $output to be just:
first tab echo 1,2
second tab echo 3,4
third tab echo 5,6
fourth tab echo 7 (if exists)
You could use modulus:
$i=0;
foreach ( $all_fields as $key => $value ) {
if( $i++%5 === 0 ){ echo 'I was number 5';}
}
or if you prefer a binary comparison (should be faster):
if( $i++&101 === 0 ){ echo 'I was number 5';}
I'll give you an example, you can piece it together for your code:
Lets say you have an N amount of span, and you want them grouped per 5 in a div:
// You start with:
echo '<div>';
for($i=1; $i<=23; $i++){
echo '<span> '.$i.' </span>'; // just an example, could be anything here
}
echo '</div>';
This will place 23 span in one big div. Now we add something to group them by 5:
// You start with:
echo '<div>';
for($i=1; $i<=23; $i++){
echo '<span> '.$i.' </span>'; // just an example, could be anything here
if( $i %5===0 ){
echo '</div><div>'; // every 5th, close the div, and open a fresh one.
}
}
echo '</div>';
This will result in 5 (=coincedence, nothing to do with %5) div's, 4 with 5 spans, and one with the remaining 3. You can do this trick with about any element.
Tip: in the modulus-if-statement you should add the max: $i %5===0 && $i!==23, to prevent </div></div><div> if $i is a number devidable by 5.
Solution came from a friend, thanks!
function eud_extract_ExtraFields() {
if (get_option('eud_fields')) {
$all_fields = unserialize(get_option('eud_fields'));
if (count($all_fields) > 0) {
$output = '';
$i = 1;
$htmlTotal = '';
foreach ($all_fields as $key => $value) {
if (isset($value[3]) && !empty($value[3])) {
if (($value[3] == 'disable') || !current_user_can($value[3])) {
continue;
}
}
$output .= '<tr>
<th><label for="eud' . esc_attr($value[1]) . '">' . esc_attr($value[0]) . '</label></th>
<td><input name="eud' . esc_attr($value[1]) . '" id="eud' . esc_attr($value[1]) . '" type="text" value="' . esc_attr(get_user_meta(get_user_id(), $value[1], true)) . '" class="regular-text code" /> <span class="description">' . ( ( isset($value[2]) && $value[2] !== '' ) ? esc_attr(stripslashes($value[2])) : '' ) . '</span></td>
</tr>';
$i++;
/* number of fields to show per tab */
if ($i % 2) {
$htmlTotal .= '<div><table class="form-table">' . $output . '</table></div>';
$output = '';
}
}
echo $htmlTotal;
}
}
}

php date only show in first row

Good Day,
I have received this code to form a plugin for Ninja Forms. This code enables you to put the submissions of a form on the front end. Everything was working fine until we added a date function. This function is supposed to put the date in front of every row it creates. Unfortunately it only puts the date in front of the first row, the every row after that, the information moves one column to the left with no date.
<?php
function test_display_submissions( $args = array() ) {
// $args = array(
// 'form_id' => 1
// );
$form_id = $args['form_id'];
$columns = $args['cols'];
$columns = explode( ',', $columns );
$sub_results = ninja_forms_get_subs( array( 'form_id' => $form_id ) );
$plugin_settings = get_option("ninja_forms_settings");
if(isset($plugin_settings['date_format'])){
$date_format = $plugin_settings['date_format'];
} else {
$date_format = 'm/d/Y';
}
$content = '<table>
<thead>
<tr>';
$content .= '<th>Date</th>';
foreach ( $columns as $id ) {
$field = ninja_forms_get_field_by_id( $id );
if( isset( $field['data']['label'] ) ){
$label = $field['data']['label'];
} else {
$label = '';
}
$content .= '<th>' . $label . '</th>';
}
$content .= '</tr>
</thead>
<tbody>';
$content .= '<td>' . date($date_format, strtotime($sub['date_updated'])) . '</td>';
foreach ( $sub_results as $sub ) {
$fields = $sub['data'];
echo '<tr>';
foreach ( $fields as $field ) {
$field_id = $field['field_id'];
$user_value = $field['user_value'];
if ( in_array( $field_id, $columns ) ) {
$content .= '<td>' . $user_value . '</td>';
}
}
$content .= '</tr>';
}
$content .= '</tbody>
</table>';
return $content;
}
add_shortcode( 'display_subs', 'test_display_submissions' );
The problem is in the foreach loop. You need to place your date in the loop, not before :
foreach ( $sub_results as $sub ) {
// Display date
$fields = $sub['data'];
$content .= '<tr>';
$content .= '<td>' . date($date_format, strtotime($sub['date_updated'])) . '</td>';
foreach ( $fields as $field ) {
$field_id = $field['field_id'];
$user_value = $field['user_value'];
if ( in_array( $field_id, $columns ) ) {
$content .= '<td>' . $user_value . '</td>';
}
}
$content .= '</tr>';
}
$content .= '</tbody>
You have the beginning after you have the date added to the table.
It should be <tbody><tr><td>DATE STUFF</td><td>MORE CONTENT</td></tr><tbody>
in this format and your date column should be placed within your foreach loop.

Categories