Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

object state is now at the property level. This allows for the correc…

…tion of issue #14
  • Loading branch information...
commit baeaf9d930bb15203ea6e695f6a075ae2b16d7e0 1 parent 2cf0fae
Jonthan Moss authored
View
37 integration-tests/TestComposeMany.php
@@ -55,5 +55,42 @@ public function testStoresParentAndChild()
$this->assertDocumentPropertyEquals($expected, 'ComposeManyParent', 'Children', $parent->id());
}
+
+ public function testStoresAddedChild()
+ {
+ $parent = new ComposeManyParent();
+ $parent->Name = 'Compose Many Parent';
+
+ $child1 = new Child();
+ $child1->Name = 'Child1';
+ $parent->Children[] = $child1;
+
+ $parent->save();
+ $this->assertCollectionExists('ComposeManyParent');
+ $this->assertCollectionDoesNotExist('Child');
+
+ $this->assertDocumentExists('ComposeManyParent', $parent->id());
+
+ $expected = array (
+ array('_ns'=>'Child', 'Name'=>'Child1', 'Age' => null),
+ );
+
+ $this->assertDocumentPropertyEquals($expected, 'ComposeManyParent', 'Children', $parent->id());
+
+
+ $child2 = new Child();
+ $child2->Name = 'Child2';
+ $parent->Children[] = $child2;
+
+ $parent->save();
+
+ $expected = array (
+ array('_ns'=>'Child', 'Name'=>'Child1', 'Age' => null),
+ array('_ns'=>'Child', 'Name'=>'Child2', 'Age' => null)
+ );
+
+ $this->assertDocumentPropertyEquals($expected, 'ComposeManyParent', 'Children', $parent->id());
+ }
+
}
View
26 integration-tests/TestHasMany.php
@@ -52,5 +52,31 @@ public function testStoresParentAndChildren()
$this->assertDocumentExists('Child', $child2->id());
}
+
+ public function testStoresAddChild()
+ {
+ $parent = new HasManyParent();
+ $parent->Name = 'Has Many Parent';
+
+ $child1 = new Child();
+ $child1->Name = 'Child1';
+
+ $parent->Children[] = $child1;
+
+ $parent->save();
+ $this->assertCollectionExists('HasManyParent');
+ $this->assertCollectionExists('Child');
+
+ $this->assertDocumentExists('HasManyParent', $parent->id());
+ $this->assertDocumentExists('Child', $child1->id());
+
+ $child2 = new Child();
+ $child2->Name = 'Child2';
+
+ $parent->Children[] = $child2;
+ $parent->save();
+ $this->assertDocumentExists('Child', $child2->id());
+
+ }
}
View
2  integration-tests/mongoUnit/constraint/DocumentPropertyEquals.php
@@ -84,7 +84,7 @@ protected function customFailureDescription($other, $description, $not)
$this->property,
$other,
$this->toString(),
- \print_r($this->found)
+ \print_r($this->found, true)
);
}
}
View
2  src/bootstrap.php
@@ -46,6 +46,8 @@ class MorphAutoloader
'morph\\property\\Integer32' => 'phar://Morph/property/Integer32.php',
'morph\\property\\Integer64' => 'phar://Morph/property/Integer64.php',
'morph\\property\\Regex' => 'phar://Morph/property/Regex.php',
+ 'morph\\property\\Complex' => 'phar://Morph/property/Complex.php',
+ 'morph\\property\\StatefulCollection'=> 'phar://Morph/property/StatefulCollection.php',
'morph\\query\\Property' => 'phar://Morph/query/Property.php',
'morph\\format\\Collection' => 'phar://Morph/format/Collection.php',
'morph\\exception\\ObjectNotFound' => 'phar://Morph/exception/ObjectNotFound.php',
View
17 src/morph/Object.php
@@ -25,14 +25,6 @@ class Object
protected $id;
/**
- * The current state of this object
- *
- * one of Morph_Enum::STATE_*
- * @var string
- */
- protected $state;
-
- /**
* The data associated with this object
* @var \morph\PropertySet
*/
@@ -50,7 +42,6 @@ class Object
*/
public function __construct($id = null)
{
- $this->state = Enum::STATE_NEW;
$this->id = $id;
$this->propertySet = new PropertySet();
$this->validators = array();
@@ -95,7 +86,7 @@ public function id()
*/
public function state()
{
- return $this->state;
+ return $this->propertySet->getState();
}
/**
@@ -131,9 +122,8 @@ public function __setData(array $data, $state = Enum::STATE_DIRTY)
unset($data['_ns']);
}
foreach ($data as $propertyName => $value) {
- $this->propertySet->__setRawPropertyValue($propertyName, $value);
+ $this->propertySet->__setRawPropertyValue($propertyName, $value, $state);
}
- $this->state = $state;
return $this;
}
@@ -194,9 +184,6 @@ public function __set($propertyName, $propertyValue)
{
if (\array_key_exists($propertyName, $this->propertySet)) {
$this->propertySet[$propertyName]->setValue($propertyValue);
- if ($this->state == Enum::STATE_CLEAN) {
- $this->state = Enum::STATE_DIRTY;
- }
}else{
$this->addProperty(new \morph\property\Generic($propertyName, $propertyValue));
\trigger_error("The property $propertyName was not found in object of class " . \get_class($this) . ' but I have added it as a generic property type', E_USER_WARNING);
View
19 src/morph/PropertySet.php
@@ -69,13 +69,28 @@ public function __getRawPropertyValue($name)
* @param $name
* @param $value
*/
- public function __setRawPropertyValue($name, $value)
+ public function __setRawPropertyValue($name, $value, $state = null)
{
$name = $this->reverseStorageName($name);
if(!isset($this[$name])) {
$this[$name] = new \morph\property\Generic($name);
}
- $this[$name]->__setRawValue($value);
+ $this[$name]->__setRawValue($value, $state);
+ }
+
+ public function getState()
+ {
+ $state = \morph\Enum::STATE_NEW;
+ foreach ($this as $n => $property) {
+ $propertyState = $property->getState();
+ if ( \morph\Enum::STATE_DIRTY == $propertyState) {
+ $state = $propertyState;
+ break;
+ } elseif ( \morph\Enum::STATE_CLEAN == $propertyState) {
+ $state = $propertyState;
+ }
+ }
+ return $state;
}
/**
View
34 src/morph/property/Complex.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * @package Morph
+ * @subpackage Property
+ * @author Jonathan Moss <xirisr@gmail.com>
+ * @copyright Jonathan Moss 2009
+ */
+namespace morph\property;
+/**
+ * Class to represent a property within a table
+ *
+ * See Morph_Property_* for more specific implementations
+ *
+ * If you wish to create a more specialised property type you can extend
+ * this class. Overloading getValue() and setValue() allow you to
+ * provide automatic marshalling of data.
+ *
+ * @package Morph
+ * @subpackage Property
+ */
+class Complex extends Generic
+{
+ /**
+ * Called when the property changes
+ *
+ * @return void
+ */
+ public function _onChange()
+ {
+ if ($this->state == \morph\Enum::STATE_CLEAN) {
+ $this->state = \morph\Enum::STATE_DIRTY;
+ }
+ }
+}
View
14 src/morph/property/ComposeMany.php
@@ -16,7 +16,7 @@
* @package Morph
* @subpackage Property
*/
-class ComposeMany extends Generic
+class ComposeMany extends Complex
{
/**
@@ -33,7 +33,7 @@ class ComposeMany extends Generic
public function __construct($name, $type)
{
$this->type = $type;
- $default = new \morph\Collection();
+ $default = new \morph\property\StatefulCollection($this);
$default->setPermissableType($type);
parent::__construct($name, $default);
}
@@ -64,9 +64,9 @@ public function setValue($value){
* (non-PHPdoc)
* @see tao/classes/Morph/property/Morph_Property_Generic#__setRawValue()
*/
- public function __setRawValue($value)
+ public function __setRawValue($value, $state = null)
{
- $collection = new \morph\collection();
+ $collection = new \morph\Collection();
if (count($value) > 0) {
foreach ($value as $item) {
$object = new $this->type;
@@ -74,7 +74,10 @@ public function __setRawValue($value)
$collection->append($object);
}
}
- $this->value = $collection;
+ $this->value = new \morph\property\StatefulCollection($this, $collection);
+ if (null != $state) {
+ $this->state = $state;
+ }
}
/**
@@ -85,7 +88,6 @@ public function __getRawValue()
{
$rawValue = array();
if($this->value->count() > 0){
- //$rawValue = $this->Value->getArrayCopy();
foreach ($this->value as $value) {
$rawValue[] = $value->__getData();
}
View
24 src/morph/property/Generic.php
@@ -32,6 +32,14 @@ class Generic
* @var mixed
*/
protected $value;
+
+ /**
+ * The current state of this property
+ *
+ * @see Morph_Enum::STATE_*
+ * @var string
+ */
+ protected $state = \morph\Enum::STATE_NEW;
/**
*
@@ -44,6 +52,14 @@ public function __construct($name, $default = null)
$this->name = $name;
$this->value = $default;
}
+
+ /**
+ * @return string
+ */
+ public function getState()
+ {
+ return $this->state;
+ }
/**
* Returns the value associated with this property
@@ -62,6 +78,9 @@ public function getValue()
*/
public function setValue($value)
{
+ if ($this->state == \morph\Enum::STATE_CLEAN) {
+ $this->state = \morph\Enum::STATE_DIRTY;
+ }
$this->__setRawValue($value);
}
@@ -83,9 +102,12 @@ public function __getRawValue()
* @param $value
* @return Morph_Property_Generic
*/
- public function __setRawValue($value)
+ public function __setRawValue($value, $state = null)
{
$this->value = $value;
+ if (null != $state) {
+ $this->state = $state;
+ }
return $this;
}
View
21 src/morph/property/HasMany.php
@@ -15,7 +15,7 @@
* @package Morph
* @subpackage Property
*/
-class HasMany extends Generic
+class HasMany extends Complex
{
/**
@@ -43,7 +43,7 @@ class HasMany extends Generic
public function __construct($name, $type)
{
$this->type = $type;
- $default = new \morph\Collection();
+ $default = new \morph\property\StatefulCollection($this);
$default->setPermissableType($type);
parent::__construct($name, $default);
}
@@ -52,9 +52,13 @@ public function __construct($name, $type)
* (non-PHPdoc)
* @see tao/classes/Morph/property/Morph_Property_Generic#__setRawValue()
*/
- public function __setRawValue($value)
+ public function __setRawValue($value, $state = null)
{
$this->references = $value;
+ $this->loaded = false;
+ if (null != $state) {
+ $this->state = $state;
+ }
}
/**
@@ -94,7 +98,8 @@ public function getValue()
*/
public function setValue($value)
{
- if($value instanceof \morph\Collection) {
+ if($value instanceof \morph\property\StatefulCollection) {
+ $value->setOwner($this);
$this->value = $value;
$this->references = array();
}
@@ -108,6 +113,7 @@ public function setValue($value)
private function loadFromReferences()
{
$ids = array();
+ $collection = null;
if (count($this->references) > 0) {
foreach ($this->references as $reference){
$ids[] = $reference['$id'];
@@ -118,12 +124,13 @@ private function loadFromReferences()
$object = new $this->type;
- $this->value = \morph\Storage::instance()
+ $collection = \morph\Storage::instance()
->findByQuery($object, $query)
->toCollection(); //@todo this could get nasty with large collections!
- } else {
- $this->value = new \morph\Collection();
+
}
+
+ $this->value = new \morph\property\StatefulCollection($this, $collection);
$this->loaded = true;
}
View
8 src/morph/property/HasOne.php
@@ -59,6 +59,9 @@ public function __construct($name, $type, \morph\Object $default = null)
public function setValue($value)
{
$this->isPermissableType($value);
+ if ($this->state == \morph\Enum::STATE_CLEAN) {
+ $this->state = \morph\Enum::STATE_DIRTY;
+ }
$this->value = $value;
return $this;
}
@@ -95,9 +98,12 @@ public function __getRawValue()
* (non-PHPdoc)
* @see tao/classes/Morph/property/Morph_Property_Generic#__setRawValue()
*/
- public function __setRawValue($value)
+ public function __setRawValue($value, $state = null)
{
$this->reference = $value;
+ if (null !== $state) {
+ $this->state = $state;
+ }
}
/**
View
60 src/morph/property/StatefulCollection.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * @author Jonathan Moss
+ * @copyright 2009 Jonathan Moss <xirisr@gmail.com>
+ * @package Morph
+ */
+namespace morph\property;
+/**
+ * Morph collection object
+ *
+ * This is designed to work with finder methods within Morph_Object
+ *
+ * This object behaves like an array (e.g. it is Iterable, Countable and
+ * provides ArrayAccess).
+ *
+ * This collection class also provides a bunch of additional functionality
+ * such as sorting, filtering, reducing etc
+ *
+ * @package Morph
+ */
+class StatefulCollection extends \morph\Collection
+{
+
+ protected $owner;
+
+ public function __construct(\morph\property\Complex $owner, \morph\Collection $collection = null)
+ {
+ if (null !== $collection)
+ {
+ foreach ($collection as $object) {
+ $this->append($object);
+ }
+ }
+ $this->setOwner($owner);
+ }
+
+ public function setOwner(\morph\property\Complex $owner)
+ {
+ $this->owner = $owner;
+ }
+
+ public function append($object)
+ {
+ $this->onChange();
+ parent::append($object);
+ }
+
+ public function offsetSet($index, $newval)
+ {
+ $this->onChange();
+ parent::offsetSet($index, $newval);
+ }
+
+ private function onChange()
+ {
+ if (null !== $this->owner) {
+ $this->owner->_onChange();
+ }
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.