пятница, 20 января 2017 г.

uninstal xdebug

Uninstall php-xdebug

To remove just php-xdebug package itself from Ubuntu 16.04 (Xenial Xerus) execute on terminal:
sudo apt-get remove php-xdebug

Uninstall php-xdebug and it's dependent packages

To remove the php-xdebug package and any other dependant package which are no longer needed from Ubuntu Xenial.
sudo apt-get remove --auto-remove php-xdebug

Purging php-xdebug

If you also want to delete configuration and/or data files of php-xdebug from Ubuntu Xenial then this will work:
sudo apt-get purge php-xdebug
To delete configuration and/or data files of php-xdebug and it's dependencies from Ubuntu Xenial then execute:
sudo apt-get purge --auto-remove php-xdebug

среда, 18 января 2017 г.

clean to linux

sudo apt-get install -f
sudo apt-get autoremove
sudo apt-get clean

.htaccess

Options +FollowSymLinks

IndexIgnore */*
RewriteEngine on

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
RewriteRule . index.php

воскресенье, 15 января 2017 г.

permission chmod

Permission
sudo chmod 775 -R folder/

сделать группу www-data владельцем папки 
sudo chown root:www-data frontend/models

Теперь папка принадлежит пользователю root и папке www-data. Обратите внимание: Apache работает на сайте в качестве пользователя www-data, который также входит в группу www-data. Теперь передайте группе www-data право на запись в папке:
chmod 775 frontend/models

Create db Teminal

Create db to command line & Migrate (yii2)

mysql -u root -p
***
create database <name_db> character set utf8 collate utf8_general_ci;
exit

-------------------------------
use <name_db>;
show tables;

------------------------------
migrate

php yii migrate/create <table_name>


------------------------------------
for gii
сделать группу www-data владельцем папки 
sudo chown root:www-data frontend/models

Теперь папка принадлежит пользователю root и папке www-data. Обратите внимание: Apache работает на сайте в качестве пользователя www-data, который также входит в группу www-data. Теперь передайте группе www-data право на запись в папке:
chmod 775 frontend/models
Очистить таблицу TRUNCATE mytable;

импорт базы данных
Заходим в MySQL:
1
mysql -u Login -p DB_name -h Host 
(вместо Login и DB_name вводим данные пользователя БД и хост, например localhost)
Выбираем базу данных:
1
 use db_name 
(вместо db_name вводим название БД)
Делаем импорт файла в выбранную бд:
1
source db_name.sql 

суббота, 7 января 2017 г.

modules yii2 part2

Гибкая модульная архитектура на Yii2 - Часть 2: Взаимодействие между модулями и интернационализация

Часть 1: Подключение модулей, роутинг и события
Часть 2: Взаимодействие между модулями и интернационализация
Часть 3: Работа с базой данных и миграции
В первой части мы рассмотрели общую структуру приложения и логику подключения модулей. Добавили сбор правил роутинга и описали схему работы событийной модели. В этой статье мы рассмотрим способы взаимодействия между модулями и организацию словарей для интернационализации приложения.
Исходники с тестовыми данными лежат здесь (обратите внимание, ссылка указывает не на последний коммит).

Взаимодействие между модулями

Как бы мы не изолировали модули друг от друга, иногда возникает необходимость обращения одного модуля к другому. Так же иногда необходимо обратиться к модулю из ядра приложения. Но мы не можем сделать это напрямую т.к. это добавляет модулю зависимость и мы уже не сможем безболезненно его удалить.
Нам нужен механизм, который будет решать две задачи:
  1. Возможность непрямого обращения к модульным классам. Так, чтобы в случае отсутствия модуля он просто возвращал null без падения.
  2. Возможность получения нужного класса из активной версии модуля. Мы просто запрашиваем класс MyClass из модуля MyModule. А система сама определяет активную версию этого модуля и ищет нужный класс в ней.
Обычно в таких случаях используют DI-контейнеры. Yii2 предоставляет собственную реализацию этого контейнера. Использование этого компонента решит первую задачу, но не поможет нам в решении второй. Дело в том, что в контейнер надо заранее передавать подключенные классы. А нам необходимо делать это динамически в момент обращения к нему.
Для решения этой задачи добавим два прокси-метода в класс базовых модулей:
namespace app\components;
use app\models\entities\Module as ModuleAr;
use yii\base\Exception;
use yii\helpers\Inflector;
abstract class MainModule extends Module
{
    /**
     * Возвращает объект класса $className из версии $version.
     *
     * @param string $className Имя класса, относительно корня модуля.
     * @param array $constructorArgs = [] Аргументы, передаваемые в конструктор.
     * @param string $moduleVersion = null Версия, в которой будет осуществляться поиск класса. Если NULL - будет использована активная версия.
     * @return mixed|null Объект класса или NULL, если класс не доступен.
     * @throws \yii\base\Exception
     */
    public static function getObject($className, array $constructorArgs = [], $moduleVersion = null)
    {
        $class = static::createFullClassName($className, $moduleVersion);
        return $class && class_exists($class) ? new $class(...$constructorArgs) : null;
    }
    /**
     * Возвращает полное имя класса $className из версии $version.
     *
     * @param string $className Имя класса, относительно корня модуля.
     * @param string $moduleVersion = null Версия, в которой будет осуществляться поиск класса. Если NULL - будет использована активная версия.
     * @return mixed|null Имя класса или NULL, если класс не доступен.
     * @throws \yii\base\Exception
     */
    public static function getClass($className, $moduleVersion = null)
    {
        $class = static::createFullClassName($className, $moduleVersion);
        return $class && class_exists($class) ? $class : null;
    }
    /**
     * Формирует полное имя класса из его относительного имени и версии модуля.
     *
     * @param string $name Имя класса, относительно корня модуля.
     * @param string $moduleVersion = null Id of module's version. Версия модуля. Если NULL - будет использована активная версия.
     * @return string|null Full name of class. Имя класса или NULL, если у модуля нет активной версии.
     */
    private static function createFullClassName($name, $moduleVersion = null)
    {
        $moduleClass = static::class;
        $moduleId = Inflector::underscore(substr($moduleClass, strrpos($moduleClass, '\\') + 1));
        if ($moduleVersion === null) {
            $moduleVersion = ModuleAr::getActiveVersionIdByModuleId($moduleId);
        }
        if ($moduleVersion === null) {
            return null;
        }
        $namespace = substr($moduleClass, 0, strrpos($moduleClass, '\\'));
        $className = ltrim($name, "\\");
        return "\\{$namespace}\\modules\\{$moduleVersion}\\{$className}";
    }
    // ...
}
Посмотрим, как работают эти методы. Например, в модуле ExampleBilling у нас есть модель ExampleInvoice. Нам нужно получить экземпляр этого класса. Мы пишем следующее:
use \app\modules\example_billing\ExampleBilling;
// ...
$object = ExampleBilling::getObject('models\entities\ExampleInvoice');
if ($object) {
  // Работаем с полученным объектом.
}
Фасад сначала определяет, что сейчас для модуля ExampleBilling подключена версия v1. Проверяет существование класса \app\modules\example_billing\modules\v1\models\entities\ExampleInvoice. Если класс доступен - создает его экземпляр и возвращает нам.
Так же эти методы удобны, когда мы пишем общую логику для нескольких версий модуля. Например, у нас есть две версии v1 и v2, которые незначительно отличаются моделями ExampleInvoice. Мы выносим общую логику в версию common (которую нельзя назначить активной) и наследуем от нее классы в версиях. Но мы не можем обращаться к модели, находящейся в какой-то версии, напрямую из common т.к. активна может быть любая версия. В таком случае, используем тот же фасад и получим класс из той версии, которая будет активна в момент выполнения. Пример можно посмотреть в методе \app\modules\example_billing\modules\v1\models\entities\ExampleCommonModel().
Таким образом, использую фасады и события, мы можем связывать модули друг с другом, не создавая при этом зависимостей, ломающих работу приложения. Как и в случае с событиями, если вы не хотите завязываться на классы корневых модулей, вы можете вынести эти фасады в какой-нибудь глобальный объект и вызывать их, явно указывая модуль.

