Разбираюсь с проектирование приложения на yii2. Решил отказаться от ActiveRecord (разве что для админки оставить) и разделить всё по слоям.
Интерфейс модели пользователя
<?php
namespace app\core\models\user;
use app\core\models\city\CityInterface;
use app\core\models\country\CountryInterface;
interface UserInterface
{
/**
* Возвращает ID пользователя
* @return integer
*/
public function getId();
/**
* Устанавливает ID пользователя
* @param $id
*/
public function setId($id);
/**
* Возвращает имя
* @return string
*/
public function getFirstName();
/**
* Возвращает фамилию
* @return string
*/
public function getLastName();
/**
* Возвращает отчество
* @return string
*/
public function getPatronymic();
/**
* Возвращает город
* @return CityInterface
*/
public function getCity();
/**
* Возвращает страну
* @return CountryInterface
*/
public function getCountry();
/**
* Возвращает дату регистрации пользователя
* @return \DateTime
*/
public function getRegistrationDate();
/**
* Возвращает email
* @return string
*/
public function getEmail();
/**
* Возвращает установленный пароль
* @return string
*/
public function getPassword();
/**
* @param $firstName string Устанвалвивет имя пользователя
*/
public function setFirstName($firstName);
/**
* @param $lastName string Устанавливает фамилию пользователя
*/
public function setLastName($lastName);
/**
* @param $patronymic string Устанавливает отчество пользователя
*/
public function setPatronymic($patronymic);
/**
* @param $email string Устанавливает email пользователя
*/
public function setEmail($email);
/**
* @param $password string Устанаваливает пароль
*/
public function setPassword($password);
}
Реализация интерфейса пользователя
<?php
namespace app\core\models\user;
use yii\base\Model;
use yii\base\Object;
use app\core\models\city\CityInterface;
use app\core\models\country\CountryInterface;
class User extends Object implements UserInterface
{
/**
* @var $_id integer
*/
private $_id;
/**
* @var $_firstName string
*/
private $_firstName;
/**
* @var $_lastName string
*/
private $_lastName;
/**
* @var $_patronymic string
*/
private $_patronymic;
/**
* @var $_city CityInterface
*/
private $_city;
/**
* @var $_country CountryInterface
*/
private $_country;
/**
* @var $_registrationDate \DateTime
*/
private $_registrationDate;
/**
* @var $_email string
*/
private $_email;
/**
* @var $_password string
*/
private $_password;
/**
* Возвращает имя
* @return string
*/
public function getFirstName()
{
return $this->_firstName;
}
/**
* Возвращает фамилию
* @return string
*/
public function getLastName()
{
return $this->_lastName;
}
/**
* Возвращает отчество
* @return string
*/
public function getPatronymic()
{
return $this->_patronymic;
}
/**
* Возвращает город
* @return CityInterface
*/
public function getCity()
{
return $this->_city;
}
/**
* Возвращает страну
* @return CountryInterface
*/
public function getCountry()
{
return $this->_country;
}
/**
* Возвращает дату регистрации пользователя
* @return \DateTime
*/
public function getRegistrationDate()
{
return $this->_registrationDate;
}
/**
* Возвращает email
* @return string
*/
public function getEmail()
{
return $this->_email;
}
/**
* @param $firstName string Устанвалвивет имя пользователя
*/
public function setFirstName($firstName)
{
$this->_firstName = $firstName;
}
/**
* @param $lastName string Устанавливает фамилию пользователя
*/
public function setLastName($lastName)
{
$this->_lastName = $lastName;
}
/**
* @param $patronymic string Устанавливает отчество пользователя
*/
public function setPatronymic($patronymic)
{
$this->_patronymic = $patronymic;
}
/**
* @param $email string Устанавливает email пользователя
*/
public function setEmail($email)
{
$this->_email = $email;
}
/**
* @param $password string Устанаваливает пароль
*/
public function setPassword($password)
{
$this->_password = $password;
}
/**
* Возвращает ID пользователя
* @return integer
*/
public function getId()
{
return $this->_id;
}
/**
* Устанавливает ID пользователя
* @param $id
*/
public function setId($id)
{
$this->_id = $id;
}
}
И есть сервис для этой модели.
Интерфейс сервиса модели юзера
namespace app\core\models\user;
interface UserServiceInterface
{
/**
* Возвращает пользователя по его ID
* @param $id integer ID пользователя
* @return UserInterface
*/
public function findById($id);
/**
* Возвращает пользователя по его E-mail
* @param $email string Email пользователя
* @return UserInterface
*/
public function findByEmail($email);
/**
* Возвращает всех пользователей
* @return UserInterface[]
*/
public function findAll();
/**
* Сохраняет пользователя
* @param UserInterface $user
*
*/
public function save(UserInterface $user);
/**
* Удаляет пользователя
* @param UserInterface $user
*/
public function delete(UserInterface $user);
}
и реализация этого интерфейса сервиса
<?php
namespace app\core\models\user;
use yii\db\Command;
use yii\db\Query;
class UserService implements UserServiceInterface
{
/**
* Возвращает пользователя по его ID
* @param $id integer ID пользователя
* @return UserInterface
*/
public function findById($id)
{
return $this->findOneByAttribute('id', $id);
}
/**
* Возвращает пользователя по его E-mail
* @param $email string Email пользователя
* @return UserInterface
*/
public function findByEmail($email)
{
return $this->findOneByAttribute('email', $email);
}
/**
* Возвращает всех пользователей
* @return UserInterface[]
*/
public function findAll()
{
$query = new Query();
$rows = $query->all();
$users = [];
foreach ($rows as $row) {
$users = $this->load($row);
}
return $users;
}
/**
* Сохраняет пользователя
* @param UserInterface $user
*
*/
public function save(UserInterface $user)
{
$command = new Command();
$columns = [
'first_name' => $user->getFirstName(),
'last_name' => $user->getLastName(),
'patronymic' => $user->getPatronymic(),
'email' => $user->getEmail(),
];
if ($user->getPassword() != null) {
$columns['password_hash'] = \Yii::$app->security->generatePasswordHash($user->getPassword());
}
if ($user->getId() == null) {
$command->insert(UserActiveRecord::tableName(), $columns);
$user->setId(\Yii::$app->db->getLastInsertID());
} else {
$command->update(UserActiveRecord::tableName(), $columns, ['id' => $user->getId()]);
}
}
/**
* Удаляет пользователя
* @param UserInterface $user
*/
public function delete(UserInterface $user)
{
$command = new Command();
$command->delete(UserActiveRecord::tableName(), ['id' => $user->getId()]);
}
private function load($result)
{
$user = new User();
$user->setId($result['id']);
$user->setEmail($result['email']);
$user->setFirstName($result['first_name']);
return $user;
}
private function findOneByAttribute($attribute, $value)
{
$query = new Query();
$row = $query->andWhere([$attribute => $value])->one();
if ($row) {
return $this->load($row);
} else {
return null;
}
}
}
Подскажите, в правильном ли я направлении двигаюсь? Не покидает чувство, что что-то не так :)