EEmbeddedArraysBehavior.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. /**
  3. * EEmbeddedArraysBehavior.php
  4. *
  5. * PHP version 5.2+
  6. *
  7. * @author Dariusz Górecki <darek.krk@gmail.com>
  8. * @author Invenzzia Group, open-source division of CleverIT company http://www.invenzzia.org
  9. * @copyright 2011 CleverIT http://www.cleverit.com.pl
  10. * @license http://www.yiiframework.com/license/ BSD license
  11. * @version 1.3
  12. * @category ext
  13. * @package ext.YiiMongoDbSuite
  14. * @since v1.0
  15. */
  16. /**
  17. * @since v1.0
  18. */
  19. class EEmbeddedArraysBehavior extends EMongoDocumentBehavior
  20. {
  21. /**
  22. * Name of property witch holds array od documents
  23. *
  24. * @var string $arrayPropertyName
  25. * @since v1.0
  26. */
  27. public $arrayPropertyName;
  28. /**
  29. * Class name of doc in array
  30. *
  31. * @var string $arrayDocClassName
  32. * @since v1.0
  33. */
  34. public $arrayDocClassName;
  35. private $_cache;
  36. /**
  37. * This flag shows us if we're connected to an embedded document
  38. *
  39. * @var boolean $_embeddedOwner
  40. */
  41. private $_embeddedOwner;
  42. public function events() {
  43. if (!$this->_embeddedOwner) {
  44. return parent::events();
  45. }
  46. else {
  47. // If attached to an embedded document these events are not defined
  48. // and would throw an error if attached to
  49. $events = parent::events();
  50. unset($events['onBeforeSave']);
  51. unset($events['onAfterSave']);
  52. unset($events['onBeforeDelete']);
  53. unset($events['onAfterDelete']);
  54. unset($events['onBeforeFind']);
  55. unset($events['onAfterFind']);
  56. return $events;
  57. }
  58. }
  59. /**
  60. * @since v1.0
  61. * @see CBehavior::attach()
  62. */
  63. public function attach($owner)
  64. {
  65. // Test if we have correct embding class
  66. if(!is_subclass_of($this->arrayDocClassName, 'EMongoEmbeddedDocument'))
  67. throw new CException(Yii::t('yii', get_class($testObj).' is not a child class of EMongoEmbeddedDocument!'));
  68. $this->_embeddedOwner = !($owner instanceof EMongoDocument);
  69. parent::attach($owner);
  70. $this->parseExistingArray();
  71. }
  72. /**
  73. * Event: initialize array of embded documents
  74. * @since v1.0
  75. */
  76. public function afterEmbeddedDocsInit($event)
  77. {
  78. $this->parseExistingArray();
  79. }
  80. /**
  81. * @since v1.0
  82. */
  83. private function parseExistingArray()
  84. {
  85. if(is_array($this->getOwner()->{$this->arrayPropertyName}))
  86. {
  87. $arrayOfDocs = array();
  88. foreach($this->getOwner()->{$this->arrayPropertyName} as $doc)
  89. {
  90. $obj = new $this->arrayDocClassName;
  91. $obj->setAttributes($doc, false);
  92. // If any EEmbeddedArraysBehavior is attached,
  93. // then we should trigger parsing of the newly set
  94. // attributes
  95. foreach (array_keys($obj->behaviors()) as $name) {
  96. $behavior = $obj->asa($name);
  97. if ($behavior instanceof EEmbeddedArraysBehavior) {
  98. $behavior->parseExistingArray();
  99. }
  100. }
  101. $arrayOfDocs[] = $obj;
  102. }
  103. $this->getOwner()->{$this->arrayPropertyName} = $arrayOfDocs;
  104. }
  105. }
  106. /**
  107. * @since v1.0.2
  108. */
  109. public function afterValidate($event)
  110. {
  111. parent::afterValidate($event);
  112. foreach($this->getOwner()->{$this->arrayPropertyName} as $doc)
  113. {
  114. if(!$doc->validate())
  115. $this->getOwner()->addErrors($doc->getErrors());
  116. }
  117. }
  118. public function beforeToArray($event)
  119. {
  120. if(is_array($this->getOwner()->{$this->arrayPropertyName}))
  121. {
  122. $arrayOfDocs = array();
  123. $this->_cache = $this->getOwner()->{$this->arrayPropertyName};
  124. foreach($this->_cache as $doc)
  125. {
  126. $arrayOfDocs[] = $doc->toArray();
  127. }
  128. $this->getOwner()->{$this->arrayPropertyName} = $arrayOfDocs;
  129. return true;
  130. }
  131. else
  132. return false;
  133. }
  134. /**
  135. * Event: re-initialize array of embedded documents which where toArray()ized by beforeSave()
  136. */
  137. public function afterToArray($event)
  138. {
  139. $this->getOwner()->{$this->arrayPropertyName} = $this->_cache;
  140. $this->_cache = null;
  141. }
  142. }