/** * @param EntityManager $entityManager * @param Meta\Entity $meta */ public function __construct(EntityManager $entityManager, Meta\Entity $meta) { $this->entityManager = $entityManager; $this->class = $meta->getName(); $this->meta = $meta; }
/** * @param Meta $meta * @return Entity * @throws \HireVoice\Neo4j\Exception */ private function createProxy(Meta $meta) { $proxyClass = $meta->getProxyClass(); $className = $meta->getName(); if (class_exists($proxyClass, false)) { return $this->initializeProperties($this->newInstance($proxyClass), $meta); } $targetFile = "{$this->proxyDir}/{$proxyClass}.php"; if ($this->debug || !file_exists($targetFile)) { $functions = ''; $reflectionClass = new \ReflectionClass($className); foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { if (!$method->isConstructor() && !$method->isDestructor() && !$method->isFinal()) { $functions .= $this->methodProxy($method, $meta); } } $properties = $meta->getProperties(); $properties[] = $meta->getPrimaryKey(); $properties = array_filter($properties, function ($property) { return !$property->isPrivate(); }); $properties = array_map(function ($property) { return $property->getName(); }, $properties); $properties = var_export($properties, true); $content = <<<CONTENT <?php use HireVoice\\Neo4j\\Extension; use HireVoice\\Neo4j\\Extension\\ArrayCollection; class {$proxyClass} extends {$className} implements HireVoice\\Neo4j\\Proxy\\Entity { private \$neo4j_hydrated = array(); private \$neo4j_meta; private \$neo4j_node; private \$neo4j_loadCallback; private \$neo4j_relationships = false; private \$neo4j_initialized = false; function getEntity() { \$entity = new {$className}; foreach (\$this->neo4j_meta->getProperties() as \$prop) { \$prop->setValue(\$entity, \$prop->getValue(\$this)); } \$prop = \$this->neo4j_meta->getPrimaryKey(); \$prop->setValue(\$entity, \$prop->getValue(\$this)); return \$entity; } {$functions} function __addHydrated(\$name) { \$this->neo4j_hydrated[] = \$name; } function __setMeta(\$meta) { \$this->neo4j_meta = \$meta; } function __setNode(\$node) { \$this->neo4j_node = \$node; } function __getNode() { return \$this->neo4j_node; } function __setLoadCallback(\\Closure \$loadCallback) { \$this->neo4j_loadCallback = \$loadCallback; } public function __load() { \$this->neo4j_initialized = true; } public function __isInitialized() { return \$this->neo4j_initialized; } private function __loadProperty(\$name, \$propertyName) { if (in_array(\$propertyName, \$this->neo4j_hydrated)) { return; } if (! \$this->neo4j_meta) { throw new \\HireVoice\\Neo4j\\Exception('Proxy not fully initialized. Relations are not available when loading the object from a session or other forms of serialization.'); } \$property = \$this->neo4j_meta->findProperty(\$name); if (strpos(\$name, 'set') === 0) { \$this->__addHydrated(\$propertyName); return; } if (false === \$this->neo4j_relationships) { \$command = new Extension\\GetNodeRelationshipsLight(\$this->neo4j_node->getClient(), \$this->neo4j_node); \$this->neo4j_relationships = \$command->execute(); } \$this->__addHydrated(\$propertyName); \$collection = new ArrayCollection; foreach (\$this->neo4j_relationships as \$relation) { if (\$relation['type'] == \$propertyName) { // Read-only relations read the start node instead if (\$property->isTraversed()) { if( \$this->neo4j_meta->getRelation(\$propertyName)->getDirection() == 'from'){ \$nodeUrl = \$relation['end']; \$root = \$relation['start']; }else{ \$nodeUrl = \$relation['start']; \$root = \$relation['end']; } } else { \$nodeUrl = \$relation['start']; \$root = \$relation['end']; } if (basename(\$root) == \$this->getId()) { \$node = \$this->neo4j_node->getClient()->getNode(basename(\$nodeUrl)); \$loader = \$this->neo4j_loadCallback; \$collection->add(\$loader(\$node)); } } } if (\$property->isRelationList()) { \$property->setValue(\$this, \$collection); } else { if (count(\$collection)) { \$property->setValue(\$this, \$collection->first()); } } } function __sleep() { return {$properties}; } } CONTENT; if (!is_dir($this->proxyDir)) { if (false === @mkdir($this->proxyDir, 0775, true)) { throw new Exception('Proxy Dir is not writable'); } } else { if (!is_writable($this->proxyDir)) { throw new Exception('Proxy Dir is not writable'); } } file_put_contents($targetFile, $content); } require $targetFile; return $this->initializeProperties($this->newInstance($proxyClass), $meta); }