Wordpress - Advanced Category Excluder - Undefined Variable Error - wordpress

Trying to use the Advanced Category Excluder plugin and everything works great except on my 404 page I'm getting all of these "Undefined variable" errors on line 446
Try it here:
http://bolivares.com/test
Line 446 reads return $filter;
In full context:
function ace_get_section()
{
global $wp_query, $ace_targets;
if (is_array($ace_targets))
{
foreach ($ace_targets as $key=>$val)
{
if (!empty($wp_query->$key) && $wp_query->$key == 1) $filter = $key;
}
}
return $filter;
}
Plugin Page
http://wordpress.org/extend/plugins/advanced-category-excluder/
Anyone know how this can be resolved?

That $filter variable is defined only when some conditions are met but when conditions are not met the variable is undefined as the notice says.
So try to add $filter=""; in the beginning of the function like this:
function ace_get_section()
{
global $wp_query, $ace_targets;
$filter="";
if (is_array($ace_targets))
{
foreach ($ace_targets as $key=>$val)
{
if (!empty($wp_query->$key) && $wp_query->$key == 1) $filter = $key;
}
}
return $filter;
}

Related

Woocommerce validate checkout function error on pageload

I am making a custom validation process for a client, but it depends on country. In the Netherlands, one can use IDIN for this.
So i need to do a check in the checkout to find out if the country is "Netherlands". If that is the case, an extra field is needed to do the validation of the customer. This can be echo'ed via a shortcode.
So far i have the following:
function validate_country( $fields, $errors ){
$return = false;
if ( $fields[ 'billing_country' ] == 'Netherlands' ) {
$return = true;
$errors->add( 'validation', 'Please fill in the IDIN requirement' );
}
return $return;
}
add_action( 'woocommerce_after_checkout_validation', 'validate_country', 10,2 );
function print_idin_form() {
if(validate_country()){
echo do_shortcode('[bluem_identificatieformulier]');
}
}
add_action('woocommerce_checkout_after_customer_details','print_idin_form');
However, when i use this, it throws an error on pageload because obviously, the validate_country function is not executed yet. The error I get is:
Fatal error: Uncaught ArgumentCountError: Too few arguments to function validate_country(), 0 passed
How to solve this?

WordPress prevent delete taxonomy

I would like to prevent that some categories are accidentally deleted. For this I use a meta entry for the category to be protected.
I use the following code for this:
// edit: wrong hook! ** add_action( 'delete_term_taxonomy', 'taxonomy_delete_protection', 10, 1 );
add_action( 'pre_delete_term', 'taxonomy_delete_protection', 10, 1 );
function taxonomy_delete_protection ( $term_id )
{
if (get_term_meta ($term_id, 'delete-protect', true) === true)
{
wp_die('Cannot delete this category');
}
}
Unfortunately, instead of my error message, only "Something went wrong" is displayed. Why?
Edit: The `delete_term_taxonomy` is the wrong hook for my code, because it deleted the meta before i can check the meta entry. `pre_delete_term` does fire before anything happens with the category.
The "Why" is because of the following JavaScript that ships with WordPress:
$.post(ajaxurl, data, function(r){
if ( '1' == r ) {
$('#ajax-response').empty();
tr.fadeOut('normal', function(){ tr.remove(); });
/**
* Removes the term from the parent box and the tag cloud.
*
* `data.match(/tag_ID=(\d+)/)[1]` matches the term ID from the data variable.
* This term ID is then used to select the relevant HTML elements:
* The parent box and the tag cloud.
*/
$('select#parent option[value="' + data.match(/tag_ID=(\d+)/)[1] + '"]').remove();
$('a.tag-link-' + data.match(/tag_ID=(\d+)/)[1]).remove();
} else if ( '-1' == r ) {
$('#ajax-response').empty().append('<div class="error"><p>' + wp.i18n.__( 'Sorry, you are not allowed to do that.' ) + '</p></div>');
tr.children().css('backgroundColor', '');
} else {
$('#ajax-response').empty().append('<div class="error"><p>' + wp.i18n.__( 'Something went wrong.' ) + '</p></div>');
tr.children().css('backgroundColor', '');
}
});
The expected response to this POST request is:
'1' if the term was deleted
'-1' if your user doesn't have permission to delete the term.
For all other cases, "Something went wrong" is displayed.
You are terminating the script early with wp_die, yielding an unexpected response, which comes under "other cases".
There isn't a way to provide a custom error message in the notice box here without writing some JavaScript of your own.
This is my current solution, not perfect but it works.
The "Something went wrong" message show up if you delete the taxonomy with the row action. So i unset the "delete" action so it couldn't be triggered this way.
add_filter ('category_row_actions', 'unset_taxonomy_row_actions', 10, 2);
function unset_taxonomy_row_actions ($actions, $term)
{
$delete_protected = get_term_meta ($term->term_id, 'delete-protect', true);
if ($delete_protected)
{
unset ($actions['delete']);
}
return $actions;
}
Then i hide the "Delete" Link in the taxonomy edit form with css. It's still could be triggered if you inspect the site and it's link, but there is no hook to remove this action otherwise.
add_action( 'category_edit_form', 'remove_delete_edit_term_form', 10, 2 );
function remove_delete_edit_term_form ($term, $taxonomy)
{
$delete_protected = get_term_meta ($term->term_id, 'delete-protect', true);
if ($delete_protected)
{
// insert css
echo '<style type="text/css">#delete-link {display: none !important;}</style>';
}
}
Finally the check before deleting the taxonomy. This should catch all other ways, like the bulk action "delete". I didn't found another way yet to stop the script from deleting the taxonomy.
add_action ('pre_delete_term', 'taxonomy_delete_protection', 10, 1 );
function taxonomy_delete_protection ( $term_id )
{
$delete_protected = get_term_meta ($term_id, 'delete-protect', true);
if ($delete_protected)
{
$term = get_term ($term_id);
$error = new WP_Error ();
$error->add (1, '<h2>Delete Protection Active!</h2>You cannot delete "' . $term->name . '"!');
wp_die ($error);
}
}
This solution provides a way to disable all categories from being deleted by a non Admin. This is for anyone like myself who's been searching.
function disable_delete_cat() {
global $wp_taxonomies;
if(!current_user_can('administrator')){
$wp_taxonomies[ 'category' ]->cap->delete_terms = 'do_not_allow';
}
}
add_action('init','disable_delete_cat');
The easiest solution (that will automatically take care of all different places where you can possibly delete the category/term) and in my opinion the most flexible one is using the user_has_cap hook:
function maybeDoNotAllowDeletion($allcaps, $caps, array $args, $user)
{
if ($args[0] !== 'delete_term') return $allcaps;
// you can skip protection for any user here
// let's say that for the default admin with id === 1
if ($args[1] === 1) return $allcaps;
$termId = $args[2];
$term = get_term($termId);
// you can skip protection for all taxonomies except
// some special one - let's say it is called 'sections'
if ($term->taxonomy !== 'sections') return $allcaps;
// you can protect only selected set of terms from
// the 'sections' taxonomy here
$protectedTermIds = [23, 122, 3234];
if (in_array($termId, $protectedTermIds )) {
$allcaps['delete_categories'] = false;
// if you have some custom caps set
$allcaps['delete_sections'] = false;
}
return $allcaps;
}
add_filter('user_has_cap', 'maybeDoNotAllowDeletion', 10, 4);

