“Светофорчики” или flash-сообщения

by Larin

Интро

Сидел на днях перечитывал RSS-ки за пару недель, пытался вновь войти в программистский римт… уж сильно меня увлекло мое давнее увлечение – конструирование шокеров. :) Но об этом, я скорее всего, напишу позже. Так вот, сидел-перечитывал и наткнулся на статьи Владимира Лучанинова “Вернуться назад и сообщить о результате” и “Разные flash для ошибок, сообщений и подтверждений“.

У него статьи посвящены flash-собщениям (я их люблю называть “светофорчиками”) в CakePHP. Читая я вспомнил, что у меня в проектах тоже есть такие сообщения, и они никак не зависят от системы, т.е. их без труда можно будет добавить на любой сайт.

Немного проектирования

Теперь когда все читатели блога в той или иной степени разобрались с UML (статья 1 & статья 2), я решил по мере сил, сопровождать диаграммами код из моих статей. И прошу вас, читатели, быть внимательными и искать неточности в диаграммах – ошибки бывают у всех. :) Будем учиться вместе.

Для реализации сообщений “светофорчиков” нам необходмы 2 класса:

  1. класс описывающий само сообщение;
  2. класс овечающий за отображение сообщений.

И так, диаграмма классов нашего примера:

Диаграмма классов

Все предельно просто и много кодить нам не придется. Зато посетителям сайта будут показываться красивые сообщения. =)

Теперь смоделируем алгоритм работы:

Диаграмма последовательности

На этой диаграмме, для большей налядности, я сделал небольшую неточность – инициализировать объект MessageBox будет скорее всего не пользователь, как показано на диаграмме, а некий объек, например, контроллер. Но т.к. я решил описать реализацию сообщений без привязки к определенной системе, было решено “нагрузить” этой задачей пользователя, но лишь виртуально. :)

Думаю, здесь все понятно и диаграммы не вызывают никаких вопросов. Если же вопросы есть – перчитайте мои статьи по UML.

И совсем немного кода

И вот настал момент, когда слово станет делом. :) Т.е. момент кодирования наших задумок.

Код класса Message выглядит следующим образом:


<?php
class Message
{
	private $content;

	public function __construct(string $content)
	{
		$this->content = $content;
	}

	public function send()
	{
		$_SESSION['session_messages'][] = $this->content;
	}

	public function view()
	{
		return $this->content;
	}
}
?>

Далее опишем класс MessageBox:


<?php
class MessageBox
{
	public $messages = array();

	public function __construct()
	{
		if (isset($_SESSION['session_messages']) && is_array($_SESSION['session_messages'])) {
			$messages = $_SESSION['session_messages'];
			$co = sizeof($messages);
			for ($i = 0; $i < $co; $i++) {
				$this->messages[] =  new Message($messages[$i]);
			}
		}

		//Очищаем массив сообщений он нам больше не нужен
		if (isset($_SESSION['session_messages'])) $_SESSION['session_messages'] = array();
	}

	public function getMessage()
	{
		$data = '';
		for ($i = 0, $k = sizeof($this->messages); $i < $k; $i++) {
			$data .= $this->messages[$i]->view() . '<br/>';
		}
		return $data;
	}
}
?>

Вот и весь код. А теперь как его использовать. Например, после добавлние поста, надо уведомить пользователя о результате опрации:


<?php
$post = new Post();
$post->title = 'Test';
$post->text = '<p>text</p>';

if ($post->save) {
	$msg = new Message('Ваш пост успешно добавлен.');
} else {
	$msg = new Message('Ошибка при добавлении!');
}
$msg->send();

//И редиректим куда необходимо...
header('Location: http://куда_надо');
exit(); //Никогда не забывайте ставить exit() после редиректа
?>

И далее, в зависимости от того как у вас устроена система вызываем класс MessageBox во фронт-контроллере. Например, отрывок кода index.php:


<?php
/**
* Здесь какой-то код
**/

//Т.к. сообщения мы показываем сразу после переадресации
//а она идет при помощи метода GET
if ('POST' != $_SERVER['REQUEST_METHOD']) {
	$mBox = new MessageBox();
	//Передаем сообщения в шаблонизатор
	$view->set('notice', $mBox->getMessage());
}

/**
* Здесь какой-то код
**/
?>

Все сообщения-светофорчики, они же flash-сообщения готовы!

Я описал самый простой вид сообщений. Совершенно логично было бы дополнить класс Message еще одним свойством, например, type. Который бы указывал на тип сообщения: уведомление, ошибка, подтверждение. И в зависимости от типа выбиралось бы CSS оформление сообщения.

Но это я оставляю вам, что б вы тоже не скучали. Может быть, кому то придут интересные мысли по доработке или полной модернизации этих классов, пишите в комментариях – обсудим.