Drupal: custom taxonomy page, exclude nodes with some taxonomy child (without views module) - drupal

i have a news aggregator project.
in this project i have categories like this.
sport
sport:football (tick)
sport:basketball(tick)
sport:volleyball
sport:Tennis
politic
politic:your country (tick)
politic:others
above tree shows how users want news to be aggregated.
i save all selected and not selected taxonomies in two different variable for each user in database as an array width function variable_set
now i want in sport taxonomy page, default drupal page, only shows nodes that football and basketball is their category, and nodes from tennis and volleyball will not be shown.
i mean overriding behaviour of default taxonomy pages.
i know this can happen with views module buttttt number of taxonomies is not fixed. it will be more and more during the life of the news aggregator website. now the number of them now is more than 340 taxonomies.
now i have written this code. this code. this codes works well but i want in parent taxonomy page, nodes shows that user collected their subchildren taxonomy.
function caspian_bartik_menu_alter(&$menu) {
$menu['taxonomy/term/%taxonomy_term']['page callback'] = 'caspian_bartik_term_page';
$menu['taxonomy/term/%taxonomy_term']['access arguments'] = array('access content');
$menu['taxonomy/term/%taxonomy_term']['page arguments'] = array(2);
}
function caspian_bartik_term_page($term){
$voc = taxonomy_vocabulary_load($term->vid);
// here you generate the actual content of the page
// could be done e.g. with an entityfieldquery as follows
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->fieldCondition('field_category', 'tid', $term->tid , '=')
->fieldCondition('field_category', 'tid', array(135) , 'NOT IN')
->propertyOrderBy('created', 'DESC');
$result = $query->execute();
if (!empty($result['node'])) {
$build['content']['nodes'] = node_view_multiple(node_load_multiple(array_keys($result['node'])), 'teaser');
} else {
$build['content']['status']['#markup'] = t('No results found for term ID !tid.', array('!tid' => $term->tid));
}
return $build;
}
this line does not work
->fieldCondition('field_category', 'tid', array(135) , 'NOT IN')
thanks for your help.

When you say
this line does not work
does the PHP application crashes or you don't get the result you expect ?
This query logic seems to be weird
->fieldCondition('field_category', 'tid', $term->tid , '=')
->fieldCondition('field_category', 'tid', array(135) , 'NOT IN')
Imagine your $term->tid = 1. You are selecting the field_category where tid is 1 AND $term->tid NOT IN (135). This will give you nodes attached to 1 category and not multiple ... Is this what you want?

Related

How can I count the instances of a custom taxonomy term in the scope of a custom post type?