Navigating through Wordpress sibling pages using functions.php

I'm trying to find a way to get through sibling pages on my wordpress hosted site. After a bit of searching I found this to put into my functions.php:
function siblings($link) {
global $post;
$siblings = get_pages('child_of='.$post->post_parent.'&parent='.$post->post_parent);
foreach ($siblings as $key=>$sibling){
if ($post->ID == $sibling->ID){
$ID = $key;
}
}
$closest = array('before'=>get_permalink($siblings[$ID-1]->ID),'after'=>get_permalink($siblings[$ID+1]->ID));
if ($link == 'before' || $link == 'after') { echo $closest[$link]; } else { return $closest; } }
It's almost perfect for what I need. The only problems are:
It sorts them alphabetically and I need them sorted by the Order Number
I need it to loop (so the last pages links to the first) and not just end
It automatically says "Previous of Next" and I would like to get rid of that "of"
If anyone has input on any of the three issues, I would greatly appreciate it. I'm doing some tinkering myself but I figured that most of you are probably a lot better at this than I am. That, and I've gotten "500 Server Errors" one too many times.
Thanks
Here is your modified piece of code. It solves your first two requests. The last one is not part of provided code. This code does not generate either of mentined words. It only echoes or returns permalinks.
function siblings($link) {
global $post;
$siblings = get_pages('child_of='.$post->post_parent.'&parent='.$post->post_parent.'&sort_column=menu_order');
foreach ($siblings as $key=>$sibling){
if ($post->ID == $sibling->ID){
$ID = $key;
}
}
if( $ID == 0 ){
$closest = array('before'=>get_permalink($siblings[count($siblings)-1]->ID),'after'=>get_permalink($siblings[$ID+1]->ID));
}elseif( $ID == count($siblings)-1 ){
$closest = array('before'=>get_permalink($siblings[$ID-1]->ID),'after'=>get_permalink($siblings[0]->ID));
}else{
$closest = array('before'=>get_permalink($siblings[$ID-1]->ID),'after'=>get_permalink($siblings[$ID+1]->ID));
}
if ($link == 'before' || $link == 'after') { echo $closest[$link]; } else { return $closest; } }
EDIT: Added &sort_column=menu_order to get_pages arguments to solve first request

Drupal PHP block visibility rules

