private function createProxy(GraphElement $meta)
    {
        //Get the proxy class name, as well as the regular class name
        $proxyClass = $meta->getProxyClass();
        $className = $meta->getName();

        //If the class already exists, just make an instance of it with the correct properties and return it.
        if(class_exists($proxyClass, false))
        {
            return $this->newInstance($proxyClass);
        }

        //Create a target file for the class
        $targetFile = "{$this->proxyDir}/$proxyClass.php";

        //If the file doesn't exist
        if($this->debug || !file_exists($targetFile))
        {
            //Initialize functions
            $functions = '';

            $reflectionClass = new \ReflectionClass($className);

            //Loop through entities public methods
            foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method)
            {
                //If the method isn't a constructor, destructor, or final, add it to the methods via method proxy.
                if(!$method->isConstructor() && !$method->isDestructor() && !$method->isFinal())
                {
                    $functions .= $this->methodProxy($method, $meta);
                }
            }

            //Get the properties and primary key.
            $properties = $meta->getProperties();
            $properties[] = $meta->getPrimaryKey();

            //Filter out private properties
            $properties = array_filter($properties, function ($property) {
                return !$property->isPrivate();
            });

            //Create an array map by property name
            $properties = array_map(function ($property) {
                return $property->getName();
            }, $properties);

            //Create php code for properties.
            $properties = var_export($properties, true);

            //Create the actual class.
            $content = <<<CONTENT
<?php

class $proxyClass extends $className implements LRezek\\Arachnid\\Proxy\\Entity
{
    private \$neo4j_hydrated = array();
    private \$neo4j_meta;
    private \$neo4j_entity;
    private \$neo4j_loadCallback;

    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 __setEntity(\$entity)
    {
        \$this->neo4j_entity = \$entity;
    }

    function __getEntity()
    {
        return \$this->neo4j_entity;
    }

    function __setLoadCallback(\$loadCallback)
    {
        \$this->neo4j_loadCallback = \$loadCallback;
    }

    private function __load(\$name, \$propertyName)
    {
        //Already hydrated
        if(in_array(\$propertyName, \$this->neo4j_hydrated))
        {
            return;
        }

        if(! \$this->neo4j_meta)
        {
            throw new \\LRezek\\Arachnid\\Exception('Proxy not fully initialized.');
        }

        \$property = \$this->neo4j_meta->findProperty(\$name);

        if(strpos(\$name, 'set') === 0)
        {
            \$this->__addHydrated(\$propertyName);
            return;
        }

        //Make property node
        if(\$property->isStart() || \$property->isEnd())
        {
            \$loader = \$this->neo4j_loadCallback;

            //Get the node
            if(\$property->isStart())
            {
                \$node = \$this->neo4j_entity->getStartNode();
            }
            else
            {
                \$node = \$this->neo4j_entity->getEndNode();
            }

            \$node = \$loader(\$node);

            //Set the property
            \$property->setValue(\$this, \$node);
        }

        //Hydrate the property
        \$this->__addHydrated(\$propertyName);

    }

    function __sleep()
    {
        return $properties;
    }
}


CONTENT;

            //Make sure the proxy directory is an actual directory
            if(!is_dir($this->proxyDir))
            {
                if(false === @mkdir($this->proxyDir, 0775, true))
                {
                    throw new Exception('Proxy Dir is not writable.');
                }
            }

            //Make sure the directory is writable
            else if(!is_writable($this->proxyDir))
            {
                throw new Exception('Proxy Dir is not writable.');
            }

            //Write the file
            file_put_contents($targetFile, $content);
        }

        //Add file to class loader
        require $targetFile;

        //Return an instance of the proxy class
        return $this->newInstance($proxyClass);
    }
