Parse class properties for metadata extraction if valid contains valid annotation local tag

@param ReflectionClass $reflectedClass The document reflected object to parse

@return array                            An array filled with Definition instance
422687
protected function processPropertiesParsing(\ReflectionClass $reflectedClass)
    {
        $metadata = array();

        $reflectedProperties = $reflectedClass->getProperties();

        foreach ($reflectedProperties as $reflectedProperty) {
            if ($this->isBoomgoProperty($reflectedProperty)) {
                $propertyMetadata = $this->parseMetadataProperty($reflectedProperty);
                $metadata['definitions'][$reflectedProperty->getName()] = $propertyMetadata;
            }
        }

        return $metadata;
    }
824348
private function keyPerEntityRequired(\ReflectionClass $reflectionClass)
    {
        $classMetadata = $this->getEncryptionMetadataFor($reflectionClass->getName());

        $keyPerEntityModes = array(
            EncryptionService::MODE_PER_USER_SHAREABLE,
            EncryptionService::MODE_SYSTEM_ENCRYPTION,
        );

        return $classMetadata->encryptionEnabled
            && in_array($classMetadata->encryptionMode, $keyPerEntityModes);
    }
776405
private function getPhpFileStmt(\ReflectionClass $class) : array
    {
        $traverser = new NodeTraverser();
        $visitor = new CodeGenVisitor();
        $traverser->addVisitor($visitor);
        $fileName = $class->getFileName();
        if (is_bool($fileName)) {
            throw new InvalidSourceClassException(get_class($class));
        }
        $file = file_get_contents($fileName);
        if ($file === false) {
            throw new \RuntimeException($fileName); // @codeCoverageIgnore
        }
        $stmts = $this->parser->parse($file);
        if (is_array($stmts)) {
            $traverser->traverse($stmts);
        }

        return $visitor();
    }
1333059
public function parse(\ReflectionClass $class)
    {
        $className = $class->getName();

        if ($class->isTrait()) {
            return false;
        }

        if (!isset($this->documents[$className])) {
            /** @var Document $document */
            $document = $this->reader->getClassAnnotation($class, self::DOCUMENT_ANNOTATION);

            if ($document === null) {
                throw new MissingDocumentAnnotationException(
                    sprintf(
                        '"%s" class cannot be parsed as document because @Document annotation is missing.',
                        $class->getName()
                    )
                );
            }

            $fields = [];
            $aliases = $this->getAliases($class, $fields);

            $this->documents[$className] = [
                'type' => $document->type ?: Caser::snake($class->getShortName()),
                'properties' => $this->getProperties($class),
                'fields' => array_filter(
                    array_merge(
                        $document->dump(),
                        $fields
                    )
                ),
                'aliases' => $aliases,
                'analyzers' => $this->getAnalyzers($class),
                'objects' => $this->getObjects(),
                'namespace' => $class->getName(),
                'class' => $class->getShortName(),
            ];
        }
        return $this->documents[$className];
    }
