Count loops in foreach and act based on that - php

Hi i have a function in PHP, which returns colors of my products in woocommerce.
My function:
global $product;
if ( $product->is_type('variable') ) {
$taxonomy = 'pa_color';
$colors = explode(',',$product->get_attribute($taxonomy));
echo '<div class="colour-swatch">';
foreach ($colors as $color) {
echo '<div class="swatch '. strtolower(trim($color)) .'">';
echo '<div class="circle">';
echo '<div style="background-color: var(--'. strtolower(trim($color)) .');"></div>';
echo '';
echo '</div>';
echo '</div>';
}
echo '</div>';
}
What i need is make it count how many colors it finds inside the loop (so how many times the loop is done). And echo it below.
So if one loop is done, it should (echo "1 color").
If 2 or more colors is found it should echo "x colors" (so include the s on color to make it correct).

// To print the total size of the colors.(the number of times the loop ran)
$sz = sizeof($colors);
echo $sz . (($sz==1) ? " color" : " colors");

Related

Display multiple product custom fields within a loop in WooCommerce

I have created 5 custom meta values for my products on WC but not every product have all custom fields.
At the moment, I am displaying the meta data like so:
<div class="meta">
<?php if($product->get_meta('metabox_animal') != '') echo '<div class="type"><p>Row One</p></div>' . $product->get_meta('metabox_animal'); ?>
<?php if($product->get_meta('metabox_medical') != '') echo '<div class="type"><p>Row Two</p></div>' . $product->get_meta('metabox_medical'); ?>
<?php if($product->get_meta('metabox_general') != '') echo '<div class="type"><p>Row Three</p></div>' . $product->get_meta('metabox_general'); ?>
<?php if($product->get_meta('metabox_capacity') != '') echo '<div class="type"><p>Row Four</p></div>' . $product->get_meta('metabox_capacity'); ?>
<?php if($product->get_meta('metabox_pet') != '') echo '<div class="type"><p>Row Five</p></div>' . $product->get_meta('metabox_pet'); ?>
</div>
Is there a way that I can create a loop that will cycle through all of the meta values and if they exist, display them but if they're blank / empty / not used show a container 'NOT APPLICABLE'?
Any help would be greatly appreciated!
This not tested and only one way you might get this done:
<?php
$html = '';
// collection of meta keys and their display label
$meta_keys_with_labels = [
['animal', 'Row One'],
['medical', 'Row Two'],
['general', 'Row Three'],
['capacity', 'Row Four'],
['pet', 'Row Five']
];
$html .= '<div class="meta">';
// loop to check if meta key/value exists and append to html string
foreach ($meta_keys_with_labels as $meta) {
// unpack the key and display label
[$key, $label] = $meta;
// grab meta value
$meta_value = $product->get_meta("metabox_$key");
// append meta value to html string
if (!empty($meta_value)) {
$html .= "<div class=\"type\"><p>$label</p></div>$meta_value";
}
}
$html .= '</div>';
echo $html;
Sure!
You can create an array of all the meta terms that you need to retrieve.
Following your code this is the code you will need. Of course you can add/remove as you see fit.
<?php
$meta_terms = [
'metabox_animal',
'metabox_medical',
'metabox_general',
'metabox_capacity',
'metabox_pet'
];
foreach ($meta_terms as $meta_term) {
$meta = $product->get_meta($meta_term);
if (!empty($meta)) {
echo '<div class="type"><p>' . $meta . '</p></div>';
}
}
So... what the hell did we do here?
First we created an array of all the meta data that we need to retrieve.
After we created that array we need to start an iteration to get, check and display each meta data.
For that we use a foreach (PHP foreach).
ok
In the foreach block, using the variable $meta_term that contains the meta string that we need to retrieve we now use it to get the product meta data.
Now we check if the meta data is not empty, using the !empty() function, if it's not empty than we know that there is value we can output so, using echo we can now build the proper html.
Hope this help =D
You can set your related data in an array, then use a foreach loop as follow and if a custom field value is empty or doesn't exist, "NOT APPLICABLE" will be displayed instead (code is commented):
<?php
// Data array with Meta key / Label pairs
$data = array(
'metabox_animal' => __("Row One"),
'metabox_medical' => __("Row Two"),
'metabox_general' => __("Row Three"),
'metabox_capacity' => __("Row Four"),
'metabox_pet' => __("Row Five"),
);
echo '<div class="meta">';
// Loop through the data array of Meta key / Label pairs
foreach ( $data as $meta_key => $label ) {
$meta_value = $product->get_meta($meta_key); // Get the meta value
$meta_value = empty($meta_value) ? __("NOT APPLICABLE") : $meta_value; // If empty show "NOT APPLICABLE"
echo '<div class="type"><strong>' . $label . '</strong>: ' . $meta_value . '</div>';
}
echo '</div>';
?>
I have changed a bit your html. If it's not convenient and you want to keep yours, just replace:
echo '<div class="type"><strong>' . $label . '</strong>: ' . $meta_value . '</div>';
by this line:
echo '<div class="type"><p>' . $label . '</p></div>' . $meta_value;

Understanding ask - group Indexes together in foreach loop

To be short - the code works.
But how ?
I made a PHP curl so scrape a website and get some events. Works.
Then i wanted to group some scraped events together. Tested some variations and to the end i did this:
$communities[$current_color][] = $li->plaintext;
Works. But i cant imagine how this is a grouping function....
Anyone an idea?
Here is the most important of my code:
echo '<article class="month">';
foreach( $html->find('tr') as $tr ){
$montName = $tr->find('.ev_td_left', 0);
echo '<h3>' . $montName->plaintext . '</h3>';
echo '<ul>';
foreach( $tr->find('li') as $li ){
$style = $li->style;
preg_match( "/#.{6}/", $style, $li_bgcolor );
/**
* Array nach Farben gruppieren
*/
$current_color = $li_bgcolor[0];
$communities[$current_color][] = $li->plaintext;
echo '<li><span class="event" style="background-color:'.$li_bgcolor[0].';"></span>'.$li->plaintext.'</li>';
}
echo '</ul>';
echo '<br/>';
}
echo '</article>';

Auto increment through a php loop

I have a case where I am using the code below to populate a template of sorts. Within the templates' javascript I would individually check the data attribute field I setup, essentially causing me to have multiple JS files instead of one that is shared. I then thought I could use a generic name field too, but prepend a number through the loop.
For example, with the line of code below where the `name="testField". I want to see if there is a way that I can add a number, but auto increment it through the loop with php.
Is this possible?
echo '<div class="markerItem" name="testField' . $number . '" "data-marker="' . $marker_data . '">';
PHP Code
if ($marker_stmt = $con->prepare($sql_marker)) {
$marker_stmt->execute();
$marker_rows = $marker_stmt->fetchAll(PDO::FETCH_ASSOC);
echo '<div id="projMarker">';
foreach ($marker_rows as $marker_row) {
$marker_solution = $marker_row['solution'];
$maker_item = $marker_row['subSolution'];
$marker_data = $marker_row['subSolution'];
echo '<div class="markerItem" data-marker="' . $marker_data . '">';
echo $marker_item;
echo '</div>';
}
}
echo '</div>';
if ($marker_stmt = $con->prepare($sql_marker)) {
$marker_stmt->execute();
$marker_rows = $marker_stmt->fetchAll(PDO::FETCH_ASSOC);
echo '<div id="projMarker">';
foreach ($marker_rows as $key=>$marker_row) {
$marker_solution = $marker_row['solution'];
$maker_item = $marker_row['subSolution'];
$marker_data = $marker_row['subSolution'];
echo '<div class="markerItem" name="testField_'.$key.'" data-marker="' . $marker_data . '">';
echo $marker_item;
echo '</div>';
}
}
echo '</div>';
Using this, $key is assigned from the array index which will be a number starting from 0 and ending at count($marker_rows)-1.
Suprisingly, I couldn't find an appropriate duplicate for this.
You can easily increment or decrement variables in PHP.
$number = 0;
foreach ($marker_rows as $marker_row) {
...
$number++; // $number will now be $number+1
}
You can use $number++ directly in your attribute (if concatenating) as this will return the current $number then increment the value.

How do i display list items from php array

Ive been trying make this display as html list items it just a string that i explode then loop over each item i cant get it to out put correctly. Could some one please show me where im going wrong or suggest an new approch.
this is what ive tried
$path = "1/2/3/4";
$expath = explode("/",$path);
$ret = '';
echo '<ul>';
foreach ($expath as $pitem) {
echo '<li><a href='.$ret .= $pitem. "/".'>'.$pitem.'</a></li>';
}
echo '</ul>';
.
Desired out put on hrefs
1
1/2
1/2/3
1/2/3/4
Desired visual out LIs
1
2
3
4
Output i get be warned
1
12/>212/>23/>312/>23/>34/>4
$path = "1/2/3/4";
$expath = explode("/", $path);
echo '<ul>';
foreach ($expath as $i => $pitem) {
$slice = array_slice($expath, 0, $i + 1);
$path = implode('/', $slice);
echo '<li>' . $pitem . '</li>';
}
echo '</ul>';
$list = explode("/", "1/2/3/4");
This will create an array $list as:
echo $list[0]; // 1
echo $list[1]; // 2
echo $list[2]; // 3
echo $list[3]; // 4
This line is the problem: echo '<li><a href='.$ret .= $pitem. "/".'>'.$pitem.'</a></li>';
Should be formatted like:
echo "<li><a href='{$ret}={$pitem}/'>{$pitem}</a></li>";
or echo '<li>'.$pitem.'</li>';
Its because your $ret. Place that inside the loop. In your code you concatenate $pitem with $ret all older $ret values also get concat.
Try
<?php
$path = "1/2/3/4";
$expath = explode("/",$path);
echo '<ul>';
foreach ($expath as $pitem) {
$ret = '';
echo '<li><a href='.$ret .= $pitem. "/".'>'.$pitem.'</a></li>';
}
echo '</ul>';
If you want = sign tobe there in the url then just change echo by following
echo "<li><a href='$ret=$pitem/'>$pitem</a></li>";
PHP echo with double quotes will print variable value.

Echo selective data (rows) from multidimensional array in PHP

I have an array coming from a .csv file. These are coming from a real estate program. In the second column I have the words For Sale and in the third column the words For Rent that are indicated only on the rows that are concerned. Otherwise the cell is empty. I want to display a list rows only For Sale for example. Of course then if the user clicks on a link in one of the rows, the appropriate page will be displayed.
I can't seem to target the text in the column, and I can't permit that the words For Sale be used throughout the entire array because they could appear in another column (description for example).
I have tried this, but to no avail.
/* The array is $arrCSV */
foreach($arrCSV as $book) {
if($book[1] === For Sale) {
echo '<div>';
}
echo '<div>';
echo $book[0]. '<br>';
echo $book[1]. '<br>';
echo $book[2]. '<br>';
echo $book[3]. '<br>';
echo $book[6]. '<br><br><br>';
echo '</div>';
}
I also tried this:
foreach($arrCSV as $key => $book) {
if($book['1'] == 'For Sale') {
echo '<div>';
}
echo '<div>';
echo $book[0]. '<br>';
echo $book[1]. '<br>';
echo $book[2]. '<br>';
echo $book[3]. '<br>';
echo $book[6]. '<br><br><br>';
echo '</div>';
}
Do you mean:
foreach($arrCSV as $key => $book) {
if($book['1'] == 'For Sale') {
echo '<div></div>';
}else{
echo '<div>';
echo $book[0]. '<br>';
echo $book[1]. '<br>';
echo $book[2]. '<br>';
echo $book[3]. '<br>';
echo $book[6]. '<br><br><br>';
echo '</div>';
}
}
I found a solution here:
PHP: Taking Array (CSV) And Intelligently Returning Information
$searchCity = 'For Sale'; //or whatever you are looking for
$file = file_get_contents('annonces.csv');
$results = array();
$lines = explode("\n",$file);
//use any line delim as the 1st param,
//im deciding on \n but idk how your file is encoded
foreach($lines as $line){
//split the line
$col = explode(";",$line);
//and you know city is the 3rd element
if(trim($col[1]) == $searchCity){
$results[] = $col;
}
}
And then:
foreach($results as $Rockband)
{
echo "<tr>";
foreach($Rockband as $item)
{
echo "<td>$item</td>";
}
echo "</tr>";
}
As you can see I'm learning. It turns out that by formulating a question, a series of similar posts are displayed, which is much quicker and easier than using google. Thanks.

Categories