Archive for April, 2007

USB Disk? Linux yes, Windows No!

It happened to me that sometimes ago (more or less February 2005) the USB hard disk (20Gb) from Linux worked well, but froom windows there was no chance to makes it work.

Finally I solved with Linux. After plugging the usb disk I’ve recreated the partition table with cfdisk (Win95 Fat32 0b) and then recreating the file system mkdosfs -c -F32 /dev/sda1. Finally I had to format from again from windows ’cause that program (call it Operating System is too much), didn’t recognize the usb device as formatted.

The question still remain, even now that the problem is here again and I will have to do the operation again: why with Linux I have no problem while windows fail to detect the hard disk?

Comments

CakePHP: HasAndBelongsToMany (HABTM)

Originally posted on June 6th, 2006 on another blog.

Cake allow you to relate two tables in a n<->m relation. This is done by the HasAndBelongsToMany relationship (HABTM). In order to implement this relationship you need three table: the two tables to be related and a table for the relationship.

Profiles      relation-table          Users
--------      --------------          -----
id* --------> profile_id*     |------ id*
dx            user_id*    <---|       dx

If you’ll follow the cake naming conventions, implementing this relation is very simple. Let’s quickly sum up the conventions

  1. Relation table must be named like PluralTable1_PluralTable2
  2. Tables that give the name to the relation table must be alphabetically sorted. So if you have a users and a profiles table, you’ll get the profiles_users.
  3. The fields of the relation table must be the primary keys of the related tables and must be named like SingularTable_id. For example profile_id and user_id.
drop table if exists profiles_users;
create table profiles_users(
   profile_id int( 8) unsigned not null default 0,
   user_id int( 8) unsigned not null default 0,
   primary key(profile_id, user_id)
)engine=MyISAM;

Now in the model of the tables you need to relate them. This is done by the $hasAndBelongsToMany variable.

class User extends AppModel{
   var $name="User";
   var $hasAndBelongsToMany = array("Profile");
}

class Profile extends AppModel{
   var $name="Profile";
   var $displayField = "dx";
   var $hasAndBelongsToMany = array("User");
}

Done and done. Now everything should be handled automatically by cake.

Now you just need to insert the fields in the form. Example on the manual use a multiple section <select> tag. In order to create this control you just need the HtmlHelper and selectTag():

$html->selectTag('Profile/Profile',$profiles,null,array('multiple'=>'multiple'))

The only trick is the field name that must be RelatedTable/RelatedTable. In the example, if we are adding a user (users table) and need to save the specified profiles (profiles table), the name to be specified will be Profile/Profile.

In case you don’t like the use of a multiple select and prefer to use more than one checkbox, the workaround is something like the following.

In the needed controller let’s extract the needed values

class UsersController extends AppController{
   var $name="Users";

  function add(){
      ...
      $this->set("profiles",$this->User->Profile->generateList());
      ...
   }
}

Then in the view something like

<?php
   if(is_array($profiles)){
      foreach($profiles as $profile => $title){
         print "<input type='checkbox' value='{$profile}'
		name='data[Profile][Profile][]'>" . $title . "\n";
      }
   }
?>

Notice the name parameter. I’ve not used the HtmlHelper::checkbox() since I failed to make it works in this case.

Comments (22)

CakePHP: Call to undefined function: getfieldvalue()

Since 1.1.14.4797 version of CakePHP, the function DataSource::getFieldValue() has been disappeared :), but a reference is remained in the aclnode.php.

Starting from a post on the mailing list, if you get an error like Fatal error: Call to undefined function: getfieldvalue() in …\cake\libs\controller\components\dbacl\models\aclnode.php on line 113, you can easily fix it by changing the line (aclnode.php:113) from

