|
Posted by Henk Verhoeven on 06/14/06 23:43
With phpPeanuts, after putting database access information in
scriptMakeSettings.php you only have to write a class like this:
includeClass('PntDbObject', 'pnt/db');
class Book extends PntDbObject {
function initPropertyDescriptors() {
parent::initPropertyDescriptors();
$this->addDbFieldProps();
}
function getTableName() {
return 'Book';
}
function getClassDir() {
return 'library';
}
}
Now you can do things like this:
include ("../classes/classSite.php");
$site = new Site('library');
// create a book entry, then insert it to the database
$book = new Book();
$book->set('author', 'John Smith');
$book->set('publisher', "O'Reilly");
$book->set('title', 'Greatest Book Ever Written');
$book->set('author_Email', 'john.smith@oreilly.com');
$book->save();
$insert_id = $book->get('id');
// Or we can load a book, knowing its ID, and even make
// changes to it
$clsDes =& PntClassDescriptor::getInstance('Book');
$book =& $clsDes->getPeanutWithId('156932');
$author = $book->get('author');
$book->set('title', 'New Title');
$book->set('publisher', "New Publisher");
$book->save();
// Or search for all books written by John Smith
$clsDes =& PntClassDescriptor::getInstance('Book');
$books =& $clsDes->getPeanutsWith('author', 'John Smith');
So far it is all much alike, except that it will not only work in php5
but also in php4. Of course it is usually the user who enters this kind
of data. If we replace all this code by simply:
include ("../classes/classSite.php");
$site = new Site('library');
$site->handleRequest();
and put it in library/index.php we can have the user edit a new book at
the following url:
library/index.php?pntType=Book&id=0
This will generate a form the user can fill out. He can insert the new
book by pressing the 'Create New' button. The values he entered will
then be converted from strings to numbers, date etc according to the
type taken from the table columns using the locale settings made in
classStringConverter, validated by the Book object against the maximum
lenghts from the table columns and the book will be inserted.
editing an existing book by id can be done the same way at the following
url:
library/index.php?pntType=Book&id=156932
and searching for books at:
library/index.php?pntType=Book&pntHandler=SearchPage
As you can see at the advanced search form, the queries can be
reasonably complex.
But in the end the entire database design needs to be improved:
+--------------+ +--------+
| Book | | Author |
+--------------+ +--------+
| id | | id |
| authorId |--------| name |
| publisher | | email |
| title | +--------+
+--------------+
we need the following classes for this:
includeClass('PntDbObject', 'pnt/db');
class Book extends PntDbObject {
function initPropertyDescriptors() {
parent::initPropertyDescriptors();
$this->addDbFieldProps();
$this->addDerivedProp('author', 'Author', false);
}
function getTableName() {
return 'Book';
}
function getClassDir() {
return 'library';
}
}
class Author extends PntDbObject {
function initPropertyDescriptors() {
parent::initPropertyDescriptors();
$this->addDbFieldProps();
$this->addMultiValueProp('books', 'Book');
}
function getTableName() {
return 'Author';
}
function getClassDir() {
return 'library';
}
}
now we can have the user edit a new author at
library/index.php?pntType=Author&id=0
after he has inserted the new author he can once again edit a new book at:
library/index.php?pntType=Book&id=0
in the form that is generated the 'author' field will now hold a
dropdown from which the user van select an author. The 'author' label
will act as a hyperlink to the author. Once the new book has inserted it
will automatically show up in the list that is under the button 'Books'
of the author's edit-page. Or we can obtain this page by the following url:
library/index.php?pntType=Author&id=121&pntProperty=books&pntHandler=PropertyPage
(assuming the id of the author record is 121)
The code for making and modifying books and authors programatically will
look like this:
// create a new author entry, then insert it to the database
$author = new Author();
$author->set('name', 'John Smith');
$author->set('email', 'john.smith@oreilly.com');
$author->save();
// create a book entry, then insert it to the database
$book = new Book();
$book->set('author', $author);
$book->set('publisher', "O'Reilly");
$book->set('title', 'Greatest Book Ever Written');
$book->save();
$insert_id = $book->get('id');
// Or we can load a book, knowing its ID, and make
// changes to it
$clsDes =& PntClassDescriptor::getInstance('Book');
$book =& $clsDes->getPeanutWithId('156932');
$book->set('publisher', "New Publisher");
//we can navigate to the author of the book and make changes to it
$author =& $book->get('author');
$author->set('email', "john.smith@NewPublisher.com");
$author->save();
// Or search for John Smith and retrieve all books he has written
$clsDes =& PntClassDescriptor::getInstance('Author');
$authors =& $clsDes->getPeanutsWith('name', 'John Smith');
forEach(array_keys($authors) as $key {
$books =& $authors[$key]->get('books');
}
// phpPeanuts allows quite complex navigational queries using
// the Query model, for example search for all books
// written by a Smith, and published by O'Reilly
includeClass('PntSqlJoinFilter', 'pnt/db/query');
$filter1 =& PntSqlFilter::getInstance('Book, 'publisher');
$filter1->set('comparatorId', '=');
$filter1->set('value1', "O'Reilly");
$filter2 =& PntSqlFilter::getInstance('Book, 'author.name');
$filter2->set('comparatorId', 'LIKE');
$filter2->set('value1', "%Smith");
$combiFilter =& new PntSqlCombiFilter(); // does AND
$combiFilter->addPart($filter1);
$combiFilter->addPart($filter2);
$clsDes =& PntClassDescriptor::getInstance('Book');
$queryHandler =& $clsDes->getSelectQueryHandler();
$queryHandler->addSqlFromSpec($combiFilter); //generates SQL
$books = $clsDes->_getPeanutsRunQueryHandler($queryHandler);
I hope you don't mind i do not go into details about the code under the
hood, you can download it from www.phpPeanuts.org or browse it directly
at http://www.phppeanuts.org/site/index_php/Menu/121/Code.html
Greetings,
Henk Verhoeven.
BTW, the above code has not been tested, it may contain typo's and bugs
Navigation:
[Reply to this message]
|