© 2010 - 2011 /home/sinkler/
Cегодня занялся прикручиванием авторизации через сервис loginza.ru на один из своих сайтов, при этом требовалось сохранить существующую систему регистрации и авторизации.
Основная проблема: все OpenID-провайдеры возвращают различную информацию о пользователе, а, иногда, вообще не возвращают. Приходится вручную перед интеграцией анализировать, что приходит от сервера и что нам писать в базу.
Дабы хоть кому-то упростить жизнь, публикую параметры, которые приходили мне от популярных OpenID-сервисов.
Хоть я особо тут и не пишу ничего, но спам-боты меня очень любят досаждать своими комментариями. Премодерация, конечно, работает, но как-то иногда лень удалять все эти десятки сообщений, тем более что множественное удаление сообщений мне тоже лень делать.
Решил себе приделать простенький метод борьбы со спамом от Михаила Андреева.
Смысл прост: заменяем настоящие названия полей формы на случайный набор символов, а старые поля скрываем через css.
echo $this->Form->input('34kjffe343', array('label' => __('Ваше имя', true)));
echo $this->Form->input('name', array('label' => false));
echo $this->Form->input('34f3f34f3fc34r6', array('label' => __('Ваш электронный адрес', true)));
echo $this->Form->input('email', array('label' => false));
echo $this->Form->input('458vn54jfkjm3', array('label' => __('Сайт', true)));
echo $this->Form->input('url', array('label' => false));
echo $this->Form->input('934hf9v34fhjc', array('label' => __('Комментарий', true), 'type' => 'textarea'));
echo $this->Form->input('comment', array('label' => false, 'type' => 'textarea'));
#CommentName, #CommentEmail, #CommentUrl, #CommentComment{
display: none;
}
Дабы не менять логики контролера, немного схитрим и вспомним про метод модели beforeValidate...
Селектор жуквери element#id неккоректно работает в браузерах Opera 9 и Internet Explorer 7. Вместо всех елементов с заданным id выбирается только первый. Дабы и в них всё работало, используйте .class
Как это ни печально, но в версии CakePHP 1.3.3 опять криво работают каллбэки модели, если модель использует поведение Tree.
В чем заключается эта кривость? Допустим, вы пытаетесь удалить запись №1 в модели Category, использующей tree behavior, у которой есть дочерние записи №2 и 3.
$this->Category->delete(1);
И, допустим в модели определен каллбэк beforeDelete(). Вы будете удивлены, но beforeDelete() сработает только для записи №1, проигнорировав записи 2 и 3.
Не знаю, может в этом есть какая-то глубокая логика, но мне лично и многим другим, судя по обсуждениям в google groups, она не понятна.
В версии CakePHP 1.2 это "лечилось" переопределением в app_model.php метода deleteAll и использованием его вместо delete:
function deleteAll($conditions, $cascade = true, $callbacks = true) {
$this->Behaviors->disable('Tree');
$return = parent::deleteAll($conditions, $cascade, $callbacks);
$this->Behaviors->enable('Tree');
return $return;
}
С кейком 1.3.3 у меня эта фишка не прокатила, рыться глубоко в коде мне лень, поэтому для beforeDelete делаю так:
1. Переношу весь код из beforeDelete в приватный метод beforeDeleteId($id):
private function beforeDeleteId($id) {
//код Вашего каллбэка
return true;
}
2. В beforeDelete() прописываю:
function beforeDelete() {
$children = $this->children($this->id, false, array('id'));
if (!empty($children)) {
$ids = Set::format($children, '{1}', array('{n}', "{n}.$this->alias.id"));
foreach ($ids as $id) {
if(!$this->beforeDeleteId($id)) {
return false;
}
}
}
return $this->beforeDeleteId($this->id);
}
С afterDelete() ситуация немного сложнее, т.к. после удаления мы не можем узнать детей удаленной записи (они ведь тоже уже удалены). Что ж, будем узнавать их и запоминать перед удалением...
Представим себе ситуацию: имеем блок, который выводит новости.
<!-- BEGIN:news -->
<td class="div_1">
<table>
<tr>
<td valign="top" class="image"><a href="{news.link}"><img src="{news.image}" alt="" /></a></td>
<td valign="top">
<span>{news.date}</span>
<p>{news.title}</p>
<img src="{config.path.img}icon_str.gif" alt="" /><a href="{news.link}">Подробнее</a>
</td>
</tr>
</table>
</td>
<!-- END:news -->
Блок используется на всех страницах сайта. Естественно, логично будет вынести парсинг этого блока куда-нибудь в бифор-каллбек контроллера, чтобы каждый раз не определять его вручную. А теперь представим, что злыдни-дизайнеры решили выводить на разных страницах разное количество новостей и при этом не говорят нам какое, а сами хотят определять это число.

