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