-
-
Save dzentota/99513928239bb7187750dc82240441cf to your computer and use it in GitHub Desktop.
ActiveRecord based Repository in Yii2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace app\repositories; | |
use app\entities\Employee\Address; | |
use app\entities\Employee\Employee; | |
use app\entities\Employee\EmployeeId; | |
use app\entities\Employee\Name; | |
use app\entities\Employee\Phone; | |
use app\entities\Employee\Phones; | |
use app\entities\Employee\Status; | |
use app\models\ArEmployeePhones; | |
use app\models\ArEmployees; | |
use ProxyManager\Factory\LazyLoadingValueHolderFactory; | |
use ProxyManager\Proxy\LazyLoadingInterface; | |
use Ramsey\Uuid\Uuid; | |
use yii\helpers\Json; | |
class ArEmployeeRepository implements EmployeeRepository | |
{ | |
private $hydrator; | |
private $lazyFactory; | |
public function __construct( | |
// ArEmployees $ar, | |
Hydrator $hydrator, | |
LazyLoadingValueHolderFactory $lazyFactory | |
) | |
{ | |
$this->hydrator = $hydrator; | |
$this->lazyFactory = $lazyFactory; | |
} | |
public function get(EmployeeId $id) | |
{ | |
$employee = ArEmployees::findOne($id->getId()); | |
if (!$employee) { | |
throw new NotFoundException('Employee not found.'); | |
} | |
return $this->hydrator->hydrate(Employee::class, [ | |
'id' => new EmployeeId($employee->employee_id), | |
'name' => new Name( | |
$employee->employee_name_last, | |
$employee->employee_name_first, | |
$employee->employee_name_middle | |
), | |
'address' => new Address( | |
$employee->employee_address_country, | |
$employee->employee_address_region, | |
$employee->employee_address_city, | |
$employee->employee_address_street, | |
$employee->employee_address_house | |
), | |
'createDate' => new \DateTimeImmutable($employee->employee_create_date), | |
'phones' => $this->lazyFactory->createProxy( | |
Phones::class, | |
function (&$target, LazyLoadingInterface $proxy) use ($employee) { | |
$target = new Phones(array_map(function ($phone) { | |
return new Phone( | |
$phone->phone_country, | |
$phone->phone_code, | |
$phone->phone_number | |
); | |
}, $employee->arEmployeePhones)); | |
$proxy->setProxyInitializer(null); | |
} | |
), | |
'statuses' => array_map(function ($status) { | |
return new Status( | |
$status['value'], | |
new \DateTimeImmutable($status['date']) | |
); | |
}, Json::decode($employee->employee_statuses)), | |
]); | |
} | |
public function add(Employee $employee) | |
{ | |
$model = new ArEmployees(); | |
$row = self::extractEmployeeData($employee); | |
$model->attributes = $row; | |
$model->save(); | |
$this->updatePhones($employee, $model); | |
} | |
public function save(Employee $employee) | |
{ | |
$model = ArEmployees::findOne($employee->getId()->getId()); | |
if (!$model) { | |
throw new NotFoundException('Employee not found.'); | |
} | |
$row = self::extractEmployeeData($employee); | |
$model->attributes = $row; | |
$model->save(); | |
$this->updatePhones($employee, $model); | |
} | |
public function remove(Employee $employee) | |
{ | |
$model = ArEmployees::findOne($employee->getId()->getId()); | |
if (!$model) { | |
throw new NotFoundException('Employee not found.'); | |
} | |
$model->delete(); | |
//phones get removed due to foreign key | |
} | |
public function nextId() | |
{ | |
return new EmployeeId(Uuid::uuid4()->toString()); | |
} | |
private static function extractEmployeeData(Employee $employee) | |
{ | |
$statuses = $employee->getStatuses(); | |
return [ | |
'employee_id' => (string) $employee->getId()->getId(), | |
'employee_create_date' => (string) $employee->getCreateDate()->format('Y-m-d H:i:s'), | |
'employee_name_last' => (string) $employee->getName()->getLast(), | |
'employee_name_middle' => (string) $employee->getName()->getMiddle(), | |
'employee_name_first' => (string) $employee->getName()->getFirst(), | |
'employee_address_country' => (string) $employee->getAddress()->getCountry(), | |
'employee_address_region' => (string) $employee->getAddress()->getRegion(), | |
'employee_address_city' => (string) $employee->getAddress()->getCity(), | |
'employee_address_street' => (string) $employee->getAddress()->getStreet(), | |
'employee_address_house' => (string) $employee->getAddress()->getHouse(), | |
'employee_current_status' => (string) end($statuses)->getValue(), | |
'employee_statuses' => Json::encode(array_map(function (Status $status) { | |
return [ | |
'value' => $status->getValue(), | |
'date' => $status->getDate()->format(DATE_RFC3339), | |
]; | |
}, $statuses)), | |
]; | |
} | |
private function updatePhones(Employee $employee, ArEmployees $model) | |
{ | |
$data = $this->hydrator->extract($employee, ['phones']); | |
$phones = $data['phones']; | |
if ($phones instanceOf LazyLoadingInterface && !$phones->isProxyInitialized()) { | |
return; | |
} | |
$model->unlinkAll('arEmployeePhones', true); | |
if ($phones = $employee->getPhones()) { | |
array_map(function (Phone $phone) use ($model) { | |
$employeePhone = new ArEmployeePhones(); | |
$employeePhone->phone_country = $phone->getCountry(); | |
$employeePhone->phone_code = $phone->getCode(); | |
$employeePhone->phone_number = $phone->getNumber(); | |
$employeePhone->link('phoneEmployee', $model); | |
}, $phones); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment