Rio Bautista’s TechLog

Tech solutions worth remembering

cakePHP calls crashing Apache

While doing some experimenting on cakePHP, I kept getting win32 exception errors from apache.exe causing it to stop.  It doesn’t happen on my other PHP programs.  So I thought maybe it had something to do with how cakePHP is using PHP and apache.

To figure out what was happening, I allowed Visual Studio to debug the apache.exe at the point of the error.  While in debug mode, I checked the call-stack to see any information that might give me a clue and there it was.  The last call was ZendOptimization().

Now since I’m not really using Zend extensions on my programs.  I thought maybe I should try disabling this just to isolate the problem.  To do that commented out the Zend options in my php.ini.  After a few tries, it still wasn’t working, then realized there were 2 copies of the php.ini one was under the xampp\php and another was under xampp\apache\bin.  Well you guessed it, I should have been editing the one under xampp\apache\bin for this to take effect.  And of course don’t forget to restart your apache.

February 1, 2008 Posted by | CakePHP, php, xampp | Leave a comment

Reformatting the default CakePHP layout (default.ctp)

So after working on my authentication and application security I thought it’s time to mess with the looks of my site.  To start off, I wanted to obviously change the title of my site and do some minor changes on the main layout.

When you want to change something a programmers first instinct is to look for the text you want to change by maybe doing a grep or a file-search.   And I did, however, the title appeared in a file called default.ctp that was outside my app folder.  And we wouldn’t want to mess with anything outside the app folder specially if it’s inside the cake folder.

After a few more reading, it turns out we need to create our own default.ctp inside our app folder e.g. app/views/layouts/default.ctp.  So what I did was to copy the default.ctp from the cake/libs/views/layout and customized it to my preference.  I realized, the application title, is kinda redundant (as how it was implemented) and I was hoping there’d be some configuration item that I could simply change to globally specify my application title but no.  I’d probably have to do that myself as part of the configuration class.

I’m currently looking for a summary of all the available variables I could put in the default.ctp (of course with some description and explanation as to how to effectively use them)  like I see there’s $title_for_layout, $scripts_for_layout, $content_for_layout,  $cakeDebug.  If I don’t find one, then I’d probably write one if I later find to be important.

January 15, 2008 Posted by | CakePHP, php | 14 Comments

Syntax highlighting CakePHP using Eclipse

I’m still waiting for an Eclipse plugin for CakePHP so for now I’m settling with the available PHP syntax highlighting on eclipse. So far I had to define two file-types e.g. *.thtml (for 1.1.x.x) and *.ctp (for 1.2.x.x). Do the following steps for each file-type you want to be associated with the PHP-Editor:

  1. Open your Eclipse workspace;
  2. Click on Window | Preferences;
  3. On the Preference Dialog expand the General node on the tree;
  4. Click on Content-Types under General;
  5. On the right panel under Content-Types, expand the Text node;
  6. Select PHP Source under the Text node;
  7. You’ll see the list of files associated on the list below e.g. File-Associations;
  8. Click on the Add button and type the fie extension e.g. *.ctp under file-type;
  9. Click on Ok to add the file-type;
  10. Click on Ok to close the Preference Window;

If there’s a currently opened file (with the extension you added), it will not reflect syntax highlighting until you close and reopen the file. You’re all set!

January 15, 2008 Posted by | CakePHP, php | 11 Comments

Intersecting Entities on CakePHP Models

I’m creating a User Model as shown on the data model to the right. In this model, I’d like to be able to assign several Roles to each User. To do this, I’d need to add an “intersecting” entity (UserRole). However, I couldn’t figure out how to implement an intersecting entity in CakePHP. But after further reading, it turns out that there is a particular type of association in CakePHP specifically for handling intersections and that is the hasAndBelongsToMany (HABTM) association.

It turns out the “UserRole” does not become a class of it’s own, but instead will only be used as a joining table. In effect, we’re still associating User with Role using UserRole as the joining table.  Though as Abba pointed out, it’s possible to make UserRole as another class using the “with” parameter.

So to do this, following the CakePHP convention, I created the following tables:


— Table structure for table `roles`

CREATE TABLE `roles` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
`description` varchar(255) NOT NULL,
`initControllerAction` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;


— Dumping data for table `roles`

INSERT INTO `roles` VALUES (1, ‘Admin’, ‘System Administrator’, ‘test’);
INSERT INTO `roles` VALUES (2, ‘User’, ‘Regular User’, ”);
INSERT INTO `roles` VALUES (3, ‘Visitor’, ‘Visitor’, ‘test’);
INSERT INTO `roles` VALUES (4, ‘Operator’, ‘System Operator’, ‘test’);