1321364
protected function loadReceiverProperties(\ReflectionClass $class)
    {
        $receiverPropertiesTypes = [];
        $properties = $class->getProperties();

        //Store receiver properties
        foreach ($properties as $property) {
            $annotations = $this->reader->getPropertyAnnotations($property);
            foreach ($annotations as $key => $annotationObj) {
                if ($annotationObj instanceof ReceiverPropertyAnnotation && !in_array($class, $receiverPropertiesTypes)) {
                    if (!$annotations[$key]->getTypes()) {
                        $message = $class->name.':$'.$property->name.'" field';

                        throw AnnotationException::requiredError('type', 'ReceiverProperty annotation', $message, 'array or string');
                    }
                    foreach ($annotations[$key]->getTypes() as $type) {
                        $receiverProperty = new ReceiverProperty();
                        $receiverProperty->setFieldName($property->name);
                        $receiverPropertiesTypes[$type][] = $receiverProperty;
                    }
                }
            }
        }

        //Set receiver properties as required if necessary
        foreach ($receiverPropertiesTypes as $type => $receiverProperties) {
            /* @var ReceiverProperty[] $receiverProperties */
            foreach ($receiverProperties as $receiverProperty) {
                $receiverPropertyName = $receiverProperty->getFieldName();
                $refProperty = $class->getProperty($receiverPropertyName);
                $annotations = $this->reader->getPropertyAnnotations($refProperty);

                foreach ($annotations as $key => $annotationObj) {
                    if ($annotationObj instanceof Column && $annotationObj->nullable === false) {
                        throw new Exception(sprintf(
                                'Property "%s" in class "%s" has a @ReceiverProperty annotation and by consequence must have "nullable=true" for ORM\Column annotation',
                                $refProperty->name,
                                $refProperty->class
                            ));
                    } elseif ($annotationObj instanceof NotBlank) {
                        throw new Exception(sprintf(
                                'Property "%s" in class "%s" has a @ReceiverProperty annotation and by consequence can not use NotBlank annotation',
                                $refProperty->name,
                                $refProperty->class
                            ));
                    } elseif ($annotationObj instanceof NotNull) {
                        throw new Exception(sprintf(
                                'Property "%s" in class "%s" has a @ReceiverProperty annotation and by consequence can not use NotNull annotation',
                                $refProperty->name,
                                $refProperty->class
                            ));
                    } elseif ($annotationObj instanceof ReceiverPropertyAnnotation && $annotationObj->isRequired()) {
                        $receiverProperty->setRequired(true);
                    }
                }
            }
        }

        return $receiverPropertiesTypes;
    }
824993
private static function getSetters(\ReflectionClass $reflectionClass)
    {
        foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) {
            if (!$reflectionMethod->isStatic() && 1 === $reflectionMethod->getNumberOfParameters() && 0 === strpos($reflectionMethod->name, 'set')) {
                yield $reflectionMethod;
            }
        }
    }
547241
protected function getPropertiesMeta(ReflectionClass $reflection): array
    {
        $meta = [];
        $defaults = $reflection->getDefaultProperties();
        $properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC);

        foreach ($properties as $item) {
            $name = $item->getName();
            $meta[$name] = [
                'name' => $name,
                'title' => uncase($name)
            ];

            if (array_key_exists($name, $defaults)) {
                $meta[$name]['default'] = $defaults[$name];
            }
        }

        return $meta;
    }
253839
public static function getClass($class) {
        $cache = null;

        if (is_object($class)) {
            $cache = new Cache('gcs_cache_annotation_' . strtolower(str_replace('\\', '-', get_class($class))), 0);
        }
        else {
            $cache = new Cache('gcs_cache_annotation_' . strtolower(str_replace('\\', '-', $class)), 0);
        }

        if ($cache->isExist() && Config::config()['user']['debug']['environment'] != 'development') {
            return $cache->getCache();
        }

        $data = ['class' => [], 'methods' => [], 'properties' => []];

        $reflectionClass = new \ReflectionClass($class);

        //Class annotations
        $parser = new Parser($reflectionClass->getDocComment());
        $dataClasses = $parser->parse();

        foreach ($dataClasses as $key => $dataClass) {
            $processorClass = new Processor($dataClass);
            array_push($data['class'], [0 => ['annotation' => $dataClass['type'], 'instance' => $processorClass->process()]]);
        }

        //Method annotations
        $methodsName = $reflectionClass->getMethods();

        foreach ($methodsName as $methodName) {
            $method = new \ReflectionMethod($class, $methodName->getName());

            $parser = new Parser($method->getDocComment());
            $dataMethods = $parser->parse();

            if (count($dataMethods) > 0) {
                $data['methods'][$methodName->getName()] = [];

                foreach ($dataMethods as $key => $dataMethod) {
                    $processorMethods = new Processor($dataMethod);
                    array_push($data['methods'][$methodName->getName()], ['annotation' => $dataMethod['type'], 'instance' => $processorMethods->process()]);
                }
            }
        }

        //Properties annotations
        $propertiesNames = $reflectionClass->getProperties();

        foreach ($propertiesNames as $propertyName) {
            $property = new \ReflectionProperty($class, $propertyName->getName());

            $parser = new Parser($property->getDocComment());
            $dataProperties = $parser->parse();

            if (count($dataProperties) > 0) {
                $data['properties'][$propertyName->getName()] = [];

                foreach ($dataProperties as $key => $dataProperty) {
                    $processorProperties = new Processor($dataProperty);
                    array_push($data['properties'][$propertyName->getName()], ['annotation' => $dataProperty['type'], 'instance' => $processorProperties->process()]);
                }
            }
        }

        $cache->setContent($data);
        $cache->setCache();

        return $data;
    }