In a Drupal block's Page Visibility Settings I'd like to prevent a certain block from showing if the second value in the path is a number. This does not seem to be working for me. Cheers.
Show block ONLY when arguments are:
domain.com/video/one (arg 0 is 'video' and arg 1 is present and NOT a number)
Don't show:
domain.com/video
domain.com/video/1
<?php
if (arg(0) == 'video' && is_nan(arg(1)) && empty(arg(2))) {
return TRUE;
}
else {
return FALSE;
}
?>
I'm assuming this is in a hook_block/hook_block_view function? You could try a different approach:
if (preg_match('/^video\/[0-9]+$/', $_GET['q'])) {
// Path has matched, don't show the block. Are you sure you should be returning TRUE here?
return TRUE;
}
else {
// Path has matched, go ahead and show the block
return FALSE;
}
You can simply use the following code:
<?php
$arg1 = arg(1);
$arg2 = arg(2);
// Check arg(1) is not empty, or is_numeric() returns TRUE for NULL.
return (arg(0) == 'video' && !empty($arg1) && !is_numeric($arg1) && empty($arg2));
?>
As KingCrunch already said, is_nan() doesn't return TRUE when its argument is a number.
The code you reported contains another error too: empty() can be used only with variables, as reported in the PHP documentation.
empty() only checks variables as anything else will result in a parse error. In other words, the following will not work: empty(trim($name)).
The code I reported shows the block for paths like "video/video1"; if you want to show the block also for paths such as "video/video1/edit", then the following code should be used.
<?php
$arg1 = arg(1);
return (arg(0) == 'video' && !empty($arg1) && !is_numeric($arg1));
?>
Using arg() doesn't work if the path you are looking for is a path alias. Suppose that "video/video1" is a path alias for "node/10"; in that case arg(0) will return "node," and arg(1) will return "10." The same is true for $_GET['q'] that will be equal to "node/10."
This happens because Drupal, during its bootstrap, initialize $_GET['q'] with the following code:
// Drupal 6.
if (!empty($_GET['q'])) {
$_GET['q'] = drupal_get_normal_path(trim($_GET['q'], '/'));
}
else {
$_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage', 'node'));
}
// Drupal 7.
if (!empty($_GET['q'])) {
$_GET['q'] = drupal_get_normal_path($_GET['q']);
}
else {
$_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage', 'node'));
}
If you what you are checking is a path alias, then you should use the following code:
// Drupal 6.
$arg = explode('/', drupal_get_path_alias($_GET['q']);
return (arg[0] == 'video' && !empty($arg[1]) && !is_numeric(arg[1]) && empty($arg[2]));
// Drupal 7.
$arg = explode('/', drupal_get_path_alias();
return (arg[0] == 'video' && !empty($arg[1]) && !is_numeric(arg[1]) && empty($arg[2]));
Dont know, what your arguments looks like, but I assume you mixed up two kinds of types. is_nan() only works with numbers. If you want to test, if a value is a number,
var_dump(is_numeric(arg(1));
is_nan() tests, if a "numeric" value is a concrete value or "not a number" like "infinite" or the result of "0/0" or such.

drupal module, check if node type

As a more specific take on this question:
drupal jQuery 1.4 on specific pages
How do I check, inside a module, whether or not a node is a certain type to be able to do certain things to the node.
Thanks
The context:
I'm trying to adapt this code so that rather than working on 'my_page' it works on a node type.
function MYMODULE_preprocess_page(&$variables, $arg = 'my_page', $delta=0) {
// I needed a one hit wonder. Can be altered to use function arguments
// to increase it's flexibility.
if(arg($delta) == $arg) {
$scripts = drupal_add_js();
$css = drupal_add_css();
// Only do this for pages that have JavaScript on them.
if (!empty($variables['scripts'])) {
$path = drupal_get_path('module', 'admin_menu');
unset($scripts['module'][$path . '/admin_menu.js']);
$variables['scripts'] = drupal_get_js('header', $scripts);
}
// Similar process for CSS but there are 2 Css realted variables.
// $variables['css'] and $variables['styles'] are both used.
if (!empty($variables['css'])) {
$path = drupal_get_path('module', 'admin_menu');
unset($css['all']['module'][$path . '/admin_menu.css']);
unset($css['all']['module'][$path . '/admin_menu.color.css']);
$variables['styles'] = drupal_get_css($css);
}
}
}
Thanks.
Inside of a module, you can do this:
if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) != 'edit') {
if (!($node)) {
$node = node_load(arg(1));
}
if ($node->type == 'page') {
// some code here
}
}
That will load a node object given the current node page (if not available). Since I don't know the context of code you are working with, this is kind of a rough example, but you can always see properties of a node by doing node_load(node_id). But, depending on the Drupal API function, it may already be loaded for you.
For example, hook_nodeapi.
http://api.drupal.org/api/function/hook_nodeapi
You could do:
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'view':
// some code here
}
}
Try this:-
function MyModule_preprocess_node(&$vars) {
if ($vars['type'] == 'this_type') {
// do some stuff
}
}
Try this:-
$node = node_load(arg(1));
$node =$node->type;
if($node == 'node_type'){
//do something
}

Resources