RSS feed

Nutsmuggling

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!

Faking an IP with Webrat

Lately I have been diving into TDD, and more specifically BDD, thanks to the wonderful Cucumber testing framework.

Today I have had to test a specifical IP based feature. Simply put, I get the user IP and store it into the database.

The simple rails way to get a visitor IP address is

request.remote_ip

If you do this while developing you’ll usually get a predictable

127.0.0.1

How do I test that my controller puts a correct IP in the database?
At first I thought about creating a mock request object. But this way I would be testing only the saving portion of the method, not the part detecting the IP. In other words, I needed to simulate an IP address at a lower layer.

Webrat to the rescue! Thanks to the nice folks at the webrat irc channel I got an answer. Simply:

header('REMOTE_ADDR', ip_address)

The Webrat headermethod lets you set all the header variable of you session. Handy, isn’t it?

Events Manager comments disabled

Hi folks,
just a quick note for warning that comments on EM are going to be disabled for a while.
Why?
Despite a disclaimer at the beginning of the post and a huge banner people is posting support problems as comments, instead that on the forum. I guess I should increase the banner size of make it flashy with JS.
As soon as I have some time (not that sooinish) I’ll clean the thread and leave only relevant comments (pre-forum tweak suggestions and release announcements). And re-enable commenting.
For now comments are closed. Use the forum, PLEASE!
Davide