Tuesday, December 13, 2011

Using CakePHP to build semi-custom queries.

So I have been working on a maintenance scheduler and wrote a custom sql query for a upcoming maintenance report. Then converted it to a Cake built statement. Awesome. Works great and doesn't break any of my datasources, or model methods...

I have always wondered how something like this would pan out, and it works wonderful. Building Subqueries with the buildStatement() method, using custom joins, including using the subqueries as the source of the join... even a cross join. The only thing that is a little spooky is I can't seem to disable the ON clause for the cross join. Anyone know if that is possible? I just set it to 1 = 1... but cross joins don't need ON clauses.

Cake Version of Original: $dbo = $this->MaintenanceLog->getDataSource(); $MaxService = $dbo->buildStatement( array( 'fields' => array('vehicle_service_task_id', 'vehicle_id', 'MAX(odometer_reading) as LastServiceMiles', 'MAX(`date`) as LastServiceDate'), 'table' => $dbo->fullTableName($this->MaintenanceLog), 'alias' => 'MaxService', 'group' => array('vehicle_service_task_id', 'vehicle_id'), 'conditions' => array(), 'order' => null, 'limit' => null ) ,$this->MaintenanceLog ); //pr($MaxService); $MaxMileage = $dbo->buildStatement( array( 'fields' => array('vehicle_id', 'MAX(mileage_beginning) AS MaxStart','MAX(mileage_ending) AS MaxEnding','MAX(log_date) as LastDailyLog'), 'table' => $dbo->fullTableName($this->MaintenanceLog->Vehicle->DailyLog), 'alias' => 'Dl', 'group' => array('vehicle_id'), 'conditions' => array(), 'order' => null, 'limit' => null, 'joins' => array( array( 'table'=>$dbo->fullTableName($this->MaintenanceLog->Vehicle), 'type'=>'left', 'alias'=>'Vh', 'conditions'=>array('Vh.id = Dl.vehicle_id') ) ) ) ,$this->MaintenanceLog ); //pr($MaxMileage); $vehicleTasks = $this->MaintenanceLog->Vehicle->find('all',array( 'recursive' => -1, 'conditions' => array('NOT' => array('LastServiced.LastServiceDate' => NULL)), 'fields' => array('Task.id', 'Task.title','Task.mileage_interval' , Task.date_interval' 'Vehicle.id', 'Vehicle.name', 'MaxMileage.MaxEnding', 'MaxMileage.LastDailyLog', 'LastServiced.LastServiceMiles', 'LastServiced.LastServiceDate' ,'(DATEDIFF(CURDATE(),LastServiced.LastServiceDate)) AS DaysSinceService', '(MaxMileage.MaxEnding-LastServiced.LastServiceMiles) AS MilesSinceService'), 'joins' => array( array( 'table' => $dbo->fullTableName($this->MaintenanceLog->VehicleServiceTask), 'alias' => 'Task', 'type' => 'CROSS', 'conditions' => '1=1' ), array( 'table' => '('.$MaxService.')', 'alias' => 'LastServiced', 'type' => 'LEFT', 'conditions' => array( 'LastServiced.vehicle_id = Vehicle.id', 'LastServiced.vehicle_service_task_id = Task.id' ) ), array( 'table' => '('.$MaxMileage.')', 'alias' => 'MaxMileage', 'type' => 'LEFT', 'conditions' => array( 'MaxMileage.vehicle_id = Vehicle.id' ) ) ) )); Original Query: SELECT Task.id, Task.title,Task.mileage_interval , Task.date_interval , Vehicle.id, Vehicle.name, MaxEnding, LastDailyLog, LastServiced.LastServiceMiles, LastServiceDate ,(DATEDIFF(CURDATE(),LastServiceDate)) AS DaysSinceService, (MaxEnding-LastServiceMiles) AS MilesSinceService FROM `db_name`.`vehicle_service_tasks` Task CROSS JOIN `db_name`.`vehicles` Vehicle LEFT JOIN ( SELECT vehicle_id, MAX(mileage_beginning) AS MaxStart, MAX(mileage_ending) AS MaxEnding, MAX(log_date) as LastDailyLog FROM `db_name`.`vehicle_daily_logs` Dl LEFT JOIN db_name.vehicles Vh ON (Vh.id = Dl.vehicle_id) GROUP BY vehicle_id ) AS MaxMileage ON (MaxMileage.vehicle_id = Vehicle.id) LEFT JOIN ( SELECT vehicle_service_task_id, vehicle_id, MAX(odometer_reading) as LastServiceMiles, MAX(`date`) as LastServiceDate FROM `db_name`.`maintenance_logs` GROUP BY vehicle_service_task_id, vehicle_id ) AS LastServiced ON (LastServiced.vehicle_id = Vehicle.id AND LastServiced.vehicle_service_task_id = Task.id) WHERE LastServiceDate IS NOT NULL