Интернационализация (I18N)

Практически любое приложение требует перевода на несколько языков. Yii2 предоставляет для этого готовый инструмент. Все, что нам остается сделать, это разнести хранение словарей по модулям. Так чтобы каждый модуль хранил свои переводы.
В стандартной документации описан способ сделать это. Но, как и в случае с контейнерами, нам это подходит. Ведь мы не инициализируем модули в момент их подключения. Плюс нужна возможность обращения к словарю из любой версии, не только из активной.
Есть решение, которое позволяет сделать это достаточно просто. Суть его заключается в том, чтобы, основываясь на модуле и версии, формировать правильный путь к файлу словаря. Для этого переопределим компонент источника переводов:
// app/config/common.php
return [
    // ...
    'components' => [
        // ...
        'i18n' => [
            'translations' => [
                '*' => [
                    'class' => \app\components\PhpMessageSource::class,
                    'basePath' => '/messages',
                ],
            ],
        ],
    ],
];
Переопределим метод \app\components\PhpMessageSource::getMessageFilePath() следующим образом:
namespace app\components;
use yii\base\Exception;
class PhpMessageSource extends \yii\i18n\PhpMessageSource
{
    /**
     * @param string $category Категория. Должна иметь один из видов:
     * - moduleId.moduleVersion.categoryName
     * - moduleId.categoryName
     * - categoryName
     * @param string $language
     * @return string Путь к файлу
     * @throws Exception
     * @see \yii\i18n\PhpMessageSource::getMessageFilePath()
     */
    protected function getMessageFilePath($category, $language)
    {
        $categoryList = explode('.', $category);
        $bathPath = trim($this->basePath, '\\/');
        switch (count($categoryList)) {
            case 1:
                return $this->getFullFileName("@app/{$bathPath}/{$language}", $categoryList[0]);
                break;
            case 2:
                return $this->getFullFileName("@app/modules/{$categoryList[0]}/{$bathPath}/{$language}", $categoryList[1]);
                break;
            case 3:
                return $this->getFullFileName("@app/modules/{$categoryList[0]}/modules/{$categoryList[1]}/{$bathPath}/{$language}", $categoryList[2]);
                break;
            default :
                throw new Exception("Invalid category name: '{$category}.");
                break;
        }
    }