private function createProxy(GraphElement $meta)
    {
        //Get the proxy class name, as well as the regular class name
        $proxyClass = $meta->getProxyClass();
        $className = $meta->getName();

        //If the class already exists, just make an instance of it with the correct properties and return it.
        if(class_exists($proxyClass, false))
        {
            return $this->newInstance($proxyClass);
        }

        //Create a target file for the class
        $targetFile = "{$this->proxyDir}/$proxyClass.php";

        //If the file doesn't exist
        if($this->debug || !file_exists($targetFile))
        {
            //Initialize functions
            $functions = '';

            $reflectionClass = new \ReflectionClass($className);

            //Loop through entities public methods
            foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method)
            {
                //If the method isn't a constructor, destructor, or final, add it to the methods via method proxy.
                if(!$method->isConstructor() && !$method->isDestructor() && !$method->isFinal())
                {
                    $functions .= $this->methodProxy($method, $meta);
                }
            }

            //Get the properties and primary key.
            $properties = $meta->getProperties();
            $properties[] = $meta->getPrimaryKey();

            //Filter out private properties
            $properties = array_filter($properties, function ($property) {
                return !$property->isPrivate();
            });

            //Create an array map by property name
            $properties = array_map(function ($property) {
                return $property->getName();
            }, $properties);

            //Create php code for properties.
            $properties = var_export($properties, true);

            //Create the actual class.
            $content = <<<CONTENT
<?php

class $proxyClass extends $className implements LRezek\\Arachnid\\Proxy\\Entity
{
    private \$neo4j_hydrated = array();
    private \$neo4j_meta;
    private \$neo4j_entity;
    private \$neo4j_loadCallback;

    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 __setEntity(\$entity)
    {
        \$this->neo4j_entity = \$entity;
    }

    function __getEntity()
    {
        return \$this->neo4j_entity;
    }

    function __setLoadCallback(\$loadCallback)
    {
        \$this->neo4j_loadCallback = \$loadCallback;
    }

    private function __load(\$name, \$propertyName)
    {
        //Already hydrated
        if(in_array(\$propertyName, \$this->neo4j_hydrated))
        {
            return;
        }

        if(! \$this->neo4j_meta)
        {
            throw new \\LRezek\\Arachnid\\Exception('Proxy not fully initialized.');
        }

        \$property = \$this->neo4j_meta->findProperty(\$name);

        if(strpos(\$name, 'set') === 0)
        {
            \$this->__addHydrated(\$propertyName);
            return;
        }

        //Make property node
        if(\$property->isStart() || \$property->isEnd())
        {
            \$loader = \$this->neo4j_loadCallback;

            //Get the node
            if(\$property->isStart())
            {
                \$node = \$this->neo4j_entity->getStartNode();
            }
            else
            {
                \$node = \$this->neo4j_entity->getEndNode();
            }

            \$node = \$loader(\$node);

            //Set the property
            \$property->setValue(\$this, \$node);
        }

        //Hydrate the property
        \$this->__addHydrated(\$propertyName);

    }

    function __sleep()
    {
        return $properties;
    }
}


CONTENT;

            //Make sure the proxy directory is an actual directory
            if(!is_dir($this->proxyDir))
            {
                if(false === @mkdir($this->proxyDir, 0775, true))
                {
                    throw new Exception('Proxy Dir is not writable.');
                }
            }

            //Make sure the directory is writable
            else if(!is_writable($this->proxyDir))
            {
                throw new Exception('Proxy Dir is not writable.');
            }

            //Write the file
            file_put_contents($targetFile, $content);
        }

        //Add file to class loader
        require $targetFile;

        //Return an instance of the proxy class
        return $this->newInstance($proxyClass);
    }
