19 заметок с тегом

yii2

Ctrl + ↑ Позднее

Получить чистый sql-запрос из AR и AQ в Yii2

Собираем запрос, используя Active Record или Active Query и чтобы убедиться в правильности запроса смотрим на сам SQL.

// собираем AR
$orders = Order::find()->where(['status' => 1])->orderBy('date ASC');

// Получим sql в чистом виде:
$orders->createCommand()->getRawSql();

И увидим результат:

SELECT * FROM "order" WHERE "status"=1 ORDER BY "date"
2017   active query   active record   AR   php   sql   yii2

Установка и настройка Composer

Без php не поставить, потому начинаем именно с php. Актуальная версия на сегодняшний день — это версия 7.0:

sudo apt install php7.0-cli

Теперь можно ставить Composer:

curl -sS https://getcomposer.org/installer | php

В итоге мы получим файл composer.phar, который и является исполняемым. Запускать его необходимо командой:

php composer.phar

Выполнив нехитрую команду, мы сможем исполнять вводя «composer» вместо «php composer.phar»

sudo mv composer.phar /usr/local/bin/composer

Если вы устанавлиаете Yii2, то обратите внимание, что необходимо установить плагин Composer Asset Plugin, т. к. позволит работать с некоторыми пакетами, которые контролируются менеджерами пакетов Bower и Npm. В частности, в Yii2 — это Bower, который «подтягивает» Jquery и Twitter Bootstrap.

composer global require "fxp/composer-asset-plugin"
2016   bower   composer   composer-asset-plugin   php   php-cli   yii2

Обернуть dump базы в миграцию Yii

На yii1 это делается следующим образом:

$this->executeSqlFile( __DIR__ . '/sql_query/' . 'example.sql');

В yii2 необходимо сделать так:

$this->execute( file_get_contents( __DIR__ . '/sql_query/' . 'example.sql'));
2016   dump   execute   executeSqlFile   yii   yii2
2016   comment   migrate   yii   yii2

Yii2 и автокомплит (autocomplete)

Для тех, кто хочет современный и быстрый и с больших количеством «фишек» автокомплит, то советую обратить внимание на https://github.com/devbridge/jQuery-Autocomplete

Хороший подробный мануал поможет быстро прикрутить в «нужное место». Большие возможности по настройке.
Я напишу лишь о том, как я его прикрутил к yii2.

Файл jquery.autocomplete.js размещаю в директории @web/js.
Сам файл я подключаю не через глобальный assets/AppAsset.php, а локально в конкретном представлении:

$this->registerJsFile( '@web/js/jquery.autocomplete.js', ['depends' => 'yii\web\JqueryAsset'] );

Причем, устанавливаю зависимость загрузки от JqueryAsset (т. е. после загрузки основного файла jquery.js).
В том же представлении, немного ниже уже размещаю сам код:

