Manage Account

 

 

Modifying the Members Plugin by Justin Tadlock for Multisite Installations

Justin Tadlock's Members plugin has become pretty much a default piece of every project I do lately. The ability to fine grain user permissions is almost always a critical part of any business website built using WordPress. A typical set up might involve employees having low level access to backend functions, managers having greater abilities, and owners having access to nearly everything … with "nearly" being the key word. There are a number of things — like the ability to switch themes or update plugins — that I don't want clients accessing in case they accidentally make a change that causes problems with their site.

With the Members plugin you can pretty easily set up roles that are appropriate for your particular application. On a recent project using a multisite install of WordPress, however, I came across a slightly annoying issue — the Members plugin is designed to not allow you to delete the default role or the role you're currently logged in with. In the case of the default role, you need to first change the default to something else, then you can go back and delete the current default role. All members who are assigned the current default role will be assigned the new default role when you delete the old one. So if your default was Subscriber and you make the new default be a custom role you created, say Member, when you delete Subscriber everyone with that role will be reassigned to Member.

If you're logged in and your account has the custom role Owner, you won't be able to delete that role for obvious reasons. You'd need to log out and log back in as another role with delete_roles permissions. The issue I ran into is that with Multisite, when I'm logged in as a Super Admin I have no ability to delete roles. I don't want to have to create an account for each site, give that account the delete_roles capability, and then log out and back in everytime I want to make a change.

The solution? A small modification to the edit-roles.php file, located in /plugins/members/components/. Change as follows:

#160   <?php if ( $role !== $default_role && !$user->has_cap( $role ) ) { ?>

To

#160  <?php if ( $role !== $default_role && ( !$user->has_cap( $role ) || is_super_admin() && $role !=='administrator')) { ?>

Now super admins will be able to delete any role except for their own (Administrator) and the default role.

If you prefer, you can download the modified file here and simply replace the existing one:

Members Plugin revised edit-roles.php File Downloaded 285 times

Wondering how to change the default role for a particular site when you're using Multisite? You don't have the option on your General Settings tab like you do on a single site install. To do it in Multisite go to your Super Admin menu and click on Sites. Go to the site you want to change and click on Edit. Then scroll down the screen full of settings and you'll find Default Role with a text box next to it showing your current default. To change it type the name of the new role you wish to substitute using the role name, not the role display name. For example, you might have created a role called Paid Members but the role name might be paid-members.

Solution For Mailpress Causing Errors with the Lost Password Email in WordPress

I came across a problem today with a client site where I’m using Mailpress to handle both a newsletter and all of the default WordPress emails. Everything was working beautifully except for the lost password emails. If a user submitted the lost password form they got the email they were supposed to with the link to reset their password. But clicking on the link resulted in the dreaded:

The email could not be sent. Possible reason: your host may have disabled the mail() function.

But weirdly enough the email COULD be sent, and in fact it was.

For those who simply want the solution, here you go. For those who are curious about what caused the problem, it’s explained below.

Solution:

In the Mailpress plugin folder open /mp-includes/wp_pluggable.class.php and replace the following code:

  1. /**
  2. * wp_mail() - Function to send mail
  3. */
  4. if ( !function_exists( 'wp_mail' ) ) :
  5. function wp_mail( $to, $subject, $message, $headers = '', $attachements = false )
  6. {
  7. MP_Pluggable::wp_mail( $to, $subject, $message, $headers, $attachements);
  8. }
  9. endif;
  10.  
  11. /plugins/mailpress/mp-includes/wp_pluggable.class.php

With this modified version:

  1. /**
  2. * wp_mail() - Function to send mail
  3. */
  4. if ( !function_exists( 'wp_mail' ) ) :
  5. function wp_mail( $to, $subject, $message, $headers = '', $attachements = false )
  6. {
  7. $result = MP_Pluggable::wp_mail( $to, $subject, $message, $headers, $attachements);
  8. if($result!=0){
  9. return $result;
  10. }
  11. }
  12. endif;

That’s it, you’re good to go.

Now, for those who are wondering why this happened. WordPress allows programmers to override it’s wp_mail function and several others by simply declaring a function with the same name. It does this by wrapping the wp_mail( ) function in the following condition:

  1. if ( !function_exists( 'wp_mail' ) ) :

