Subversion hosting, CVS hosting, Trac hosting, Bugzilla hosting and software collaboration Providing hosted Subversion, CVS, Trac and Bugzilla repositories
 

July 17, 2009

Avoid Monotonous Tasks With WWW::Mechanize

Filed under: Software Development — Tags: , — Greg Larkin @ 2:59 pm
Scheutz Mechanical Calculator

The Scheutz Mechanical Calculator

Hi everyone,

A SourceHosting.net client recently asked to create a large number of users in a custom installation of phpDeadlock that he uses to manage access to his Subversion repository here. Since phpDeadlock doesn’t have a user management API, this sounded like a monotonous, error-prone task.  After entering 10-15 users, the chances of misspelling a name or email address or clicking the wrong button in the UI will likely increase dramatically.

I briefly investigated adding records directly to the backend MySQL database, but since various other actions are fired by user creation, including email notifications to the new user and the system administrator, using the application’s UI was the safest choice.

I had run across the WWW::Mechanize Perl module a while back, but hadn’t used it yet. I knew it could be used to automate interaction with a web site, and after reading through the rich list of methods, I promptly began hacking a script together to parse a list of email addresses supplied by the client and use it to drive the user creation UI.

The module implements a headless web browser, including cookie jar, history, form submission and other behaviors that you would expect, except it doesn’t parse and execute Javascript. That was a non-issue for me.

phpDeadlock has an administrator login prompt that requests a password before any privileged pages are accessed. Logging in to the application was a no-brainer in WWW::Mechanize:

use WWW::Mechanize;
use String::Random;
use Text::Capitalize;

my $mech = WWW::Mechanize->new();
$mech->get('https://phpdeadlock.mydomain.com/admin/');
$mech->set_visible('ItsASecret');
$mech->submit_form();

That was too easy! All further page requests will be authenticated. Next, the script enters a loop to process email addresses presented on STDIN, one per line, and populate the required fields:

for my $email (<STDIN>) {
    chomp $email;
    my @fields = split /\@/, $email;
    my $finitial = substr($fields[0], 0, 1);
    my $lname = substr($fields[0], 1);
    my $pw = new String::Random->randpattern("ssssssss");

    $mech->get('https://phpdeadlock.mydomain.com/admin/newuser.php');
    $mech->submit_form(
        fields => {
            firstname => capitalize($finitial),
            lastname => capitalize($lname),
            email => $email,
            username => $fields[0],
            password => $pw,
            password2 => $pw
        }
    );

    print "Added new user for $finitial $lname\n";
}

If the user’s full name had been supplied, I could have easily parsed that and set the firstname and lastname fields appropriately.

The possibilities for using this module are endless, and I encourage you to try it out, especially when you’re dreading a repetitive web application UI task.  Make sure to check the list of other Perl modules that are based on WWW::Mechanize, too!


Call me - Greg Larkin: error

July 16, 2009

Improving PHP Application Performance

Filed under: Software Development — Tags: , — Greg Larkin @ 9:47 am
Photo by: Mark McArdle

Photo by: Mark McArdle

Hi everyone,

I came across a helpful list of PHP optimization tips, and I’d like to share it with you here: http://php100.wordpress.com/2009/07/13/php-performance/

In addition, using the XDebug profiler for collecting performance data and KCacheGrind for viewing it is highly recommended to keep your PHP applications running smoothly!


Call me - Greg Larkin: error

March 7, 2008

Basic Views In CodeIgniter

Filed under: Software Development — Tags: , , , , — Greg Larkin @ 3:24 pm

Hi everyone,

A while back, I hooked up my CodeIgniter sample application to a MySQL database. That was easy, and now I’ll show how to move your presentation code into separate view files, instead of echo’ing HTML from inside a controller file.

According to the CodeIgniter manual, views are stored in the /views (hmm, that makes sense!) directory of your application, and they can be divided up across functional areas with subdirectories. Since it’s possible to create page snippets and load them in sequence, you might have a directory structure like this:

/views
  /global
    /layout
      /header.php
      /footer.php
  /navigation
      /left_side.php
      /bottom_links.php
  /user
    /add.php
    /edit.php
    /delete.php
    ...
  /group
    /add.php
    /edit.php
    /delete.php
    ...
  /...
  /...

