Вернуться назад и сообщить о результате

Некоторые задачи не совсем укладываются в парадигму Model-View-Controller, потому что у них нет как такового View. Они просто тихо делают свою задачу (backup, импорт/экспорт, оптимизация, удаление,...) и выдают либо, что всё ОК, либо ошибку. Раньше я для большинства таких задач использовал exit/die. Но это как-то не красиво.

Другой вариант - это делать так как в Cake-шаблонах по умолчанию

PHP:
  1. $this->Session->setFlash('Record was successfully deleted');
  2. $this->redirect(array('action'=>'index'), null, true);

Но раз уж есть возможность делать красивые flash-сообщения, то можно дальше оптимизировать код.
Тут надо учесть 2 вещи. Во-первых, я очень люблю, когда кода с которым работаешь, очень мало. У Джоела я прочитал интересное правило - функция должна помещаться в один экран без прокруток (тут, правда, я немного хитрю - меряю по основному 21" монитору, а не по второму 17"). Во-вторых, хоть все и советуют использовать фигурные кавычки для любого if, я иногда их не ставлю для return/die, то есть, когда конструкция завершает работу функции, либо для $i++, то есть когда кода очень мало. Поэтому было бы приятно вместо

PHP:
  1. if (!$id) {
  2.     $this->Session->setFlash('Invalid Customer.');
  3.     $this->redirect(array('action'=>'index'), null, true);
  4. }

писать

PHP:
  1. if (!$id) $this->redirectBack('error: Invalid Customer.');

А компьютер пусть сам догадывается, что это ошибка и нужно вывести "Invalid Customer." и что нужно переадресовать на предыдущую страницу.
Для этого в app_controller.php надо добавить

PHP:
  1. /**
  2. * Set flash message and redirect
  3. *
  4. * @param string $message Optional flash message. Accepted 'error: something', and 'ok: something'
  5. * @param string/array $url Redirect url. If not mentioned will redirect to previous page
  6. */
  7. function redirectBack($message=null, $url=null) {
  8.     if (!empty($message)) {
  9.         if (preg_match('/^error:(.+)$/', $message, $m)) {
  10.             $this->flash(trim($m[1]), 'error');
  11.         } elseif (preg_match('/^ok:(.+)$/', $message, $m) || preg_match('/^success:(.+)$/', $message, $m)) {
  12.             $this->flash(trim($m[1]), 'success');
  13.         } else {
  14.             $this->flash($message);
  15.         }
  16.     }
  17.  
  18.     if (empty($url)) {
  19.         $url = $this->referer();
  20.     }
  21.     $this->redirect($url, null, true);
  22. }


Понравилось?

  1. Подпишись через RSS
  2. Расскажи о http://php.southpark.com.ua друзьям.
    Все способы хороши: ICQ, E-mail, свой блог, комментарий в чужом блоге или сообщение на форуме
  3. Добавь статью на news2.ru, Хабрахабр или в закладки

Огромное спасибо!

И не стесняйтесь комментировать - у меня стоит плагин, который убирает rel="nofollow" у людей, которые написали больше 5 комментариев.

RSS feed | Trackback URI

14 комментариев »

Comment by Sam Subscribed to comments via email
2007-12-06 19:58:09

Отлично. Попробую. Только параллельно с редиректом подцеплю вывод в сгенерённое JS-окошко.

 
2007-12-06 22:37:49

Если JS-окошко сделано специально для дебага, то лучше пользоваться Firebug. Я для CakePHP написал helper - http://php.southpark.com.ua/2007/vyvod-iz-php-v-firebug-helper-dlya-cakephp/

 
Comment by Evgeny Sergeev Subscribed to comments via email
2007-12-07 03:46:09

>У Джоела я прочитал интересное правило - функция должна помещаться в один экран
>без прокруток (тут, правда, я немного хитрю - меряю по основному 21" монитору, а не
> по второму 17").

Не согласен. Функция должна выполнять одно действие которое с точки зрения поставленной задачи является элементарным (не факто что атомарным!). При этом имя функции должно быть описательным, т.е. все что делается в функции должно содержаться в ее имени. В итоге функция как раз и занимает не более одного экрана! :-)

 
2007-12-07 09:07:07

У меня иногда функции контроллеров раздуваются после добавления десятка каких-то мелких улучшений, которые вроде относятся к этому действию. И иногда тяжело заметить как функция становится монстром, но как только не влезает в экран - сразу понятно, что пора её в рефакторинг. Либо разбить на несколько подфункций, либо что-то просится в модель. То есть, "не больше одного экрана" - это просто триггер, который говорит, что здесь надо думать.

А множество функций на одну строку, которые используются всего один раз, в контроллерах плодить тоже не очень хорошо - код тогда сложнее понять.

 
Comment by Sam Subscribed to comments via email
2007-12-07 11:29:30

Хелпер я видел. Архив блога перелопатил весь.

Я имел ввиду не дебаг, а именно вывод сообщения пользователю.

 
Comment by larin Subscribed to comments via email
2007-12-07 13:29:13

Владимир, спасибо что напомнили =))) У меня есть замечательный универсальный класс для flash-сообщений, скоро выложу в блоге на обсуждение.

 
Comment by Sam Subscribed to comments via email
2007-12-07 13:36:11

Я не Владимир :)

 
Comment by larin Subscribed to comments via email
2007-12-07 13:41:59

@Sam
Так я ж к автору блога обращался. Он то вроде Владимир )))

 
Comment by Sam Subscribed to comments via email
2007-12-07 13:52:15

Ой, блин... чё-то меня сегодня плющит :) День варенья влияет...

 
Comment by larin Subscribed to comments via email
2007-12-07 14:11:26

[оффтоп]
@Sam
У тебя сегодня День Варенья??? ПОЗДРАВЛЯЮ!
Буду краток: здоровья, любви, денег и удачи! =)))
[/оффтоп]

 
Comment by Sam Subscribed to comments via email
2007-12-07 14:18:06

Спасибо.

 
2007-12-07 14:59:19

@larin: О, интересно будет почитать.
@Sam: С Днём варенья! :)

Кстати, никто не знает, можно ли в WordPress сделать древовидные комментарии как на LiveJournal?
У меня в среднем к записи 6 комментариев, но всё же было бы приятно.

 
Comment by larin Subscribed to comments via email
2007-12-07 15:27:55

@Владимир Лучанинов
Конечно можно, например, Brians Threaded Comments
А вообще Google & Яндекс выдают кучу интересного по запросу: "WordPress древовидные комментарии" =)))

 
2007-12-09 23:10:33

[...] и наткнулся на статьи Владимира Лучанинова “Вернуться назад и сообщить о результате” и “Разные flash для ошибок, сообщений и [...]

 
Имя (required)
E-mail (required - never shown publicly)
URL
Текст комментария
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> in your comment.