What this means is, if there isn’t already a function called wp_mail, then go ahead and proceed with creating one. But if there is, then skip this. Since your plugin and theme files get loaded before the file where this code is (/wp-includes/pluggable.php starting at line 233), your version of wp_mail already exists and hence it’s the one that gets used.

Mailpress takes advantage of this to define it’s own version of wp_mail — that’s what you just changed in the code above. And it works great. Except for when it comes to the reset password process. The reason is this: When you click on the reset password link in the first email, you are being sent to wp-login.php with two pieces of info. appended to the URL — a unique reset password key and your user login. The wp-login.php file does some magic to verify that key and generate a new password which is inserted into the database and then emailed to you. But before it generates the new password, it checks to make sure that it can actually send it to you.

In wp-login.php starting at line 259 you’ll find the following code:

  1. if ( $message && !wp_mail($user->user_email, $title, $message) )
  2. wp_die( __('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function.') );

It looks to see if a message has been created and if so it calls the wp_mail function. The ! — which is a PHP operator meaning NOT — means that if wp_mail() doesn’t return some value, then something is wrong so stop the process (otherwise you’d never get your new password).

And that’s where the bug is. WordPress expects wp_mail to return “true” if it was successful. Mailpress’s version of wp_mail returns the number of emails sent. So when you hit the login page and WordPress does it’s check to see if it should go ahead and reset your password, it never gets back a response and it fails. By making the slight tweak to return the result, it gets the response it’s looking for and all is good.

Hope that helps a few of you out.

Easy Pagination Class for WP Plugins & Projects

I’m currently working on a client project built using WordPress that involves a number of custom templates and some custom database tables. I have a few pages where I need to show client records in table form with navigation through through the results (previous, next, jump to record X, etc.). As I was about to start coding up a class to handle it I thankfully did a quick Google search first and found: http://www.catchmyfame.com/2007/07/28/finally-the-simple-pagination-class/

The one file class allows you to easily paginate any database results with all of the above navigation options. Integrating it into WordPress was a matter of tweaking the URL parameters it was based on. With that done I simply included the class in a custom plugin I’m writing for this project, declared a new global instance of the paginator class (so that I could access it on my templates) and that was it, all set.

I’ve attached the modified file as a download. The original site has great instructions on how to use it as well. The section of the site where I’m using it isn’t publicly accessible but I’ll stick a demo up here shortly showing how to use it in WordPress.

Wordpress Paginator Downloaded 310 times

Gravity Forms Ajax Submits Fails in IE — Here’s the Fix

Ran into a problem with Gravity Forms, IE8 and ajax form submission where it was kicking out an “error, object expected” every time. After many hours of digging through the code I figured out the issue.

Short version is that the way it was written, when you first load a page with a form it gets output on the page. When you submit via ajax, the request goes back to that same form function, and checks to see what the result is. The result is passed to a hidden iframe, then that content is used to replace the existing form HTML.

The issue is that what is being passed to the iframe INCLUDES the jquery call to make it all work, wrapped in a document.ready() call. When it is passed to the iframe, IE8 doesn’t see jquery as being loaded — it treats the iframe like a totally separate page. The solution was to split the jquery stuff out on ajax pages so that it is loaded only the first time the page is loaded, and all that is sent to the iframe is the actual form.

An updated copy of form_display.php is attached. Just download, replace the one in your plugin folder and you’re good to go.

Gravity Forms Form-Display.PHP Update Downloaded 457 times

Access a New WordPress Install without the Admin Account Info

If you’ve ever done a new install of WordPress and for whatever reason not gotten the initial email with the admin user name and password, you know it can be a real pain in the arse. I know people who have ended  up deleting the install and doing it over again thinking there was no other way to access WP.

If you have access to the WP database however, you are in luck.

Using PhpMyAdmin or your dbase tool of choice, access the new WordPress table and browse the wp_users table – there will be one record, for the new admin user.

WP uses a function called wp_hash_password() to generate the passwords. So I just did an echo of wp_hash_password(‘password’) to see what it would store in the database if you used “password” as your password. Output is: $P$BWRXG..rmf7CMNWqugvFlwWj.7pwQl/

So just paste that in the admin password field and then you can login to WP using “password” as your password and then change it from your Profile link. *Make sure you do change that password immediately for security reasons.