How to use Ajax in a WordPress Post

I recently put together an Ajax autocomplete example using PHP and Mysql so I could post it on my blog, but after getting it working outside wordpress on an independent page I had trouble getting it into wordpress.

I had used plugins in the past which allowed for php code to be used with shortcodes, but inline javascript calls are not something I had gotten past the wordpress editor before. The php code used for retrieving data from the database is in a separate file so no shortcode is needed for that portion.

The inclusion of the javascript autosuggest functions is something I first tried putting in a code block in the wordpress post itself as a link to the external file (autosuggest.js), but unfortunately that didn’t work. Then I saw an article where someone suggested putting the javascript in the theme file header.php and surround it with a php if statement checking for the specific post you want it to appear on. I tried that but later removed it because I wanted my ajax to work on the index page, archive pages, and category/tag/author pages – not just the “single post” page.

Then I went back to the plugin I had installed (CSS & JavaScript Toolbox) for css and javascript and tried putting the entire contents of the autosuggest.js file into one javascript block and installing that in the footer. That worked perfectly so I did the same thing for the css file using the same plugin.

The next challenge was to add the inline JavaScript (ajax) function calls from within the html code for the sample input box in the wordpress post. When I tried just putting it all into the html editor for wordpress the javascript was removed. This was not just a snippet of complete javascript or css though, so I couldn’t just use the same plugin to make another code block and put it in the header or footer.

Since PHP is executed as the page loads, I figured I could put my auto-complete input box with ajax call into a php shortcode and put the shortcode where I wanted the input box to be in my html code. That way wordpress would not filter out the javascript when saving the post contents to the database because it would be hidden behind a shortcode which would be replaced during page loading.

This worked beatifully, including the inline javascript by putting it inside a php shortcode. I used the Shortcode Exec PHP plugin for this, which is very easy to work with.

Allow Email as Username within WP-Members Plugin

Today I figured out how to let people use their email to login instead of their username to the WordPress driven site called Jacked Pack. I had already installed the WP-Members plugin in order to add custom registration fields to the WordPress account page (for the “HUGEness profile”), but when I tried installing the WP Email Login plugin it didn’t have any effect. I figured this was because the WP-Members plugin already supercedes the regular login functionality, so I asked Chad Butler (who created the WP-Members plugin) about the issue.

Fortunately Chad had already created a way for people to add plugins to his plugin, so that’s what I ended up doing in this case. I followed his instructions by creating a file called wp-members-pluggable.php in my /wp-content/plugins directory and copying the wpmem-login function into it (I found that function in the wp-members-core.php file in the wp-members plugin folder). Then I added my own simple function (which was taken from the WP Email Login plugin) to get the username from an email address in case someone enters an email in the username field. Then I added just one line to the wpmem-login function which calls my function. Once I got that working, I copied the wpmem_inc_login function (which I found in the wp-members-dialogs.php file in the wp-members plugin folder) into my wp-members-pluggable.php file and changed one line to tell people they can use Username or Email in the first field.

See below for my complete plugin for the WP-Members WordPress Plugin, or download it here:
[sourcecode language=”php”]
user_login, $user ) )
$username = $user->user_login;
return $username;
} // end of check for email in the username
endif;

if ( ! function_exists( ‘wpmem_inc_login’ ) ):
/**
* Login Dialog
*
* Loads the login form for user login
*
* @since 1.8
*
* @uses apply_filters Calls wpmem_restricted_msg filters message content
* @uses wpmem_login_form()
*
* @param string $page
* @return string the generated html for the login form
*/
function wpmem_inc_login( $page=”page” )
{
global $wpmem_regchk;

$str = ”;
$arr = get_option( ‘wpmembers_dialogs’ );

if( $page == “page” ){
if( $wpmem_regchk!=”success” ){

// this shown above blocked content
$str = ‘

‘ . stripslashes($arr[0]) . ‘

‘;

// filter blocked content message
$str = apply_filters( ‘wpmem_restricted_msg’, $str );

}
}

//$arr = array( __( ‘Existing users Login’, ‘wp-members’ ), __( ‘Username’, ‘wp-members’ ), ‘text’, ‘log’, __( ‘Password’, ‘wp-members’ ), ‘password’, ‘pwd’, ‘login’, __( ‘Login’, ‘wp-members’ ), ‘username’, ‘password’ );
$arr = array( __( ‘Existing users Login’, ‘wp-members’ ), __( ‘Username or Email’, ‘wp-members’ ), ‘text’, ‘log’, __( ‘Password’, ‘wp-members’ ), ‘password’, ‘pwd’, ‘login’, __( ‘Login’, ‘wp-members’ ), ‘username’, ‘password’ );

$str = $str . wpmem_login_form( $page, $arr );
return $str;
}
endif;
?>
[/sourcecode]

