Schema.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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. use RuntimeException;
  10. /**
  11. * This class encapsulates a schema definition, usually for a model class, and is comprised
  12. * of named fields and types.
  13. */
  14. class Schema extends \lithium\core\Object implements \ArrayAccess {
  15. protected $_fields = array();
  16. protected $_meta = array();
  17. protected $_locked = false;
  18. protected $_types = array();
  19. protected $_autoConfig = array('fields', 'meta', 'locked');
  20. public function __construct(array $config = array()) {
  21. $defaults = array('fields' => array());
  22. parent::__construct($config + $defaults);
  23. }
  24. protected function _init() {
  25. parent::_init();
  26. foreach ($this->_fields as $key => $type) {
  27. if (is_string($type)) {
  28. $this->_fields[$key] = compact('type');
  29. continue;
  30. }
  31. if (isset($this->_fields[$key][0]) && !isset($this->_fields[$key]['type'])) {
  32. $this->_fields[$key]['type'] = $this->_fields[$key][0];
  33. unset($this->_fields[$key][0]);
  34. }
  35. }
  36. }
  37. public function fields($name = null, $key = null) {
  38. if (!$name) {
  39. return $this->_fields;
  40. }
  41. $field = isset($this->_fields[$name]) ? $this->_fields[$name] : null;
  42. if ($field && $key) {
  43. return isset($field[$key]) ? $field[$key] : null;
  44. }
  45. return $field;
  46. }
  47. public function names() {
  48. return array_keys($this->_fields);
  49. }
  50. public function defaults($name = null) {
  51. if ($name) {
  52. if (isset($this->_fields[$name]['default'])) {
  53. return $this->_fields[$name]['default'];
  54. }
  55. return null;
  56. }
  57. $defaults = array();
  58. foreach ($this->_fields as $key => $value) {
  59. if (isset($value['default'])) {
  60. $defaults[$key] = $value['default'];
  61. }
  62. }
  63. return $defaults;
  64. }
  65. public function meta($name = null) {
  66. if (!$name) {
  67. return $this->_meta;
  68. }
  69. return isset($this->_meta[$name]) ? $this->_meta[$name] : null;
  70. }
  71. public function has($field) {
  72. if (is_string($field)) {
  73. return isset($this->_fields[$field]);
  74. }
  75. if (is_array($field)) {
  76. return array_intersect($field, array_keys($this->_fields)) == $field;
  77. }
  78. }
  79. /**
  80. * Detects properties of a field, i.e. if it supports arrays.
  81. *
  82. * @param string $condition
  83. * @param string $field
  84. * @return boolean
  85. */
  86. public function is($condition, $field) {
  87. if (!isset($this->_fields[$field])) {
  88. return null;
  89. }
  90. return isset($this->_fields[$field][$condition]) && $this->_fields[$field][$condition];
  91. }
  92. public function type($field) {
  93. if (!isset($this->_fields[$field]['type'])) {
  94. return null;
  95. }
  96. $type = $this->_fields[$field]['type'];
  97. return isset($this->_types[$type]) ? $this->_types[$type] : $type;
  98. }
  99. public function cast($object, $key, $data, array $options = array()) {
  100. return $data;
  101. }
  102. public function reset() {
  103. $this->_fields = array();
  104. }
  105. /**
  106. * Appends additional fields to the schema. Will not overwrite existing fields if any conflicts
  107. * arise.
  108. *
  109. * @param array $fields New schema data.
  110. * @return void
  111. */
  112. public function append(array $fields) {
  113. if ($this->_locked) {
  114. throw new RuntimeException("Schema cannot be modified.");
  115. }
  116. $this->_fields += $fields;
  117. }
  118. /**
  119. * Merges another `Schema` object into the current one.
  120. *
  121. * @param object $schema Another `Schema` class object to be merged into the current one.
  122. * If this schema contains field names that conflict with existing field names,
  123. * the existing fields will not be overwritten.
  124. * @return void
  125. */
  126. public function merge($schema) {
  127. if ($this->_locked) {
  128. throw new RuntimeException("Schema cannot be modified.");
  129. }
  130. $this->_fields += $schema->fields();
  131. }
  132. public function offsetGet($key) {
  133. return $this->fields($key);
  134. }
  135. public function offsetSet($key, $value) {
  136. if ($this->_locked) {
  137. throw new RuntimeException("Schema cannot be modified.");
  138. }
  139. $this->_fields[$key] = $value;
  140. }
  141. public function offsetExists($key) {
  142. return isset($this->_fields[$key]);
  143. }
  144. public function offsetUnset($key) {
  145. unset($this->_fields[$key]);
  146. }
  147. }
  148. ?>