Skip to content

Commit

Permalink
To support basics of entity management, http processing.
Browse files Browse the repository at this point in the history
  • Loading branch information
mostafabarmshory committed Feb 18, 2021
1 parent 4623951 commit ae9ffdb
Show file tree
Hide file tree
Showing 12 changed files with 311 additions and 13 deletions.
14 changes: 14 additions & 0 deletions src/Exception/InvalidArgumentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
namespace Pluf\Core\Exception;

use Pluf\Orm\Attribute\Entity;
use Pluf\Orm\Attribute\Column;
use Pluf\Orm\Attribute\Transients;
use Throwable;

#[Entity]
#[Transients(["line", "file", "string", "trace", "previous"])]
class InvalidArgumentException extends \Pluf\Core\Exception
{
}

7 changes: 7 additions & 0 deletions src/Exception/InvalidBodyContentException.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
<?php
namespace Pluf\Core\Exception;

use Pluf\Orm\Attribute\Entity;
use Pluf\Orm\Attribute\Column;
use Pluf\Orm\Attribute\Transients;
use Throwable;

#[Entity]
#[Transients(["line", "file", "string", "trace", "previous"])]
class InvalidBodyContentException extends \Pluf\Core\Exception
{
}
Expand Down
14 changes: 14 additions & 0 deletions src/Exception/NotSupportedMethodException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
namespace Pluf\Core\Exception;

use Pluf\Orm\Attribute\Entity;
use Pluf\Orm\Attribute\Column;
use Pluf\Orm\Attribute\Transients;
use Throwable;

#[Entity]
#[Transients(["line", "file", "string", "trace", "previous"])]
class NotSupportedMethodException extends \Pluf\Core\Exception
{
}

6 changes: 6 additions & 0 deletions src/Exception/ResourceNotFoundException.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
<?php
namespace Pluf\Core\Exception;


use Pluf\Orm\Attribute\Entity;
use Pluf\Orm\Attribute\Column;
use Pluf\Orm\Attribute\Transients;
use Throwable;

