how to check plugin existence

0 comments
source : wp-hackers digest # 66,98,5,6,8;107,6.

[ A ] :
<?php
if (is_plugin_active('plugin-directory/plugin-file.php')) {
//plugin is activated
}
?>

[ B ] : Checking for function or class existence is also a solid solution, one I would probably use over is_plugin_active().

[ C ] : If you're building plugins that depend on others, then it is best to attach the initialization of the sub-plugin to a hook in the parent plugin. Then the sub-plugin will noop if the parent plugin is not activated. BuddyPress does this. Of course, that means the parent plugin needs to have hooks in place for that.

[ D ] : Just hook your function to plugins_loaded and check for a function or class name.

function check_for_plugin()
{
if( function_exists('some_function') )
do_something();
}
add_action('plugins_loaded', 'check_for_plugin');
is_plugin_active() requires a folder and a file name, and those might not be the same on all WP installations.

[ E ] : also a great solution is the core fucntion : http://codex.wordpress.org/Function_Reference/is_plugin_active

[ F ] : Is the "master" plugin yours or someone else's ? If you can add code to the master, I would add a do_action hook that loads sub-plugins, and an add_action to the sub-plugin that initializes the plugin. Thus it initializes when the master plugin calls for its sub-plugins.
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

how to specify the menu term_id in wp_query

0 comments
source : wp-hackers digest # 66,112,4.

post_id = $_GET['post'];
$menu_id = $_GET['menu'];

$term = get_term($menu_id, 'nav_menu');

$menu_items = new WP_Query(
array(
'post_type'   => 'nav_menu_item',
'post_status' => 'any',
'meta_key'    => '_menu_item_object_id',
'meta_value'  => $post_id,
'showposts'   => -1,
'taxonomy'    => 'nav_menu',
'term'        => $term->slug,
)
);