— ——————————————————–


— Table structure for table `users`

CREATE TABLE `users` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(50) NOT NULL,
`first_name` varchar(50) NOT NULL,
`last_name` varchar(50) NOT NULL,
`password` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;


— Dumping data for table `users`

INSERT INTO `users` VALUES (1, ‘admin’, ‘Test’, ‘Administrator’, ‘cdd80313584fc62e1da825e72be7d27d’);

— ——————————————————–


— Table structure for table `users_roles`

CREATE TABLE `users_roles` (
`user_id` int(11) NOT NULL,
`role_id` int(11) NOT NULL,
PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


— Dumping data for table `users_roles`

INSERT INTO `users_roles` VALUES (1, 1);
INSERT INTO `users_roles` VALUES (1, 2);

After creating and populating the tables, we’ll simply need to update the User model (app/models/user.php) to add the following lines:

class User extends AppModel {
var $name = 'User';
// this is how to implement an intersecting entity in CakePHP
var $hasAndBelongsToMany = array(
'Role' => array (
'className' => 'Role',
'joinTable' => 'users_roles',
'foreignKey' => 'user_id',
'associationForeignKey'=> 'role_id',
'conditions' => '',
'order' => '',
'limit' => '',
'unique' => true,
'finderQuery' => '',
'deleteQuery' => ''
)
);
}

I tried doing a simple pr($user) from my authentication program and it worked like magic :).

January 14, 2008 Posted by | CakePHP, php | , | 3 Comments

Integrating Flickr into my PHP web-app

I’m now to grab some photos from Flickr. Photos tagged with a given string and link to those images from my site.