А сегодня настал мой день рождения и испольнилось мне 19 лет. 
Огромное спасибо всем, кто мучал мой телефон звонками и смс, кто полностью переписал мою стену в контакте три раза, кто слал длинные душераздирающие сообщения в джаббер и ICQ, в общем всем, кто создал мне в этот день отличное настроение, вы все самые-самые-самые крутые ![]()

Итак, у меня, наконец, появилось время и я закончил перевод официального руководства по миграции с CakePHP 1.2 на версию 1.3.
Перевод получился сжатым, без лишних слов (не люблю много букав в куроводствах), по сравнению с оригиналом. Если я пропустил что-то важное или допустил неточность - обязательно напишите об этом в комментариях к статье.
Замена файлов каталога App
- webroot/index.php: Должен быть заменен в связи с изменением загрузочного процесса.
- config/core.php: Были введены в действие дополнительные настройки, которые требуются для PHP 5.3.
Удаленные константы
- CIPHER_SEED - Эта константа была заменена на настройку Security.cipherSeed которую теперь можно изменить в app/config/core.php
- PEAR
- INFLECTIONS
- VALID_NOT_EMPTY
- VALID_EMAIL
- VALID_NUMBER
- VALID_YEAR
Настройка и загрузка приложения
App::build(array(
'plugins' => array('/full/path/to/plugins/', '/next/full/path/to/plugins/'),
'models' => array('/full/path/to/models/', '/next/full/path/to/models/'),
'views' => array('/full/path/to/views/', '/next/full/path/to/views/'),
'controllers' => array('/full/path/to/controllers/', '/next/full/path/to/controllers/'),
'datasources' => array('/full/path/to/datasources/', '/next/full/path/to/datasources/'),
'behaviors' => array('/full/path/to/behaviors/', '/next/full/path/to/behaviors/'),
'components' => array('/full/path/to/components/', '/next/full/path/to/components/'),
'helpers' => array('/full/path/to/helpers/', '/next/full/path/to/helpers/'),
'vendors' => array('/full/path/to/vendors/', '/next/full/path/to/vendors/'),
'shells' => array('/full/path/to/shells/', '/next/full/path/to/shells/'),
'locales' => array('/full/path/to/locale/', '/next/full/path/to/locale/')
));
Inflector::rules('singular', array(
'rules' => array('/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta'),
'uninflected' => array('singulars'),
'irregular' => array('spins' => 'spinor')
));

Для того чтобы ваш сайт на CakePHP корректно работал с кодировкой utf8, необходимо сделать четыре вещи:
1. Идем в файл app/config/database.php и меняем значение ключа "encoding" на "utf8":
class DATABASE_CONFIG {
var $default = array(
'driver' => 'mysql',
'persistent' => true,
'host' => 'localhost',
'login' => 'root',
'password' => 'password',
'database' => 'cake_db',
'prefix' => '',
'encoding' => 'utf8'
);
}
И не забудьте удостовериться, что база данных, которую использует кейк, в кодировке utf8 (я использую utf8_general_ci).
2. Теперь откройте файл app/config/core.php и ищем параметр конфигурации "App.encoding". Меняем его на "utf-8".
/**
* Application wide charset encoding
*/
Configure::write('App.encoding', 'utf-8');

Хелперы в CakePHP предназначены для быстрого представления и форматирования ваших данных удобным способом, они значительно убыстряют разработку приложений, делают её менее монотонной. CakePHP 1.2 по умолчанию включает 12 хелперов, имеющих огромное количество всевозможных методов. Два хелпера, которые вы будете наиболее часто использовать (или уже используете) в своих проектах - это Html и Form. Хелпер Html помогает быстро использовать повторяющиеся разделы html-кода, например, создавать ссылки, списки, вставлять изображения в ваши отображения. Form-хелпер поможет вам быстро создавать формы.
Как исползовать хелперы? Первым делом, подключите необходимых помощников в контроллере, используя переменную $helpers.
var $helpers = array('Html, Form');
Теперь вы можете использовать их в своих отображенях, например
echo $html->link('Гугль', 'http://google.ru/');
Но, с течением времени и с развитием ваших приложений, вам наверняка захочется создать своих помощников.
Например, на ваших страницах очень часто используется форма с выпадающим списоком для выбора одного из предложенных цветов и с кнопкой "выбрать":
<form method="post" action="/cake/blog/colors/set/">
<div class="input select">
<label for="ColorColor">Выберите цвет</label>
<select name="data[Color][color]" id="ColorColor">
<option value="green">Зеленый</option>
<option value="red">Красный</option>
<option value="white">Белый</option>
</select>
</div>
<div class="submit"><input type="submit" value="Выбрать" /></div>
</form>
Конечно, можно каждый раз создавать эту форму с помощью хелпера Form, а можно создать своего помощника и добавить в него метод, который будет делать это за вас.