$this->registerJs( "
    $(function () {
        $('#city_name').autocomplete({
            serviceUrl: '/site/city',
            minLength: 2,
            lookupLimit: 10,
            type: 'POST',
            paramName: 'city_name',
            dataType: 'json',
            transformResult: function (response) {
                return {
                    suggestions: $.map(response, function (value, key) {
                        return {value: value.value + ', ' + value.tvalue, valueCity: value.value};
                    })
                };
            },
            onSelect: function (suggestion) {
                $('#city_name').val(suggestion.valueCity);
            }
        });

    });
" );

Суть запроса в том, что я в поле ввода в представлении начинаю вводить название какого-нибудь населенного пункта, а в ответ получаю список совпадений (см. скриншот).

Размещение в базе данных городов и их интеграцию с Yii я описывать не буду — это не является темой данного поста.
Но что важно, на выходе мы можем с помощью этого плагина манипулировать данными. А именно:
«minLength» — минимальное количество символов, после ввода которых, запрос «идет в Контроллер» SiteComntroller;
«paramName» — поле, аттрибутом которого является name=«city_name». Так плагин понимает значение какого поля отправлять в Контроллер;
«transformResult» — параметр, который позволяет полученный response преобразовать в том формате, который нам необходим. Например, я получаю в ответе массив данных Город, Регион и Страна, а в представлении данный массив раскладываю в строку, разделяя значения запятыми.
«onSelect» позволяет задать логику после того, как Пользователь выбрал предложенный вариант из списка.

Со стилями тоже можно поиграться, по умолчанию рекомендуют подгрузить в основной css-файл следующее:

.autocomplete-suggestions { border: 1px solid #999; background: #FFF; overflow: auto; }
.autocomplete-suggestion { padding: 2px 5px; white-space: nowrap; overflow: hidden; }
.autocomplete-selected { background: #F0F0F0; }
.autocomplete-suggestions strong { font-weight: normal; color: #3399FF; }
.autocomplete-group { padding: 2px 5px; }
.autocomplete-group strong { display: block; border-bottom: 1px solid #000; }

Остальные возможности плагина изучайте в документации.

2016   autocomplete   jquery   yii2

Геокодирование от Яндекса, используя Yii

На Yii2 надо было мне реализовать обратное геокодирование. Я знаю город (населенный пункт), но не знаю координаты.

Лучший вариант — прикрутить гео от Яндекса или Гугла.
Прикручивать буду от Яндекса. Заглянул в github на готовые библиотеки для yii.
Есть отличный, я бы даже сказал, навороченный вариант от разработчиков Яндекса https://github.com/yandex-php/php-yandex-geo. По всем правилам ооп, написанный на хорошем php (еще бы:D). Но в нем куча ненужных мне функций (например работа с локалью, прямое гео и т. д.). Тащить лишнее в проект не хочется.

Порылся и нашел неплохой вариант https://github.com/vitalik74/yii2-geocode-yandex.
Реализован в виде отдельного класса, который можно подключить в любом месте проекта (я подключил его как модель). К тому же, данный класс позволяет работать только с обратным геокодированием.
В общем, я сэкономил добрые полчаса, котоые мне потребовались бы на написание обработчика с нуля.
Для удобства, я внес небольшие корректировки, которые учитывали специфику моей задачи:

Мне нужен только один ответ, а не массив ответов (т. к. название населенного пункта, район и страну я уже знаю):

public $results = 1;

У меня город, потому:

public $kind = 'locality';

В функции get массив $params я собираю сам, аттрибуты в функцию передаваться не будут:

...
public function get($geocode, array $params = [], $apiKey = '')
{
	$params = ['key' => $this->key, 'results' => $this->results, 'kind' => $this->kind ];
	...
}

Теперь, в нужном месте, мне достаточно определить класс:

$geo = new Geocode();
$result = $geo->get('Москва, Россия');

Соответственно переменная $result содержит все необходимые данные. В частности, необходимые мне координаты содержаться во вложенном массиве «Point»

2016   api   geo   yandex   yii   yii2   геокодер   Яндекс API

Асинхронно обновить captcha в Yii2

Столкнулся с тем, что в Yii2 кнопки для обновления captcha в ajax нет.
Начинаем делать правильно и своими силами:
Сделаем кнопку во view

$form->field($registration, 'captcha')->widget(Captcha::className(), [
	'template' => '<a href="javascript:void(0);" id="fox"></a>
		<div>{image}</div>{input}',
	'options' => [
		'placeholder'=>'Введите буквы с картинки'
	],
]);

и «повесим» на эту кнопку js-код:

$(document.body).on('click', '#fox', function(e) {
	$.ajax({
		type: 'GET',
		url: '/site/captcha',
		data: {refresh: 1},
		success: function (data) {
			$("img[id$='-captcha-image']").attr('src', data.url);
		}
	});
});

Форму будем валидировать так:

namespace models\form;

use Yii;
use yii\base\Model;

class Registration extends Model
{
...
	public function rules()
	{
		return [
			[['username', 'captcha', 'password'], 'required'],
			['username', 'email', 'message' => '{attribute} введен некорректно!'],
			
			['captcha', 'captcha', 'captchaAction' => 'site/captcha'],
			['username', 'validateEmail'],
		];
	}
...
}
2015   ajax   captcha   validate   yii2   асинхронно

Указать title для вывода во view на Yii1 и Yii2

Работа во view с $this изменилась, и старыми методами в Yii2 теперь не получится работать.

Вывести title
В контроллере указать title:

$this->view->title = 'Заголовок, который будет выведен в H1';

После этого во view в нужном месте укажите:

<h1><?= $this->title; ?></h1>
2015   title   view   yii   yii2

Текущий контроллер/модель/экшн в Yii и Yii2

Очень часто необходимо знать, какой текущий Контроллер или, например, Модель. Такое пригодится, чтобы при определенных условиях действовало какое-либо правило. В качестве примера пусть будет следующее:
В экшне «actionIndex» Контроллера SiteController показывается статичный заголовок «Добро пожаловать, земляне!».
При этом, данное правило должно действовать в layout, т. к. Заголовок задается в нем:

if (Yii::$app->controller->id == 'site' && Yii::$app->controller->action->id == 'index')
{
	echo 'Добро пожаловать, земляне!';
}

Т. к. ситуации бывают разные, то я просто приведу примеры для Yii1 и Yii2:

текущий Контроллер:

Yii::$app->controller->id

получить Контроллер в качестве объекта:

Yii::$app->controller

текущий Экшн:

Yii::$app->controller->action->id

А если нужен полный путь, то можно так его получить:

Yii::$app->controller->route

или, ели обратиться внутри контроллера:

$this->route

А из представления так:

$this->context->route

Для Yii1 все практически идентично.
текущий Контроллер:

Yii::app()->controller->id

а можно и так:

Yii::app()->controller->getId()

текущий Экшн:

Yii::app()->controller->action->id

текущий Модуль:

Yii::app()->controller->module->id

Если надо получить текущий Контроллер и Экшн в формате «контроллер/экшн», то:

Yii::app()->controller->getRoute()
2015   php   yii   yii2