Then when you want to render a particular page, say the “add user” page of your web app’s administrative interface, the code would look like this:

$this->load->view(‘global/layout/header.php’);
$this->load->view(‘global/navigation/left_side.php’);
$this->load->view(‘user/add.php’);
$this->load->view(‘global/navigation/bottom_links.php’);
$this->load->view(‘global/layout/footer.php’);

I haven’t gotten that complex yet, but I did move the code to display my user count into a view and set the value in the controller like so:

function count_users()
{
        $numUsers = $this->user->count_users();
        $data = array(‘num_users’ => $numUsers);
        $this->load->view(‘user/showcount’, $data);
}

The file /views/user/showcount.php is pretty simple:

<html>
<head><title>Welcome to the User Area!</title></head>
<body>
This page is rendered by the file: <?php echo __FILE__; ?>
<p>There are <?php echo $num_users; ?> users defined in the database.
<p><?php echo anchor(‘user’, ‘Go back’); ?>
</body>
</html>

Ok, this all seems to be pretty easy. Of course, there’s a bunch more functionality in the CodeIgniter framework, but I think what I’ll do for my next post is shift gears and go through the same basic exercises using CakePHP, Prado, and the Zend Framework.

It will be interesting to see if there’s any similarity to the way the classic “Hello, world.” program varies in complexity based on implementation language!


Call me - Greg Larkin: error

March 6, 2008

FreeBSD Port For CodeIgniter Upgraded to 1.6.1

Filed under: Software Development — Tags: , , , , , — Greg Larkin @ 7:01 pm

Hi everyone,

I’ve submitted some new FreeBSD port upgrades over the past week, including new support for CodeIgniter 1.6.1. In addition to the version bump of the upstream distribution, I also added some new bits to allow customization of certain CI files. The port is also careful to avoid removing those modified files when a new port upgrade comes along.

The reference for how to handle user-configurable files installed as part of a port can be found in the excellent FreeBSD Porter’s Handbook in the Configuration Files section.

In the new CodeIgniter port, the following user-configurable files are installed:


&lt;INSTALL_DIR&gt;/index.php
&lt;INSTALL_DIR&gt;/index.php.sample
&lt;INSTALL_DIR&gt;/system/application/config/autoload.php
&lt;INSTALL_DIR&gt;/system/application/config/autoload.php.sample
&lt;INSTALL_DIR&gt;/system/application/config/config.php
&lt;INSTALL_DIR&gt;/system/application/config/config.php.sample
&lt;INSTALL_DIR&gt;/system/application/config/database.php
&lt;INSTALL_DIR&gt;/system/application/config/database.php.sample
&lt;INSTALL_DIR&gt;/system/application/config/hooks.php
&lt;INSTALL_DIR&gt;/system/application/config/hooks.php.sample
&lt;INSTALL_DIR&gt;/system/application/config/mimes.php
&lt;INSTALL_DIR&gt;/system/application/config/mimes.php.sample
&lt;INSTALL_DIR&gt;/system/application/config/routes.php
&lt;INSTALL_DIR&gt;/system/application/config/routes.php.sample
&lt;INSTALL_DIR&gt;/system/application/config/smileys.php
&lt;INSTALL_DIR&gt;/system/application/config/smileys.php.sample
&lt;INSTALL_DIR&gt;/system/application/config/user_agents.php
&lt;INSTALL_DIR&gt;/system/application/config/user_agents.php.sample

What this does is install a reference copy of each file (*.sample) that is not expected to be edited by the user. The actual file that CodeIgniter uses to render pages (no .sample suffix) is user-configurable as needed.

Then some crazy-looking shell code in the pkg-plist file makes sure that any edited files are not removed if the port is deinstalled or upgraded (reformatted for readability):

@unexec if cmp -s %D/%%WWWDIR%%/%%CI_CONF_DIR%%/autoload.php.sample \

    %D/%%WWWDIR%/%%CI_CONF_DIR%%/autoload.php; then \

    rm -f %D/%%WWWDIR%%/%%CI_CONF_DIR%%/autoload.php; else \

    %%ECHO_MSG%% "===> Customized %D/%%WWWDIR%%/%%CI_CONF_DIR%%/autoload.php \

    has not been removed"; fi

