Uses reflection to get all public and protected properties (excluding those that begin with a underscore)
and parses their names from camelCase to snake_case to be used in Phalcon column mapping

@return array
767573
public function columnMap()
    {
        $columnMap = [];
        $child     = new static();
        $reflect   = new \ReflectionObject($child);
        $props     = $reflect->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED);
        foreach ($props as $prop) {
            if (substr($prop->getName(), 0, 1) !== '_') {
                $output             = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $prop->getName()));
                $columnMap[$output] = $prop->getName();
            }
        }

        return $columnMap;
    }
970266
public function getProperties()
    {
        return [
            'workspaceName' => $this->workspaceName,
            'currentDateTime' => $this->currentDateTime,
            'dimensions' => $this->dimensions,
            'targetDimensions' => $this->targetDimensions,
            'invisibleContentShown' => $this->invisibleContentShown,
            'removedContentShown' => $this->removedContentShown,
            'inaccessibleContentShown' => $this->inaccessibleContentShown,
            'currentSite' => $this->currentSite,
            'currentDomain' => $this->currentDomain
        ];
    }
1041018
public function getParamNames(): array
    {
        $names = [];

        foreach ($this->getPublicProperties() as $param) {
            $names[] = $param->getName();
        }

        return $names;
    }
745502
public function getPropertyNames() {
    return array_map(function (ClassMemberNode $property) {
      return ltrim($property->getName(), '$');
    }, $this->getProperties()->toArray());
  }
734523
public function properties()
    {
        if ($this->properties === null || $this->parsedProperties === false) {
            $this->parsedProperties = true;

            $model = $this->proto();
            $properties = $model->metadata()->properties();

            $listProperties = null;
            if ($this->properties === null) {
                $collectionConfig = $this->collectionConfig();
                if (isset($collectionConfig['properties'])) {
                    $listProperties = array_flip($collectionConfig['properties']);
                }
            } else {
                $listProperties = array_flip($this->properties);
            }

            if ($listProperties) {
                // Replacing values of listProperties from index to actual property values
                $properties = array_replace($listProperties, $properties);
                // Get only the keys that are in listProperties from props
                $properties = array_intersect_key($properties, $listProperties);
            }

            $this->properties = $properties;
        }

        return $this->properties;
    }
1351972
public static function getProperties(array $exceptions = []): array {
		
		// because we're static, we can't use $this and get_object_vars().
		// we could use the class name and get_class_vars() but then we'd only
		// get public properties, and we want public and protected ones.  so,
		// we'll use a ReflectionClass.
		
		$reflection = new \ReflectionClass(get_called_class());
		$properties = $reflection->getProperties(
			\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED
		);
		
		$temp = [];
		foreach ($properties as $property) {
			$property = $property->getName();
			
			// we don't really care where in the $exceptions we find $property
			// so we'll use in_array(): bool instead of array_search(): mixed
			// here.
			
			if (!in_array($property, $exceptions)) {
				$temp[] = $property;
			}
		}
		
		return $temp;
	}
698929
public function getClassProperties()
    {
        if (empty($this->_properties)) {
            $properties = $this->_getReflection()->getProperties();
            foreach ($properties as $property) {
                $this->_properties[] = $property->getName();
            }
        }
        return $this->_properties;
    }
328608
public function toArray(): array
    {
        $this->internalDataListUpdate();

        // Copied from DataObjectToArrayTrait. Do not modify here !!!
        $toArray = function($object) use (&$toArray) {
            $result = [];
            $vars = get_object_vars($object);
            foreach ($vars as $name => $value) {
                if ($name !== 'internalDataObjectData') {
                    $reflectionProperty = new \ReflectionProperty($object, $name);
                    if ($reflectionProperty->isPublic()) {
                        $result[$name] = null;
                    }
                }
            }
            if (isset($object->internalDataObjectData)) {
                foreach ($object->internalDataObjectData as $name => $value) {
                    $result[substr($name, 1)] = null;
                }
            }
            ksort($result);
            foreach ($result as $name => $null) {
                $value = $object instanceof \ArrayAccess ? $object[$name] : (isset($object->$name) ? $object->$name : null);
                if (is_object($value)) {
                    if (method_exists($value, 'toArray')) {
                        $result[$name] = $value->toArray();
                    } else {
                        if ($value instanceof \DateTime) {
                            $result[$name] = $value->format('c');
                        } else {
                            $propertyVars = $toArray($value);
                            foreach ($propertyVars as $propertyVarName => $propertyVarValue) {
                                if (is_object($propertyVarValue)) {
                                    $propertyVars[$propertyVarName] = $toArray($propertyVarValue);
                                }
                            }
                            $result[$name] = $propertyVars;
                        }
                    }
                } else {
                    $result[$name] = $value;
                }
            }
            return $result;
        };

        $result = [];
        foreach ($this->internalDataListData as $index => $object) {
            $object = $this->internalDataListUpdateValueIfNeeded($this->internalDataListData, $index);
            if (method_exists($object, 'toArray')) {
                $result[] = $object->toArray();
            } else {
                $result[] = $toArray($object);
            }
        }
        return $result;
    }
