Подсказки по Yii. Глава четырнадцатая.
-
Отдача файлов на скачивание с помощью sendFile.
Собственно, сразу пример:
- Yii::app()->request->sendFile('fileName.txt', file_get_contents(Yii::getPathOfAlias('webroot.uploads').DIRECTORY_SEPARATOR.'test.txt'));
Первый параметр, передаваемый в функцию - это название файла при отдаче его пользователю.
Второй параметр - содержимое файла.
Третьим параметром можно вручную указать mimeType файла, по-умолчанию null (определяется автоматически).
Четвёртым параметром можно указать флаг - true/false. Будет означать прекращать ли выполнение приложения после вызова фукнции sendFile, по-умолчанию true.
Если включен профайлер (логирование), например расширение yii-debug-toolbar, то перед вызовом функции sendFile добавьте вызов метода disableProfiler (данный метод доступен только в Open Real Estate CMS):
- Controller::disableProfiler();
(код метода можно увидеть в файле protected\components\Controller.php)
Это необходимо для того, чтобы в содержимое файла при скачивании не попали записи профайлера.
-
Отдача больших файлов на скачивание с помощью xSendFile.
Для работы должен быть установлен модуль Apache XSendfile (иначе файлы будут отдаваться весом 0 байт).
Cайт разработчика: https://tn123.org/mod_xsendfile/
Использование в Yii:
- Yii::app()->request->xSendFile(Yii::getPathOfAlias('webroot.uploads').DIRECTORY_SEPARATOR.'test.txt', array(
- 'saveName'=>'fileName.txt',
- 'mimeType'=>'text/plain',
- 'terminate'=>true,
- ));
функция очень схожа с Yii::app()->request->sendFile (плюс ко всему наглядно понятно какие параметры и ключи за что отвечают поэтому повторяться не буду).
Установка и настройка xSendFile под XAMPP:
- Скачать бинарники под Windows с сайта разработчика;
- Скопировать из скачанного архива файл mod_xsendfile.so в apache\modules;
-
В apache\conf\httpd.conf добавить запись:
- LoadModule xsendfile_module modules/mod_xsendfile.so
-
Добавить в файл apache\conf\httpd.conf или файл apache\conf\extra\httpd-vhosts.conf (в зависимости от настроек) после DocumentRoot "C:/xampp/htdocs" две строчки:
- XSendFile On
- XSendFilePath "C:/xampp/htdocs"
-
CHtml::ajaxLink.
Чтобы не писать каждый раз вручную:
- $.ajax({
- type: 'POST',
- url: url,
- data: data,
- success: function(html){
- $('#result_id').html(html);
- }
- });
можно воспользоваться готовым решением CHtml::ajaxLink.
Создадим контроллер TestController.php в папке protected\controllers:
- <?php
- class TestController extends Controller {
- public $defaultAction = 'getApartment';
-
- public $items = array(
- array('id' => 1, 'title' => 'Заголовок 1'),
- array('id' => 2, 'title' => 'Заголовок 2'),
- array('id' => 3, 'title' => 'Заголовок 3'),
- );
-
- function actionGetApartment() {
- $item = $this->getRandomItem();
-
- if(Yii::app()->request->isAjaxRequest) {
- $this->renderPartial('_item_random', array(
- 'item' => $item,
- ));
- }
- else {
- $this->render('index_random', array(
- 'item' => $item,
- ));
- }
- }
-
- private function getRandomItem() {
- return $this->items[array_rand($this->items, 1)];
- }
- }
В папку protected\views\test положим файл с названием _item_random.php:
- <?php
- echo 'id = '. $item['id']. '<br />';
- echo 'title = '.$item['title'];
- ?>
и файл index_random.php:
- <h1>Изучаем CHtml::ajaxLink</h1>
- <div id="apartments-list">
- <?php
- $this->renderPartial('_item_random', array(
- 'item' => $item,
- ));
- ?>
- </div>
-
- <?php echo CHtml::ajaxLink('След. объект', array('getApartment'), array('update' => '#apartments-list'))?>
В итоге страница будет иметь вид:
Итак, разберём подробнее вышенаписанный код.
При вызове http://my-domain/test мы попадаем в метод actionGetApartment, в котором берём случайным образом элемент из массива $this->items.
Далее идёт проверка на тип запроса: если это AJAX запрос, то отдаём форму _item_random.php, если же нет (при первой загрузке страницы), то форму index_random.php.
Сгенерированный автоматически код на странице при вызове CHtml::ajaxLink имеет следующий вид:
- <script type="text/javascript">
-
- jQuery(function($) {
- $('body').on('click','#yt0',function(){
- jQuery.ajax({'url':'/my-domain/test/getApartment','cache':false,'success':function(html){jQuery("#apartments-list").html(html)}});return false;
- });
- });
-
- </script>
Если необходимо изменить функцию, вызываемую при успешном AJAX запросе, то можно изменить параметры следующим образом:
- <?php echo CHtml::ajaxLink('След. объект', array('getApartment'), array('success' => 'js:function(html){ console.log(html); $("#apartments-list").html(html) }'))?>
Так мы вывели ответ в консоль и обновили элемент с ID равным apartments-list.
-
Мультиязычность в Yii. Поиск не переведённых слов/фраз/предложений.
На помощь придёт событие onMissingTranslation.
В config/main.php
- ...
- 'messages'=>array(
- 'forceTranslation'=>true,
- 'onMissingTranslation' => array('CustomEventHandler', 'handleMissingTranslation'),
- ),
- ...
Первое значение массива - это название класса, а второе значение - название метода в этом классе.
Код класса CustomEventHandler в файле protected\components\CustomEventHandler.php имеет вид:
- <?php
- class CustomEventHandler {
- static function handleMissingTranslation($event) {
-
-
-
- $sql = "INSERT INTO {{not_translate_message}} (category, message, language)
- VALUES (:category, :message, :language)";
-
- Yii::app()->db->createCommand($sql)
- ->bindValue(':category', $event->category, PDO::PARAM_STR)
- ->bindValue(':message', $event->message, PDO::PARAM_STR)
- ->bindValue(':language,', $event->language, PDO::PARAM_STR)
- ->execute();
- }
- }