%%WWWDIR%%/%%CI_CONF_DIR%%/autoload.php.sample

@exec if [ ! -f %D/%%WWWDIR%%/%%CI_CONF_DIR%%/autoload.php ]; then \

    cp -p %D/%F %B/autoload.php; fi

This concept needs to be implemented in several of the other ports that I maintain, including CakePHP and Prado. If anyone has a list of files that are user-configurable in each of those frameworks, please send it along!


Call me - Greg Larkin: error

February 20, 2008

Hooking My CodeIgniter Application to MySQL

Filed under: Software Development — Tags: , , , — Greg Larkin @ 7:19 pm

Hi everyone,

When I last posted about my sample application development with CodeIgniter, I had created a simple Hello, World application. The next thing I want to explore is how easy it is to connect to a MySQL database and retrieve data.

As a quick side note, the CodeIgniter User Guide is well-written and very clear with plenty of examples. That’s always nice to see and instills some confidence in the quality of the underlying code.

According to the guide, all of the database connections should be defined in the application/config/database.php file. After setting up a new database named “ci” and a database user, I opened database.php and set up my connection:

$db[‘default’][‘hostname’] = "localhost";
$db[‘default’][‘username’] = "ci";
$db[‘default’][‘password’] = "ci";
$db[‘default’][‘database’] = "ci";
$db[‘default’][‘dbdriver’] = "mysql";
$db[‘default’][‘dbprefix’] = "";
$db[‘default’][‘active_r’] = TRUE;
$db[‘default’][‘pconnect’] = TRUE;
$db[‘default’][‘db_debug’] = TRUE;
$db[‘default’][‘cache_on’] = FALSE;
$db[‘default’][‘cachedir’] = "";

That was easy enough. Now I’ve got the skeleton of a model defined in application/models/user_model.php:

class Group_model extends Model {
    function Group_model()
    {
        parent::Model();
        $this->load->database();
    }
}

The $this-&gt;load-&gt;database() statement automatically connects to MySQL using the default connection I defined previously. Now I can use the $this-&gt;db object to run queries and process results elsewhere in my model file.

I’ll replace my original hard-coded count_users function with something that runs an actual database query:

function count_users()
{
    $query = $this->db->query(‘SELECT COUNT(*) AS num_users FROM user’);
    if ($query->num_rows() > 0)
    {
        return $query->row()->num_users;
    }
}

Of course, I have to leave a newbie coding error in there for someone to notice. Anyone? Anyone? Bueller?

Here’s my simple MySQL database schema:


– Table structure for table `user`

