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:
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)) {