PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Shanty/Mongo/DocumentSet.php

https://bitbucket.org/ilyabazhenov/speakplace
PHP | 261 lines | 150 code | 43 blank | 68 comment | 36 complexity | 01e0be0be1db5961973a37709f541820 MD5 | raw file
  1. <?php
  2. /**
  3. * @category Shanty
  4. * @package Shanty_Mongo
  5. * @copyright Shanty Tech Pty Ltd
  6. * @license New BSD License
  7. * @author Coen Hyde
  8. */
  9. class Shanty_Mongo_DocumentSet extends Shanty_Mongo_Document
  10. {
  11. const DYNAMIC_INDEX = '$';
  12. protected static $_requirements = array(
  13. self::DYNAMIC_INDEX => 'Document'
  14. );
  15. /**
  16. * Get the property keys for this Document Set
  17. *
  18. * @return array
  19. */
  20. public function getPropertyKeys()
  21. {
  22. $keys = parent::getPropertyKeys();
  23. sort($keys, SORT_NUMERIC);
  24. return $keys;
  25. }
  26. /**
  27. * Get a property
  28. *
  29. * @param mixed $property
  30. */
  31. public function getProperty($index = null)
  32. {
  33. $new = is_null($index);
  34. // If property exists and initialised then return it
  35. if (!$new && array_key_exists($index, $this->_data)) {
  36. return $this->_data[$index];
  37. }
  38. // Make sure we are not trying to create a document that is supposed to be saved as a reference
  39. if ($new && $this->hasRequirement(static::DYNAMIC_INDEX, 'AsReference')) {
  40. require_once 'Shanty/Mongo/Exception.php';
  41. throw new Shanty_Mongo_Exception("Can not create a new document from documentset where document must be saved as a reference");
  42. }
  43. if (!$new) {
  44. // Fetch clean data for this property if it exists
  45. if (array_key_exists($index, $this->_cleanData)) $data = $this->_cleanData[$index];
  46. else return null;
  47. }
  48. else $data = array();
  49. // If property is a reference to another document then fetch the reference document
  50. if (MongoDBRef::isRef($data)) {
  51. $collection = $data['$ref'];
  52. $data = MongoDBRef::get($this->_getMongoDB(false), $data);
  53. // If this is a broken reference then no point keeping it for later
  54. if (!$data) {
  55. $this->_data[$index] = null;
  56. return $this->_data[$index];
  57. }
  58. $reference = true;
  59. }
  60. else {
  61. $reference = false;
  62. $collection = $this->getConfigAttribute('collection');
  63. }
  64. $config = array ();
  65. $config['new'] = $new;
  66. $config['requirementModifiers'] = $this->getRequirements(self::DYNAMIC_INDEX.'.');
  67. $config['parentIsDocumentSet'] = true;
  68. $config['connectionGroup'] = $this->getConfigAttribute('connectionGroup');
  69. $config['db'] = $this->getConfigAttribute('db');
  70. $config['collection'] = $collection;
  71. if (!$reference) {
  72. // If this is a new array element. We will $push to the array when saving
  73. if ($new) $path = $this->getPathToDocument();
  74. else $path = $this->getPathToProperty($index);
  75. $config['pathToDocument'] = $path;
  76. $config['criteria'] = $this->getCriteria();
  77. $config['hasId'] = $this->hasRequirement(self::DYNAMIC_INDEX, 'hasId');
  78. }
  79. // get the document class
  80. $documentClass = $this->hasRequirement(self::DYNAMIC_INDEX, 'Document');
  81. if (isset($data['_type']) && !empty($data['_type'][0])) {
  82. $documentClass = $data['_type'][0];
  83. }
  84. $document = new $documentClass($data, $config);
  85. // if this document was a reference then remember that
  86. if ($reference) {
  87. $this->_references->attach($document);
  88. }
  89. // If this is not a new document cache it
  90. if (!$new) {
  91. $this->_data[$index] = $document;
  92. }
  93. return $document;
  94. }
  95. /**
  96. * Set property
  97. *
  98. * @param $index
  99. * @param $document
  100. */
  101. public function setProperty($index, $document)
  102. {
  103. $new = is_null($index);
  104. // Make sure index is numeric
  105. if (!$new && !is_numeric($index)) {
  106. require_once 'Shanty/Mongo/Exception.php';
  107. throw new Shanty_Mongo_Exception("Index must be numeric '{$index}' given");
  108. }
  109. // Unset element
  110. if (!$new && is_null($document)) {
  111. $this->_data[$index] = null;
  112. return;
  113. }
  114. // Make sure we are not keeping a copy of the old document in reference memory
  115. if (!$new && isset($this->_data[$index]) && !is_null($this->_data[$index])) {
  116. $this->_references->detach($this->_data[$index]);
  117. }
  118. // Throw exception if value is not valid
  119. $validators = $this->getValidators(self::DYNAMIC_INDEX);
  120. if (!$validators->isValid($document)) {
  121. require_once 'Shanty/Mongo/Exception.php';
  122. throw new Shanty_Mongo_Exception(implode($validators->getMessages(), "\n"));
  123. }
  124. if ($new) {
  125. $keys = $this->getPropertyKeys();
  126. $index = empty($keys) ? 0 : max($keys)+1;
  127. }
  128. // Filter value
  129. // $value = $this->getFilters(self::DYNAMIC_INDEX)->filter($document);
  130. if (!$this->hasRequirement(self::DYNAMIC_INDEX, 'AsReference')) {
  131. // Make a new document if it has been saved somewhere else
  132. if (!$document->isNewDocument()) {
  133. $documentClass = get_class($document);
  134. $document = new $documentClass($document->export(), array('new' => false, 'pathToDocument' => $this->getPathToProperty($index)));
  135. }
  136. else {
  137. $document->setPathToDocument($this->getPathToProperty($index));
  138. }
  139. // Inform the document of it's surroundings
  140. $document->setConfigAttribute('connectionGroup', $this->getConfigAttribute('connectionGroup'));
  141. $document->setConfigAttribute('db', $this->getConfigAttribute('db'));
  142. $document->setConfigAttribute('collection', $this->getConfigAttribute('collection'));
  143. $document->setConfigAttribute('criteria', $this->getCriteria());
  144. $document->applyRequirements($this->getRequirements(self::DYNAMIC_INDEX.'.'));
  145. }
  146. $this->_data[$index] = $document;
  147. }
  148. /**
  149. * Export all data
  150. *
  151. * @return array
  152. */
  153. public function export()
  154. {
  155. // Since this is an array, fill in empty index's with null
  156. $exportData = parent::export();
  157. // Fix PHP "max(): Array must contain at least one element" bug
  158. // if DocumentSet has no data
  159. if (count($exportData) > 0) {
  160. $maxKey = max(array_keys($exportData));
  161. for ($i = 0; $i<$maxKey; $i++) {
  162. if (array_key_exists($i, $exportData)) {
  163. continue;
  164. }
  165. $exportData[$i] = null;
  166. }
  167. ksort($exportData);
  168. }
  169. return $exportData;
  170. }
  171. /**
  172. * Add a document to this set
  173. *
  174. * @param Shanty_Mongo_Document $document
  175. */
  176. public function addDocument(Shanty_Mongo_Document $document)
  177. {
  178. return $this->setProperty(null, $document);
  179. }
  180. /**
  181. * Add a document to the push queue
  182. *
  183. * @param Shanty_Mongo_Document $document
  184. */
  185. public function pushDocument(Shanty_Mongo_Document $document)
  186. {
  187. $this->push(null, $document);
  188. }
  189. /**
  190. * Get all operations
  191. *
  192. * @param Boolean $includingChildren Get operations from children as well
  193. */
  194. public function getOperations($includingChildren = false)
  195. {
  196. if ($this->hasRequirement(self::DYNAMIC_INDEX, 'AsReference')) $includingChildren = false;
  197. return parent::getOperations($includingChildren);
  198. }
  199. /**
  200. * Remove all operations
  201. *
  202. * @param Boolean $includingChildren Remove operations from children as wells
  203. */
  204. public function purgeOperations($includingChildren = false)
  205. {
  206. if ($this->hasRequirement(self::DYNAMIC_INDEX, 'AsReference')) $includingChildren = false;
  207. return parent::purgeOperations($includingChildren);
  208. }
  209. public function __call($name, $arguments = array())
  210. {
  211. switch ($name) {
  212. case 'new':
  213. return $this->getProperty();
  214. }
  215. require_once 'Shanty/Mongo/Exception.php';
  216. throw new Shanty_Mongo_Exception("Captured in __call. Method $name does not exist.");
  217. }
  218. }