I tried checking the Flickr API documentation but all it shows there are the available methods and their documentation. But with some poking around I finally found this page (http://www.flickr.com/services/api/auth.howto.web.html) which gives me the “how to’s” to get me started.

We’ll now need to download an API from the list. I initially picked-out the PHP5 API but after going through the doc, it turns out we need to make sure the CURL and SimpleXML extensions should be enabled. I’m not sure if that’s available on the target server so I’m going for the phpFlickr library for PHP4. It comes with some PEAR files but doesn’t really require you to have PEAR running on your server.

Below is a simple program to search for pictures having a particular tag (as I’m supposed to do with my site) :


<?
require_once(“phpFlickr.php”);
$f = new phpFlickr(“yourAPIkey”);
$result = $f->photos_search(array(‘tags’=>’rio’));
$photo = $result[‘photo’][0];
$info = $f->photos_getInfo($photo[‘id’]);
print_r($info);
?>

What I’ll try to do now is to display the picture on my site. This is not on the standard documentation and from searching the internet I came across this solution. You should be able to access the picture from the Flickr site using a URL like this:

http://farm{farm_id}.static.flickr.com/{server-id}/{id}_{secret}.jpg

or

http://farm{farm_id}.static.flickr.com/{server-id}/{id}_{secret}_[mstb].jpg

You’ll be able to get the farm_id, server-id, id and secret by executing the photos_getInfo which returns an array containing all info about about given picture_id. Using the code above we can add this line to display an image from Flickr:

echo “<img src=’http://farm{$info[‘farm’]}.static.flickr.com/{$info[‘server’]}/{$photo[‘id’]}_{$info[‘secret’]}_m.jpg’>”;

You should now be able to display a picture from Flickr. Have fun…

January 10, 2008 Posted by | Flickr API, php | Leave a comment

Installing CakePHP

I’m now setting up CakePHP for my PharmaSIS website. I haven’t tried this before so I’m logging my every move:

  1. Using Eclipse I checked out a copy of CakePHP from https://svn.cakephp.org/repo/trunk/cake/ and selected 1.2.x.x
  2. I’m now trying to get the initial page running:
    1. Added a virtual host to my Apache httpd.conf file:

      <virtualhost 80="">
      ServerName demo.PharmaSIS
      DocumentRoot "c:/projects/cake/CakePHP12/app/webroot"
      DirectoryIndex index.php
      <directory "c:/projects/cake/CakePHP12/app/webroot">
      AllowOverride All
      Allow from All
      </directory>
      </virtualhost>

    2. Added an entry in my /etc/hosts:
      • 127.0.0.1 demo.PharmaSIS
  3. Restarted Apache
  4. Accessed http://demo.PharmaSIS and got to the default CakePHP page
    1. There’s this notice which I’ll try to figure out that says:
      “Notice (1024): Please change the value of ‘Security.salt’ in app/config/core.php to a salt value specific to your application [CORE\cake\libs\debugger.php, line 535]”
    2. Changed my security salt to some random string by edting app/config/core.php
  5. That removed the Security.salt notice but it’s now telling me I don’t have a database configuration file
    1. Renamed the database.php.default to database.php and edited the settings to:

      class DATABASE_CONFIG {
      var $default = array(
      'driver' => 'mssql',
      'persistent' => false,
      'host' => 'mssql12.mssqlserver',
      'port' => '',
      'login' => 'myusername',
      'password' => 'mypassword',
      'database' => 'thedatabasename',
      'schema' => '',
      'prefix' => '',
      'encoding' => ''
      );
      }

    2. I’m not able connect to the database.
    3. Apparently, there’s nothing like a default port so I had to specify the port (using the MSSQL default 1433)
  6. The page is showing all green and seem to be correct.

That ends the installation portion of this session. Next thing I’ll do is probably to experiment on authentication.

January 8, 2008 Posted by | CakePHP, php | Leave a comment

Accessing a POP3 mailbox using PHP

I was tasked to write a simple PHP process that should download email from a given POP3 account and process the content.

First thing that comes to my mind is to use a POP3 library from PHP Classes which I did. It seemed simple enough though I had to make a few tweaks to get it running. Here’s a short tutorial of what I did:

  1. Download the POP3 class library from PHP Classes;
  2. Copy the PHP class to your source directory. You may want to rename it to follow your convention;
  3. In your client PHP program you’ll of course need to add reference to this library:


    <?
    require_once(“POP3.class.php5.inc”);

    ?>

  4. Now to start a POP3 session, you’ll need to create a POP3 instance and issue a connect command:

    <?
    require_once(“POP3.class.php5.inc”);
    $pop3 = new POP3();
    $pop3->connect(‘pop3.yourmailserver.com’);

    ?>

  5. However, this did not work on my server. By default, this POP3 class attempts to use sockets and APOP and that doesn’t seem to work on my POP3 server. But that doesn’t mean it won’t work with your server. Now, you can pass 3 parameters to the constructor to change these options:

    <?
    require_once(“POP3.class.php5.inc”);
    $pop3 = new POP3(false,’testlog.txt’, false);
    $pop3->connect(‘pop3.yourmailserver.com’);

    ?>

  6. Now you’re ready to login:

    <?
    require_once(“POP3.class.php5.inc”);
    $pop3 = new POP3(false,’testlog.txt’, false);
    $pop3->connect(‘pop3.yourmailserver.com’);
    $pop3->login(‘username‘,’password‘, false);

    ?>
  7. Note that I added a third parameter to explicitly say that I’m not using APOP (which again doesn’t work on my POP server);
  8. Let’s try checking for new mail:

    <?
    require_once(“POP3.class.php5.inc”);
    $pop3 = new POP3(false,’testlog.txt’, false);
    $pop3->connect(‘pop3.yourmailserver.com’);
    $pop3->login(‘username’,’password’, false);

    $status = $pop3->getOfficeStatus();
    if ($status == false) {
        die(‘Error retrieving mailbox status’);
    }
    $mail_count = $status[‘count’];
    ?>

  9. getOfficeStatus returns an associative array status of your mailbox. Why not do a print_r to see what other information can be retrieved from the $status array;
  10. Finally we’ll extract each email from the box:

    <?
    require_once(“POP3.class.php5.inc”);
    $pop3 = new POP3(false,’testlog.txt’, false);
    $pop3->connect(‘pop3.yourmailserver.com’);
    $pop3->login(‘username’,’password’, false);

    $status = $pop3->getOfficeStatus();
    if ($status == false) {
        die(‘Error retrieving mailbox status’);
    }
    $mail_count = $status[‘count’];
    for ($i = 1; $i <= $mail_count; $i++) {
        $email = $pop3->getMails(array($i));
        list($id, $message) = each($email);
    }
    ?>

  11. You might wonder why I had to put $i in a array, that’s because getMails require an array of message numbers to extract and also returns an array of extracted messages indexed by their message numbers. This is why we used list and each to extract the message from the $email array (don’t expect $email[0] to contain the message).

There, I hope this explains enough to let you use the POP3 class available in PHP Classes without going through the troubles I went through. What’s left to do now to complete your mail client is to parse each message you retrieve. I’ll probably post that next.

January 8, 2008 Posted by | email, getMails, php, pop3 | 3 Comments