RSS feed

Nutsmuggling

How to allow tags in Wordpress comments unobtrusively

Scenario: I am using the tinymcecomments plugin to give some formatting capabilities to commenters.
With the latest WP update I realised the span tag was removed from comments; colors attributes are filtered by the kses filter.

Hum.

After investigating I come across this suggestion in the Codex:

Acceptance of HTML tags in the comments field is managed in the file kses.php, located in the wp-includes folder.

Open this file in a text editor, and locate the list of HTML tags near the top of the file. Each HTML tag is listed on a separate line, in the construction of a PHP array of allowed tags. Lines which begin with // are commented-out, or disabled, so lines which begin with // designate HTML tags that are not allowed in comments.

To stop people from posting HTML in comments, edit your kses.php file as desired to allow or disallow specific HTML tags in comments, by adding // to the very beginning of the appropriate lines of the list. To exclude all HTML tags, comment out all lines which allow HTML tags. Be sure to save your file when done.

That’s a start but hey, is the Codex really suggesting that I alter the WP core? Next update my all precious settings will go away. C’mon, we can do better than that!

In the kses source code I find this:

 
if (!defined('CUSTOM_TAGS'))
	define('CUSTOM_TAGS', false);
 
if (!CUSTOM_TAGS) {     
	etc

So basically I can redefine all the allowed tags structure in a constant. Not bad. But hey, do I really want to redefine both the $allowedposttags and the $allowedtags variables? Naaah…

So I scavenged in the source code and I came across a fit filter. I wrote a little function for my functions.php file; needless to say, this could have gone into a plugin.

add_filter('preprocess_comment','fa_allow_tags_in_comments');
 
function fa_allow_tags_in_comments($data) {
	global $allowedtags; 
	$allowedtags['span'] = array('style'=>array());
	$allowedtags['p'] = array();   
	return $data;
}

See? Much more concise than overwriting the variables. And more future-proof: if subsequent versions of Wordpress change the variable there is no constant barring the changes.

Cheers,
Davide

Events Manager 2.2, security hole closed

Hello folks,
I just released Events Manager 2.2. It’s a minor upgrade, here is the changelog:

  • Added a option to get events through a select
  • Closed many bugs causing a notices/warning visible only in debug mode
  • Closed a critical security hole discovered by Danilo Massa (to be released on May 10th)

The first point is the only proper feature, it allows you to use a select for the events venue. It’s something that comes in handy for people/organizations whose events take place in the same venues all the times.

The second point is something I should have done AGES ago. I put Worpress in debug mode and thus could see all the stuff that’s usually spitted directly into the error log. There were many small bugs, caused mainly by the lack of isset here and there. I believe there are still minor notice/warnings, but I got rid of most of them.

Point three is what urged me to release ASAP. Danilo Massa kindly notified me of a security hole in Events Manager, providing a simple one-liner to fix it. Since the vulnerability is pretty serious I hurried to apply Danilo’s patch and release 2.2.

This release is quite stable, it’s employed in a client portal, so you should have no problem with the upgrade.

Enjoy,
Davide

Events Manager 2.1

Hello folks,
just a short note to announce the release of Events Manager 2.1.
It’s probably not as stable as the lack of a or b would suggest, but it is definitely much stabler than the previous version. Also, I got tired of letters.

Here’s the changelog:

  • Properly added Marcus Sykes as a contributor
  • Added a full calendar
  • Added an #_EDITEVENT placeholder
  • Added Brazialian Portuguese localization and some translatable strings
  • Added a today scope for events lists
  • Increased to 3 te default lists limit
  • Categories are now displayed in the events table
  • Now weeks starts according to WP settings
  • Moved the hide page option up for better access
  • Attributes column was not created when the plugin was upgraded, fixed
  • Added comment field to the RSVP form and #_COMMENT placeholder in RSVP email templates
  • Added customizable title to small calendar
  • Removed php short tags
  • Changed RVSP ‘no seats available message’ for better English
  • Bugfix: there was a time bug
  • Bugfix: event_time not taken into consideration in ordering events, fixed
  • Bugfix: on calendar for days after 28 on the event calendar view
  • Bugfix: for events in days with single digit
  • Bugfix: events link in the calendar now work with permalink
  • Bugfix: today in next mont was not matched in the calendar
  • Bugfix: _RESPPHONE was not matched in emails
  • Bugfix: fixed security vulnerability, which could lead to sql inject attacks
  • Bugfix: locations with apostrophe were duplicated
  • Bugfix: bloginfo(‘wpurl’) instead of bloginfo(‘url’)
  • Bugfix: now loading textdomain in the new (not deprecated) way

Most of the bugfixes, and some of the features, were sponsored by Sara of Paperlantern, to whom I am most grateful.

Also, I just got a haircut:

Cheers,
Davide

Wordpress: disable moderation for a single comment

I am working an very complex portal based on Wordpress. The more I code, the more I befriend the functions.php file, where all my small tweaks reside. Last in the list (pun!) a super simple action to automatically approve comments belonging to a specific post (which I use as a guestbook):

function approve_guestbook_comments($comment_ID) {
	$comment = get_comment($comment_ID);    
	if ($comment->comment_post_ID == guestbook_page())
		wp_set_comment_status($comment_ID,'approve');
 
}
add_action('comment_post','approve_guestbook_comments');

As you see it’s a super-simple tweak, but it’s quite effective.

Enjoy,
Davide

Mass import users into WP

I am working on a complex blog/e-commerce system together with my colleagues at @ntw. I had to import some 10.000 users into WP. The task was easier than expected. The basic idea is leveraging on the wp_insert_user($userdata) function, defined in wp-includes/registration.php. If you look at the source, you’ll see that $userdata is an array containing a number of keys:

	* The $userdata array can contain the following fields:
	* 'ID' - An integer that will be used for updating an existing user.
	* 'user_pass' - A string that contains the plain text password for the user.
	* 'user_login' - A string that contains the user's username for logging in.
	* 'user_nicename' - A string that contains a nicer looking name for the user.
	*		The default is the user's username.

The other keys are user_url,user_email, display_name, nickname, first_name, last_name, description, rich_editing, user_registered, role, jabber, aim, yim; for more detal consult the source itself.

My script goes like this:

<?php
include 'wp-blog-header.php'; 
include 'wp-includes/registration.php';   
include 'wp-includes/pluggable.php'; 
ini_set("memory_limit","1024M"); 
ini_set("max_execution_time", "240");
global $wpdb;
?>
 
<h1>Importazione utenti EC</h1>
 
<?php
$connection = mysql_connect("host", "user", "password") or die("Unable to connect to MySQL");
mysql_select_db("database", $connection) or die("Unable to connect to the database"); 
$result = mysql_query("SELECT * FROM source_users ;");
	while ($row = mysql_fetch_object($result)) {
		echo "<strong>ID:</strong>".$row->id." <strong>login:</strong>".$row->user_name." <strong>password:</strong> ".$row->password." <strong>e-mail:</strong>".$row->email_address." <strong>name:</strong> ".$row->name." <strong>surname:</strong> ".$row->surname."<br/>";  
		// Add the ID to trick WP
		$add_id = "INSERT INTO ".$wpdb->users." (id, user_login) VALUES (".$row->id.",'"."$row->user_name"."' ); ";
		 mysql_query($add_id) or die(mysql_error());
		// Add the rest
		$userdata = array(
		 'ID' => $row->id,  
		 'user_login' => $row->user_name,
		 'user_pass' => wp_hash_password($row->password),
		 'user_nicename' => $row->user_name,
		 'user_email' => $row->email_address,
		 'first_name'  => $row->name,
		 'last_name'  => $row->surname,
		 'role' => 'subscriber'
		);                          
		wp_insert_user($userdata) ;
	}
}
 
 
mysql_close($connection);

Some highlights:

  • Import all the WP files you need
  • Change PHP memory and time limits if you have many records
  • Explicitly encrypt the password with wp_hash_password. I have no idea why this is necessary, the WP code should do this by itself; but trust me, it is.

Since we are using the wp_insert_user() function, WP will crate records both in the users and in the usermeta tables.

A last warning. This huge amount of users could conflict with your php settings. To get WP working properly I had to add this line to wp-config.php:

	define('WP_MEMORY_LIMIT', '64M');

Without it I could not get the users list in the admin session. I also filed a bug, but this last line should keep you on the safe side.
Enjoy!