partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

commit 74976fcd857538feb4a49875ddad79ab2a41e75f
parent af03bc935bcdb63e62f678af4138d2dd5655ca0d
Author: Felicitus <felicitus@felicitus.org>
Date:   Wed,  4 Nov 2015 16:12:56 +0100

Added support for the VirtualField annotation, refactored service into smaller methods

Diffstat:
Asrc/PartKeepr/DoctrineReflectionBundle/Annotation/VirtualField.php | 16++++++++++++++++
Msrc/PartKeepr/DoctrineReflectionBundle/Services/ReflectionService.php | 170+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
2 files changed, 143 insertions(+), 43 deletions(-)

diff --git a/src/PartKeepr/DoctrineReflectionBundle/Annotation/VirtualField.php b/src/PartKeepr/DoctrineReflectionBundle/Annotation/VirtualField.php @@ -0,0 +1,16 @@ +<?php +namespace PartKeepr\DoctrineReflectionBundle\Annotation; + +use Doctrine\ORM\Mapping\Annotation; + +/** + * @Annotation + * @Target("PROPERTY") + */ +final class VirtualField implements Annotation +{ + /** + * @var string + */ + public $type; +} diff --git a/src/PartKeepr/DoctrineReflectionBundle/Services/ReflectionService.php b/src/PartKeepr/DoctrineReflectionBundle/Services/ReflectionService.php @@ -44,9 +44,16 @@ class ReflectionService return $entities; } + /** + * Returns the ExtJS Model contents for a given entity + * + * @param $entity string The ExtJS class name + * + * @return string The ExtJS model code + */ public function getEntity($entity) { - $bIsTree = false; + $bTree = false; $parentClass = "PartKeepr.data.HydraModel"; @@ -54,31 +61,59 @@ class ReflectionService $cm = $this->em->getClassMetadata($entity); - if ($cm->getReflectionClass()->isSubclassOf("PartKeepr\CategoryBundle\Entity\AbstractCategory")) { $parentClass = "PartKeepr.data.HydraTreeModel"; - $bIsTree = true; + $bTree = true; } - $fields = $cm->getFieldNames(); - $fieldMappings = array(); - foreach ($fields as $field) { - $currentMapping = $cm->getFieldMapping($field); + $fieldMappings = array_merge($fieldMappings, $this->getVirtualFieldMappings($cm)); + $fieldMappings = array_merge($fieldMappings, $this->getDatabaseFieldMappings($cm)); - if ($currentMapping["fieldName"] == "id") { - $currentMapping["fieldName"] = "@id"; - $currentMapping["type"] = "string"; - } + $associationMappings = $this->getDatabaseAssociationMappings($cm, $bTree); - $fieldMappings[] = array( - "name" => $currentMapping["fieldName"], - "type" => $this->getExtJSFieldMapping($currentMapping["type"]), - ); + $renderParams = array( + "fields" => $fieldMappings, + "associations" => $associationMappings, + "className" => $this->convertPHPToExtJSClassName($entity), + "parentClass" => $parentClass, + ); + + $targetService = $this->reader->getClassAnnotation( + $cm->getReflectionClass(), + "PartKeepr\DoctrineReflectionBundle\Annotation\TargetService" + ); + + if ($targetService !== null) { + $renderParams["uri"] = $targetService->uri; } + $ignoreIds = $this->reader->getClassAnnotation( + $cm->getReflectionClass(), + "PartKeepr\DoctrineReflectionBundle\Annotation\IgnoreIds" + ); + + if ($ignoreIds !== null) { + $renderParams["ignoreIds"] = true; + } else { + $renderParams["ignoreIds"] = false; + } + + return $this->templateEngine->render('PartKeeprDoctrineReflectionBundle::model.js.twig', $renderParams); + } + + /** + * Returns association mapping for a given entity + * + * @param ClassMetadata $cm + * @param bool|false $bTree + * + * @return array + */ + protected function getDatabaseAssociationMappings(ClassMetadata $cm, $bTree = false) + { $associations = $cm->getAssociationMappings(); $associationMappings = array(); @@ -108,10 +143,10 @@ class ReflectionService $getter = "get".ucfirst($association["fieldName"]); $getterField = lcfirst($cm->getReflectionClass()->getShortName()).str_replace( - ".", - "", - $this->convertPHPToExtJSClassName($association["targetEntity"]) - ); + ".", + "", + $this->convertPHPToExtJSClassName($association["targetEntity"]) + ); if ($getterPlural) { $getterField .= "s"; @@ -120,7 +155,7 @@ class ReflectionService // The self-referencing association may not be written for trees, because ExtJS can't load all nodes // in one go. - if (!($bIsTree && $association["targetEntity"] == $entity)) { + if (!($bTree && $association["targetEntity"] == $cm->getName())) { $associationMappings[$associationType][] = array( "name" => $association["fieldName"], "target" => $this->convertPHPToExtJSClassName($association["targetEntity"]), @@ -130,36 +165,73 @@ class ReflectionService } } - $renderParams = array( - "fields" => $fieldMappings, - "associations" => $associationMappings, - "className" => $this->convertPHPToExtJSClassName($entity), - "parentClass" => $parentClass, - ); + return $associationMappings; + } - $targetService = $this->reader->getClassAnnotation( - $cm->getReflectionClass(), - "PartKeepr\DoctrineReflectionBundle\Annotation\TargetService" - ); + /** + * Returns all virtual field mappings + * + * @param ClassMetadata $cm + * + * @return array + */ + protected function getVirtualFieldMappings(ClassMetadata $cm) + { + $fieldMappings = array(); - if ($targetService !== null) { - $renderParams["uri"] = $targetService->uri; + foreach ($cm->getReflectionClass()->getProperties() as $property) { + $virtualFieldAnnotation = $this->reader->getPropertyAnnotation( + $property, + 'PartKeepr\DoctrineReflectionBundle\Annotation\VirtualField' + ); + + if ($virtualFieldAnnotation !== null) { + $fieldMappings[] = array( + "name" => $property->getName(), + "type" => $this->getExtJSFieldMapping($virtualFieldAnnotation->type), + ); + } } - $ignoreIds = $this->reader->getClassAnnotation( - $cm->getReflectionClass(), - "PartKeepr\DoctrineReflectionBundle\Annotation\IgnoreIds" - ); + return $fieldMappings; + } - if ($ignoreIds !== null) { - $renderParams["ignoreIds"] = true; - } else { - $renderParams["ignoreIds"] = false; + /** + * Returns database field mappings + * + * @param ClassMetadata $cm + * + * @return array + * @throws \Doctrine\ORM\Mapping\MappingException + */ + protected function getDatabaseFieldMappings(ClassMetadata $cm) + { + $fieldMappings = array(); + $fields = $cm->getFieldNames(); + + foreach ($fields as $field) { + $currentMapping = $cm->getFieldMapping($field); + + if ($currentMapping["fieldName"] == "id") { + $currentMapping["fieldName"] = "@id"; + $currentMapping["type"] = "string"; + } + + $fieldMappings[] = array( + "name" => $currentMapping["fieldName"], + "type" => $this->getExtJSFieldMapping($currentMapping["type"]), + ); } - return $this->templateEngine->render('PartKeeprDoctrineReflectionBundle::model.js.twig', $renderParams); + return $fieldMappings; } + /** + * Converts a doctrine/PHP type to the ExtJS type + * @param $type string the PHP/doctrine type + * + * @return string The ExtJS type + */ protected function getExtJSFieldMapping($type) { switch ($type) { @@ -192,17 +264,29 @@ class ReflectionService return "undefined"; } + /** + * Converts a PHP class name with namespaces to an ExtJS class name with namespaces + * @param $className + * + * @return string + */ protected function convertPHPToExtJSClassName($className) { return str_replace("\\", ".", $className); } + /** + * Converts an ExtJS class name with namespaces to a PHP class name with namespaces + * @param $className + * + * @return string + */ protected function convertExtJSToPHPClassName($className) { return str_replace(".", "\\", $className); } - public function createCache ($cacheDir) + public function createCache($cacheDir) { @mkdir($cacheDir, 0777, true); @@ -216,7 +300,7 @@ class ReflectionService } - protected function writeCacheFile($file, $content) + protected function writeCacheFile($file, $content) { $tmpFile = tempnam(dirname($file), basename($file)); if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {