Создание и сопровождение сайтов

Блог. Yii. Подсказки по Yii. Глава четырнадцатая.

Поиск

Подсказки по Yii. Глава четырнадцатая.

  1. Отдача файлов на скачивание с помощью sendFile.

    Собственно, сразу пример:

    1. 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):

    1. Controller::disableProfiler();  

    (код метода можно увидеть в файле protected\components\Controller.php)

    Это необходимо для того, чтобы в содержимое файла при скачивании не попали записи профайлера.

     

  2. Отдача больших файлов на скачивание с помощью xSendFile.

    Для работы должен быть установлен модуль Apache XSendfile (иначе файлы будут отдаваться весом 0 байт).

    Cайт разработчика: https://tn123.org/mod_xsendfile/

    Использование в Yii:

    1. Yii::app()->request->xSendFile(Yii::getPathOfAlias('webroot.uploads').DIRECTORY_SEPARATOR.'test.txt'array(  
    2.      'saveName'=>'fileName.txt',  
    3.      'mimeType'=>'text/plain',  
    4.      'terminate'=>true,  
    5. ));  

    функция очень схожа с Yii::app()->request->sendFile (плюс ко всему наглядно понятно какие параметры и ключи за что отвечают поэтому повторяться не буду).

    Установка и настройка xSendFile под XAMPP:

    • Скачать бинарники под Windows с сайта разработчика;
    • Скопировать из скачанного архива файл mod_xsendfile.so в apache\modules;
    • В apache\conf\httpd.conf добавить запись:
      1. LoadModule xsendfile_module modules/mod_xsendfile.so  
    • Добавить в файл apache\conf\httpd.conf или файл apache\conf\extra\httpd-vhosts.conf (в зависимости от настроек) после DocumentRoot "C:/xampp/htdocs" две строчки:
      1. XSendFile On  
      2. XSendFilePath "C:/xampp/htdocs"  

     

  3. CHtml::ajaxLink.

    Чтобы не писать каждый раз вручную:

    1. $.ajax({  
    2.     type: 'POST',  
    3.     url: url,  
    4.     data: data,  
    5.     success: function(html){  
    6.         $('#result_id').html(html);  
    7.     }  
    8. });  

    можно воспользоваться готовым решением CHtml::ajaxLink.

    Создадим контроллер TestController.php в папке protected\controllers:

    1. <?php  
    2. class TestController extends Controller {  
    3.     public $defaultAction = 'getApartment';  
    4.   
    5.     public $items = array(  
    6.         array('id' => 1, 'title' => 'Заголовок 1'),  
    7.         array('id' => 2, 'title' => 'Заголовок 2'),  
    8.         array('id' => 3, 'title' => 'Заголовок 3'),  
    9.     );  
    10.   
    11.     function actionGetApartment() {  
    12.         $item = $this->getRandomItem();  
    13.   
    14.         if(Yii::app()->request->isAjaxRequest) {  
    15.             $this->renderPartial('_item_random', array(  
    16.                 'item' => $item,  
    17.             ));  
    18.         }  
    19.         else {  
    20.             $this->render('index_random', array(  
    21.                 'item' => $item,  
    22.             ));  
    23.         }  
    24.     }  
    25.   
    26.     private function getRandomItem() {  
    27.         return $this->items[array_rand($this->items, 1)];  
    28.     }  
    29. }  

    В папку protected\views\test положим файл с названием _item_random.php:

    1. <?php  
    2.     echo 'id = '. $item['id']. '<br />';  
    3.     echo 'title = '.$item['title'];  
    4. ?>  

    и файл index_random.php:

    1. <h1>Изучаем CHtml::ajaxLink</h1>  
    2. <div id="apartments-list">  
    3.     <?php  
    4.         $this->renderPartial('_item_random'array(  
    5.             'item' => $item,  
    6.         ));  
    7.     ?>  
    8. </div>  
    9.   
    10. <?php echo CHtml::ajaxLink('След. объект'array('getApartment'), array('update' => '#apartments-list'))?>  

    В итоге страница будет иметь вид:

    yii-tips-14-01

    Итак, разберём подробнее вышенаписанный код.

    При вызове http://my-domain/test мы попадаем в метод actionGetApartment, в котором берём случайным образом элемент из массива $this->items.

    Далее идёт проверка на тип запроса: если это AJAX запрос, то отдаём форму _item_random.php, если же нет (при первой загрузке страницы), то форму index_random.php.

    Сгенерированный автоматически код на странице при вызове CHtml::ajaxLink имеет следующий вид:

    1. <script type="text/javascript">  
    2. /*<![CDATA[*/  
    3. jQuery(function($) {  
    4. $('body').on('click','#yt0',function(){  
    5.         jQuery.ajax({'url':'/my-domain/test/getApartment','cache':false,'success':function(html){jQuery("#apartments-list").html(html)}});return false;  
    6.     });       
    7. });  
    8. /*]]>*/  
    9. </script>  

    Если необходимо изменить функцию, вызываемую при успешном AJAX запросе, то можно изменить параметры следующим образом:

    1. <?php echo CHtml::ajaxLink('След. объект', array('getApartment'), array('success' => 'js:function(html){ console.log(html); $("#apartments-list").html(html) }'))?>  

    Так мы вывели ответ в консоль и обновили элемент с ID равным apartments-list.

    yii-tips-14-02

     

  4. Мультиязычность в Yii. Поиск не переведённых слов/фраз/предложений.

    На помощь придёт событие onMissingTranslation.

    В config/main.php

    1. ...  
    2. 'messages'=>array(  
    3.     'forceTranslation'=>true,  
    4.     'onMissingTranslation' => array('CustomEventHandler''handleMissingTranslation'),  
    5. ),  
    6. ...  

    Первое значение массива - это название класса, а второе значение - название метода в этом классе.

    Код класса CustomEventHandler в файле protected\components\CustomEventHandler.php имеет вид:

    1. <?php  
    2. class CustomEventHandler {  
    3.     static function handleMissingTranslation($event) {  
    4.         // можно добавить с БД о том, что нет перевода или отправить письмо администратору   
    5.         // о том, что нет перевода $event->message, категории $event->category, языка $event->language  
    6.           
    7.         $sql = "INSERT INTO {{not_translate_message}} (category, message, language) 
    8.                         VALUES (:category, :message, :language)";  
    9.                           
    10.         Yii::app()->db->createCommand($sql)  
    11.             ->bindValue(':category'$event->category, PDO::PARAM_STR)  
    12.             ->bindValue(':message'$event->message, PDO::PARAM_STR)  
    13.             ->bindValue(':language,'$event->language, PDO::PARAM_STR)  
    14.             ->execute();  
    15.     }  
    16. }  

     

Обсудить статью на форуме