Saturday, March 5, 2011

Installing a Complete Web Development Machine on Windows 7 with CakePHP

The solution listed below is running PHP in IIS7, which actually works pretty good, all things considered.

1. Install Web Platform Installer

2. Install PHP Manager, PHP 5.3, CGI (including FastCGI), URL Rewrite Module (Not quite as bullet proof as Mod Rewrite, but very well done)

3. Install MySQL CE

4. Install MySQL Workbench (If you like GUI MySQL management)

5. Copy Over CakePHP to Library, and Add PHP executable path, and cake console path to Env PATH

I recently, installed Windows 7 on my laptop, (Thanks Chuck) and it gave me the opportunity to re-create my development environment.

Supposedly, Windows has a WebMatrix Package the creates a fully functional web server stack, but it uses SQL Server express, which always just seems so heavy to me.

CakePHP on Mac OSX

Ok, so some of you geeks out there may already know this, but I didn't so I will share it with you.

The newer version of Mac OSX has apache built into it. On OSX, Apache is called Web Sharing and the Web Server itself can be turned on in the System Preferences.

Also, PHP comes installed and ready to use via the command line.

If you want an actual Web Server stack there are a couple things you need to change to make it all work.
Htaccess – By default Mac disables the htaccess rewrites and stuff. So edit
the /etc/apache2/httpd.conf to AllowOverride in the Directory Directive.
PHP – By default Mac disables the PHP module. So edit the
/etc/apache2/httpd.conf and uncomment the PHP module.

And for those of us that wear the I heart CakePHP t-shirts...

To use the Cake Console directly from the command line – Add cake to the ENV path, by adding a simple file to the
/etc/paths.d directory that contains one line of the path to the cake console file.

And there you have it, a full blown Production Environment Grade Web Server right there in every Mac.

We use a Mac at work for preparing and uploading images to our web properties... I needed to tap a couple Soap APIs from the Mac and was getting ready to install the dreaded, bulky, MAMP. I was relieved when I found this fully functional web server built in, very cool.

Tuesday, June 30, 2009

Sync your contacts between Thunderbird and Gmail using Zindus

Over the past year I have been syncing my contacts over the Apple cloud Mobile Me service. Well, my year was up, and I didn't feel like renewing.
Plus it didn't sync with Mozilla's Thunderbird, and I hate Outlook.
iTunes allows for syncing with gmail/google contacts, so that's cool. I turned that on, and that replaces the need for Mobile Me. 

But what about all my Thunderbird Contacts...


Steps:
  1. Download Zindus
  2. From the tools menu choose addons
  3. Click install and browse to where you downloaded the file
  4. Restart Thunderbird
  5. From the tools menu choose Zindus
  6. Enter your google account information, and let it go
For the steps to turn on the iPhone gmail contact syncing, see my Gmail Contacts on the iPhone Post.

Links:

Syncing your iPhone with Gmail

After having my iPhone and trying the Mobile Me service with Apple for the last year, I decided not to renew and sync with gmail contacts instead.

Here are the steps to make the switch:
  1. Plug iPhone into the computer you normally do.
  2. Click on your iPhone from the devices list.
  3. Choose the info tab up top
  4. Click the checkbox to sync contacts
  5. Choose google contacts from the sync with options
  6. Enter your google account information, and let it think for a bit.
  7. Click the Sync button in the lower right hand corner
  8. Choose the Merge Option when the window comes up
  9. The iPhone will be syncing for a minute or so, depending on how many contacts you have.
  10. You are all set.
If you are using Mozilla's Thunderbird try Zindus for syncing your contacts between Gmail and Thunderbird. For the step by step see my post, Sync your contacts between Thunderbird and Gmail using Zindus

Update: 2001 Honda Passport Pinging Issue

A previous post My Honda Passport is pinging... describes a well known problem in the car my wife drives normally. At certain engine speeds there is a pinging (stands for pre-ignition) noise, which is bad because it means that the fuel mixture is getting ignited and burning prematurely.

I followed all the steps from the information that I could find and still no luck. 
  1. I put new spark plugs in
  2. I ran through some fuel treatment
  3. I replaced the air filter
  4. I changed the oil

I can say that the spark plugs need to be changed; I think they were the original plugs from 2001, after almost 70 thousand miles.

Alas, still pinging.

Posting to your blogger blog from your email

So, I have been thinking that I should get in to a routine of blogging and sharing some of the tricks that I learn in my daily life. But, alas just another thing to do.

Never fear the blogger team has done it again. You can now post to your blog by email.

Here's the steps:
  1. Sign in to your blogger account.
  2. Click on the envelope to the left of the blog name.
  3. Choose a unique name for the email address.
  4. Start sending posts to your blog.
Pretty simple.