CREATE TABLE IF NOT EXISTS `user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR(128) NOT NULL,
`full_name` VARCHAR(128) NOT NULL,
`email` VARCHAR(128) NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;


– Dumping data for table `user`

INSERT INTO `user` (`id`, `user_name`, `full_name`, `email`) VALUES
(1, ‘glarkin’, ‘Greg Larkin’, ‘glarkin@sourcehosting.net’),
(2, ‘morsel’, ‘Morsel The Cat’, ‘morsel@meow.com’);

When I navigate to my /codeigniter/user/count_users/ URL, I see:

There are 2 users defined

Great! Next up, we’ll take a look at creating an actual output page with views.


Call me - Greg Larkin: error

February 15, 2008

CodeIgniter 1.6.1 Is Released

Filed under: Software Development — Tags: , , , , — Greg Larkin @ 4:31 pm

Hi everyone,

I just saw that CodeIgniter 1.6.1 has been released. I guess that means I’d better get on the stick and upgrade the FreeBSD CodeIgniter port! Once I do that, I’ll upgrade my PHP Framework VM with the new version of the port and continue on with the experimentation.


Call me - Greg Larkin: error

February 8, 2008

Diving Into CodeIgniter

Filed under: Software Development — Tags: , , , — Greg Larkin @ 5:19 pm

Hi everyone,

Now that I’ve got my FreeBSD virtual machine set up with the various PHP frameworks, it’s time to start putting together a sample application in each one to learn their strengths and weaknesses. The sample application will be a simple mailing list manager and contain common features such as:

  • User account self-registration
  • Email generation
  • Management interface
  • MySQL database backend

I think that will exercise enough of each framework to get a good handle on their functionality and ease of use.
I’m starting off with CodeIgniter. At first glance, the documentation seems excellent, and the code is commented very clearly. Looking at the index.php file in the root installation directory (/usr/local/www/codeigniter on FreeBSD), I see:

/*
|—————————————————————
| APPLICATION FOLDER NAME
|—————————————————————
|
| If you want this front controller to use a different "application"
| folder then the default one you can set its name here. The folder
| can also be renamed or relocated anywhere on your server.
| For more info please see the user guide:
| http://www.codeigniter.com/user_guide/general/managing_apps.html
|
|
| NO TRAILING SLASH!
|
*/
$application_folder = "application";
 

Ok, that seems easy enough. To keep the default application intact and start working on my custom application, I simply copied the existing application directory to /usr/local/www/ci_sourcehosting and updated the index.php file.

$application_folder = "/usr/local/www/ci_sourcehosting";
 

According to the welcome page displayed by CodeIgniter, I have to change the views/welcome_message.php file to change the default page contents. Ok, easy enough…

Custom Hello World on CodeIgniter

The controllers/welcome.php controller is called by default, and that’s configured in the config/routes.php file in your application directory.

To create a new controller, simply create a new class that extends Controller and name it with a capital letter. Save the new class to the lowercase version of the class name into the /controllers directory, and you’re ready to test.

My simple class is:

class User extends Controller {
    function index()
    {
        echo ‘Welcome to the user controller’;
    }
    function count-users()
    {
        echo ‘There are 0 users defined’;
    }
}
 

When I visit http://192.168.95.128/codeigniter/user, I see:

Welcome to the user controller

and http://192.168.95.128/codeigniter/user/count-users displays:

There are 0 users defined

Ok, that’s pretty straightforward, but I did have to do a bit of mucking about to get the URLs to look like http://192.168.95.128/codeigniter/user/count instead of http://192.168.95.128/<strong>index.php</strong>/codeigniter/user/count.

The CodeIgniter manual specifies a .htaccess file to be placed in the directory where the index.php front controller is located:

RewriteEngine on
RewriteCond $1 !^(index.php|images|robots.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
 

Normally, this works fine, except Apache 2.2 specifies AllowOverride None by default, so .htaccess files don’t work. After changing that, I had to make one small change to the .htaccess file, since my CodeIgniter installation is rooted at /codeigniter:

RewriteRule ^(.*)$ /codeigniter/index.php/$1 [L]
 

Next time, we’ll take a look at hooking CodeIgniter to MySQL.


Call me - Greg Larkin: error

February 1, 2008

Installing PHP Frameworks with the FreeBSD Ports Tree

Filed under: Software Development — Tags: , , , , — Greg Larkin @ 11:21 am

Hi everyone,

Ok, let’s proceed to install the various PHP frameworks that we’ll use to create a sample application.

As I mentioned in a previous post, the basic command for installing any port in the tree is:

cd /usr/ports/&lt;category&gt;/&lt;appname&gt; &amp;&amp; make install clean

Let’s start with the CakePHP framework:
cd /usr/ports/www/cakephp &amp;&amp; make install clean

After typing that command, you should see this on the screen:

FreeBSD Port Installation Options

Hmm, what is that screen for? The FreeBSD ports collection has a robust infrastructure for configuring software applications prior to installation. In this case, CakePHP works with multiple different database backends, so the port writer (i.e. me) decided to provide options so the prerequisite bits are installed before the port proper.

Looking at the options provided here, the first one named “PROD” determines the way that the Apache web server is configured for CakePHP. If this is a production server, this option should be selected so navigating to “http://<servername>/” displays the CakePHP welcome page. Since I am installing multiple frameworks on the same machine, I’ll leave this option unchecked. That way, each framework welcome page will be found at “http://<servername>/<frameworkname>/”.

I plan to use MySQL as a database backend, so the following screenshot shows the MYSQL option selected. The dialog box is navigated with the tab and arrow keys on your keyboard, and the spacebar toggles the option selections:

FreeBSD Port MySQL Option

Tab to the OK button and hit Enter, and the port build starts. Here is the full transcript of the process:

CakePHP Port Build Transcript

Notice that by selecting the MYSQL option prior to installation, the port build fetched and built the MySQL client library and the PHP MySQL module, as well as some other packages:

mysql-client-5.0.51
php5-pcre-5.2.5_1
php5-pdo-5.2.5_1
php5-pdo_mysql-5.2.5_1
php5-session-5.2.5_1

This helps us get a working PHP installation that supports CakePHP out of the box.

Now, it’s the moment of truth – does the CakePHP default page display correctly? In order to load the page on your host machine, find the VM’s IP address with the following command:

/sbin/ifconfig -a | grep -w inet | grep -v 127.0.0.1 | awk '{ print $2 }'

That gives me 192.168.95.128, so here’s the URL where I should find the CakePHP default page: http://192.168.95.128/cakephp/. The address will likely be different for you.

This looks good!

CakePHP Default Page

Now as an exercise for the reader, try installing the rest of the frameworks and make sure that they display their welcome pages:

CodeIgniter
PRADO
Zend Framework

If you have any trouble, write in with comments and feedback.


Call me - Greg Larkin: error

January 28, 2008

Update the FreeBSD Ports Tree

Filed under: Software Development — Tags: , — Greg Larkin @ 2:18 pm

Hi everyone,

Now that we’ve got the FreeBSD 6.2 VM booted up under VMware Player or VMware Server, we need to make sure that we’ve got the latest version of the ports tree installed. Since you may be reading this well after I build the original VM image, the FreeBSD ports tree has probably changed a lot, and it’s possible that new versions of the PHP frameworks are available.

First of all, what is the ports tree? Quite simply, it’s a large collection of directories (18,000+ at last count!), one for every 3rd party software package that has been ported to FreeBSD. What does this gain you? The idea is that any piece of ported software can be installed on your FreeBSD system as easily as typing the following command in the appropriate directory:

cd /usr/ports/&lt;category&gt;/&lt;appname&gt; &amp;&amp; make install clean

e.g.
cd /usr/ports/databases/mysql50-server &amp;&amp; make install clean

That’s it! The same command will install anything from a simple Perl module to the Java development kit.

The command to update your FreeBSD VM with the latest ports tree is equally simple. Log in as root and type the following:

portsnap fetch update

You’ll see some output like this:

Sample FreeBSD portsnap run

Now we’re ready to install some PHP frameworks, but that’s a post for another day!


Call me - Greg Larkin: error

January 25, 2008

Booting Your First VMware Virtual Machine

Filed under: Software Development — Tags: , , , — Greg Larkin @ 11:13 am

Hello everyone,

Now that we’ve got some example virtual machines to play around with, let’s move on to the next step and get one running.

I’m using VMware Player on Windows XP, and the VM files have been extracted to My Documents\My Virtual Machines. The folder contents look like this:

VMware Installation Directory

Digging into the VM installation directory proper, you see all of the files that make up your virtual machine:

Virtual Machine Directory

The .vmx file is a text file that contains all of the virtual machine configuration options. You can change the VM memory allocation, add/remove devices, etc. just by editing that file. The .vmdk files are the virtual machine’s disks and store its state across reboots.

If your VM ever runs out of disk space and you still have room on your host operating system, you can create additional vmdk files and attach them to the VM. That sure is easier than cracking open a server case and physically installing new drives!

Next, double-click on the FreeBSD 6.2 Basic Installation.vmx file, and VMware Player starts up and boots the VM:

FreeBSD Boot Menu

After the usual messages, the virtual machine has booted, and you see the familiar UNIX login prompt:

FreeBSD Boot Completion

Next time, we’ll dive into installing the various PHP frameworks under FreeBSD. The FreeBSD ports system is designed for ease of use, and you’ll see how simple it is to get a software package and all of its dependencies installed with one command.


Call me - Greg Larkin: error
Pages: 1 2 Next

Powered by WordPress