Restart foreach loop in PHP - php

I have an array with products as objects in it. Each object contains a key = category_title
I have a foreach loop that generates products in Bootstrap rows with configurable columns, in my case $col=3.
What I need is to have a new row if a new category_title comes up.
I created an array to push all the category_titles in it and create a variable if it is a new category. But now I am stuck.
The foreach looks like this:
<?php foreach($productspercat as $product): ?>
<!-- Make sure product is enabled and visible #front end -->
<?php // if($product->enabled && $product->visibility):?>
<?php
$catnew = false;
$categorytitle = $product->category_title;
if(!in_array($categorytitle, $totalcategories, true)):?>
<?php array_push($totalcategories,$categorytitle );
$catnew=true;
?>
<?php endif;?>
<div class="j2store-products-row <?php echo 'row-'.$row; ?> row">
<?php endif;?>
<div class="col-sm-<?php echo round((12 / $col));?>">
<h2><?php echo $categorytitle; ;
var_dump($catnew);
?></h2>
test
</div>
<?php $counter++;
$firstrun = true; ?>
<?php if (($rowcount == $col) or ($counter == $total)) : ?>
</div>
<?php endif; ?>
<?php // endif; ?>
<?php endforeach;?>
So basically if a new category comes up, it should close the row and start a fresh row with a new column count.
appreciate any help!

If you don't want to page refresh then you can do that by using jQuery or Angular JS.
By jQuery you can add data by jquery prepend() function if you wanna add data in starting or append() function to add ending section.

<?php
// Arranged products by category title
$arrangedProducts = array()
foreach($productspercat as $product) {
if (!array_key_exists($product->category_title, $arrangedProducts)) {
$arrangedProducts[$product->category_title] = array();
}
$arrangedProducts[$product->category_title][] = $product;
}
// each category is a key and its value is an array with all its products
foreach ($arrangedProducts as $categoryTitle => $products) {
// you create a new row
// ....
foreach ($products as $product) {
// you display product information
}
// you end the row
}
?>

Related

How to make a template variable global?

