Metadata/Resource/MiningTools.php
<?php
/**
* @copyright 2014 Integ S.A.
* @license http://opensource.org/licenses/MIT The MIT License (MIT)
* @author Javier Lorenzana <javier.lorenzana@gointegro.com>
*/
namespace GoIntegro\Hateoas\Metadata\Resource;
// Interfaces.
use GoIntegro\Hateoas\JsonApi\ResourceEntityInterface;
// Metadata.
use GoIntegro\Hateoas\Metadata\Entity\MetadataCache;
// Datos.
use GoIntegro\Hateoas\Util\Inflector;
// ORM.
use Doctrine\ORM\Mapping\ClassMetadata;
// Reflexión.
use GoIntegro\Hateoas\Util\Reflection;
// Recursos.
use GoIntegro\Hateoas\JsonApi\EntityResource;
// Excepciones.
use Exception;
trait MiningTools
{
/**
* @var array
* @see http://jsonapi.org/format/#document-structure-resource-object-attributes
*/
private static $reservedGetters = ["getId", "getType", "getHref", "getLinks"];
/**
* @param string|ResourceEntityInterface $entityClassName
* @return \ReflectionClass
* @todo Support searching through any number of parent classes?
*/
public function getResourceClass($entityClassName)
{
$className = MetadataMiner::DEFAULT_RESOURCE_CLASS;
$class = $this->metadataCache->getReflection($entityClassName);
$parentClass = $class->getParentClass();
$resourceClassName = $this->entityClassToResourceClass($class);
if (class_exists($resourceClassName)) {
$className = $resourceClassName;
} elseif (
!empty($parentClass)
&& $parentClass->implementsInterface(
MetadataMiner::RESOURCE_ENTITY_INTERFACE
)
) {
$resourceClassName
= $this->entityClassToResourceClass($parentClass);
if (class_exists($resourceClassName)) {
$className = $resourceClassName;
}
}
return $this->metadataCache->getReflection($className);
}
/**
* @param \ReflectionClass $class
* @return string
*/
protected function entityClassToResourceClass(\ReflectionClass $class)
{
$path = strtr($this->resourceClassPath, '/', '\\');
return str_replace('Entity', $path, $class->getName()) . 'Resource';
}
/**
* @param string|ResourceEntityInterface $entityClass
* @return string
*/
protected function parseSubtype($entityClassName)
{
$class = $this->metadataCache->getReflection($entityClassName);
return Inflector::typify($class->getShortName());
}
/**
* @param \GoIntegro\Hateoas\JsonApi\ResourceEntityInterface|string $entityClassName
* @param ResourceRelationships $relationships
* @return array
* @todo Publicar o eliminar el parámetro $entityClassName.
*/
protected function getFields(
$entityClassName,
ResourceRelationships $relationships
)
{
$fields = [];
$class = $this->metadataCache->getReflection($entityClassName);
foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
if (in_array($method->getShortName(), self::$reservedGetters)) {
continue;
}
if (Reflection::isMethodGetter($method)) {
$fields[] = Inflector::hyphenate(
substr($method->getShortName(), 3)
);
}
}
foreach (ResourceRelationships::$kinds as $kind) {
$fields = array_diff($fields, array_keys($relationships->$kind));
}
$fields = array_diff($fields, $relationships->dbOnly);
return new ResourceFields($fields);
}
}