$idList = DataSource::getFieldValue(...

to

$idList = Set::extract(...

Comments

CakePHP, MySQL and Blob

Originally posted on May 26th, 2006, here is how I got files stored inside database with blob data type. However I advice you to store file on hard drive and some meta-data in the data base, then when a content is required, retrieve the file correct file based upon the meta-data stored in the database.

First of all the table where to store data. Let’s assume something similar to this

create table actors(
   id int( 8) unsigned not null auto_increment,
   ...
   photo mediumblob default null,
   created datetime default null,
   modified datetime default null,
   primary key(id)
)engine=MyISAM,character set=utf8;

In order to store blob data, you will need as a view something similar to the following

<form method="post" action="/actors/add" enctype="multipart/form-data">
   <fieldset>
      ...
      <p>
         Send us a photo: <?=$html->file("Actor/photo")?>
      </p>
   </fieldset>
   <?=$html->submit("Send!")?>
</form>

notice the form’s enctype attribute.

Then the controller

function add(){
    if(empty($this->params["data"])){
        $this->render();
    }else{
      if($this->Actor->validates($this->data)){
         $photo = $this->params["data"]["Actor"]["photo"];
         if($photo["size"]>0){
            $fileData = fread(fopen($photo["tmp_name"],"r"),$photo["size"]);
            $this->params["data"]["Actor"]["photo"] = $fileData;
         }else{
             $this->params["data"]["Actor"]["photo"] = null;
         }
         if($this->Actor->save($this->params["data"])){
            $this->flash("added with code " . $this->Actor->getLastInsertID(),"/");
         }
      }else{
          $this->validateErrors($this->Actor);
      }
   }
}

Code can surely be tuned and made better. Note that in MySQL if you use the blob type, you will be able to store up to 64Kb of data. For more information and how to store more informations inside the blob field refer to data type storage requirements. Also read: blob & text type.

Comments (5)

MySQL + PHP: authentication problem

Originally posted on May 15, 2006 on another blog of mine.

If after giving some permission to a database for a user with the command like

grant insert,delete,update,select on test.* to 'cake'@'localhost' indentified by 'cake';

php pages respond you with something like

Warning: mysql_connect(): Client does not support authentication protocol requested by server; consider upgrading MySQL client in H:\www\multi-cake\cake\libs\model\dbodbo_mysql.php on line 116

Warning: mysql_select_db(): supplied argument is not a valid MySQL-Link resource in H:\www\multi-cake\cake\libs\modeldbodbo_mysql.php on line 119

The problem is given by the new mysql password hashing system. To solve the problem there are two ways. The first is to update the saved password with the command like

set password for 'cake'@'localhost' = old_password('cake');

the other is to run the mysql daemon with the old hashing algorithm, executing it with the --old-passwords paramter.

Comments

System error 1067 has occurred

Originally posted on June 5th, 2006. I got back to the office after a little holiday and making my local mysql and apache start up. Then I got from MySQL the error: System error 1067 has occurred.

What does it means? It seemed a problem due to permission denied after a security update. Went to the C:\Program Files\xampp directory and give the Full Control to Everyone. Problem solved.

Comments

Web page caching

It happened to an application I released (PHP and CakePHP) that once got into production environments, there were some caching problems. For example after a login, the menu didn’t get the correct profile and with a simple refresh (CTRL+R) of the browser everything is solved.

Well in order to solve this problem I added to whole pages (app/views/layouts/default.thtml for the framework) the following code

<?php
header(”Cache-control: no-cache”);
header(”Expires: ” . gmdate(”D, d M Y H:i:s”) . ” GMT”);
?>

<meta http-equiv=”pragma” content=”no-cache” />

Comments

CakePHP: controller without model

Having a controller without a model in CakePHP is very simple: just declare the variable $uses=null in the controller.

class MycoolsController extends AppController{
var $name=”Mycools”;
var $uses = null;

}

Comments

Learning CakePHP

I’ll try to sum up here some points where someone can learn how to use the framework CakePHP.

While the best and up to date place surely is the manual, with his blog tutorial, the api and the bakery, there is also a tutorial written by Duane O’Brien: Cook up Web sites fast with CakePHP. While it seems to use some deprecated methods, it’s always a good starting point in order to have survey of the framework.

This tutorial is available in two version: an online (only with free registration) and a pdf (freely available)

  • Part 1: Adding related information and services. web pdf
  • Part 2: Bake bigger and better with CakePHP. web pdf
  • Part 3: Use Sanitize for your protection. web (free access)
  • Part 4: Use CakePHP’s Session and Request Handler components. web pdf
  • Part 5: Adding cache web (free access)

Update

Following the daniel “cakebaker” hofstetter’s blog, I discovered that there’s also another tutorial written by an IBM’s developer, how to build a wiki with cakephp. For the online version of Criki - the creation of a wiki with CakePHP, as usual you need a free registration, but for the pdf version, download is free.

Update

Here are some references for the cakephp

If you have more other advices use the comments :)

Comments (3)

Print protected pdf

I’ve downloaded a pdf that has some protection. It was 94 pages length and I had to read it.

What? 94 pages to be read on a screen? It will make my eyes like two fog lamps! :) Yes I know that if I red it on the screen I got less pollution but I can’t read long papers on the screen.

Now in order to print it (or even only some pages) you need the ghostscript.

If you are on a *nix system things are easier ’cause surely there is a packaged version of the scripts.

Instead if you are running windows, surely there’s a porting for windows but I’ve used the one provided with cygwin. So install cygwin with the ghostscript package (choose it by the installer).

Now convert the pdf to a postscript file and the the postscript file to a pdf. Open the new pdf with Acrobat Reader and that’s all :)

~$ pdf2ps protected.pdf unprotected.ps
~$ ps2pdf unprotected.ps unprotected.pdf

You’ll get a pdf with less resolution that is hard to read on the screen but that print well.

Comments (10)

« Previous entries