1<?php 2 3namespace Doctrine\DBAL\Types; 4 5use Doctrine\DBAL\DBALException; 6use Doctrine\DBAL\ParameterType; 7use Doctrine\DBAL\Platforms\AbstractPlatform; 8 9use function array_map; 10use function get_class; 11use function str_replace; 12use function strrpos; 13use function substr; 14 15/** 16 * The base class for so-called Doctrine mapping types. 17 * 18 * A Type object is obtained by calling the static {@link getType()} method. 19 */ 20abstract class Type 21{ 22 /** @deprecated Use {@see Types::BIGINT} instead. */ 23 public const BIGINT = Types::BIGINT; 24 25 /** @deprecated Use {@see Types::BINARY} instead. */ 26 public const BINARY = Types::BINARY; 27 28 /** @deprecated Use {@see Types::BLOB} instead. */ 29 public const BLOB = Types::BLOB; 30 31 /** @deprecated Use {@see Types::BOOLEAN} instead. */ 32 public const BOOLEAN = Types::BOOLEAN; 33 34 /** @deprecated Use {@see Types::DATE_MUTABLE} instead. */ 35 public const DATE = Types::DATE_MUTABLE; 36 37 /** @deprecated Use {@see Types::DATE_IMMUTABLE} instead. */ 38 public const DATE_IMMUTABLE = Types::DATE_IMMUTABLE; 39 40 /** @deprecated Use {@see Types::DATEINTERVAL} instead. */ 41 public const DATEINTERVAL = Types::DATEINTERVAL; 42 43 /** @deprecated Use {@see Types::DATETIME_MUTABLE} instead. */ 44 public const DATETIME = Types::DATETIME_MUTABLE; 45 46 /** @deprecated Use {@see Types::DATETIME_IMMUTABLE} instead. */ 47 public const DATETIME_IMMUTABLE = Types::DATETIME_IMMUTABLE; 48 49 /** @deprecated Use {@see Types::DATETIMETZ_MUTABLE} instead. */ 50 public const DATETIMETZ = Types::DATETIMETZ_MUTABLE; 51 52 /** @deprecated Use {@see Types::DATETIMETZ_IMMUTABLE} instead. */ 53 public const DATETIMETZ_IMMUTABLE = Types::DATETIMETZ_IMMUTABLE; 54 55 /** @deprecated Use {@see Types::DECIMAL} instead. */ 56 public const DECIMAL = Types::DECIMAL; 57 58 /** @deprecated Use {@see Types::FLOAT} instead. */ 59 public const FLOAT = Types::FLOAT; 60 61 /** @deprecated Use {@see Types::GUID} instead. */ 62 public const GUID = Types::GUID; 63 64 /** @deprecated Use {@see Types::INTEGER} instead. */ 65 public const INTEGER = Types::INTEGER; 66 67 /** @deprecated Use {@see Types::JSON} instead. */ 68 public const JSON = Types::JSON; 69 70 /** @deprecated Use {@see Types::JSON_ARRAY} instead. */ 71 public const JSON_ARRAY = Types::JSON_ARRAY; 72 73 /** @deprecated Use {@see Types::OBJECT} instead. */ 74 public const OBJECT = Types::OBJECT; 75 76 /** @deprecated Use {@see Types::SIMPLE_ARRAY} instead. */ 77 public const SIMPLE_ARRAY = Types::SIMPLE_ARRAY; 78 79 /** @deprecated Use {@see Types::SMALLINT} instead. */ 80 public const SMALLINT = Types::SMALLINT; 81 82 /** @deprecated Use {@see Types::STRING} instead. */ 83 public const STRING = Types::STRING; 84 85 /** @deprecated Use {@see Types::ARRAY} instead. */ 86 public const TARRAY = Types::ARRAY; 87 88 /** @deprecated Use {@see Types::TEXT} instead. */ 89 public const TEXT = Types::TEXT; 90 91 /** @deprecated Use {@see Types::TIME_MUTABLE} instead. */ 92 public const TIME = Types::TIME_MUTABLE; 93 94 /** @deprecated Use {@see Types::TIME_IMMUTABLE} instead. */ 95 public const TIME_IMMUTABLE = Types::TIME_IMMUTABLE; 96 97 /** 98 * The map of supported doctrine mapping types. 99 */ 100 private const BUILTIN_TYPES_MAP = [ 101 Types::ARRAY => ArrayType::class, 102 Types::BIGINT => BigIntType::class, 103 Types::BINARY => BinaryType::class, 104 Types::BLOB => BlobType::class, 105 Types::BOOLEAN => BooleanType::class, 106 Types::DATE_MUTABLE => DateType::class, 107 Types::DATE_IMMUTABLE => DateImmutableType::class, 108 Types::DATEINTERVAL => DateIntervalType::class, 109 Types::DATETIME_MUTABLE => DateTimeType::class, 110 Types::DATETIME_IMMUTABLE => DateTimeImmutableType::class, 111 Types::DATETIMETZ_MUTABLE => DateTimeTzType::class, 112 Types::DATETIMETZ_IMMUTABLE => DateTimeTzImmutableType::class, 113 Types::DECIMAL => DecimalType::class, 114 Types::FLOAT => FloatType::class, 115 Types::GUID => GuidType::class, 116 Types::INTEGER => IntegerType::class, 117 Types::JSON => JsonType::class, 118 Types::JSON_ARRAY => JsonArrayType::class, 119 Types::OBJECT => ObjectType::class, 120 Types::SIMPLE_ARRAY => SimpleArrayType::class, 121 Types::SMALLINT => SmallIntType::class, 122 Types::STRING => StringType::class, 123 Types::TEXT => TextType::class, 124 Types::TIME_MUTABLE => TimeType::class, 125 Types::TIME_IMMUTABLE => TimeImmutableType::class, 126 ]; 127 128 /** @var TypeRegistry|null */ 129 private static $typeRegistry; 130 131 /** 132 * @internal Do not instantiate directly - use {@see Type::addType()} method instead. 133 */ 134 final public function __construct() 135 { 136 } 137 138 /** 139 * Converts a value from its PHP representation to its database representation 140 * of this type. 141 * 142 * @param mixed $value The value to convert. 143 * @param AbstractPlatform $platform The currently used database platform. 144 * 145 * @return mixed The database representation of the value. 146 */ 147 public function convertToDatabaseValue($value, AbstractPlatform $platform) 148 { 149 return $value; 150 } 151 152 /** 153 * Converts a value from its database representation to its PHP representation 154 * of this type. 155 * 156 * @param mixed $value The value to convert. 157 * @param AbstractPlatform $platform The currently used database platform. 158 * 159 * @return mixed The PHP representation of the value. 160 */ 161 public function convertToPHPValue($value, AbstractPlatform $platform) 162 { 163 return $value; 164 } 165 166 /** 167 * Gets the default length of this type. 168 * 169 * @deprecated Rely on information provided by the platform instead. 170 * 171 * @return int|null 172 */ 173 public function getDefaultLength(AbstractPlatform $platform) 174 { 175 return null; 176 } 177 178 /** 179 * Gets the SQL declaration snippet for a column of this type. 180 * 181 * @param mixed[] $column The column definition 182 * @param AbstractPlatform $platform The currently used database platform. 183 * 184 * @return string 185 */ 186 abstract public function getSQLDeclaration(array $column, AbstractPlatform $platform); 187 188 /** 189 * Gets the name of this type. 190 * 191 * @return string 192 * 193 * @todo Needed? 194 */ 195 abstract public function getName(); 196 197 /** 198 * @internal This method is only to be used within DBAL for forward compatibility purposes. Do not use directly. 199 */ 200 final public static function getTypeRegistry(): TypeRegistry 201 { 202 if (self::$typeRegistry === null) { 203 self::$typeRegistry = self::createTypeRegistry(); 204 } 205 206 return self::$typeRegistry; 207 } 208 209 private static function createTypeRegistry(): TypeRegistry 210 { 211 $registry = new TypeRegistry(); 212 213 foreach (self::BUILTIN_TYPES_MAP as $name => $class) { 214 $registry->register($name, new $class()); 215 } 216 217 return $registry; 218 } 219 220 /** 221 * Factory method to create type instances. 222 * Type instances are implemented as flyweights. 223 * 224 * @param string $name The name of the type (as returned by getName()). 225 * 226 * @return Type 227 * 228 * @throws DBALException 229 */ 230 public static function getType($name) 231 { 232 return self::getTypeRegistry()->get($name); 233 } 234 235 /** 236 * Adds a custom type to the type map. 237 * 238 * @param string $name The name of the type. This should correspond to what getName() returns. 239 * @param string $className The class name of the custom type. 240 * 241 * @return void 242 * 243 * @throws DBALException 244 */ 245 public static function addType($name, $className) 246 { 247 self::getTypeRegistry()->register($name, new $className()); 248 } 249 250 /** 251 * Checks if exists support for a type. 252 * 253 * @param string $name The name of the type. 254 * 255 * @return bool TRUE if type is supported; FALSE otherwise. 256 */ 257 public static function hasType($name) 258 { 259 return self::getTypeRegistry()->has($name); 260 } 261 262 /** 263 * Overrides an already defined type to use a different implementation. 264 * 265 * @param string $name 266 * @param string $className 267 * 268 * @return void 269 * 270 * @throws DBALException 271 */ 272 public static function overrideType($name, $className) 273 { 274 self::getTypeRegistry()->override($name, new $className()); 275 } 276 277 /** 278 * Gets the (preferred) binding type for values of this type that 279 * can be used when binding parameters to prepared statements. 280 * 281 * This method should return one of the {@link ParameterType} constants. 282 * 283 * @return int 284 */ 285 public function getBindingType() 286 { 287 return ParameterType::STRING; 288 } 289 290 /** 291 * Gets the types array map which holds all registered types and the corresponding 292 * type class 293 * 294 * @return string[] 295 */ 296 public static function getTypesMap() 297 { 298 return array_map( 299 static function (Type $type): string { 300 return get_class($type); 301 }, 302 self::getTypeRegistry()->getMap() 303 ); 304 } 305 306 /** 307 * @deprecated Relying on string representation is discouraged and will be removed in DBAL 3.0. 308 * 309 * @return string 310 */ 311 public function __toString() 312 { 313 $type = static::class; 314 $position = strrpos($type, '\\'); 315 316 if ($position !== false) { 317 $type = substr($type, $position); 318 } 319 320 return str_replace('Type', '', $type); 321 } 322 323 /** 324 * Does working with this column require SQL conversion functions? 325 * 326 * This is a metadata function that is required for example in the ORM. 327 * Usage of {@link convertToDatabaseValueSQL} and 328 * {@link convertToPHPValueSQL} works for any type and mostly 329 * does nothing. This method can additionally be used for optimization purposes. 330 * 331 * @return bool 332 */ 333 public function canRequireSQLConversion() 334 { 335 return false; 336 } 337 338 /** 339 * Modifies the SQL expression (identifier, parameter) to convert to a database value. 340 * 341 * @param string $sqlExpr 342 * 343 * @return string 344 */ 345 public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform) 346 { 347 return $sqlExpr; 348 } 349 350 /** 351 * Modifies the SQL expression (identifier, parameter) to convert to a PHP value. 352 * 353 * @param string $sqlExpr 354 * @param AbstractPlatform $platform 355 * 356 * @return string 357 */ 358 public function convertToPHPValueSQL($sqlExpr, $platform) 359 { 360 return $sqlExpr; 361 } 362 363 /** 364 * Gets an array of database types that map to this Doctrine type. 365 * 366 * @return string[] 367 */ 368 public function getMappedDatabaseTypes(AbstractPlatform $platform) 369 { 370 return []; 371 } 372 373 /** 374 * If this Doctrine Type maps to an already mapped database type, 375 * reverse schema engineering can't tell them apart. You need to mark 376 * one of those types as commented, which will have Doctrine use an SQL 377 * comment to typehint the actual Doctrine Type. 378 * 379 * @return bool 380 */ 381 public function requiresSQLCommentHint(AbstractPlatform $platform) 382 { 383 return false; 384 } 385} 386