Update July 5th, 2013

I was asked about the registration function as well (see comments from Brian Weiss below) and although I haven’t made a plugin for the WP-Members registration function I have done auto registrations in a separate file. I tried posting code in a comment and it didn’t turn out well, so here is the relevant code I used (in a separate php file I created in the wordpress directory) to auto create wordpress accounts based on their email and firstname (you could do it without using their name if you want, since the users will never need to know their username). If someone puts this into a plugin for the WP-Members registration function please let me know and I’ll link to it so others who want to do that can see the solution.
[sourcecode language=”php”]
#Initial try at an unclaimed username
$username = $firstName.rand(1,1000);

#Now create a WP account
include(‘wp-config.php’);

// Initialize connection and select database
mysql_connect(DB_HOST, DB_USER, DB_PASSWORD)
or die(‘Could not connect: ‘ . mysql_error());
//echo ‘Connected successfully’;
mysql_select_db(DB_NAME) or die(‘Could not select database’);
//echo “connected to db
“;

#WP Username has to be unique
while (username_exists( $username )) {
$username = $firstName.rand(1,1000);
}
$random_password = wp_generate_password( $length=12, $include_standard_special_chars=false );
//echo “about to create user $username with pwd $random_password and email $email
“;
$user_id = wp_create_user( $username, $random_password, $email );
if (is_int($user_id)) {
//echo “new user id is $user_id
“;
} else {
if(is_wp_error($user_id)) { echo $user_id->get_error_message(); }
exit;
}
// then send a welcome email and/or redirect wherever you want…
[/sourcecode]

How to Transfer a Folder Full of Files and Sub-Directories to an FTP Server

