2017-08-24 2 views
2

Je réfléchis à la façon de créer une application volumineuse pour un client dans Yii2. Mon expérience vient de plusieurs petits projets Yii2.Planification d'une grande application Yii2

Quelles sont les principales décisions qui doivent être prises au cours des premières étapes qui ne peuvent pas être modifiées plus tard facilement et quels sont les modèles de solution Yii2 typiques pour cela?

Voici quelques caractéristiques que je pense à:

Administration des utilisateurs

Un début de saut est l'extension Yii2 utilisateur ou Yii2-usario. Donne la gestion des utilisateurs, la connexion de l'utilisateur, les caractéristiques de réinitialisation de mot de passe et autres.

Multi-location

Pour gérer plusieurs clients dans une base de données, il est recommandé d'ajouter l'identifiant client à chaque table et utiliser les comportements Yii2 ajouter ce champ de table à chaque requête de base de données.

caractéristiques optionnelles/complexes

Yii2 prévoit la séparation de code "modules". Les modules Yii2 peuvent avoir des composants, des modèles, des vues, des contrôleurs, ... et sont parfaits pour fournir des fonctionnalités indépendantes à un stade ultérieur. Ou pour séparer les fonctionnalités de l'application principale.

Y a-t-il des modèles Yii2 similaires à savoir dès le début du projet afin d'éviter une refonte majeure du projet?

+0

est-il une bonne solution pour les manuels d'aide oder oniine intégrée? De préférence aider où un utilisateur peut faire des commentaires sur son propre chef? – WeSee

Répondre

2

Un important boniment disponible en Yii2 est pour moi le RBAC (Les accès d'autorisation par rôles) ..

Si la demande est grande souvenez vous pourriez avoir besoin internazionalization pour la date, la monnaie et formate et multilangue

audit pour vérifier qui l'accès à ce (il y a une bonne extension pour cela aussi)

+0

Pouvez-vous m'aider !! comment faire l'audit dans yii2 –

+0

je l'ai utilisé et est bon pour mon besoin https://github.com/bedezign/yii2-audit – scaisEdge

+0

J'utilise également la même extension, mais je suis nouvelle bie pour ce cadre, donc je ne peux pas obtenir comment pour utiliser ce –

1

à yii2, vous pouvez exécuter plusieurs applications d'un base de code. Le modèle avancé de yii2 vous donne un bon point de départ, mais vous pouvez avoir plus d'une application «frontend». Cela vous aidera à partager ou à diviser configurations (y compris les bases de données) pour vos interfaces. Ainsi, vous pouvez réutiliser des modules communs dans vos applicaions et avoir la liberté de faire quelque chose de complètement différent.

peut-être que c'est hors de portée, mais pour l'implémentation de la multi-location j'ai limité l'accès aux lignes de données aux membres du groupe uniquement via le comportement. Une clause where est automatiquement appliquée à toutes les sélections, de sorte que le client ne peut que renvoyer les lignes qu'il possède. dans votre code, vous pouvez maintenant faire des sélections et des jointures sans avoir à penser à la propriété.

ActiveRecord.php

<?php 
namespace common\models; 

use Yii; 
use yii\helpers\Url; 

class ActiveRecord extends \yii\db\ActiveRecord 
{ 

    public function behaviors() 
    { 
     return [ 
      'group' => [ 
       'class'  => \x1\data\behaviors\GroupBehavior::className(), 
       'map'  => ['gid' => 'group_id'], 
       'className' => \common\models\Group::className(), 
      ], 
     ]; 
    } 


    public static function checkAccess() { 
     if (!Yii::$app instanceof \yii\console\Application) { 
      $user  = Yii::$app->get('user', false); 
      $identity = ($user) ? $user->getIdentity() : null; 

      if (empty($identity)) { 
       if (!empty($user->loginUrl)) 
        return Yii::$app->getResponse()->redirect($user->loginUrl); 
       else 
        throw new \yii\web\UnauthorizedHttpException; 
      } 
     } 
    } 


    // 
    // select only rows within the user's group, 
    // except for console app 
    // 
    public static function find() { 
     self::checkAccess(); 
     return (new ActiveQuery(get_called_class()))->current(); 
    } 

} 

?> 

GroupBehaviour.php

<?php 
namespace x1\data\behaviors; 

use Yii; 
use yii\base\Event; 
use yii\db\BaseActiveRecord; 

/* 

class myModel extends \yii\db\ActiveRecord 
{ 

    public function behaviors() 
    { 
     return [ 
      'group' => [ 
       'class'  => \x1\data\behaviors\GroupBehavior::className(), 
       'map'  => ['gid' => 'group_id'], 
       'className' => \common\models\Group::className(), 
      ], 
     ]; 
    } 

} 

*/ 
class GroupBehavior extends \yii\behaviors\AttributeBehavior 
{ 
    public $map  = ['gid' => 'group_id']; 
    public $className = null; 
    public $value; 


    public function getGroup() { 
     return $this->owner->hasOne($this->className, $this->map); 
    } 


    /** 
    * @inheritdoc 
    */ 
    public function init() 
    { 
     parent::init(); 

     if ($this->className == null) { 
      throw new \yii\base\InvalidConfigException("'className' must be set"); 
     } 

     if (!is_array($this->map)) { 
      throw new \yii\base\InvalidConfigException("'map' must be an array; e.g.: ['gid' => 'group_id']"); 
     } else { 
      if (!count($this->map) > 0) { 
       throw new \yii\base\InvalidConfigException("'map' must contain the mapping group => local; e.g.: ['gid' => 'group_id']"); 
      } 
     } 

     if (!Yii::$app instanceof \yii\console\Application) { 
      if (empty($this->attributes)) { 
       $this->attributes = [ 
        BaseActiveRecord::EVENT_BEFORE_INSERT => array_values($this->map)[0], 
       ]; 
      } 
     } 
    } 

    /** 
    * Evaluates the value of the user. 
    * The return result of this method will be assigned to the current attribute(s). 
    * @param Event $event 
    * @return mixed the value of the user. 
    */ 
    protected function getValue($event) 
    { 
     if ($this->value === null) { 
      $user = Yii::$app->get('user', false); 
      $group = array_keys($this->map)[0]; 
      return ($user && !$user->isGuest) ? $user->identity->group->$group : null; 
     } else { 
      return call_user_func($this->value, $event); 
     } 
    } 

} 

ActiveQuery.php

<?php 
namespace common\models; 
use Yii; 

class ActiveQuery extends \yii\db\ActiveQuery 
{ 
    private $_alias = null; 

    private function getAlias() { 

     if ($this->_alias === null) { 

      if (empty($this->from)) { 
       $modelClass = $this->modelClass; 
       $tableName = $modelClass::tableName(); 
      } else { 
       foreach ($this->from as $alias => $tableName) { 
        if (is_string($alias)) { 
         $this->_alias = $alias; 
         return $this->_alias; 
        } else { 
         break; 
        } 
       } 
      } 

      if (preg_match('/^(.*?)\s+({{\w+}}|\w+)$/', $tableName, $matches)) { 
       $this->_alias = $matches[2]; 
      } else { 
       $this->_alias = $tableName; 
      } 

     } 
     return $this->_alias; 
    } 

    public function current() 
    { 
     $alias = $this->getAlias(); 

     if (!Yii::$app instanceof \yii\console\Application) 
      $this->andWhere(['IN', sprintf('COALESCE(%s.group_id,0)', $alias), [0, Yii::$app->user->identity->group_id]]); 

     return $this; 
    } 


    public function rawSql() { 
     return $this->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql; 
    } 

} 

?> 
+0

Merci. Mais wow, c'est beaucoup de code. Pourquoi ne pas simplement utiliser un petit comportement dans ActiveRecord qui vérifie si l'enregistrement appartient au tentant de l'utilisateur? – WeSee

+0

je ne pouvais pas trouver une solution plus simple - commentaires bienvenus. 1. étendre ActiveQuery pour ajouter automatiquement un filtre par client. 2. enregistrez cette ActiveQuery dans ActiveRecord. GroupBehaviour n'est peut-être pas nécessaire. –