    private function getFullFileName($path, $category)
    {
        $path = \Yii::getAlias($path);
        return isset($this->fileMap[$category])
            ? $path . $this->fileMap[$category]
            : $path . '/'.str_replace('\\', '/', $category) . '.php';
    }
}
Здесь все понятно. Путь к файлу формируется на основе полученного модуля и версии.
  • dictionary - вернет путь \app\messages\dictionary.php.
  • example_billing.dictionary - вернет путь \app\modules\example_billing\messages\dictionary.php. Для словарей, общих для все версий модуля.
  • example_billing.v1.dictionary - вернет путь \app\modules\example_billing\modules\v1\messages\dictionary.php.
Теперь мы можем получить перевод из любого модуля. Теперь для удобства добавим фасад, который будет автоматически подставлять id модуля и его активную версию:
namespace app\components;

use app\models\entities\Module as ModuleAr;
use yii\base\Exception;
use yii\helpers\Inflector;

abstract class MainModule extends Module
{
    public static function t($category, $message, $params = [], $language = null, $version = null)
    {
        $class = static::class;
        $id = Inflector::underscore(substr($class, strrpos($class, '\\') + 1));
        if ($version === null) {
            $version = ModuleAr::getActiveVersionIdByModuleId($id);
        }
        if ($version === null) {
            throw new Exception("Invalid module id: {$id}");
        }
        $category = "{$id}.{$version}.{$category}";
        return \Yii::t($category, $message, $params, $language);
    }
}
Примеры использования можно посмотреть в методе: \app\controllers\ExampleUserController::actionTestMessage().

Заключение

В этой статье мы разобрались с тем, как модули могут взаимодействовать друг с другом и не добавлять при этом зависимостей. А так же добавили модульности в механизм интернационализации. В следующей статье поговорим о работе с базой данных и модульных миграциях.

JavaScript learn

Чтобы вставить элемент после какого-то элемента, нужно создать прототип. Element.prototype.appendAfter = function (element) { element.paren...