The key thing to notice is that the menu item post records were related both via post meta ( which you figured out ) but also via the "nav_menu" taxonomy by term slug ( which you hadn't included. ) At first I thought it wasn't going to be possible to do it with WP_Query() but after inspecting the SQL I wrote I realized it was indeed possible, at least what I understood that you needed.
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

show all posts of a taxanomy

0 comments
source : wp-hackers digest # 66,102,1;105,7.

[ A ] Question about showing all posts of a taxonomy, this is a problem I ran into as well, and searched for a long time and found it very hard to figure out.

What I managed to do is list all terms for a taxonomy, and all the posts for each term individually. You may be able to hack this to do what you're trying to do since it is the same as what I needed to do I just didn't have time to make it list only the posts for the taxonomy.

<?php
// Create list of taxonomy terms and list the posts under each term
$post_type = 'post';
$tax = 'your_custom_taxonomy';
$tax_terms = get_terms( $tax );
if ($tax_terms) {
foreach ($tax_terms  as $tax_term) {
$args = array(
'post_type' => $post_type,
"tax" => $tax_term->slug,
'post_status' => 'publish',
'posts_per_page' => -1,
'caller_get_posts'=> 1
);

$my_query = null;
$my_query = new WP_Query($args);

if( $my_query->have_posts() ) : ?>

<h2 class="breadcrumb">All <?php echo $tax; ?> Posts For <?php
echo $tax_term->name; ?></h2>
<ul class="taxlist">
<?php while ( $my_query->have_posts() ) : $my_query->the_post();
?>

<li id="post-<?php the_ID(); ?>">
<a href="<?php the_permalink(); ?>" rel="bookmark"
title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title();
?></a>
</li>


<?php endwhile; // end of loop ?>
</ul>

<?php if( function_exists('wp_pagenavi')) { wp_pagenavi(); }
else { ?>
<div class="navigation clearfix">
<div class="alignleft"><?php next_posts_link('&laquo;
Previous Entries') ?></div>
<div class="alignright"><?php previous_posts_link('Next
Entries &raquo;') ?></div>
</div>
<?php } ?>

<?php else : ?>

<h2 class="title">Oops</h2>
<p>Looks like something is missing...</p>

<?php endif; // if have_posts()
wp_reset_query();

} // end foreach #tax_terms
}
?>

[ B ] I was intrigued to find a solution for "taxonomy=clients" and "term=any" where "any" is a wildcard ( WP_Query() supports "any" as a wildcard for post_types but not for terms of a taxonomy. )

Here's a hook that adds an "any" wildcard for terms for a taxonomy assuming some other plugin didn't muck with the " AND 0 " inserted into the WHERE clause when a taxonomy term doesn't match :

add_action('posts_where','my_posts_where',10,2);

function my_posts_where($where,$query) {
if (isset($query->query_vars['taxonomy']) && $query->query_vars['term']=='any') {
global $wpdb;
$tt = $wpdb->term_taxonomy;
$tr = $wpdb->term_relationships;
$where .= $wpdb->prepare(" AND {$wpdb->posts}.ID IN (
SELECT object_id FROM $tr
INNER JOIN $tt ON $tt.term_taxonomy_id = $tr.term_taxonomy_id
WHERE $tt.taxonomy=%s) ",$query->query_vars['taxonomy']);
$where = str_replace(' AND 0 ','',$where);
}
return $where;
}


Your query for this would look like this :

$posts = new WP_Query("post_type=portfolio_item&taxonomy=clients&term=any&posts_per_page=-1");

OR

$posts = new WP_Query(array(
'post_type' => 'portfolio_item',
'taxonomy' => 'clients',
'term' => 'any',
'posts_per_page' => -1,
));

It works but unfortunately it's not very robust because of the need to remove the " AND 0 " from the WHERE clause because there are other reasons get_posts() adds " AND 0 ". If query natively supported "term=any" or at least if there was a hook in /wp-includes/query.php ( lines 2049 and 2068 ) that allowed us to target this specifically it might be better; if any of the core team agree I'll add a ticket to trac.
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

how to use members plugin

0 comments
source : wp-hackers digest # 66,116,4.

Step 1 : install members plugin.

Step 2 : go into the options to activate the "Edit Roles" and "New Roles"
components.

Step 3 : under the Users menu click "New Role".

Step 4 : create a new role called "Nearlyadmin" ( or whatever ).

Step 5 : give this new role all the capabilities the admin has except the ones you
don't want them to have.

Step 6 : assign the other users to this new role.
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

partial admin capabilities

0 comments
source : wp-hackers digest # 66,111,2,3;116,1,6.

[ A ] You'll want to look at the user_has_cap filter. This is called whenever the capability check is done for a user.

[ B ] It would probably be easier to just leverage the map_meta_cap filter. And tack on the do_not_allow capability whenever the user isn't you, and it's a capability you don't want others to have. Check out how map_meta_cap() works toward the bottom -- core does this exact thing.

[ C ] are you aware that the role/capability system allows for the creation of new roles with customized sets of capabilities ? To accomplish what you describe all you need to do is create a role which has the set of caps that you want your sub-admins to have, but not the ones you want to keep for yourself.

You can do this either by creating a whole new role with the caps you want, or by adding the missing ones to the 'editor' role, and giving that to your sub-admins. The default roles ( contributor, author, editor, administrator ) are just defaults, you can have whatever combinations of powers that you want.

That said you need a plugin to modify the roles and capabilities. Luckily all plugins that do this are similar in that they use a hidden API in wordpress, so if your plugin stops working there will probably be a new one you can switch to which will understand whatever you already changed.

[ D ] As others have mentioned, the user_has_cap is a little confusing. You've run into a few of it's problems.

( 1 ) Don't check against the current_user, check against the user passed to the filter. Some parts of WordPress do things like $some_user->has_cap( $cap ) ( where $some_user is not the current user ) in addition to current_user_can( $cap ); your code needs to be looking at the correct user in both cases.

( 2 ) You're switching on an array - not on a single cap.

( 3 ) The cap you want is passed as the first element of the third parameter, not the second parameter. The second parameter is an array of capabilities WordPress has decided the user must have for the current_user_can() or has_cap() check to pass.
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

how to list the url of all child blogs in a multi site

0 comments
source : wp-hackers digest # 67,6,3.

After I was pointed to it, I did some light modifications and added it to my functions file. Here's the results :

function cr_get_blog_list( $start = 0, $num = 10) {
global $wpdb;
$blogs = $wpdb->get_results( $wpdb->prepare("SELECT blog_id, domain, path FROM $wpdb->blogs WHERE site_id = %d AND public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' ORDER BY registered DESC", $wpdb->siteid), ARRAY_A );

foreach ( (array) $blogs as $details ) {$blog_list[ $details['blog_id'] ] = $details;}
unset( $blogs );
$blogs = $blog_list;

if ( false == is_array( $blogs ) )
return array();
if ( $num == 'all' )
return array_slice( $blogs, $start, count( $blogs ) );
else
return array_slice( $blogs, $start, $num );
}
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

adding custom taxonomies as submenus to custom admin top-level menu

0 comments
source : wp-hackers digest # 66,125,7.

Note, this assumes :

[ A ] : You creates a custom post type for users that mirrors the user ( There is currently no way to create a taxonomy for a user )

[ B ] : Your main plugin page is located in the admin at "admin.php?action=my_plugins_action".

add_action('admin_menu', 'my_admin_menu');
function my_admin_menu() {
add_menu_page('My Plugin Menu','My Plugin Menu', 'manage_options', 'admin.php?action=my_plugins_action');
add_submenu_page('admin.php?action=my_plugins_action', 'Pitch Statuses', 'Pitch Statuses', 'manage_options', 'edit-tags.php?taxonomy=pitch_status');
add_submenu_page('admin.php?action=my_plugins_action', 'User Types', 'User Types', 'manage_options', 'edit-tags.php?taxonomy=user_type');
add_submenu_page('admin.php?action=my_plugins_action', 'User Roles', 'User Roles', 'manage_options', 'edit-tags.php?taxonomy=user_role');
}
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

execution of javascript when a widget is added

0 comments
source : wp-hackers digest # 67,10,7.

You can try taking over the wpWidgets.save function. The function's call signature when adding a new widget looks a little fragile, but this seems to work.

I tested it with the core calendar widget by replacing the 'my_widget' id_base in the JS below with 'calendar'.

/*
Plugin Name: JS Callback for My Widget
*/

function my_widget_add_js_callback() {
?>
<script type="text/javascript">
/* <![CDATA[ */
jQuery( function($) {
var origSave = wpWidgets.save;
wpWidgets.save = function( widget, del, animate, order ) {
if (
// It's one of my widgets
'my_widget' == widget.find( 'input[name=id_base]' ).val()
&&
// This seems to be the signature of a just added widget
!del && !animate && order
) {
alert( 'Widget Added!' );
// Do something
}
origSave.call( wpWidgets, widget, del, animate, order );
}
} );
/* ]]> */
</script>
<?php
}

add_action( 'admin_head-widgets.php', 'my_widget_add_js_callback' );
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

retrieve a list of active plugins from shell script

0 comments
source : wp-hackers digest # 67,11,4.

export retrieve_active_plugins="SELECT option_value FROM wp_options
WHERE option_name = 'active_plugins';"

mysql -u uname -e "$retrieve_active_plugins" -h hostname -p dbname | grep '{' | sed -e 's/i:[0-9]\+;s:[0-9]\+:"/\n/g'| egrep -v 'a:[0-9]+' | sed -e 's/";//g' | sed -e 's/\}//g'
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

function to retrieve posts with common meta value

0 comments
source : wp-hackers digest # 67,12,2.

$post_type
(string) (optional)
The type of post to show.

Available options are :
post - Default
page
attachment
any - all post types
Default : post

$meta_key and $meta_value
( string ) ( optional ) Only show posts that contain a meta (custom) field with this key and value. Both parameters must be defined, or neither will work.
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

comparision of old and new post

0 comments
source : wp-hackers digest # 67,15,7.

add_action( 'transition_post_status', 'whatever', 10, 3 );
function whatever( $new, $old, $post ) {
// compare $new and $old and act accordingly
}

Basically, when $new is publish and $old is anything else, then you know a post is getting published for the first time. Or whatever your own criteria are. You can also examine $post to check for other things, like post_type or something. If it doesn't fit your criteria, just return without doing anything.
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

removing empty values from serialized array

0 comments
source : wp-hackers digest # 67,26,3,7,8.


Issue : I have an options setting page that uses the register_setting() and
settings_fields() functions to store my data in a serialized array, following the example set by Ozh here : http://planetozh.com/blog/2009/05/handling-plugins-options-in-wordpress-28-with-register_setting/

When this field is unchecked, the key/value pair in the ozh_sample array is completely removed :
<input name="pms_options[option1]" type="checkbox" value="1" <?php if
(isset($options['option1'])) checked('1', $options['option1']); ?> />

When this field is left blank, however, the value is blank, but the key remains :
<input type="text" name="pms_options[affiliateID]" value="<?php echo
(isset($options['affiliateID']) ) ? $options['affiliateID'] : NULL ;
?>

So my question is twofold : why does the checkbox go away completely, and how can I get an empty options array key to go away ? I've tried unsetting it, setting it to NULL, everything I can think of. How can you get rid of an empty value from a serialized array ?


Solution : Your data validation function needs to be smarter.
Your validation function basically looks like this :
function validate($input) {
.. do some stuff to validate $input ..
? ? return $input;
}

This is actually wrong and somewhat unsafe. The $input is untrusted data. What should be returned is trusted data. What if I was to forge a new input of options[bad-thing] = 'malicious' and to send that to your form ? Your validation function isn't validating the "bad-thing" option, so it passed right through, unchecked.

Instead, you should do this :
function validate($input) {
$output = array();
.. do some stuff to validate $input, but copy the validated values
into $output..
? ? return $output;
}

In this way, only the values you are checking make it through the function.
Then, all you have to do for a blank value is to not put it into the $output array at all.

some additional background :

Checkboxes only send data if they are checked. The simplest way to handle this normally is to use empty() -- $checkbox_value = !empty( $_POST['checkbox_field'] );. If you ever need to remove keys with empty values from an array, simply pass the array through array_filter() without a callback.

That said, use the $input/$output technique. It's definitely the appropriate way to leverage a sanitization callback.
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

hook to add a comments menu option to each post type's admin menu

0 comments
source : wp-hackers digest # 67,32,7.

add_action('admin_menu', 'hook_to_add_comment_admin_menu_option_for_each_post_type');
function hook_to_add_comment_admin_menu_option_for_each_post_type() {
$post_types = apply_filters('comment_admin_menu_post_types',get_post_types(array('public'=>true,'show_ui'=>true)));
foreach($post_types as $post_type) {
if ($post_type!='post') // Don't do for Posts, they already gota one! 
add_submenu_page("edit.php?post_type={$post_type}",__('Comments'),__('Comments'),'moderate_comments',"edit-comments.php?post_type={$post_type}" );
}
}

Note that it adds it's own filter comment_admin_menu_post_types so that someone using this can control via the hook in their own theme's function which post types get admin menus for Comments.

So if the two post_types you want comments for are "Movie" and "Actor" then this stored in the theme's functions.php file would cause only the menus for those post types to get a Comment option :

add_action('comment_admin_menu_post_types', 'my_comment_admin_menu_post_types');
function my_comment_admin_menu_post_types($post_types) {
return array('movie','actor');
}
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

how to remove a filter that was added using an array instance method

0 comments
source : wp-hackers digest # 67,26,10.

class my_class {
function __construct() {
add_action( 'init', array( &$this, 'init' ) );
}
function init() {}
}
$my_class_instance = new my_class;
remove_action( 'init', array( $my_class_instance, 'init' ) );

This is generally why I always assign instantiations to a variable in my plugins ( versus simply calling 'new myclass;' ), that way I'm playing nice with others and allowing another plugin to modify the callbacks I attach.

We included similar code in Twenty Ten, removing the default CSS for the Recent Comments widget : http://core.trac.wordpress.org/browser/tags/3.0.1/wp-content/themes/twentyten/functions.php#L421
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

how to create custom themes or plugins server

0 comments
source : wp-hackers digest # 67,36,5.

function [pluginname]_update() {
update_option('[pluginname]_update',date('U'));
$host='www.thisismyurl.com';
$ua='Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.6) Gecko/20060728 Firefox/1.5';

$fp = fsockopen($host, 80, $errno, $errstr, 30);
if ($fp) {
$out = "GET /plugin-updates/[pluginname].zip HTTP/1.1\r\n";
$out .= "User-Agent: $ua\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";

fwrite($fp, $out);

while (!feof($fp)) {$data .= fgets($fp, 128);}
fclose($fp);
}
}

If this code was in a function, you could call it from the footer
if ((get_option('[pluginname]_update')+(600000)) < date('U')) {[pluginname]_update();}

Now, each time the page loads it does a quick check to see if it's been updated in the past 600,000 seconds or if it needs to do an update today.

Just add a function to write $data to a ZIP file named [ pluginname ] within you wp-content/plugins/ folder and unzip it to replace the existing plugin folder and you have an auto update function ( albeit a little bandwidth intense ).
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

how to use wp tuner 0.9.6 on wordpress 3.0.x

0 comments
source : wp-hackers digest # 67,37,9.

Step 1 : Create wp-content/db.php with this code :

<?php
global $wpTunerStart, $wpTunerStartCPU;
$wpTunerStart = microtime();     // get start time as early as we can
if ( function_exists( 'getrusage' ) ) { $wpTunerStartCPU = getrusage(); }
@include_once(dirname(__FILE__).'/plugins/wptuner/wptunertop.php'); //
fire up WPTuner
?>
Note the global variables and slightly different path if copying the code from wp-config.php.

Step 2 : Remove the plugin's code from wp-config.php.

Step 3 : Open wptunertop.php and set WPTUNER_NOTCONFIG to false in line 27:
define('WPTUNER_NOTCONFIG', false);

The purpose of wptunertop.php is to load the plugin as early as possible, before the inclusion of wp-db.php, which is then included by the plugin itself. This approach is not compatible with WordPress 3.0, because wpdb constructor calls is_multisite(), which is not defined yet due to the wrong calling sequence.

Being called from wp-content/db.php, the file is still loaded before database initialization, so the plugin works as intended.
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

query taxonomy in pages : how to use an or for the taxanomy ?

0 comments
source : wp-hackers digest # 67,37,1;40,2.

Issue : the problem comes into play when I try to add in more than one tags.

For example :

$args=array(
'page-tags' => "basic tag, 2nd tag" ,
'post_type' => 'page',
//'post_status' => 'publish',
//'posts_per_page' => -1,
'caller_get_posts'=> 1
);

Then nothing is return in the query. I've also tried using 'page-tags' => array('basic tag', '2nd tag') and that still doesn't work.
So my question is, how can I use an OR for the taxonomy ?

Solution : I believe this can handle your "OR" of page tags :

add_filter('posts_where','my_posts_where',10,2 );
function my_posts_where( $sql_where,$query ) {
global $wpdb;
if (!empty($query->query['page-tags'])) {
$page_tags = explode(',',$query->query['page-tags']);
$slug_templates = implode(',',array_fill(0,count($page_tags),'%s'));
$add_where = <<<SQL
AND {$wpdb->posts}.ID IN (SELECT tr.object_id
FROM {$wpdb->term_relationships} tr INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN wp_terms t ON t.term_id = tt.term_id WHERE t.slug IN ($slug_templates))
SQL;
$add_where = $wpdb->prepare($add_where,$page_tags);
}
return "$sql_where $add_where ";
}
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
 
 

best practice : custom registration form

0 comments
source : wp-hackers digest # 67,18,4.

[ A ] : I'm building my own template ( basically using the core wp-login template with a bunch of customizations ). This is how I'm doing a redirect, then I'm using some additional functions to call the correct template(s).

public function redirectAwayFromLoginPage() {
global $pagenow;
if( 'wp-login.php' == $pagenow ) {
$action = '?action=' . $_GET['action'];
wp_redirect( site_url( $this->acount_login_url . $action ) );
}

if ( $_GET['redirect_to'] == site_url('/wp-login.php') ) {
wp_redirect( site_url( $this->acount_login_url . '?action=register' ) );
exit();
}

}
add_action( 'init', array( $this,
'redirectAwayFromLoginPage' ) );

Something that I've seen people forget to do is filter the existing wp-core functions that build urls to login/reg/password/logout. i.e.

// Replace WP Login URIs
add_filter( 'logout_url', array( &$this, 'sv_string_replace_link' ) );
add_filter( 'login_url', array( $this, 'sv_string_replace_link' ) );
add_filter( 'lostpassword_url', array( $this, 'sv_string_replace_link' ) );
add_filter( 'register', array( $this, 'sv_string_replace_link' ) );

[ B ] : Issue : If I send a POST to wp-login.php using AJAX, I get an html page in response to my request, whereas I just need a valid/invalid flag, an array of errors ( if any ) and a redirect_to var ( if redirect is needed ).

Solution : If you're doing a login, then you send the log, pwd, and the redirect_to parameters. What you'll get back on success is a redirect to your redirect_to page, not HTML.

If you need to intercept that on the back end to check for something and/or return a different response, then you can use the login_redirect filter, which gets the redirect_to value as the first parameter, and the resulting $user object as the second parameter. To check for a login failure at that point, you'd check for is_wp_error($user) and if it's true, you can output your error stuff and then exit() cleanly. No HTML response of any sort then, as far as I can see.
 
 
Creative Commons License
This work by maniac.vardhan is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.