160642
private function getAllUseStatementsMarkedAsAnnotation(\ReflectionClass $class): array
    {
        $tokens = \token_get_all(\file_get_contents($class->getFileName()));

        $uses = [];
        $buffer = '';
        $startUseParse = false;

        foreach ($tokens as $token) {
            if (\is_scalar($token)) {
                // Single element
                if ($token == ';' || $token = ',') {
                    if ($startUseParse) {
                        // Add "use" statement to collection
                        $uses[] = trim($buffer);
                        // Clear buffer
                        $buffer = ''; // Clear buffer

                        if ($token == ';') {
                            // Stop parse "use"
                            $startUseParse = false;
                        }
                    }
                }

                continue;
            }

            $type = $token[0];
            $value = $token[1];

            if (\in_array($type, [T_ABSTRACT, T_CLASS, T_INTERFACE, T_TRAIT])) {
                // Start class or interface or trait
                break;
            }

            if ($type == T_USE) {
                $startUseParse = true;
                continue;
            }

            if ($startUseParse) {
                $buffer .= $value;
            }
        }

        $useFiltering = function ($class, $searchChild = true) use (&$useFiltering) {
            if (!$class) {
                return false;
            }

            $parts = \explode(' as ', $class, 2);
            $class = $parts[0];

            try {
                $reflection = new \ReflectionClass($class);
            } catch (\ReflectionException $e) {
                if ($searchChild) {
                    foreach (\get_declared_classes() as $declaredClass) {
                        if (\strpos($declaredClass, $class) === 0) {
                            if (true === $useFiltering($declaredClass, false)) {
                                return true;
                            }
                        }
                    }
                }

                return false;
            }

            if ($reflection->getName() == Transactional::class) {
                return false;
            }

            return \strpos($reflection->getDocComment(), '@Annotation') !== false;
        };

        $uses = \array_filter($uses, $useFiltering);

        return $uses;
    }
433285
public function parseTableName(\ReflectionClass $reflection)
    {
        $hd = $this->parser->parse($reflection->getDocComment());

        if (!empty($hd[0])) {
            return $hd[1];
        }

        $table = substr($reflection->getName(), strlen($reflection->getNamespaceName()));

        return strtolower(str_replace('\\', '', $table));
    }
1113439
private function getClassInfo($defClass) {
		if (is_object($defClass)) {
			if ($defClass instanceof ReflectionClass) {
				$className = $defClass->getName();
				$refClass = $defClass;
			} else {
				$className = get_class($defClass);
				$refClass = new ReflectionClass($className);
			}
		} else {
			$className = $defClass;
			$refClass = new ReflectionClass($className);
		}

		return [ $className, $refClass ];
	}
434589
private function getAnnotations($class)
    {
        $parsed = $this->getParser()->parse($class);
        if (!is_array($parsed)) {
            return [];
        }
        $context = [
            'class' => $class,
            'declaringClass' => $class,
            'type' => Context::TYPE_CLASS,
            'name' => $class
        ];
        $annotations = [];
        if (!empty($parsed['class'])) {
            foreach ($parsed['class'] as $value) {
                $anno = $this->create($value, $context);
                if ($anno) {
                    $annotations[] = $anno;
                }
            }
        }
        $map = [
            'methods' => Context::TYPE_METHOD,
            'properties' => Context::TYPE_PROPERTY
        ];
        $reflection = new \ReflectionClass($class);
        foreach ($map as $type_name => $type) {
            if (!empty($parsed[$type_name])) {
                foreach ($parsed[$type_name] as $name => $values) {
                    $reflType = $type == 'method' ? $reflection->getMethod($name)
                               : $reflection->getProperty($name);
                    $context['type'] = $type;
                    $context['name'] = $name;
                    $context['declaringClass'] = $reflType->getDeclaringClass()->getName();
                    foreach ($values as $value) {
                        $anno = $this->create($value, $context);
                        if ($anno) {
                            $annotations[] = $anno;
                        }
                    }
                }
            }
        }
        return $annotations;
    }
