DocumentSet.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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\collection;
  9. use lithium\data\entity\Document;
  10. class DocumentSet extends \lithium\data\Collection {
  11. /**
  12. * Contains the original database value of the array. This value will be compared with the
  13. * current value (`$_data`) to calculate the changes that should be sent to the database.
  14. *
  15. * @var array
  16. */
  17. protected $_original = array();
  18. protected function _init() {
  19. parent::_init();
  20. $this->_original = $this->_data;
  21. }
  22. public function sync($id = null, array $data = array(), array $options = array()) {
  23. $defaults = array('materialize' => true);
  24. $options += $defaults;
  25. if ($options['materialize']) {
  26. $this->_exists = true;
  27. }
  28. $this->offsetGet(null);
  29. $this->_original = $this->_data;
  30. }
  31. /**
  32. * Determines if the `DocumentSet` has been modified since it was last saved
  33. *
  34. * @return boolean
  35. */
  36. public function modified() {
  37. if (count($this->_original) !== count($this->_data)) {
  38. return true;
  39. }
  40. foreach ($this->_original as $key => $doc) {
  41. $updated = $this->_data[$key];
  42. if (!isset($updated)) {
  43. return true;
  44. }
  45. if ($doc !== $updated) {
  46. return true;
  47. }
  48. if (!is_object($updated) || !method_exists($updated, 'modified')) {
  49. continue;
  50. }
  51. $modified = $this->_data[$key]->modified();
  52. if (in_array(true, $modified)) {
  53. return true;
  54. }
  55. }
  56. return false;
  57. }
  58. /**
  59. * Adds conversions checks to ensure certain class types and embedded values are properly cast.
  60. *
  61. * @param string $format Currently only `array` is supported.
  62. * @param array $options
  63. * @return mixed
  64. */
  65. public function to($format, array $options = array()) {
  66. $options += array('handlers' => array(
  67. 'MongoId' => function($value) { return (string) $value; },
  68. 'MongoDate' => function($value) { return $value->sec; }
  69. ));
  70. $this->offsetGet(null);
  71. return parent::to($format, $options);
  72. }
  73. public function export(array $options = array()) {
  74. $this->offsetGet(null);
  75. return array(
  76. 'exists' => $this->_exists,
  77. 'key' => $this->_pathKey,
  78. 'data' => array_values($this->_original),
  79. 'update' => array_values($this->_data)
  80. );
  81. }
  82. /**
  83. * Extract the next item from the result ressource and wraps it into a `Document` object.
  84. *
  85. * @return mixed Returns the next `Document` if exists. Returns `null` otherwise
  86. */
  87. protected function _populate() {
  88. if ($this->closed() || !$this->_result->valid()) {
  89. return;
  90. }
  91. $data = $this->_result->current();
  92. $result = $this->_set($data, null, array('exists' => true, 'original' => true));
  93. $this->_result->next();
  94. return $result;
  95. }
  96. protected function _set($data = null, $offset = null, $options = array()) {
  97. if ($schema = $this->schema()) {
  98. $model = $this->_model;
  99. $pathKey = $this->_pathKey;
  100. $options = compact('model', 'pathKey') + $options;
  101. $data = !is_object($data) ? $schema->cast($this, $offset, $data, $options) : $data;
  102. $key = $model && $data instanceof Document ? $model::key($data) : $offset;
  103. } else {
  104. $key = $offset;
  105. }
  106. if (is_array($key)) {
  107. $key = count($key) === 1 ? current($key) : null;
  108. }
  109. if (is_object($key)) {
  110. $key = (string) $key;
  111. }
  112. if (method_exists($data, 'assignTo')) {
  113. $data->assignTo($this);
  114. }
  115. $key !== null ? $this->_data[$key] = $data : $this->_data[] = $data;
  116. if (isset($options['original']) && $options['original']) {
  117. $key !== null ? $this->_original[$key] = $data : $this->_original[] = $data;
  118. }
  119. return $data;
  120. }
  121. }
  122. ?>