#[Entity]
#[Transients(["line", "file", "string", "trace", "previous"])]
class ResourceNotFoundException extends \Pluf\Core\Exception
{

Expand Down
5 changes: 5 additions & 0 deletions src/Exception/UnhandledException.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
<?php
namespace Pluf\Core\Exception;

use Pluf\Orm\Attribute\Entity;
use Pluf\Orm\Attribute\Column;
use Pluf\Orm\Attribute\Transients;
use Throwable;

#[Entity]
#[Transients(["line", "file", "string", "trace", "previous"])]
class UnhandledException extends \Pluf\Core\Exception
{

Expand Down
40 changes: 40 additions & 0 deletions src/Process/Entity/CreateEntities.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
namespace Pluf\Core\Process\Entity;

use Pluf\Orm\EntityManager;

/**
* Creates a list of customer and return them as result
*
*
* @author maso
*
*/
class CreateEntities
{

/**
* Store list of cusomers into the repositoer
*
*
* @param EntityManager $entityManager
* @param array $customers
* list of customer
* @return mixed[] list of entities to persist
*/
public function __invoke(EntityManager $entityManager, $entities): array
{
if (! is_array($entities)) {
$entities = [
$entities
];
}
$resultList = [];
foreach ($entities as $customer) {
$item = $entityManager->persist​($customer);
$resultList[] = $item;
}
return $resultList;
}
}

21 changes: 21 additions & 0 deletions src/Process/Entity/EntityManagerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
namespace Pluf\Core\Process\Entity;

use Pluf\Scion\UnitTrackerInterface;

class EntityManagerFactory
{

public function __invoke(\Pluf\Orm\EntityManagerFactory $entityManagerFactory, UnitTrackerInterface $unitTracker)
{
$entityManager = $entityManagerFactory->createEntityManager();
try {
return $unitTracker->next([
"entityManager" => $entityManager
]);
} finally {
$entityManager->close();
}
}
}

27 changes: 27 additions & 0 deletions src/Process/Entity/EntityManagerTransaction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
namespace Pluf\Core\Process\Entity;

use Pluf\Scion\UnitTrackerInterface;
use Throwable;
use Pluf\Orm\EntityManager;

class EntityManagerTransaction
{

public function __invoke(EntityManager $entityManager, UnitTrackerInterface $unitTracker)
{
$transaction = $entityManager->getTransaction();
$transaction->begin();
try {
$result = $unitTracker->next([
"entityManager" => $entityManager
]);
$transaction->commit();
return $result;
} catch (Throwable $th) {
$transaction->rollback();
throw $th;
}
}
}

35 changes: 35 additions & 0 deletions src/Process/Entity/ReadEntities.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
namespace Pluf\Core\Process\Entity;

use Pluf\Orm\AssertionTrait;
use Pluf\Orm\EntityQuery;

class ReadEntities
{
use AssertionTrait;

private string $class;
private string $name = "entities";

public function __construct(string $class, string $name = "entities")
{
$this->class = $class;
$this->name = $name;
}

/**
* Store list of cusomers into the repositoer
*
*
* @param EntityQuery $entityQuery to perform on entities
* @return array of results
*/
public function __invoke(EntityQuery $entityQuery): array
{
return $entityQuery->entity($this->class)
->mode('select')
->exec();
}

}

27 changes: 27 additions & 0 deletions src/Process/Http/RequestToEntityQuery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
namespace Pluf\Core\Process\Http;

use Pluf\Orm\EntityManager;
use Pluf\Scion\UnitTrackerInterface;
use Psr\Http\Message\ServerRequestInterface;

/**
* Creates an entity query based on http request
*
* NOTE: the class must set.
*
* @author maso
*
*/
class RequestToEntityQuery
{
public function __invoke(ServerRequestInterface $request, EntityManager $entityManager, UnitTrackerInterface $unitTracker)
{
$entityQuery = $entityManager->createQuery();
//XXX: maso, 2021: read params from the request header.
return $unitTracker->next([
'entityQuery' => $entityQuery
]);
}
}

40 changes: 27 additions & 13 deletions src/Process/Http/ResponseBodyEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,10 @@ public function __invoke(
try {
$result = $unitTracker->next();
} catch (Throwable $t) {
if (! ($t instanceof Exception)) {
$ex = new Exception\UnhandledException(
message: $t->getMessage(),
previous: $t);
} else {
$ex = $t;
}
$status = $ex->getStatus();
// TODO: maso, 2021: enable exception json annotations
$result = [
'message' => $t->getMessage()
];
$result = $this->convertToSerializable($t);
$status = $result->getStatus();
}

// TODO: maso, 2021: support objectMapper
// $supportMime = $request->getHeader("Accepted");
$contentType = 'application/json';
Expand All @@ -67,5 +57,29 @@ public function __invoke(
->withHeader("Content-Type", $contentType)
->withBody($streamFactory->createStream($resultEncode));
}

public function convertToSerializable(Throwable $t){
if ($t instanceof Exception) {
return $t;
}
$message = $t->getMessage();
$params = [];
$solutions = [];
$previous = $t;
if($t instanceof \Pluf\Orm\Exception){
$params = $t->getParams();
$solutions = $t->getSolutions();
} else if($t instanceof \atk4\core\Exception){
$params = $t->getParams();
$solutions = $t->getSolutions();
}
return new Exception\UnhandledException(
status: 500,
code: $t->getCode(),
message: $t->getMessage(),
params: $params,
previous: $previous,
solutions: $solutions);
}
}

88 changes: 88 additions & 0 deletions src/Process/HttpBodyToEntities.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php
namespace Pluf\Core\Process;

use Pluf\Orm\ModelDescriptionRepository;
use Pluf\Orm\ObjectMapperBuilder;
use Pluf\Scion\UnitTrackerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Pluf\Orm\AssertionTrait;

class HttpBodyToEntities
{
use AssertionTrait;

private string $class;
private bool $multi;
private string $name = "entities";

public function __construct(string $class, bool $multi = true, string $name = "entities")
{
$this->class = $class;
$this->multi = $multi;
$this->name = $name;
}

public function __invoke(
ModelDescriptionRepository $modelDescriptionRepository,
ServerRequestInterface $request,
UnitTrackerInterface $unitTracker)
{
$this->assertEquals("POST", $request->getMethod(), "Unsupported method {{method}}", ["method" => $request->getMethod()]);

$type = $this->getContentType($request);
$this->assertNotEmpty($type, "Content type is not specified.");
switch ($type) {
case "json":
$data = $request->getBody();
break;
case "array":
default:
$data = $request->getParsedBody();
break;
}

$builder = new ObjectMapperBuilder();
$objectMapper = $builder->addType($type)
->setModelDescriptionRepository($modelDescriptionRepository)
->supportList($this->multi)
->build();

$res = [];
$res[$this->name] = $objectMapper->readValue($data, $this->class, $this->multi);
return $unitTracker->next($res);
}

public function getContentType(ServerRequestInterface $request): string
{
$contentTypes = $request->getHeader("Content-Type") ?? [];

$parsedContentType = 'application/json';
foreach ($contentTypes as $contentType) {
$fragments = explode(';', $contentType);
$parsedContentType = current($fragments);
}
$contentTypesWithParsedBodies = [
'application/json',
'application/xml',
'application/yml'
];

$type = null;
if (in_array($parsedContentType, $contentTypesWithParsedBodies)) {
switch ($parsedContentType) {
case 'application/json':
$type = "json";
break;
case 'application/xml':
case 'application/yml':
default:
$type = null;
}
} else {
$type = "array";
}

return $type;
}
}

0 comments on commit ae9ffdb

Please sign in to comment.