Inside a template part file there's a variable I'd like to be able to use in my page templates. Page templates are in the theme directory, and the template part file are in a sub-directory called template parts.
My template part file is called 'roster-get-annual-data.php', and the variable is the title of a custom post type. How can I make this title variable available in my page template?
Inside my template file (roster-get-annual-data.php) - within a wp_query:
if ($rosterQuery->have_posts()) {
while ($rosterQuery->have_posts()) {
$rosterQuery->the_post();
$post_title = $post->post_title;
set_query_var('post_title', $post_title);
?>
<h1><?php echo $post_title; ?></h1>
<div class="teams-wrapper">
<?php
$teams = get_field('single_rosters');
foreach ($teams as $post) {
// Setup this post for WP functions (variable must be named $post).
setup_postdata($post);
// set the individual roster's ID
$rosterId = $post->ID;
// get the Class Title
if (!empty(get_field('class', $rosterId)) && !empty(get_field('grad_year', $rosterId))) {
$classTitle = ucwords(get_field('class', $rosterId)) . ' - Class of ' . get_field('grad_year', $rosterId);
} else {
$classTitle = get_the_title();
}
?>
<h2><?php echo $classTitle; ?></h2>
<?php
// create empty $players array
$players = array();
// loop through the players acf repeater
if (have_rows('players', $rosterId)) {
?>
<?php
while (have_rows('players', $rosterId)) {
the_row();
// place players into an array
$players[] = get_sub_field('name');
}
?>
<?php
}
// display the PLAYERS NAMES
?>
<p class="players"><?php echo implode(', ', $players); ?></p>
<?php
}
// Reset the global post object so that the rest of the page works correctly.
wp_reset_postdata();
?>
</div>;
?>
And then in my page template:
$post_title = get_query_var('post_title');
get_template_part('template-parts/roster-get-annual', 'data');
I thought this would give me just the $post_title variable, but instead it outputs the entire template without the $post_title variable.
It´s not 100% clear to me what you want to achieve. But if you want pass args to a template you can do it with the 3rd parameter:
get_template_part('template-part', 'name', array('customkey' => 'value') );
see doc:
https://developer.wordpress.org/reference/functions/get_template_part/

How to get list of current wordpress categories and inject each in script

I'm trying to create php code that will get the list of categories that are assigned to a wordpress post (of the current page) and then loop through the array list and each category that IS has been assigned to the post and add it to the script.
this is the script i need to inject the category name in:
<script> window.abkw = '<category name>';</script>
so i wrote this but it does not seem to work...
<?php
$ads = the_category();
for ($i = 0; $i < count($ads); ++$i) {
$d = $ads[$i];
<script> window.abkw = $d[$i];</script>
}
?>here
I'm new to php so please excuse my ignorance... and thank you so much.!
use get_categories() (https://developer.wordpress.org/reference/functions/get_categories/)
$categories = get_categories(array('hide_empty' => 0'));
foreach($categories as $category) {
echo '<script> window.abkw = '.$category->cat_name.';</script> ';
}
What if you use jquery data()...
https://api.jquery.com/data/#data-html5
--edited--
I expand the way
template-example.php
...
<?php
$categories = get_categories(array('hide_empty' => 0'));
foreach($categories as $category): ?>
<div class="js-category" style="visibility:hidden;" data-category = "<?php echo $category->cat_name ?>"></div> //invisible div
<?php endforeach; ?>
...
file.js
var categories = $(".js-category").data("category");
...

Getting a conditional message out of a foreach loop

I'm displaying all the posts in the category that have a valid date as follows -
<?php $blog = $pages->find('posts');
foreach($blog->children() as $blogpost): ?>
<?php if ($blogpost->title() <= $latest && $blogpost->category == $thisCat): ?>
//HTML for displaying post goes here
<?php endif ?>
<?php end foreach ?>
That works fine when those posts validate my condition, and displays nothing if it doesn't. What I want to do is display an error message (like 'there are no posts here') when there are no posts that pass the condition. I can't just do a simple else condition in that if query because it's inside the foreach loop. I can't take the if query out of the foreach loop because it relies on a variable that is defined as part of it ($blogpost).
Kind of stuck in this catch 22... Any suggestions?
How about...
<?php
$blog = $pages->find('posts');
$found_something = false;
foreach($blog->children() as $blogpost) {
if ($blogpost->title() <= $latest && $blogpost->category == $thisCat) {
$found_something = true;
//HTML for displaying post goes here
}
}
if(!$found_something) {
// display error message
}
?>
By the way, is there a specific reason why you're using the alternative PHP syntax?
I'd create a counter variable which increments each time when you display a post.
<?php $blog = $pages->find('posts');
$displayedPosts = 0;
foreach($blog->children() as $blogpost): ?>
<?php if ($blogpost->title() <= $latest && $blogpost->category == $thisCat):
$displayedPosts++; ?>
//HTML for displaying post goes here
<?php endif ?>
<?php end foreach ?>
<?php
if ($displayedPosts == 0) {
echo 'ERROR!';
}
?>
Using a boolean variable (as tmh did) is probably better in this case unless you want to count the posts.
Just count your posts , if it's 0 display just the message , else execute foreach loop :
<?php $blog = $pages->find('posts');
if(count($blog->children())==0){ echo 'No post Here'; }
else{
foreach($blog->children() as $blogpost): ?>
<?php if ($blogpost->title() <= $latest && $blogpost->category == $thisCat): ?>
//HTML for displaying post goes here
<?php endif ?>
<?php end foreach ?>
<?php } ?>

Incorporating extra loop into random selection?

I have the code below that is selecting a random set of questions from Wordpress.
<?php
$rows = get_field('step_by_step_test');
$row_count = count($rows);
$rand_rows = array();
$questions = get_field('select_number_of_questions');
for ($i = 0; $i < min($row_count, $questions); $i++) {
$r = rand(0, $row_count - 1);
while (array_search($r, $rand_rows) !== false) {
$r = rand(0, $row_count - 1);
}
$rand_rows[] = $r;
echo $rows[$r]['question'];
}
?>
I want to incorporate a bit of extra code (below), how can I make sure it's selecting the same random question?
<?php if(get_sub_field('answer_options')): ?>
<?php while(has_sub_field('answer_options')): ?>
<?php echo the_sub_field('answer'); ?>
<?php endwhile; ?>
<?php endif; ?>
Why dont you change your approach slightly?
<?php
$rows = get_field('step_by_step_test'); // Get the test
$question_count = get_field('select_number_of_questions'); // Get the number of questions
$rows = shuffle($rows); // Randomize your questions
$rows = array_slice($rows, $question_count); // Now set the array to only contain the number of questions you wanted
foreach ($rows as $row) {
echo $row['question']; // Show the question
if(get_sub_field('answer_options', $row['id'])) {
while(has_sub_field('answer_options', $row['id'])) {
echo the_sub_field('answer');
}
}
}
?>
I made the assumption that you can alter "get_sub_field" to include the ID of the question, so you can then include the ID in your "where" field of "answer_options". This will allow you to link the question.
I think that what you need is to set up the whole thing in a loop. query by custom field
Or you could store the ids of the questions you got above, an then, below, query for the answers for those specific posts.
Here's how I randomized my WordPress slider using the Advanced Custom Fields plugin + Royal Slider with a modified version of TheSwiftExchange's code above
<div id="full-width-slider" class="royalSlider heroSlider rsMinW">
<?php
/*
* Slider Repeater field shuffled
* http://stackoverflow.com/questions/12563116/incorporating-extra-loop-into-random-selection
*/
$rows = get_field('slider');
// For Debugging:
// echo "<pre>";
// var_dump($rows);
// echo "</pre>";
$quotes = get_field('slide_text'); // Get the number of images
shuffle($rows); // Randomize your slides
foreach ($rows as $row) {
$slideImageID = $row['slide_image'];
$slideImage = wp_get_attachment_image_src( $slideImageID, 'full' );
$slideText = $row['slide_text'];
?>
<div class="rsContent">
<div class="royalCaption">
<div class="royalCaptionInner">
<div class="infoBlock">
<?php if(!empty($slideText)) {
echo $slideText;
}; ?>
</div>
</div>
</div>
<img src="<?php echo $slideImage[0]; ?>" class="" />
</div><!-- /.rsContent -->
<?php } // end foreach ?>
</div><!-- /slider-wrap -->

Zend Pagination - Seems Not to be limiting number of results on each page

I am relatively new to The Zend framework having only been working with it probably two months at the most. I am now trying to get a list of results from a query I run, send it through the zend paginator class and display 4 results per page, however it does not seem to be recognising when it has got 4 results, I believe there is an error in my code but I can not for the life of me see it, I was hoping someone here will be able to pick up on it and help me and out and probably tell me it is something stupid that I have missed. Thanks here is the code I have written.
This the query in my model
public function getAllNews()
{
$db = Zend_Registry::get('db');
$sql = "SELECT * FROM $this->_name WHERE flag = 1 ORDER BY created_at";
$query = $db->query($sql);
while ($row = $query->fetchAll()) {
$result[] = $row;
}
return $result;
}
This is code in my controller
function preDispatch()
{
$this->_helper->layout->setLayout('latestnews');
Zend_Loader::loadClass('newsArticles');
$allNews = new newsArticles();
$this->view->allNews = $allNews->getAllnews();
//die (var_dump($this->view->allNews));
$data = $this->view->allNews;
// Instantiate the Zend Paginator and give it the Zend_Db_Select instance Argument ($selection)
$paginator = Zend_Paginator::factory($data);
// Set parameters for paginator
$paginator->setCurrentPageNumber($this->_getParam("page")); // Note: For this to work of course, your URL must be something like this: http://localhost:8888/index/index/page/1 <- meaning we are currently on page one, and pass that value into the "setCurrentPageNumber"
$paginator->setItemCountPerPage(1);
$paginator->setPageRange(4);
// Make paginator available in your views
$this->view->paginator = $paginator;
//die(var_dump($data));
}
Below is the view that builds the paginator,
<?php if ($this->pageCount): ?>
<div class="paginationControl">
<!-- Previous page link -->
<?php if (isset($this->previous)): ?>
< Previous |
<?php else: ?>
<span class="disabled">< Previous</span> |
<?php endif; ?>
<!-- Numbered page links -->
<?php foreach ($this->pagesInRange as $page): ?>
<?php if ($page != $this->current): ?>
<?= $page; ?> |
<?php else: ?>
<?= $page; ?> |
<?php endif; ?>
<?php endforeach; ?>
<!-- Next page link -->
<?php if (isset($this->next)): ?>
Next >
<?php else: ?>
<span class="disabled">Next ></span>
<?php endif; ?>
</div>
<?php endif; ?>
And finally the code the makes up my view
<div id="rightColumn">
<h3>Latest News</h3>
<?php if (count($this->paginator)): ?>
<ul>
<?php foreach ($this->paginator as $item): ?>
<?php
foreach ($item as $k => $v)
{
echo "<li>" . $v['title'] . "</li>";
}
?>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?= $this->paginationControl($this->paginator, 'Sliding', '/latestnews/partial_pagination_control.phtml'); ?>
</div>
I will be greatful for any help you can give me.
Thanks
Sico
$paginator should be set to 4 as you want to show only 4 records at a time :
$paginator->setItemCountPerPage(4);
So I think the root of your problem is in your model class with the getAllNews function. The Zend_Db fetchAll function retrieves an associative array of all the records matching your query. You are returning an array of one element that is an array of all the rows retrieved by your select statement.
Try this:
public function getAllNews()
{
$db = Zend_Registry::get('db');
$sql = "SELECT * FROM $this->_name WHERE flag = 1 ORDER BY created_at";
return $db->fetchAll($sql);
}
You sould not pass values to paginator if you want it to limit your query.
There is a code will work for you
$usersTable = $this->getTable();
$registerSelect = $usersTable->select()->where('status = ?', 'OK')->order('lastLogin DESC');
$paginator = new Zend_Paginator(new Zend_Paginator_Adapter_DbTableSelect($registerSelect));
$paginator->setCurrentPageNumber($page);
$paginator->setItemCountPerPage($limit);

Categories