Задать вопрос
  • Разве Composer бесполезен в 2017?

    Ничему не научишься и никого не переубедишь.
    homer-run.gif
    Ответ написан
    1 комментарий
  • Смена страны привязки в Google Play

    seniorGDR
    @seniorGDR
    велопрограммист
    Решил эту проблему следующим образом.
    1) Идём https://wallet.google.com/manage/
    2) Заходим в настройки (иконка-шестерёнка в верхней правой части страницы)
    3) Редактируем "Домашний адрес"

    Далее, возможно опционально
    4) В меню слева выбираем "Адресная книга"
    5) Назначаем нужный адрес по умолчанию (Возможно сперва вам придётся его добавить)

    И, вуаля, всё работает. Даже кэш приложения чистить не нужно.
    Ответ написан
    5 комментариев
  • Yii: rules и очень много сценариев, в которых чёрт ногу сломит?

    XAKEPEHOK
    @XAKEPEHOK Автор вопроса
    Новое решение: отделить сценарии от правил валидации. Решил разом все свои проблемы

    Расширил ActiveRecord
    class ActiveRecord extends CActiveRecord {
      protected $modelRules = [];
    
      ...
    
      /**
       * @return array общие (базовые для модели) правила валидации, описанные в формате
       * array(
       *   'login' => array(
       *     ['required'],
       *     ['length', 'max' => 200]
       *   ),
       *   'firstName' => array(
       *     ['required'],
       *     ['length', 'max' => 200]
       *   ),
       * )
       */
      public function baseRules()
      {
        return array();
      }
    
      /**
       * @return array список сценариев с установленными правилами валидации для каждого сценария.
       * Правила валидации берутся из массива @see baseRules()
       * 'createUser' => ['login','firstName']
       * Существует возможность задать индивидуальные правила валидации для отдельного поля в заданном сценарии. Например:
       * 'createUser' => array(
       *   'login',
       *   'firstName' => array(
       *     '*', //можем унаследовать правила из @see baseRules()
       *     ['!required'], //можем удалить валидатор "required", указанный в @see baseRules() при наследовании правил
       *     ['in', 'range' => array('Alex','Jack','Sam','Jane')], //и добавляем новое правило
       *   ),
       * )
       */
      public function scenarioRules()
      {
        return array();
      }
    
      /**
       * Формирует валидатор в соотстветствии с требованиями Yii
       * @param $field string поле модели
       * @param $validator array массив с параметрами валидатора
       * @param $scenario string сценарий
       */
      protected function addBaseRule($field,$validator,$scenario)
      {
        $validatorName = [];
        preg_match('/^(!)?([^!]+)/',$validator[0],$validatorName);
        $validator[0] = $validatorName[2];
        $ruleKey = $field.'_'.$validator[0].'_'.$scenario;
    
        if (empty($validatorName[1])) {
          if (!empty($scenario)) $validator['on'] = $scenario;
          $validator[1] = $validator[0];
          $validator[0] = $field;
          $this->modelRules[$ruleKey] = $validator;
        } else unset($this->modelRules[$ruleKey]);
      }
    
      /**
       * Формирует валидатор в соотстветствии с требованиями Yii из массива @see baseRules()
       * @param $field string поле модели
       * @param $scenario string сценарий
       */
      protected function addBaseRules($field,$scenario)
      {
        $baseRules = $this->baseRules();
        if (isset($baseRules[$field])) foreach($baseRules[$field] as $validator) $this->addBaseRule($field,$validator,$scenario);
      }
    
      public function rules()
      {
        $this->modelRules = [];
        $scenarioRules = $this->scenarioRules();
        if (empty($scenarioRules)) $scenarioRules = [''];
        foreach ($scenarioRules as $scenario => $rules) {
          //Если сценариев нет, то устанавливаем общие для всех правила
          if ($scenario == 0 && empty($rules)) $rules = array_keys($this->baseRules());
          foreach ($rules as $field => $rule) {
            //Если в сценариях заданы правила
            if (is_array($rule)) {
              //Добавляем родительские правила, если есть «*»
              if (in_array('*',$rule)) $this->addBaseRules($field,$scenario);
              foreach ($rule as $validator) {
                //Проверяем, что правило не является маской. Т.е. «*»
                if (is_array($validator)) $this->addBaseRule($field,$validator,$scenario);
              }
            } else $this->addBaseRules($rule,$scenario);
          }
        }
        foreach ($this->modelRules as &$rule) uksort($rule,function($a,$b){
          if (is_numeric($a) && is_numeric($b) && $a>$b) return 1;
          return is_numeric($a) ? -1 : 1;
        });
        return $this->modelRules;
      }


    В итоге получил такую модель User
    class User extends CActiveRecord {
    
      public $currentPassword;
      public $retypePassword;
    
      pulbic function baseRules()
      {
        return array(
          'login' => array(
            array('required')
            array('length', 'max' => 80),
            array('unique'),
            array('match', 'pattern' => '~^[\da-zа-яёА-ЯЁ\.\-@_\+]+$~i'),
          ),
          'email' => array(
            array('length', 'max' => 200),
            array('unique'),
            array('email'),
            array('required'),
          ),
          'password' => array(
            array('required'),
          ),
          'currentPassword' => array(
            array('required'),
            array('passwordValidator'),
          ),
          'retypePassword' => array(
            array('required'),
            array('compare','compareAttribute' => 'password'),
          ),
          'phone' => array(
            array('length', 'max' => 12),
          ),
          'icq' => array(
            array('length', 'max' => 9),
          ),
        );
      }
    
      pulbic function scenarios()
      {
        return array(
          'registration' => array('login','email','icq','phone'),
          'updateByAdmin' => array(
            'login',
            'email',
            'icq',
            'phone',
            'password' => array(
              array('default'),
            )
          ),
          'updateByModerator' => array('email','icq','phone'),
          'changeEmail' => array('email','currentPassword'),
          'changePassword' => array('password','retypePassword','currentPassword'),
        );
      }
    }


    Расширенный AR формирует типичный для Yii массив rules, используя данные из методов scenarios() и baseRules()
    Ответ написан
    Комментировать