diff --git a/composer.json b/composer.json index ccc0752..b0a55ac 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ "pomm-project/foundation": "~2.0", "symfony/http-foundation": "~2.5|~3.0", "symfony/http-kernel": "~2.5|~3.0", - "symfony/serializer": "~2.5|~3.0" + "symfony/serializer": "~2.5|~3.0", + "symfony/property-info": "~2.8|~3.0" }, "suggest": { "pomm-project/model-manager": "~2.0", diff --git a/sources/lib/PropertyInfo/Extractor/PommExtractor.php b/sources/lib/PropertyInfo/Extractor/PommExtractor.php new file mode 100644 index 0000000..c53f9a3 --- /dev/null +++ b/sources/lib/PropertyInfo/Extractor/PommExtractor.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PommProject\SymfonyBridge\PropertyInfo\Extractor; + +use PommProject\Foundation\Pomm; +use PommProject\Foundation\Session; +use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; +use Symfony\Component\PropertyInfo\Type; + +/** + * Extract data using pomm. + * + * @package PommSymfonyBridge + * @copyright 2015 Grégoire HUBERT + * @author Nicolas Joseph + * @license X11 {@link http://opensource.org/licenses/mit-license.php} + */ +class PommExtractor implements PropertyTypeExtractorInterface +{ + private $pomm; + + public function __construct(Pomm $pomm) + { + $this->pomm = $pomm; + } + + /** + * @see PropertyTypeExtractorInterface + */ + public function getTypes($class, $property, array $context = array()) + { + if (isset($context['session:name'])) { + $session = $this->pomm->getSession($context['session:name']); + } else { + $session = $this->pomm->getDefaultSession(); + } + + if (isset($context['model:name'])) { + $model_name = $context['model:name']; + } else { + $model_name = "${class}Model"; + } + + $sql_type = $this->getSqlType($session, $model_name, $property); + $pomm_type = $this->getPommType($session, $sql_type); + + return $this->createPropertyType($pomm_type); + } + + /** + * Get the sql type of $property + * + * @return string + */ + private function getSqlType(Session $session, $model_name, $property) + { + $model = $session->getModel($model_name); + $structure = $model->getStructure(); + + return $structure->getTypeFor($property); + } + + /** + * Get the corresponding php type of a $sql_type type + * + * @return string + */ + private function getPommType(Session $session, $sql_type) + { + $pomm_types = $session->getPoolerForType('converter') + ->getConverterHolder() + ->getTypesWithConverterName(); + + if (!isset($pomm_types[$sql_type])) { + throw new \RuntimeException("Invalid $sql_type"); + } + + return $pomm_types[$sql_type]; + } + + /** + * Create a new Type for the $pomm_type type + * + * @return Type + */ + private function createPropertyType($pomm_type) + { + $class = null; + $nullable = false; + + switch ($pomm_type) { + case 'Array': + case 'Boolean': + case 'String': + $type = strtolower($pomm_type); + break; + case 'Number': + $type = Type::BUILTIN_TYPE_INT; + break; + case 'JSON': + $type = Type::BUILTIN_TYPE_ARRAY; + break; + case 'Binary': + $type = Type::BUILTIN_TYPE_STRING; + break; + case 'Timestamp': + $type = Type::BUILTIN_TYPE_OBJECT; + $name = \DateTime::class; + break; + case 'Interval': + $type = Type::BUILTIN_TYPE_OBJECT; + $name = \DateInterval::class; + break; + case 'Point': + $type = Type::BUILTIN_TYPE_OBJECT; + $name = \PommProject\Foundation\Converter\Type\Point::class; + break; + case 'Circle': + $type = Type::BUILTIN_TYPE_OBJECT; + $name = \PommProject\Foundation\Converter\Type\Circle::class; + break; + case 'NumberRange': + $type = Type::BUILTIN_TYPE_OBJECT; + $name = \PommProject\Foundation\Converter\Type\NumRange::class; + break; + case 'TsRange': + $type = Type::BUILTIN_TYPE_OBJECT; + $name = \PommProject\Foundation\Converter\Type\TsRange::class; + break; + default: + $type = Type::BUILTIN_TYPE_OBJECT; + $name = $pomm_type; + break; + } + + return new Type($type, $nullable, $class); + } +}