I have a custom taxonomy called "tasks" shared between two custom post types of "roles" and "products".
Expected results:
I need to count how many times a given "task" term is used for each "role" post type minus the count shared by a "product" post type using the same "task" term.
Actual results:
None to report as I don't know how to tackle this
Error messages:
None
What I've tried:
Google keeps coming back with how to count the post type, not the terms :(
The code below is my plan B. Here I am just doing some micro loops on each post-type (only one shown below for brevity), getting the tasks and turning them into an associative array via array_count_values
$taskList = [];
$queryRoles = new WP_Query( array(
"post_type" => "roles"
));
while ( $queryRoles->have_posts() ) : $queryRoles->the_post();
$tasks = get_the_terms( get_the_ID(), "tasks" );
foreach ( $tasks as $task ) :
$taskList[] = $task->name;
endforeach;
endwhile;
$overlappingRoleTasks = $taskList;
print_r(array_count_values($taskList));
you could do a loop restricted to only posts with tasks assigned and one restricted to only products with assigned tasks.
Then using sizeof(); which return the number of elements in an array, count each number of posts and products and then do some basic php maths.
More about sizeof(); # https://www.w3schools.com/php/func_array_sizeof.asp

How can I force a WordPress Query to satisfy ALL requirements?

I have 2 categories, called red and blue.
I have 2 posts, called red-post and blue-post. These posts are of their corresponding categories.
If I create the following query:
$bluePostQuery = new WP_Query(array('category' => 'red', 'name' => 'blue-post'));
This query will return blue-post, even though my query has category=red as a requirement. Why does this happen? blue-post is of the category blue, not red, so I want nothing returned here. Will a query always return if the name argument is provided, even if the other arguments are not met?
It may be ignoring 'category' because that is not a valid parameter for finding a category in WP Query. Here's a list of the valid params for cats. You might try using the category name parameter, like so:
$bluePostQuery = new WP_Query(
array(
'category_name' => 'red',
'name' => 'blue-post'
)
);
Alternatively, if you are searcing for a specific post, and know its slug, the category doesn't really matter, so you could just exclude it.

Filtering WooCommerce Products by $_GET

What I need to be able to do is apply a value for an attribute in the URL, so only the products match that attribute are displayed. I don't want to do any widgets or other visible filters on the page.
For this I presume I would need to use one of the webhooks, and filtering out all products that are about to be displayed.
Can anyone advise which hook will be best in this case and a simple explanation on how the triggered function will return the new array of products?
Thanks in advance!
NB: I also want to query a custom attribute, which does not have any terms, just a straight key/value.
UPDATE 1
I'm playing with two techniques; one is very reliable, and that's basically to use:
if (!$product->attributes || $product->get_attribute( 'testKey' ) != $_GET["testKey"]) {
//return;
}
at the top of content-product.php, but of course WooCommerce will still say the original value for found_posts. Certainly not ideal.
I've come across that something like this should work in functions.php:
function testFilter($meta_query) {
$meta_query[] = array (
'key' => 'testKey',
'value' => 'testVal',
'compare' => '='
);
return $meta_query;
}
add_filter( 'woocommerce_product_query_meta_query', 'testFilter', 9 );
Except it doesn't, returns no results, doesn't matter if I use LIKE, EXISTS etc. Am I using it wrong?
UPDATE 2
I'm not going to say this is the answer, as this only seems to look for one value within a group of custom attributes, but this result has helped.
add_filter( 'wpv_filter_query', 'wpv_filter_color_attribute' );
function wpv_filter_color_attribute( $query_args) {
$tax_query = array();
$tax_query['taxonomy'] = 'pa_size';
$tax_query['field'] = 'term_id';
$tax_query['terms'] = $_GET['pa_size'];
$query_args['tax_query'] = array($tax_query);
return $query_args;
}
You should replace "pa_size" with your attribute taxonomy slug, also $_GET['pa_size'] with the right URL parameter.
You can filter products by attributes using above code. I have not tried this. But, this may help you.

Wordpress Loops: Excluding by Tag String, Register by Function?

I have 3 loops running on the front page.
One for the slider, and it wants posts that have the tag "slider".
One for featured articles, and it wants posts that have the tag "featured".
And a third I am calling in loop_latest.php, it wants the 6 latest posts; the trick here is those need to be the 6 latests that do NOT have the tags "slider" or "featured".
So I have this query.
$query = new WP_Query(
array(
'showposts' => '6',
'tag_not_in' => array('featured, slider'),
) );
I'm pretty sure the problem here is that "tag_not_in" doesn't like strings, it wants IDs.
SO! Is there a way to pass it the strings?
If not, how do I divine what the IDs of tags are?
Can I run some code in "functions.php" to set and reserve the ids? featured == 777, slider == 888
Something like that?
I'd like to be able to SET them so that gets packaged with this theme. Rather than have to hope that when the client registers the tags "slider" and "featured" they match up with what I have chosen in the loops/query.
the correct parameter is tag__not_in (with 2 underscores).
additionally - to get your tag ID put this code in your functions.php
function get_tag_id_by_name($tag_name) {
global $wpdb;
$tag_ID = $wpdb->get_var("SELECT * FROM ".$wpdb->terms." WHERE `name` = '".$tag_name."'");
return $tag_ID;
}
and your new code should be:
$featuredtag = get_tag_id_by_name('featured');
$slidertag = get_tag_id_by_name('slider');
$query = new WP_Query(
array(
'showposts' => '6',
'tag__not_in' => array($featuredtag, $slidertag),
) );

Programmatically filter nodes based on their taxonomy term

I've got a session variable containing an ever changing city name.
Example - $_Session['Toronto'];
I've also got a list of unfiltered nodes with lots of fields. Most importantly they have a taxonomy term field called 'city'.
I need to be able to only display the nodes with the taxonomy terms that match the $_Session['Toronto'].
Example - Node 9 and 10 have taxonomy terms of 'Toronto' and 'Ottawa'. I will only want the node with the term of 'Toronto' to display on the page.
Any help?
With views, you can use hook_views_query_alter
D7 example
function YOURMODULE_views_query_alter(&$view, &$query){
switch ( $view->name ){
case 'YOURVIEWNAME':
$query->where[1]['conditions'][] = array(
'field' => 'term_field_name', //your term name in the sql query
'value' => $_Session['Toronto'],
'operator' => '='
);
break;
}
}

Resources