Query Database and Return the result - php

I am having a problem for a while now and I can´t seem to solve it on my own.
I have made a website, this website is multilingual and it was made in wordpress.
In my "photo album" page when I sort the items in the default language (English) everything works fine, however if I change to another translation (ex.french), the name of the category changes and the tagged items don't appear anymore.
http://madebysylvie.be/collection
In my database I manage to find the table and the rows of each category, I want to be able access it in a different language, each one has an unique ID.
I know I have to grab the ID from the database of each category and return it to my PHP script.
This is my code,
<ul class="filter_portfolio">
<?php
// Get the taxonomy
$terms = get_terms('filter', $args);
// set a count to the amount of categories in our taxonomy
$count = count($terms);
// set a count value to 0
$i=0;
// test if the count has any categories
if ($count > 0) {
// break each of the categories into individual elements
foreach ($terms as $term) {
// increase the count by 1
$i++;
// rewrite the output for each category
$term_list .= '<li class="segment-'.$i.'">' . $term->name . '</li>';
// if count is equal to i then output blank
if ($count != $i)
{
$term_list .= '';
}
else
{
$term_list .= '';
}
}
// print out each of the categories in our new format
echo $term_list;
}
?>
</ul>
However I am not good enough to do this on my own, and I would be very happy if someone could help me out on this one.
I don't know how to query my database, and I am not shore how to modify the php in order to print it in the other languages.
Thanks

Please refer to the Wordpress documentation, the "Codex":
Class Reference/wpdb – Interfacing With the Database
Displaying Posts Using a Custom Select Query
Class Reference/WP Query –
Custom Queries – how to modify queries using hooks
But remember »Most of the time you can find the information you want without actually dealing with the class internals and globals variables. There are a whole bunch of functions that you can call from anywhere that will enable you to get the information you need.«
WP_Query example from the docs:
<?php
// The Query
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo '<li>' . get_the_title() . '</li>';
}
} else {
// no posts found
}
/* Restore original Post Data */
wp_reset_postdata();

Related

php loop error for count posts in category

I have multiple categories on my wordpress page and each of the categories has 1 to n subcategories. If a subcategory contains only 1 single post I would love to display an excerpt of this post, otherwise I'll display a description of the category.
I already have the part with the "normal" categories, but there is kind of a stupid mistake regarding the "single post categories". This is what I have so far:
<?php
$args = array(
'orderby' => 'slug',
'child_of' => $cat_id,
);
$categories = get_categories( $args );
foreach ( $categories as $category ) {
$cat_count = get_category($category->cat_ID);
if($cat_count->count == 1) { ?>
<!-- Cat has only one post, display post -->
<?php } else {
<!-- Cat has multiple posts, display cat description -->
}
}
?>
Result is: I am getting the normal categories (fine!) but the first of the "single post categories" multiple times. Something might be wrong with my loop, but I don't see it. Does someone see the mistake?
There are two possible mistakes:
The category is two times in the array (Please try to var_dump it.) -> fixable with array_unique https://www.php.net/manual/de/function.array-unique.php
You forgot an echo of some debug (Somewhere - the first solution should do the trick.)
If the First Solution doesn't fix it, please post the var_dump of the array of categories.
I have a working solution now... finally!
<?php
foreach ( $categories as $category ) {
// If there is only one post available, go directly to the post
if($category->count == 1) {
$all_posts = get_posts($category);
echo '<div class="item"><h4 class="item-title">' . get_the_title($all_posts[0]->ID) . '</h4>Read more</div>';
} else {
echo '<div class="item"><h4 class="item-title">' . $category->name . '</h4>Read more</div>';
}
}
?>

Exclude Woocommerce products from search loop

