воскресенье, 19 сентября 2010 г.

Телефонный справочник. Часть 1. Базовый функционал

База данных состоит из трех таблиц:

Телефонная книжка - содержит записи об абонентах и их телофоных номерах
CREATE TABLE 'books'(
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(70) CHARACTER SET latin1 NOT NULL,
`number` varchar(30) CHARACTER SET latin1 DEFAULT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`)
)

Категории - название категорий для классификации абонентов ('Работа', 'Дом', 'Семья' и т.д.):
CREATE TABLE  `tags` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(50) CHARACTER SET latin1 NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`)
)

Т.к. один и тот же абонент может участвовать в разных катеогориях, то понадобится вспомогательная таблица для реализации связи многие ко многим:
CREATE TABLE  `books_tags` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`book_id` int(11) NOT NULL,
`tag_id` int(11) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`)
)

Название таблиц непроизвольно, если вам непонятно откуда и как они получились, то стоит ознакомиться с соглашениями CakePHP и в частности со статьей

Теперь необходимо создать MVC для таблиц books и tags (для books_tags ничего ненужно т.к. это связывающая таблица, напрямую к ней пользователь обращаться не будет).

Самый простой и быстрый способ - воспользоваться Cake Bake, с автоматической генерацией кода, без скаффолдинга с применением связи HABTM

Для пирмера приведу полседовательность действий в консоли для таблицы books:

Welcome to CakePHP v1.3.3 Console
---------------------------------------------------------------
App : app
Path: /usr/local/apache2/htdocs/t_handbook1/app
---------------------------------------------------------------
Interactive Bake Shell
---------------------------------------------------------------
[D]atabase Configuration
[M]odel
[V]iew
[C]ontroller
[P]roject
[F]ixture
[T]est case
[Q]uit
What would you like to Bake? (D/M/V/C/P/F/T/Q) 
> m
---------------------------------------------------------------
Bake Model
Path: /usr/local/apache2/htdocs/t_handbook1/app/models/
---------------------------------------------------------------
Possible Models based on your current database:
1. Book
2. BooksTag
3. Tag
Enter a number from the list above,
type in the name of another model, or 'q' to exit  
[q] > 1
Would you like to supply validation criteria 
for the fields in your model? (y/n) 
[y] > n
Would you like to define model associations
(hasMany, hasOne, belongsTo, etc.)? (y/n) 
[y] > y
One moment while the associations are detected.
---------------------------------------------------------------
Please confirm the following associations:
---------------------------------------------------------------
Book hasAndBelongsToMany Tag? (y/n) 
[y] > y
Would you like to define some additional model associations? (y/n) 
[n] > n

---------------------------------------------------------------
The following Model will be created:
---------------------------------------------------------------
Name:       Book
DB Table:   `books`
Associations:
 Book hasAndBelongsToMany Tag
---------------------------------------------------------------
Look okay? (y/n) 
[y] > y

Baking model class for Book...

Creating file /usr/local/apache2/htdocs/t_handbook1/app/models/book.php
File `/usr/local/apache2/htdocs/t_handbook1/app/models/book.php` exists, overwrite? (y/n/q) 
[n] > y
Wrote `/usr/local/apache2/htdocs/t_handbook1/app/models/book.php`
SimpleTest is not installed. Do you want to bake unit test files anyway? (y/n) 
[y] > n
---------------------------------------------------------------
Interactive Bake Shell
---------------------------------------------------------------
[D]atabase Configuration
[M]odel
[V]iew
[C]ontroller
[P]roject
[F]ixture
[T]est case
[Q]uit
What would you like to Bake? (D/M/V/C/P/F/T/Q) 
> c
---------------------------------------------------------------
Bake Controller
Path: /usr/local/apache2/htdocs/t_handbook1/app/controllers/
---------------------------------------------------------------
Possible Controllers based on your current database:
1. Books
2. BooksTags
3. Tags
Enter a number from the list above,
type in the name of another controller, or 'q' to exit  
[q] > 1
---------------------------------------------------------------
Baking BooksController
---------------------------------------------------------------
Would you like to build your controller interactively?
Warning: Choosing no will overwrite the BooksController. (y/n) 
[y] > y
Would you like to use dynamic scaffolding? (y/n) 
[n] > n
Would you like to create some basic class methods 
(index(), add(), view(), edit())? (y/n) 
[n] > y
Would you like to create the basic class methods for admin routing? (y/n) 
[n] > n
Would you like this controller to use other helpers
besides HtmlHelper and FormHelper? (y/n) 
[n] > n
Would you like this controller to use any components? (y/n) 
[n] > n
Would you like to use Session flash messages? (y/n) 
[y] > n

---------------------------------------------------------------
The following controller will be created:
---------------------------------------------------------------
Controller Name:
 Books
---------------------------------------------------------------
Look okay? (y/n) 
[y] > y

Creating file /usr/local/apache2/htdocs/t_handbook1/app/controllers/books_controller.php
File `/usr/local/apache2/htdocs/t_handbook1/app/controllers/books_controller.php` exists, overwrite? (y/n/q) 
[n] > y
Wrote `/usr/local/apache2/htdocs/t_handbook1/app/controllers/books_controller.php`
SimpleTest is not installed. Do you want to bake unit test files anyway? (y/n) 
[y] > n
---------------------------------------------------------------
Interactive Bake Shell
---------------------------------------------------------------
[D]atabase Configuration
[M]odel
[V]iew
[C]ontroller
[P]roject
[F]ixture
[T]est case
[Q]uit
What would you like to Bake? (D/M/V/C/P/F/T/Q) 
> v
---------------------------------------------------------------
Bake View
Path: /usr/local/apache2/htdocs/t_handbook1/app/views/
---------------------------------------------------------------
Possible Controllers based on your current database:
1. Books
2. BooksTags
3. Tags
Enter a number from the list above,
type in the name of another controller, or 'q' to exit  
[q] > 1
Would you like bake to build your views interactively?
Warning: Choosing no will overwrite Books views if it exist. (y/n) 
[n] > y
Would you like to create some CRUD views
(index, add, view, edit) for this controller?
NOTE: Before doing so, you'll need to create your controller
and model classes (including associated models). (y/n) 
[y] > y
Would you like to create the views for admin routing? (y/n) 
[n] > n

Creating file /usr/local/apache2/htdocs/t_handbook1/app/views/books/index.ctp
File `/usr/local/apache2/htdocs/t_handbook1/app/views/books/index.ctp` exists, overwrite? (y/n/q) 
[n] > y
Wrote `/usr/local/apache2/htdocs/t_handbook1/app/views/books/index.ctp`

Creating file /usr/local/apache2/htdocs/t_handbook1/app/views/books/view.ctp
File `/usr/local/apache2/htdocs/t_handbook1/app/views/books/view.ctp` exists, overwrite? (y/n/q) 
[n] > y
Wrote `/usr/local/apache2/htdocs/t_handbook1/app/views/books/view.ctp`

Creating file /usr/local/apache2/htdocs/t_handbook1/app/views/books/add.ctp
File `/usr/local/apache2/htdocs/t_handbook1/app/views/books/add.ctp` exists, overwrite? (y/n/q) 
[n] > y
Wrote `/usr/local/apache2/htdocs/t_handbook1/app/views/books/add.ctp`

Creating file /usr/local/apache2/htdocs/t_handbook1/app/views/books/edit.ctp
File `/usr/local/apache2/htdocs/t_handbook1/app/views/books/edit.ctp` exists, overwrite? (y/n/q) 
[n] > y
Wrote `/usr/local/apache2/htdocs/t_handbook1/app/views/books/edit.ctp`
---------------------------------------------------------------

View Scaffolding Complete.

В итоге мы получили базовый функционал для ввода категорий и записей в телефоный справочник, где для абонента можно указать любое количество категорий с помощьюю элемента "select" с возможность множественного выбора.

В следующей части будет рассказано как доделать наше приложение для работы с Ajax.

Телефонный справочник (Предисловие)

В этом и последующих постах я буду описывать создание телефонного справочника на CakePHP с использованием ассоциаций, Cake Bake и стандартного Ajax-хелпера. Вся коммуникация с веб-сервером будет происходить без перезагрузки страницы.
Статья будет полезна людям уже освоившим базовые навыки работы с кейком и желающим развить их.

воскресенье, 12 сентября 2010 г.

CakePHP - Internal Server Error

При установке рабочего Cake-проекта на одном из хостингов возникли проблемы с mod_rewrite:

Internal Server Error

The server encountered an internal error or misconfiguration and was
unable to complete your request.

Please contact the server administrator, [no address given] and
inform them of the time the error occurred, and anything you might
have done that may have caused the error.

More information about this error may be available in the server error l

Перерыл море информации, во многих источниках обсуждались проблемы кейка и mod_rewrite, предлагались альтернативные варинты htaccess (как напрмер здесь). Все перепробовал, непомогло.

В итоге подправил стандартные файлы .htaccess из корня и /app/webroot на следующие:

cakephpsite/.htaccess:

RewriteEngine on
RewriteRule ^$ /app/webroot/ [L]
RewriteRule (.*) /app/webroot/$1 [L]


cakephpsite/app/webroot/.htaccess:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?url=$1 [QSA,L]


Т.е. добавил перед именами файлов и путями "/".