681988
public function extractRelations(\ReflectionClass $reflection)
    {
        $propertyList = $reflection->getDefaultProperties();

        if ($this->cache && $res = $this->cache->get(md5(json_encode($propertyList)))) {
            return $res;
        }

        $relation = [];

        foreach ($propertyList as $name => $value) {
            $comment = $reflection->getProperty($name)->getDocComment();
            $d = $this->parser->parse($comment);
            if (!$d) {
                continue;
            }
            $relation[] = [
                'mapping_id' => $d[0],
                'model'      => $d[1],
                'target'     => $name
            ];
        }

        if ($this->cache) {
            $this->cache->set(md5(json_encode($propertyList)), $relation, 300);
        }

        return $relation;
    }
1222342
public function getDependencies(\ReflectionClass $reflected)
    {
        $dependencies = [];

        if ($constructor = $reflected->getConstructor()) {
            $parameters = $constructor->getParameters();
            foreach ($parameters as $parameter) {
                $dependencies[] = $this->getDependency($parameter, $reflected);
            }
        }

        return $dependencies;
    }
326921
protected function generateImplements(\ReflectionClass $reflectionClass)
    {

        // load the class interfaces
        $interfaces = $reflectionClass->getInterfaces();

        // initialize the array for the
        $generateInterfaces = array();

        // iterate over the specified interfaces
        foreach ($interfaces as $interfaceName => $interface) {
            // clean them up to avoid doubles
            foreach ($generateInterfaces as $obj) {
                if ($obj->isSubclassOf($interface)) {
                    continue 2;
                }
            }

            // traversable interface can not be implemented directly, so ignore it
            if ($interface->getName() === 'Traversable') {
                continue;
            }

            // append the interface
            $generateInterfaces[sprintf('\\%s', $interfaceName)] = $interface;
        }

        // implode the interfaces and return them as string
        return implode(', ', array_keys($generateInterfaces));
    }
1119673
protected function parseNodes(\ReflectionClass $class, ClassMetadata $metadata, $config)
    {
        if (!isset($config['nodes'])) {
            return;
        }

        if (!is_array($config)) {
            throw new \RuntimeException(sprintf('Invalid YAML configuration for "%s" : "properties" property need to be an array.', $metadata->name));
        }

        foreach ($config['nodes'] as $property => $nodeProperties) {
            foreach ($nodeProperties as $nodeProperty) {
                if (!isset($nodeProperty['namespace']) || !isset($nodeProperty['tag'])) {
                    throw new \RuntimeException(sprintf('Invalid YAML configuration for "%s" : "namespace" and "tag" are required.', $metadata->name));
                }

                $node = new Node([
                    'namespace' => $nodeProperty['namespace'],
                    'tag' => $nodeProperty['tag'],
                ]);

                if ($class->hasProperty($property)) {
                    $metadata->addGraphMetadata($node, new PropertyMetadata($class->name, $property));
                }

                if ($class->hasMethod($property)) {
                    $metadata->addGraphMetadata($node, new MethodMetadata($class->name, $property));
                }
            }
        }
    }
80809
public static function getClassProperties($class)
    {
        if (is_string($class)) {
            if (isset(self::$classPropertyes[$class])) {
                return self::$classPropertyes[$class];
            }

            $class = new \ReflectionClass($class);
        }

        if (!$class instanceof \ReflectionClass) {
            throw new \InvalidArgumentException('The arguments must be a valid class name or reflection');
        }

        if (isset(self::$classPropertyes[$class->getName()])) {
            return self::$classPropertyes[$class->getName()];
        }

        $props = $class->getProperties();
        $props_arr = [];
        foreach ($props as $prop) {
            $f = $prop->getName();

            $props_arr[$f] = $prop;
        }
        if ($parentClass = $class->getParentClass()) {
            $parent_props_arr = static::getClassProperties($parentClass);//RECURSION
            if (count($parent_props_arr) > 0) {
                $props_arr = array_merge($parent_props_arr, $props_arr);
            }
        }

        self::$classPropertyes[$class->getName()] = $props_arr;

        return $props_arr;
    }