DocumentSchema.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <?php
  2. /**
  3. * Lithium: the most rad php framework
  4. *
  5. * @copyright Copyright 2013, Union of RAD (http://union-of-rad.org)
  6. * @license http://opensource.org/licenses/bsd-license.php The BSD License
  7. */
  8. namespace lithium\data;
  9. class DocumentSchema extends \lithium\data\Schema {
  10. protected $_classes = array(
  11. 'entity' => 'lithium\data\entity\Document',
  12. 'set' => 'lithium\data\collection\DocumentSet'
  13. );
  14. protected $_handlers = array();
  15. protected function _init() {
  16. $this->_autoConfig[] = 'handlers';
  17. parent::_init();
  18. }
  19. public function cast($object, $key, $data, array $options = array()) {
  20. $defaults = array(
  21. 'parent' => null,
  22. 'pathKey' => null,
  23. 'model' => null,
  24. 'wrap' => true,
  25. 'first' => false
  26. );
  27. $options += $defaults;
  28. $basePathKey = $options['pathKey'];
  29. $model = (!$options['model'] && $object) ? $object->model() : $options['model'];
  30. $classes = $this->_classes;
  31. $fieldName = is_int($key) ? null : $key;
  32. $pathKey = $basePathKey;
  33. if ($fieldName) {
  34. $pathKey = $basePathKey ? "{$basePathKey}.{$fieldName}" : $fieldName;
  35. }
  36. if ($data instanceof $classes['set'] || $data instanceof $classes['entity']) {
  37. return $data;
  38. }
  39. if (is_object($data) && !$this->is('array', $pathKey)) {
  40. return $data;
  41. }
  42. return $this->_castArray($object, $data, $pathKey, $options, $defaults);
  43. }
  44. protected function _castArray($object, $val, $pathKey, $options, $defaults) {
  45. $isArray = $this->is('array', $pathKey) && (!$object instanceof $this->_classes['set']);
  46. $isObject = ($this->type($pathKey) === 'object');
  47. $valIsArray = is_array($val);
  48. $numericArray = false;
  49. $class = 'entity';
  50. if (!$valIsArray && !$isArray) {
  51. return $this->_castType($val, $pathKey);
  52. }
  53. if ($valIsArray) {
  54. $numericArray = !$val || array_keys($val) === range(0, count($val) - 1);
  55. }
  56. if ($isArray || ($numericArray && !$isObject)) {
  57. $val = $valIsArray ? $val : array($val);
  58. $class = 'set';
  59. }
  60. if ($options['wrap']) {
  61. $config = array(
  62. 'data' => $val,
  63. 'parent' => $options['parent'],
  64. 'model' => $options['model'],
  65. 'schema' => $this
  66. );
  67. $config += compact('pathKey') + array_diff_key($options, $defaults);
  68. $val = $this->_instance($class, $config);
  69. } elseif ($class === 'set') {
  70. $val = $val ?: array();
  71. foreach ($val as &$value) {
  72. $value = $this->_castType($value, $pathKey);
  73. }
  74. }
  75. return $val;
  76. }
  77. /**
  78. * Casts a scalar (non-object/array) value to its corresponding database-native value or custom
  79. * value object based on a handler assigned to `$field`'s data type.
  80. *
  81. * @param mixed $value The value to be cast.
  82. * @param string $field The name of the field that `$value` is or will be stored in. If it is a
  83. * nested field, `$field` should be the full dot-separated path to the
  84. * sub-object's field.
  85. * @return mixed Returns the result of `$value`, modified by a matching handler data type
  86. * handler, if available.
  87. */
  88. protected function _castType($value, $field) {
  89. if ($this->is('null', $field) && ($value === null || $value === "")) {
  90. return null;
  91. }
  92. if (!is_scalar($value)) {
  93. return $value;
  94. }
  95. $type = $this->type($field);
  96. return isset($this->_handlers[$type]) ? $this->_handlers[$type]($value) : $value;
  97. }
  98. }
  99. ?>