За обновлениями можно следить в telegram-канале https://t.me/quasiart

Введение

Привет всем. Обычно в своих статьях я рассказываю о том, с чем мне пришлось столкнуться. И на этот раз мне поставили задачу создать мобильную версию новостного сайта, созданного на Codeigniter. И создать нужно именно мобильную версию сайта, а не сайт с адаптивным дизайном.

Итак, было решено размещать сайт на поддомене. Допустим, если основная версия сайта размещается на домене quasi-art.ru, то мобильная версия сайта доступна по адресу m.quasi-art.ru.

Домены

Для начала был создан поддомен, ссылающийся на файлы основного сайта. Таким образом, по какому бы адресу ни пришёл посетитель, будет запущен один и тот же сайт.

Логика выбора версии сайта

Был составлен простой алгоритм, решающий простую задачу: какую версию сайта отдать посетителю. Есть 4 простых сценария.

  • Если посетитель заходит с ПК на основной сайт, ему отдаётся основная версия сайта.
  • Если пользователь заходит с мобильного устройства, ему возвращается мобильная версия сайта.
  • Если пользователь целенаправленно выбрал основную или мобильную версию сайта, перейдя по специальной ссылке, то на неё он и переходит.

Код логики оформлен в виде функции, которую я положил в хэлпер.

function showMobileVersion() {
	...
	if (isForceMobile()) {
		// Если пользователь сам переключился на мобильную версию
		if (!isMobileSubdomain()) {
			redirect($hostMobile);
		} else {
			return true;
		}
	} elseif (isForceDesktop()) {
		// Если пользователь сам переключился на полную версию
		if (isMobileSubdomain()) {
			redirect($hostDesktop);
		} else {
			return false;
		}
	} else {
		// Автоматическое определение
		if (isMobileBrowser()) {
			if (isMobileSubdomain()) {
				return true;
			} else {
				redirect($hostMobile);
			}
		} else {
			if (isMobileSubdomain()) {
				redirect($hostDesktop);
			} else {
				return false;
			}
		}
		return false;
	}
}

Контроллеры

Решение о том, какую версию сайта отдавать, решается в методах контроллеров.

if (showMobileVersion()) {
	$this->load->view('templates/templateIndexMobile', $this->data);
} else {
	$this->load->view('templates/templateIndex', $this->data);
}

Подводные грабли

Cookies для поддоменов

Я целых два часа пробился с тем, что у меня в сессию заносились не те данные. Оказалось, моя ошибка была в том, что для разных поддоменов создавалась отдельная сессия, и я работал с ними, как с одной. Чтобы сделать сессию общей для поддоменов, необходимо в настройках системы ($config['cookie_domain']) указать следующее: .quasi-art.ru. Именно так, с точкой в начале. Теперь сессия для домена и поддомена будет общей.

Кэширование

Кэширование привязано к методам контроллеров, в которых решалось, какую версию отдавать. Поэтому, посетителю отдавалась версия страницы, которая попала в кэш первой. Таким образом, если сначала создался кэш для главной страницы полной версии сайта, то эта версия отдавалась и для мобильных устройств.

Это происходило из-за того, что имя кэша представляет собой хэш от нескольких строк.

$uri = $CFG->item('base_url').
	$CFG->item('index_page').
	$URI->uri_string;
$filepath = $cache_path.md5($uri);

Стало понятно, что имя файла кэша не зависит от поддомена, поэтому было решено схитрить и изменить системный файл system/core/Output.php. Вообще, для людей, модифицирующих проекты, сопровождением которых занимаются другие разработчики, приготовлен отдельный котёл. Но это была вынужденная мера ввиду моей некомпетентности. Итак, файл Output.php был изменён следующим образом:

$uri = $CFG->item('base_url').
	$CFG->item('index_page').
	$URI->uri_string.
	$this->getSubdomain();

Для невнимательных или не читающих код замечу, что я добавил вызов функции getSubdomain. Надеюсь, для всех очевидно её возвращаемое значение.

Вывод

Мне было, конечно, интересно узнать подробнее о системе кэширования CodeIgniter, но, надеюсь, мне больше не придётся иметь с ней дела, так как сделана она очень топорно и не отличается гибкостью. Но я не собираюсь останавливаться на написании статей о том, как создать мобильную версию сайта, ведь у меня в этом есть опыт не только с CodeIgniter, но и с MODX Revolution. Сразу скажу, что в MODX создание мобильной версии заняло в разы меньше времени.