Today I had to figure out how to transfer 65GB of data (including dozens of files in separate subfolders) from a linux server (where it was stored after being pulled from a FilesAnywhere account using a recursive wget command, “wget -r -l 0 ftp://user:pass@server.com/”) to another storage account at egnyte.com.

I first tried tarring up all the files and folders and transferring that as one file, but I couldn’t get the support people at egnyte to untar it for me. So I began creating a perl script to do this task. After awhile of reading about how to make multidimensional arrays in perl for the file structure (technically this is not possible, but interacting with arrays of references in perl is very similar to multidimensional arrays in php) I decided to look for a simpler solution.

What I found was a CPAN module that allows for recursive gets and puts, (rget and rput, respectively). The details of the module are described at http://search.cpan.org/~jdlee/Net-FTP-Recursive-2.04/Recursive.pm. So after a bunch of trial and error I came up with the following script, which you can download here or copy from below.

All you need to do (once you have perl and the Net::FTP::Recursive cpan module installed-see links below for help with that) is put your ftp credentials into the file, put the perl script in the directory where you have files and folders to transfer (I actually put the perl file in the folder above where I wanted to transfer from so I wouldn’t transfer the perl file too), then execute the file by typing ‘perl putFTPDir.pl “ftp.host.com”‘ (or in my case I typed perl ../putFTPDir.pl “ftp.host.com”).

[sourcecode language=”perl”]
#!/usr/bin/perl
# Filename: putFTPDir.pl – this script will recursively transfer files in a directory tree to an ftp server
# Inputs:
# $host is an ip address of the ftp server to connect to
# Configurable parameters:
# $user is the ftp username
# $password is the ftp password
# $remoteDirectory to transfer files and folders of files to (defaults to top level directory)
# Example usages:
# perl putFTPDir.pl “1.1.1.1”
# perl putFTPDir.pl “ftp.example.com”
use strict;
use Net::FTP::Recursive;
use FileHandle;

my $numParams = scalar(@ARGV);
if ($numParams<1) { print "Usage:\n"; print 'perl putFTPDir.pl "ftphost"'."\n"; print "ftphost is an ip address or domain name of the ftp server to connect to\n"; } my $host=$ARGV[0]; my $user='ftpuser'; #ftp username, use single quotes so special characters are not interpreted my $password='ftppassword'; #ftp password, use single quotes so special characters are not interpreted my $remoteBaseDir='/path/to/sub/directory'; #ftp remote base directory where to put all the files under my $ftp = Net::FTP::Recursive->new(“$host”, Debug => 1); #use Debug=>0 if you dont want to see what is happening or detailed error messages
$ftp->login($user,”$password”);
if (length($remoteBaseDir)>0) {
$ftp->cwd(“$remoteBaseDir”);
}
$ftp->rput();
print “Done transferring files\n”;
$ftp->quit;
exit;
[/sourcecode]

In order to install the Net::FTP::Recursive CPAN module you can follow the instructions at http://www.cpan.org/modules/INSTALL.html. Alternatively, if you don’t even have CPAN yet you can start with http://www.thegeekstuff.com/2008/09/how-to-install-perl-modules-manually-and-using-cpan-command/.

Browsers are like Churches

Last night one of my clients asked me why the same code can be interpreted so differently by different browsers. Though I agreed as I pointed out the long standing rift between Internet Explorer and most of the others, I couldn’t really explain why. But after sleeping on it I think I have a decent analogy.

The same text (or scripture) can be interpreted to mean very different things when you go to two different churches, even within the same religion. In the same way, identical html/css text can mean entirely different things when you view it through the window of one browser vs another, even on the same computer.

Yes there are commonalities between churches and across browsers. Many churches even across religions will agree that stealing is not acceptable. Just like many browsers, even across operating systems, will display an error if a requested file is not found.

However, some churches and browsers are more lenient than others in the “grey areas”. For example, certain churches accept alternate lifestyles and others exclude those who participate in them. Internet Explorer (IE) is very strict in it’s adherence to the rules. If an ending div tag is not specified IE shows no mercy, not even a helpful error message. Firefox and Chrome are more focused on the what is “in the heart”, often overlooking minor offenses and sometimes even providing helpful guidance in returning to the right path when mistakes are made.

Some churches provide free services that empower people to change. They run programs for helping people to overcome addictions and live a more fulfilling life. Some browsers like Firefox have free plugins like Firebug and Web Developer which help its users to overcome bad habits and understand how to bring their code to life.

At the end of the day, we are all in this World Wide Web together, no matter which browser we use or which church we go to. Whether online or offline the understanding and acceptance of diversity allows us to thrive while creating and enjoying wonderful experiences. 🙂

How to Easily Prepare Database Import Using Perl

I’m revisiting this topic because in my last post about translating Excel data into a text file for database import I used a php script and yet still had some manual steps (the one that bugged me most was adding custom line termination characters for multiline data). I mentioned the idea that if I wanted to put more time in I could use a Perl script to do the whole process. Well my next set of data I needed to import was almost 700 records spanning almost ten times as many lines in the tab delimited text file I exported from Excel (due to the description fields having newline characters). So here’s my latest solution:

  1. First I added a numeric column in the left-most position (within excel) and filled it with incremental integers.
  2. Then I exported the spreadsheet as tab delimited text
  3. Then I wrote a perl script to loop through the file and add line termination characters before each new record, this time I had to use double equal signs (==) because the data contained single equal signs
  4. I also found a perl module similar to the php htmlentities() function which actually worked for me, as opposed to the php function which I abandoned in favor of hard-coded string replacement commands
  5. Then I ran the perl script on my tab delimited text file to create a tab delimited file with double equal signs as the line terminator and all the funny characters encoded so they would show up correctly in a browser
  6. Finally I imported my file using the load data infile option in the phpmyadmin interface, specifying the delimiter and line termination as \t and == respectively.
  7. Then I looked at a webpage which pulled that data and it looked like it did in the excel file!

Here is the code for the perl script I created:
[sourcecode language=”perl”]
#!/usr/bin/perl
# Filename: prepareTextImport.pl – this script will take a list of data
# including multiline data where the first field is a line count.
# It will add == before each line count to enable mysql importing and
# will encode html entities and convert newline characters to
use HTML::Entities;

my $input = $ARGV[0]; #this is the file to parse
my $output = $ARGV[1]; #this is the file to create
my $lineTerminator = “==”;
my $count=1;
my $line = ”;
open (IN,$input) or die “can’t open file $input\n”;
open (OUT, “>$output”) or die “Can’t open outfile : $output\n”;
while () { # each line of the current input file
chomp;
$line .= “
“; # include this here so the
will be encoded too
$line = encode_entities($_); #This is the function which encodes html symbols
# Check if this is the beginning of a new record. If so then add the line terminator
if ($line =~ /^$count/) {
$count++;
$line = $lineTerminator.$line;
}
print OUT $line;
}
close IN;
close OUT;
print “there were $count records processed.\n”;
exit;
[/sourcecode]
The syntax for running the script (assuming perl is installed on your system – I use activeperl on my PC which is free):
[sourcecode language=”sh”]
perl prepareTextImport.pl inputFileName.txt outputFileName.txt
[/sourcecode]