259325
public static function getPersistentParams()
	{
		$rc = new \ReflectionClass(get_called_class());
		$params = [];
		foreach ($rc->getProperties(\ReflectionProperty::IS_PUBLIC) as $rp) {
			if (!$rp->isStatic() && ComponentReflection::parseAnnotation($rp, 'persistent')) {
				$params[] = $rp->getName();
			}
		}
		return $params;
	}
1176474
public function __findSerialisablePropertyAccessors() {

        // Grab the class name first.
        $className = get_class($this);

        // If no accessor map has been previously cached for this class type, cache it now.
        if (!isset (self::$__accessorMaps [$className])) {


            $reflectionClass = new \ReflectionClass ($className);

            // Create the accessors array for storing all possible accessors.
            $accessors = array();

            // Loop through all methods, checking for public get and set accessors first.
            $methods = $reflectionClass->getMethods();
            foreach ($methods as $method) {

                if ($method->isStatic())
                    continue;

                if ((substr($method->getName(), 0, 3) == "get") && ($method->getNumberOfRequiredParameters() == 0)) {
                    $propertyName = strtolower(substr($method->getName(), 3));
                    if (!isset ($accessors [$propertyName])) {
                        $accessors [$propertyName] = array();
                    }
                    $accessors [$propertyName] ["get"] = $method;
                } else if (substr($method->getName(), 0, 3) == "set") {
                    $propertyName = strtolower(substr($method->getName(), 3));
                    if (!isset ($accessors [$propertyName])) {
                        $accessors [$propertyName] = array();
                    }
                    $accessors [$propertyName] ["set"] = $method;
                }
            }

            // Now loop through all properties, checking for any public / protected ones
            $properties = $reflectionClass->getProperties();
            foreach ($properties as $property) {

                if ($property->isStatic())
                    continue;

                $propertyName = strtolower($property->getName());

                if (!isset ($accessors [$propertyName])) {
                    $accessors [$propertyName] = array();
                }
                if (!isset ($accessors [$propertyName] ["get"]))
                    $accessors [$propertyName] ["get"] = $property;
                if (!isset ($accessors [$propertyName] ["set"]))
                    $accessors [$propertyName] ["set"] = $property;

            }

            self::$__accessorMaps [$className] = $accessors;

        }

        return self::$__accessorMaps [$className];
    }
536338
public function getPropertyNames()
    {
        $result = array();

        foreach ( $this->getRawPropertyNames() as $rawName )
        {
            $result[] = String::camelize( $rawName );
        }

        return $result;
    }
602657
public function getModifiedProperties()
    {
        if ($this->read_only) {
            return array();
        }

        $modified_properties = array();
        foreach ($this->getProperties() as $name => $value) {
            $hashed_value = $this->getHashValue($value);
            if (
                array_key_exists($name, $this->property_hashes) &&
                $hashed_value !== $this->property_hashes[$name]
            ) {
                $modified_properties[$name] = $value;
            }
        }

        return $modified_properties;
    }
251044
public function toArray()
    {
        $classData = [];
        foreach ($this->getReflector()->getProperties(\ReflectionProperty::IS_PROTECTED) as $reflectionProperty) {
            if (!$reflectionProperty->isStatic()) {
                $reflectionProperty->setAccessible(true);
                $classData[$reflectionProperty->getName()] = $reflectionProperty->getValue($this);
            }
        }
        return $classData;
    }
1075111
public function attributes()
    {
        $class = new \ReflectionClass($this);

        $names = [];
        foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
            if (!$property->isStatic()) {
                $names[] = $property->getName();
            }
        }

        return ArrayHelper::merge(parent::attributes(), $names);
    }
263590
protected function getGeneratedProperties(): array
    {
        $reflectionObject = new \ReflectionObject($this);
        $properties = $reflectionObject->getProperties(\ReflectionProperty::IS_PUBLIC);
        $result = [];
        foreach ($properties as $property) {
            if (!$property->isPublic() || @$property->isDefault()) {
                continue;
            }

            $result[] = $property;
        }

        return $result;
    }
692593
protected static function getBinds() {

		$db = Database::getInstance();
		$columns = $db->describeTable(static::TABLE_NAME);
		
		$maps = [];

		foreach ($columns as $col) {
			
			// get a camelCase name, with first low case
			$property = lcfirst(str_replace(' ', '', ucwords(str_replace(['_','\\'], ' ', $col->Field))));
			$maps[$property] = $col->Field;
			
		}

		return $maps;
		
	}
648928
public function getColumns(\ReflectionClass $reflectionClass)
    {
        if ($this->isProduction()) {
            $this->grid->getColumn()->getFields();
        }

        $properties = $reflectionClass->getProperties(\ReflectionProperty::IS_PRIVATE | \ReflectionProperty::IS_PROTECTED);
        foreach ($properties as $property) {
            $propertyAnnotations = $this->extractorFactory->extract($property, Extractor::PROPERTY_ANNOTATION);
            foreach ($propertyAnnotations as $annotation) {
                if ($annotation instanceof Column) {
                    $fields[] = $property->getName();
                }
            }
        }

        return !empty($fields) ? $fields : $this->grid->getColumn()->getFields();
    }