Skip to content

Instantly share code, notes, and snippets.

@dzentota
Created May 9, 2017 18:58
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dzentota/99513928239bb7187750dc82240441cf to your computer and use it in GitHub Desktop.
Save dzentota/99513928239bb7187750dc82240441cf to your computer and use it in GitHub Desktop.
ActiveRecord based Repository in Yii2
<?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