Wordpress: is child of category function - wordpress

I I am looking for a function that merely returns true or false. The function would check if the category archive being queried is a child of a particular parent category. The function would look something like this (similar to the is_category() function):
if(is_child_of_category('3')){ //do something }
if(is_child_of_category('4')){ //do something else }
if(is_child_of_category('5')){ //do something entirely different }
I have looked through the documentation and the forums but have not found any solutions, any ideas if this has been done or how one would go about it?
/////////////
addendum
////////////
Here is the working code that I wrote with help from Gavin:
Thanks Gavin
first a function for the functions.php file to get the category id:
function getCurrentCatID(){
global $wp_query;
if(is_category() || is_single()){
$cat_ID = get_query_var('cat');
}
return $cat_ID;
}
Next use cat_is_ancestor_of
$post = $wp_query->post;
$id = getCurrentCatID();
if ( cat_is_ancestor_of(3, $id) { include(TEMPLATEPATH . '/unique.php'); }

cat_is_ancestor_of
This will return true still, however, if the category is a grandchild of the specified category.

I need something similar yesterday, so I wrote this function which hands me back an array with all the child categories + the parent-category (which might be useful if you want to, let's say, hide the comment form on all FAQ-cat posts and childs thereof, but show it on others).
Pass $catname as a var and get an array back, which you can use as an argument in e.g. in_category() function.
// Get List of Child Categories
function get_child_cats( $catname ) {
$parentcat = get_cat_ID( '$catname' );
$subcat = get_categories( array('child_of' => $parentcat ) );
$cat_array = array();
array_push($cat_array, $parentcat); // add the parent cat to the array
foreach ($subcat as $sc) {
array_push($cat_array, $sc->cat_ID);
}
return $cat_array;
}

Related

Wordpress - setting a custom post per category

I have added the below code to the functions.php file to load different post templates per category. The code is doing what it is supposed to do. The issue I am facing is that when I open posts these load correctly but whilst loading an error is displayed for a instant saying "trying to get property of non-object in .......functions.php" How may I get rid of that error? Appreciate your help.
/* ----------------------------------------------------------------------------
custom single posts per category
*/
add_filter('single_template', 'check_for_category_single_template');
function check_for_category_single_template( $t )
{
foreach( (array) get_the_category() as $cat )
{
if ( file_exists(get_stylesheet_directory() . "/single-category-{$cat->slug}.php") ) return get_stylesheet_directory() . "/single-category-{$cat->slug}.php";
if($cat->parent)
{
$cat = get_the_category_by_ID( $cat->parent );
if ( file_exists(get_stylesheet_directory() . "/single-category-{$cat->slug}.php") ) return get_stylesheet_directory() . "/single-category-{$cat->slug}.php";
}
}
return $t;
}
The error trying to get property of non-object means, you try to get a property of something that is not an object. So looking at your code you are getting two properties with ->: "slug" and "parent".
This gives us the hint, that the value saved in the $cat variable might not be an object.
You are using get_the_category_by_ID which gives you a name, not a category object. https://developer.wordpress.org/reference/functions/get_the_category_by_id/ So you cannot access any property. The problem is this: get_the_category_by_ID( $cat->parent ); There is no parent property in $cat, because it only contains the name. You need to get the object to make use of the parent property. Moreover the property is called category_parent, and not parent.
$parent_id = $cat->category_parent;
$cat = get_category($parent_id);
This should solve your problem.
If it does not solve your problem, I wrote the code in another way. It shows single steps and maybe it is useful for you or some other users.
The function to get all your category objects is: get_categories() https://developer.wordpress.org/reference/functions/get_categories/
You can save all the IDs of the categoires into a array. After that, you loop through each position of the array and check if the single post you are viewing has the same category ID. We can check if the post is in given categories using in_category() https://developer.wordpress.org/reference/functions/in_category/
I did no testing, but the code can look something like:
add_filter('single_template', 'check_for_category_single_template');
function check_for_category_single_template() {
// Get all category objects
$categories = get_categories();
// Array for IDs
$categories_ids = [];
foreach($categories as $category) {
// add id to array
array_push($categories_ids, $category->cat_ID);
}
// Loop through array of IDs
foreach($categories_ids as $category_id) {
// Check if ID equals current post category ID
if ( in_category($category_id) ) {
// get current category object
$cat = get_category($category_id);
// check if category has parent
if( $cat->category_parent > 0 ) {
$parent_id = $cat->category_parent;
// get parent object
$cat = get_category( $parent_id );
}
// get slug of category
$cat_slug = $cat->slug;
if ( file_exists(get_stylesheet_directory() . "/single-category-" .$cat_slug. ".php") ) {
return get_stylesheet_directory() . "/single-category-" .$cat_slug. ".php";
}
}
}
}

Get parent category for CPT

I'm working on an index page that lists all posts for a custom post type. I've been listing the categories for each post using <?php echo strip_tags(get_the_term_list( $post->ID, 'genre', ' ',' • ')); ?>.
We need to add sub-categories but I don't want these to display on the index page - just the parent category. Have tried using get_term_parents_list and a few other examples from here but can't get anything working.
Can anyone help?
You can use get_the_terms filter to change the terms to return.
add_filter('get_the_terms', 'only_parent_genre', 10, 3);
function only_parent_genre($terms, $post_id, $taxonomy) {
// TODO for you : Add condition to heck if you are not on your custom index too.
if(is_admin() || $taxonomy !== 'genre') {
return $terms;
}
// Loop over terms and if parent is something different than 0, it means that's its a child term
foreach($terms as $key => $term) {
if($term->parent !== 0) {
unset($terms[$key]);
}
}
return $terms;
}

Trying to extend a Wordpress plugin, need to hook a function

I am trying to add some site-specific functionality to the Wordpress plugin Appointments+. When a user is making an appointment, they select certain services and enter information into some fields for confirmation.
What I want to do is add some code so the extra information fields are related to which service they choose. For example, if they choose Service A, they have to fill in some information and those fields are validated. But if they choose Service B, hide the fields and skip the validation.
Here is an example of the original code:
function post_confirmation() {
...some extra stuff
$values = explode( ":", $_POST["value"] );
$location = $values[0];
$service = $values[1];
do_action('app-additional_fields-validate');
...more stuff
}
Here is the kind of thing I want to do, but not alter this original plugin file:
function post_confirmation() {
...some extra stuff
$values = explode( ":", $_POST["value"] );
$location = $values[0];
$service = $values[1];
if (($service == 1) || ($service == 3)) {
do_action('app-additional_fields-validate');
}
...more stuff
}
I admit that I am new to using hooks and filters. I want to disable/enable that action based on a variable in the function. How can I do that with another hook/filter?
Thank you.
Unhook the hook used for calling post_confirmation and override this function from your functions.php like
remove_action( 'current_action_hook', 'post_confirmation' );
add_action( 'current_Action_hook', 'post_custom_confirmation' );
function post_custom_confirmation(){
...some extra stuff
$values = explode( ":", $_POST["value"] );
$location = $values[0];
$service = $values[1];
if (($service == 1) || ($service == 3)) {
do_action('app-additional_fields-validate');
}
...more stuff
}
I think this should work, I have used this way during a woocommerce plugin development before nearly 2 months below is working code example , so that if you need any modification on code above, you can take reference .
remove_action( 'woocommerce_checkout_order_review', 'woocommerce_order_review', 10 );
add_action( 'woocommerce_checkout_order_review', 'pk_order_review', 10, 1 );
function pk_order_review($template) {
global $woocommerce;
$template = wc_get_template ( 'checkout/review-order.php', FALSE, FALSE, untrailingslashit( plugin_dir_path( __FILE__ ) ) . '/templates/');
return $template;
exit;
}
Another way you can do it is
add_action( 'app-additional_fields-validate', 'foo' );
function foo(){
if (($service == 1) || ($service == 3)) {
/* Your stuffs */
}
}
This is actually part answer, part new question. If that is possible to do here.
So, I finally found a way to affect the desired function.
The function I was trying to modify is contained in a class so, I did something like this:
class my_Check extends Appointments {
function __construct() {
$this->unregister_parent_hook();
add_action( 'wp_ajax_post_confirmation', array( $this, 'post_confirmation' ) );
add_action( 'wp_ajax_nopriv_post_confirmation', array( $this, 'post_confirmation' ) );
}
function unregister_parent_hook() {
global $appointments; //this was the object created with the parent class
remove_action( 'wp_ajax_post_confirmation', array( $appointments, 'post_confirmation' ) );
remove_action( 'wp_ajax_nopriv_post_confirmation', array( $appointments, 'post_confirmation' ) );
}
function post_confirmation() {
...do the stuff with my mods...
}
}
$new_Check = new my_Check();
Only, I have a new problem now. The parent class does a lot more in the __construct() (many 'add_action()'s, etc.). And $this is populated with a lot more data. The problem is, these other things and data do not seem to be carrying over into the child class. I tried adding a parent::__construct() in the child's __construct() function, but that did not seem to work.
The code with my mods works except for things that need more data in the $this carried over from the parent class.
How can I maintain all the parent class's variable, functions, hooks & filters, etc. into the child class?

How to update wordpress content

add_filter('the_content','filter_trendland_content');
//create a the function to get the content of the page by using the hook the_content
function filter_trendland_content($content) {
$getdata = $content;
if ( preg_match_all( '#(?:<a.+?href=["|\'](?P<link_url>.+?)["|\'].*?>\s*)?(?P<img_tag><img.+?src=["|\'](?P<img_url>.+?)["|\'].*?>){1}(?:\s*</a>)?#is', $getdata, $images ) ) {
foreach ( $images[img_url] as $key => $value) {
$subdomain = rand( 1, 3 );
$newurl="yaseen.media$subdomain.com";
$content = preg_replace('/\bmedia.trendland.com\b/', $newurl, $value);
print $content;
}
print $getdata;
}
//return $getdata;
}
I am using the above method to replace the url's with the new one and update the content of the page but the page content is still the same so please help me with this..
Looking at your function, it does not return a value.
Instead of printing the output, return the content back to the filter.
Also, you are iterating through an empty object - $images[img_url]. Check the documentation for preg_match_all. It returns a multi-dimensional array of matches.
You code looks over-engineered and the word boundary in your regex would probably prevent a match. The following may achieve what you need providing that all instances of media.trendland.com require replacing.
function filter_trendland_content($content) {
$subdomain = rand( 1, 3 );
$newurl='yaseen.media' . $subdomain . '.com';
$content = preg_replace('/media.trendland.com/', $newurl, $content);
return $content;
}

Editing a post after it's been published via a plugin?

I'm trying to write a plugin which edits the content of a published post. I've tried using this:
function edit( $post_ID ) {
$content = "Hello. This is a test.";
$post_info = get_post($post_ID);
$post_info->post_content = "$content";
wp_update_post( $post_info );
}
add_action('publish_post', 'edit');
Although that's not working. It enters a loop (because it's being published again) and only ends when it times out. Would there be another way to do this?
I think you have to have a static variable in the function that tracks whether the function has been called. Also, wp_update_post takes an array rather than an object -- at least that's the way I do it.
function edit( $post_ID ) {
static $plugin_has_updated = false;
if ($plugin_has_updated) return;
$plugin_has_updated = true;
$content = "Hello. This is a test.";
$post_arr = array("ID"=>$post_ID, "post_content"=>$content);
wp_update_post( $post_arr );
}
add_action('publish_post', 'edit');

Resources