Skip to content

Commit

Permalink
Performance improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
nilportugues committed Oct 14, 2015
1 parent 1c50041 commit 0dc5cea
Showing 1 changed file with 120 additions and 54 deletions.
174 changes: 120 additions & 54 deletions src/Mapping/MappingFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,23 @@
*/
namespace NilPortugues\Api\Mapping;

use ReflectionClass;

/**
* Class MappingFactory.
*/
class MappingFactory
{
/**
* @var array
*/
private static $classProperties = [];

/**
* @param array $mappedClass
*
* @throws MappingException
*
* @return Mapping
*/
public static function fromArray(array &$mappedClass)
Expand All @@ -29,43 +38,10 @@ public static function fromArray(array &$mappedClass)
$mapping = new Mapping($className, $resourceUrl, $idProperties);
$mapping->setClassAlias((empty($mappedClass['alias'])) ? $className : $mappedClass['alias']);

if (false === empty($mappedClass['aliased_properties'])) {
$mapping->setPropertyNameAliases($mappedClass['aliased_properties']);
foreach (array_keys($mapping->getAliasedProperties()) as $propertyName) {
if (false === in_array($propertyName, self::getClassProperties($className), true)) {
throw new MappingException(
sprintf('Could not alias property %s in class %s because it does not exist.', $propertyName, $className)
);
}
}
}

if (false === empty($mappedClass['hide_properties'])) {
$mapping->setHiddenProperties($mappedClass['hide_properties']);
foreach ($mapping->getHiddenProperties() as $propertyName) {
if (false === in_array($propertyName, self::getClassProperties($className), true)) {
throw new MappingException(
sprintf('Could not hide property %s in class %s because it does not exist.', $propertyName, $className)
);
}
}
}

if (!empty($mappedClass['relationships'])) {
foreach ($mappedClass['relationships'] as $propertyName => $urls) {
if (false === in_array($propertyName, self::getClassProperties($className), true)) {
throw new MappingException(
sprintf('Could not find property %s in class %s because it does not exist.', $propertyName, $className)
);
}

$mapping->setRelationshipUrls($propertyName, $urls);
}
}

if (false === empty($mappedClass['curies'])) {
$mapping->setCuries($mappedClass['curies']);
}
self::setAliasedProperties($mappedClass, $mapping, $className);
self::setHideProperties($mappedClass, $mapping, $className);
self::setRelationships($mappedClass, $mapping, $className);
self::setCuries($mappedClass, $mapping);

$otherUrls = self::getOtherUrls($mappedClass);
if (!empty($otherUrls)) {
Expand Down Expand Up @@ -122,17 +98,28 @@ private static function getIdProperties(array &$mappedClass)
}

/**
* @param array $mappedClass
* @param array $mappedClass
* @param Mapping $mapping
* @param string $className
*
* @return mixed
* @throws MappingException
*/
private static function getOtherUrls(array $mappedClass)
protected static function setAliasedProperties(array &$mappedClass, Mapping $mapping, $className)
{
if (!empty($mappedClass['urls']['self'])) {
unset($mappedClass['urls']['self']);
if (false === empty($mappedClass['aliased_properties'])) {
$mapping->setPropertyNameAliases($mappedClass['aliased_properties']);
foreach (array_keys($mapping->getAliasedProperties()) as $propertyName) {
if (false === in_array($propertyName, self::getClassProperties($className), true)) {
throw new MappingException(
sprintf(
'Could not alias property %s in class %s because it does not exist.',
$propertyName,
$className
)
);
}
}
}

return $mappedClass['urls'];
}

/**
Expand All @@ -147,20 +134,99 @@ private static function getOtherUrls(array $mappedClass)
*/
private static function getClassProperties($className)
{
$ref = new \ReflectionClass($className);
$properties = array();
foreach ($ref->getProperties() as $prop) {
$f = $prop->getName();
$properties[$f] = $prop;
if (empty(self::$classProperties[$className])) {
$ref = new ReflectionClass($className);
$properties = [];
foreach ($ref->getProperties() as $prop) {
$f = $prop->getName();
$properties[$f] = $prop;
}

if ($parentClass = $ref->getParentClass()) {
$parentPropsArr = self::getClassProperties($parentClass->getName());
if (count($parentPropsArr) > 0) {
$properties = array_merge($parentPropsArr, $properties);
}
}
self::$classProperties[$className] = array_keys($properties);
}

return self::$classProperties[$className];
}

/**
* @param array $mappedClass
* @param Mapping $mapping
* @param string $className
*
* @throws MappingException
*/
protected static function setHideProperties(array &$mappedClass, Mapping $mapping, $className)
{
if (false === empty($mappedClass['hide_properties'])) {
$mapping->setHiddenProperties($mappedClass['hide_properties']);
foreach ($mapping->getHiddenProperties() as $propertyName) {
if (false === in_array($propertyName, self::getClassProperties($className), true)) {
throw new MappingException(
sprintf(
'Could not hide property %s in class %s because it does not exist.',
$propertyName,
$className
)
);
}
}
}
}

/**
* @param array $mappedClass
* @param Mapping $mapping
* @param string $className
*
* @throws MappingException
*/
protected static function setRelationships(array &$mappedClass, Mapping $mapping, $className)
{
if (!empty($mappedClass['relationships'])) {
foreach ($mappedClass['relationships'] as $propertyName => $urls) {
if (false === in_array($propertyName, self::getClassProperties($className), true)) {
throw new MappingException(
sprintf(
'Could not find property %s in class %s because it does not exist.',
$propertyName,
$className
)
);
}

if ($parentClass = $ref->getParentClass()) {
$parentPropsArr = self::getClassProperties($parentClass->getName());
if (count($parentPropsArr) > 0) {
$properties = array_merge($parentPropsArr, $properties);
$mapping->setRelationshipUrls($propertyName, $urls);
}
}
}

/**
* @param array $mappedClass
* @param Mapping $mapping
*/
protected static function setCuries(array &$mappedClass, Mapping $mapping)
{
if (false === empty($mappedClass['curies'])) {
$mapping->setCuries($mappedClass['curies']);
}
}

/**
* @param array $mappedClass
*
* @return mixed
*/
private static function getOtherUrls(array $mappedClass)
{
if (!empty($mappedClass['urls']['self'])) {
unset($mappedClass['urls']['self']);
}

return array_keys($properties);
return $mappedClass['urls'];
}
}

0 comments on commit 0dc5cea

Please sign in to comment.