I am trying to create a custom search results page where Woocommerce product results are displayed separately to blog / general posts.
My aim is to display them as separate blocks with different styling.
[Block 1] - Woocommerce results
[Block 2] - Blog / Post results
I have managed to display the products in one loop, but I am struggling to exclude products from the post loop.
I have tried creating a custom loop, however this just displays all the posts within those terms, rather than the posts returned in the search.
The loop I usually use is:
<?php $loop = new WP_Query( array( 'post_type' => 'post' ?>
<p>Something here</p>
<?php endwhile; wp_reset_query(); ?>
However I believe this just isn't compatible and suitable for my needs.
If there's a better solution to separating these I would absolutely love to hear more.
The problem you are having is that you have one main query, where you actually want to do two queries. You could of course modify the main query to contain both post types, but you would end up with a random number of both post types where you actually want to fill both columns.
If you modify the main query to only return one of the columns, you end up with a situation where it is awful to run the other query to get the rest of the posts. I think you should be able to use the posts_join and posts_where filters if you need them, but I am unsure about posts_search. You can use either WP_Query or get_posts to finally do the two queries you need.
<?php
// Since we are searching, we probably should get the search keyword
$search = get_query_var('s');
// Since we want to be able to navigate, we probably should figure out on which page we are
$paged = get_query_var('paged');
// Anything else we want to do in search queries we should be able to do in
// a posts_join or posts_where filter by checking if is_search() is true
// With that out of the way, we can construct our queries
$query_posts_page = new WP_Query([
's' => $search,
'paged' => $paged,
'post_type' => ['post', 'page']
]);
$query_woocommerce = new WP_Query([
's' => $search,
'paged' => $paged,
'post_type' => 'product'
]);
?>
<div class="col">
<?php
if ( $query_posts_page->have_posts() ) {
while ( $the_query->have_posts() ) {
$query_posts_page->the_post();
echo get_the_title();
}
/* Restore original Post Data */
wp_reset_postdata();
} else {
echo 'Nope, no more data';
}
?>
</div>
<div class="col">
<?php
if ( $query_woocommerce->have_posts() ) {
while ( $query_woocommerce->have_posts() ) {
$query_posts_page->the_post();
echo get_the_title();
}
/* Restore original Post Data */
wp_reset_postdata();
} else {
echo 'Nope, no more data';
}
?>
</div>
There is however still another problem. we can't automatically generate pagination, considering we are running two custom queries instead of the main query. Furthermore, we are unlikely to have an equal number of normal page/posts and products.
We can figure out what the maximum number of pages is for each of the loops by using max_num_pages. You can generate something yourself using that.
<?php
$maximum_page = max($query_posts_page->max_num_pages, $query_woocommerce->max_num_pages);
for( $i = 1; $i < $maximum_page; $i++) {
echo "{$i} ";
}

Displaying and getting only the child categories

I have a section on my wordpress website that currently displays the child and parent categories of a listing. I would like for only the child categories to be displayed. I wasn't able to figure out the solution on my own, your help is appreciated.
Here is the current code I'm using for this (which also displays parent categories):
<?php
//NEW
$permalink = get_permalink( $id );
//NEW
$seo = get_the_title()." : ";
$Category_links = ' Found in the ';
$term_list_category = wp_get_post_terms(get_the_ID(), 'listings_categories', array("fields" => "ids"));
//THIS CODE REMOVES PARENTS FROM BEING DISPLAYED IN THE LISTING CATEGORIES
foreach ($term_list_category as $k=>$term) {
$children = get_term_children( $term, 'listings_categories');
if ($children)
unset($term_list_category[$k]);
}
$i = 0;
$count = count($term_list_category);
if ( $count > 0 ){
foreach ( $term_list_category as $term_category ) {
$thisCat = get_term_by( 'id', $term_category, 'listings_categories');
//NEW
$url = '<a id="'.$term_category.'" slug="'.$thisCat->{'slug'}.'" class="listing-links-cat" href="#" title="'.$thisCat->{'name'}.'" >'.$thisCat->{'name'}.'</a>';
$i ++;
$seo .= " " . $thisCat->{'name'} . "";
$Category_links .= " " . $url . "";
if($count-1 == $i){
$Category_links .= " and "; $seo .= ", ";
}elseif($count > 1 && $count !== $i){
$Category_links .= ", "; $seo .= ", ";
}
}
$Category_links .= " Categories";
?>
<? echo $Category_links; ?>
But I feel that the overall code can be improved for performance, so it doesn't search the database as much?
Your code is quite ineffecient and also have unnecessary parts to it. Your additional part makes your code even more ineffecient and causes you to hit the db hard.
FLAWS
You get plus 1 for only getting the term id's from the post terms, but unfortunately in this specific case, this tampers your code and this is the starting point of your ineffeciency as you then need to use get_term_by() on every iteration of your foreach loop. This means extra db calls on every iteration for something that should have already been there
The use of get_term_children() adds to the amount of db calls made on every iteration of your foreach loop. Again, you are making unnecessary db calls for something that should have been there in the first place
It is totally unnecessary to count the amount of terms returned by wp_get_post_terms. This adds extra ineffeciency to your code. wp_get_post_terms returns an empty array if no terms exists or a WP_Error object if the taxonomy does not exist. Keep this in mind for later on
SPEEDING IT UP AND STREAMLINING THE CODE
Lets look at what we can do to make your code more effecient
Remove the fields parameter from wp_get_post_terms. As we need more than just the ids of the terms, we need to return the complete term object. You might think that this is ineffecient, but this will save you a lot of db hits and most importantly, time, as you are getting rid of get_term_by() and get_term_children()
There is no proper way to remove parents from wp_get_post_terms(), so the best way will be to just loop over them and ignore/skip them with continue. I assume you are talking about top level terms which have 0 assigned to its $parent property, so you just need to check that the parent value is not 0
Always do proper failure checks. If you don't do that, and your code fails, php error and notices are returned, which is known as bugs. You would want to avoid that. Also, you would always want your code to fail in a controlled, expected manner without bugs. As I stated before, wp_get_post_terms() returns an empty array or a WP_Error object, so this is what you need to check for. If any of these cases occur, immediately halt execution and return the function to avoid bugs and unexpected output
PUTTING THE ABOVE IN CODE
I like to keep my template files short and sweet. For that reason, bulky code the above always goes into a function and I then just call the function in my template files where necessary. Also, just a tip, I have function specific functions files to keep my code organised and not to overload functions.php. my functions.php file is usually not more than 100 lines of code.
For example, this is part of your post's meta, so this will go into a file with other meta functions like displaying the autor name and post date.
function get_post_child_terms( $taxonomy = '' )
{
$current_post = get_queried_object_id();
$terms = wp_get_post_terms( $current_post, $taxonomy );
/*
* Check if $taxonomy has a value, also check for WP_Error or empty $terms. If any of these conditions
* are met, halt execution and return false
*/
if ( !$taxonomy || is_wp_error( $terms ) || empty( $terms ) )
return false;
/*
* We have made it to here safely, now iterate over the terms
*/
foreach ( $terms as $term ) {
/*
* Check for parent terms and ignore them
*/
if ( $term->parent == 0 )
continue;
/*
* Get an array of term names
*/
$term_names[] = $term->name;
}
/*
* Build our string of names
*/
if ( !isset( $term_names ) )
return false;
$string = 'Some text here maybe to start of: ' . implode( ',', $term_names ) . 'Maybe something at the end';
return $string;
}
USAGE
You can now simply call the function in your template as follow:
echo get_post_child_terms( 'listings_category' );
This will produce a list like this
Some text here maybe to start of: Term name 1, Term name 2, Term name 3 Maybe something at the end
FINAL NOTES
The code above is untested and might be a bit buggy.
The code above is the very least that you need. You can extend and misuse it as you see fit to fit your exact needs. A few ideas for extension might be to work in some arguments to where you can choose to display the parent terms or not, and whether the function should return a string of term names or an array of term names. The sky is the limit here
You can build in a cache system to cache your results to optimize these even further.
EDIT
The above code is now tested and is working as expected

Wordpress Dropdown Categories All Links to Single

I'm having an issue where, even though the page renders originally with "All" selected in the dropdown, if you go to a category (renders fine) and then back to "All" in the dropdown, you see a single post. This is instead of the originally displayed page with all of the categories. I need the page to basically render the same page for "All" regardless. Any thoughts?
wp_dropdown_categories('show_option_all=All&hide_empty=0&show_count=0&orderby=name&echo=0');
I did a similar post on WPSE last week and it seems that the two might be related. For convenience, here is the post
Here is a variation of the code that you use. I'm using get_categories() here to achieve the same goal. I had to adjust my code slightly to make it acceptable for your need.
There are a however other modifications you have to make for this to work. When you select the All Categories option, you will be taken to a page that will display what ever you need to display. This page you will have to manually create
There is no index archive pages in Wordpress as you might know. (Check out this post I have done on the same subject). What this means is, domain.com/category/ returns a 404.
So, to make this all work, you'll have to make a copy of page.php, rename it to something like page-category.php (see the codex on how to create custom page templates), open it up, create your custom query to display what you would like to display when this page is visited
You now need to create your page in the back end. I would suggest that you use the slug category so that when you visit domain.com/category/, this page would be displayed. (Just remember, you cannot create child pages for this page, it will break the hierarchy). I have also made the code to go to domain.com/category/ when All Categories is selected
Apart from that, the code should work fine. You just need to check the URL structures maybe, and also set the parameters in get_categories() to suite your needs. Here is the drop down code.
<select name="event-dropdown" onchange='document.location.href=this.options[this.selectedIndex].value;'>
<option value=""><?php echo esc_attr(__('Select Category')); ?></option>
<?php
$option = '<option value="' . get_option('home') . '/category/">All Categories</option>'; // change category to your custom page slug
$categories = get_categories();
foreach ($categories as $category) {
$option .= '<option value="'.get_option('home').'/category/'.$category->slug.'">';
$option .= $category->cat_name;
$option .= ' ('.$category->category_count.')';
$option .= '</option>';
}
echo $option;
?>
</select>
EDIT
I actually had an idea here that will come in handy. I've recently done an answer on displaying all categories in a list with all post titles under the specific category. This same idea can be used in your page-category.php template.
When a user selects the All Categories option, they will be taken to this page which will list all categories and post title.
Here is the complete code: (for an explanation of the code, see my post here)
In your functions.php
add_action( 'transition_post_status', 'publish_new_post', 10, 3 );
function publish_new_post() {
delete_transient( 'category_list' );
}
In your template where you need to display your list
<?php
if ( false === ( $q = get_transient( 'category_list' ) ) ) {
$args = array(
'posts_per_page' => -1
);
$query = new WP_Query($args);
$q = array();
while ( $query->have_posts() ) {
$query->the_post();
$a = '' . get_the_title() .'';
$categories = get_the_category();
foreach ( $categories as $key=>$category ) {
$b = '' . $category->name . '';
}
$q[$b][] = $a; // Create an array with the category names and post titles
}
/* Restore original Post Data */
wp_reset_postdata();
set_transient( 'category_list', $q, 12 * HOUR_IN_SECONDS );
}
foreach ($q as $key=>$values) {
echo $key;
echo '<ul>';
foreach ($values as $value){
echo '<li>' . $value . '</li>';
}
echo '</ul>';
}
?>

PHP: Add translated tags to category list

I have a website made from a template in Wordpress, I've installed a translation plugin (qtranslate).
http://madebysylvie.be/collection
In my "photo album" page when I sort the items in the default language (english) everything works fine, however if I change to another translation (ex.french), the name of the category changes and the tagged items don't appear anymore.
Here is the PHP code that executes that function,
<ul class="filter_portfolio">
<?php
// Get the taxonomy
$terms = get_terms('filter', $args);
// set a count to the amount of categories in our taxonomy
$count = count($terms);
// set a count value to 0
$i=0;
// test if the count has any categories
if ($count > 0) {
// break each of the categories into individual elements
foreach ($terms as $term) {
// increase the count by 1
$i++;
// rewrite the output for each category
$term_list .= '<li class="segment-'.$i.'">' . $term->name . '</li>';
// if count is equal to i then output blank
if ($count != $i)
{
$term_list .= '';
}
else
{
$term_list .= '';
}
}
// print out each of the categories in our new format
echo $term_list;
}
?>
</ul>
I would like to change this block of code in order to identify the tags in the translated version. I know that the trigger is the ("data-value") parameter.
The following code let's me translate the taxonomies from the default language,
function qtranslate_edit_taxonomies(){
$args=array(
'public' => true ,
'_builtin' => false
);
$output = 'object'; // or objects
$operator = 'and'; // 'and' or 'or'
$taxonomies = get_taxonomies($args,$output,$operator);
if ($taxonomies) {
foreach ($taxonomies as $taxonomy ) {
add_action( $taxonomy->name.'_add_form', 'qtrans_modifyTermFormFor');
add_action( $taxonomy->name.'_edit_form', 'qtrans_modifyTermFormFor');
}
}
}
add_action('admin_init', 'qtranslate_edit_taxonomies');
?>
Thank you very much for helping!
i suspect you use the category name to filter your database records. So in your db there is only the "englsh" name and when you "translate" it your script is unable to work properly since it uses the new "french" name.
Can you try to convert the category name to engish before executing your query?
EDIT
What i actually think is for you to find a way to pass two variables to your php script. Whatever suits your needs.
For example, some possible scenarios are:
- category in english + language (fr) = based on your selected language you query your db and return proper results(based on english work thought)
- category id + language (fr) = same as above but more generic since you use an id to get data from table.
I am guessing you must change somewhat your html and you php script (one to pass correct data and the other to return correct format).

Categories