private function createProxy ( GraphElement $ meta ) { //Get the proxy class name, as well as the regular class name $ proxyClass = $ meta -> getProxyClass ( ) ; $ className = $ meta -> getName ( ) ; //If the class already exists, just make an instance of it with the correct properties and return it. if ( class_exists ( $ proxyClass , false ) ) { return $ this -> newInstance ( $ proxyClass ) ; } //Create a target file for the class $ targetFile = "{$this->proxyDir}/$proxyClass.php" ; //If the file doesn't exist if ( $ this -> debug || ! file_exists ( $ targetFile ) ) { //Initialize functions $ functions = '' ; $ reflectionClass = new \ ReflectionClass ( $ className ) ; //Loop through entities public methods foreach ( $ reflectionClass -> getMethods ( \ ReflectionMethod :: IS_PUBLIC ) as $ method ) { //If the method isn't a constructor, destructor, or final, add it to the methods via method proxy. if ( ! $ method -> isConstructor ( ) && ! $ method -> isDestructor ( ) && ! $ method -> isFinal ( ) ) { $ functions .= $ this -> methodProxy ( $ method , $ meta ) ; } } //Get the properties and primary key. $ properties = $ meta -> getProperties ( ) ; $ properties [ ] = $ meta -> getPrimaryKey ( ) ; //Filter out private properties $ properties = array_filter ( $ properties , function ( $ property ) { return ! $ property -> isPrivate ( ) ; } ) ; //Create an array map by property name $ properties = array_map ( function ( $ property ) { return $ property -> getName ( ) ; } , $ properties ) ; //Create php code for properties. $ properties = var_export ( $ properties , true ) ; //Create the actual class. $ content =  <<<CONTENT
<?php

class $proxyClass extends $className implements LRezek\\Arachnid\\Proxy\\Entity
{
    private \$neo4j_hydrated = array();
    private \$neo4j_meta;
    private \$neo4j_entity;
    private \$neo4j_loadCallback;

    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 __setEntity(\$entity)
    {
        \$this->neo4j_entity = \$entity;
    }

    function __getEntity()
    {
        return \$this->neo4j_entity;
    }

    function __setLoadCallback(\$loadCallback)
    {
        \$this->neo4j_loadCallback = \$loadCallback;
    }

    private function __load(\$name, \$propertyName)
    {
        //Already hydrated
        if(in_array(\$propertyName, \$this->neo4j_hydrated))
        {
            return;
        }

        if(! \$this->neo4j_meta)
        {
            throw new \\LRezek\\Arachnid\\Exception('Proxy not fully initialized.');
        }

        \$property = \$this->neo4j_meta->findProperty(\$name);

        if(strpos(\$name, 'set') === 0)
        {
            \$this->__addHydrated(\$propertyName);
            return;
        }

        //Make property node
        if(\$property->isStart() || \$property->isEnd())
        {
            \$loader = \$this->neo4j_loadCallback;

            //Get the node
            if(\$property->isStart())
            {
                \$node = \$this->neo4j_entity->getStartNode();
            }
            else
            {
                \$node = \$this->neo4j_entity->getEndNode();
            }

            \$node = \$loader(\$node);

            //Set the property
            \$property->setValue(\$this, \$node);
        }

        //Hydrate the property
        \$this->__addHydrated(\$propertyName);

    }

    function __sleep()
    {
        return $properties;
    }
}


CONTENT ; //Make sure the proxy directory is an actual directory if ( ! is_dir ( $ this -> proxyDir ) ) { if ( false === @ mkdir ( $ this -> proxyDir , 0775 , true ) ) { throw new Exception ( 'Proxy Dir is not writable.' ) ; } } //Make sure the directory is writable else if ( ! is_writable ( $ this -> proxyDir ) ) { throw new Exception ( 'Proxy Dir is not writable.' ) ; } //Write the file file_put_contents ( $ targetFile , $ content ) ; } //Add file to class loader require $ targetFile ; //Return an instance of the proxy class return $ this -> newInstance ( $ proxyClass ) ; }
Creates a proxy class for a graph element.

This method will create a proxy class for an entity that extends the required class and implements
LRezek\Arachnid\Proxy\Entity. This class will be generated and stored in the directory specified by the $proxyDir
property of this class. This is done so that the object returned by a query seemingly matches the object type
being queried for, while retaining its ID and other required information.

@param GraphElement $meta The meta for the entity object being proxied.
@return mixed An instance of the proxy class.
@throws \LRezek\Arachnid\Exception If something goes wrong in file writing.
Creates a proxy class for a graph element .