From a9f18c7396250e81157e1d790be83b87cb97446e Mon Sep 17 00:00:00 2001 From: Jeremy Dormitzer Date: Fri, 30 Nov 2018 07:00:14 -0500 Subject: [PATCH] Implement update --- src/Entities/ActivityPubObject.php | 26 +++++++- src/Objects/ObjectsService.php | 72 +++++++++++++++++++--- test/ObjectsServiceTest.php | 99 ++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+), 9 deletions(-) diff --git a/src/Entities/ActivityPubObject.php b/src/Entities/ActivityPubObject.php index b99efac..38d0302 100644 --- a/src/Entities/ActivityPubObject.php +++ b/src/Entities/ActivityPubObject.php @@ -153,7 +153,7 @@ class ActivityPubObject * * @param Field $field */ - public function addField(Field $field) + public function addField( Field $field ) { $this->fields[] = $field; $this->lastUpdated = new DateTime( "now" ); @@ -168,9 +168,31 @@ class ActivityPubObject * * @param Field $field */ - public function addReferencingField(Field $field) + public function addReferencingField( Field $field ) { $this->referencingFields[] = $field; } + + /** + * Removes a field from the object + * @param Field $field The field to remove + * + */ + public function removeField( Field $field ) + { + $this->fields->removeElement( $field ); + $this->lastUpdated = new DateTime( "now" ); + } + + /** + * Sets the last updated timestamp + * + * @param DateTime $lastUpdated The new last updated timestamp + * + */ + public function setLastUpdated( $lastUpdated ) + { + $this->lastUpdated = $lastUpdated; + } } ?> diff --git a/src/Objects/ObjectsService.php b/src/Objects/ObjectsService.php index daf408b..d93015b 100644 --- a/src/Objects/ObjectsService.php +++ b/src/Objects/ObjectsService.php @@ -1,6 +1,7 @@ query( array( 'id' => $fields['id'] ) ); - if ( ! empty( $existing ) ) { - return $existing[0]; + $existing = $this->getObject( $fields['id'] ); + if ( $existing ) { + return $existing; } } $object = new ActivityPubObject(); @@ -56,13 +57,13 @@ class ObjectsService */ private function persistField( $object, $fieldName, $fieldValue ) { - if ( is_string( $fieldValue ) ) { - $fieldEntity = Field::withValue( $object, $fieldName, $fieldValue ); - $this->entityManager->persist( $fieldEntity); - } else if ( is_array( $fieldValue ) ) { + if ( is_array( $fieldValue ) ) { $referencedObject = $this->createObject( $fieldValue ); $fieldEntity = Field::withObject( $object, $fieldName, $referencedObject ); $this->entityManager->persist( $fieldEntity ); + } else { + $fieldEntity = Field::withValue( $object, $fieldName, $fieldValue ); + $this->entityManager->persist( $fieldEntity); } } @@ -137,5 +138,62 @@ class ObjectsService count( $queryTerms ) ) ); } + + /** + * Gets an object by its ActivityPub id + * + * @param string $id The object's id + * + * @return ActivityPubObject|null The object or null + * if no object exists with that id + */ + public function getObject( $id ) + { + $results = $this->query( array( 'id' => $id ) ); + if ( ! empty( $results ) ) { + return $results[0]; + } + } + + /** + * Updates $object + * + * @param string $id The ActivityPub id of the object to update + * @param array $updatedFields An array where the key is a field name + * to update and the value is the field's new value. If the value is + * null, the field will be deleted. + * + * @return ActivityPubObject|null The updated object, + * or null if an object with that id isn't in the DB + */ + public function updateObject( $id, $updatedFields ) + { + $object = $this->getObject( $id ); + if ( ! $object ) { + return; + } + foreach( $object->getFields() as $field ) { + if ( array_key_exists( $field->getName(), $updatedFields ) ) { + $newValue = $updatedFields[$field->getName()]; + if ( is_array( $newValue ) ) { + // Should I handle orphaned nodes here? + $referencedObject = $this->createObject( $newValue ); + $field->setTargetObject( $referencedObject ); + $this->entityManager->persist( $field ); + } else if ( ! $newValue ) { + $object->removeField( $field ); + $this->entityManager->persist( $object ); + $this->entityManager->remove( $field ); + } else { + $field->setValue( $newValue ); + $this->entityManager->persist( $field ); + } + } + } + $object->setLastUpdated( new DateTime( "now" ) ); + $this->entityManager->persist( $object ); + $this->entityManager->flush(); + return $object; + } } ?> diff --git a/test/ObjectsServiceTest.php b/test/ObjectsServiceTest.php index 73cbf8c..ea5b3f8 100644 --- a/test/ObjectsServiceTest.php +++ b/test/ObjectsServiceTest.php @@ -745,5 +745,104 @@ class ObjectsServiceTest extends SQLiteTestCase $this->assertTablesEqual( $expectedObjectsTable, $objectsQueryTable ); $this->assertTablesEqual( $expectedFieldsTable, $fieldsQueryTable ); } + + public function testItGetsById() + { + $fields = array( + 'id' => 'https://example.com/note/1', + 'type' => 'Note', + 'content' => 'This is a note' + ); + $object = $this->objectsService->createObject( $fields ); + $found = $this->objectsService->getObject( 'https://example.com/note/1' ); + $this->assertNotNull( $found ); + $this->assertEquals( $object, $found ); + } + + public function testItReturnsNullIfIdNotFound() + { + $fields = array( + 'id' => 'https://example.com/note/1', + 'type' => 'Note', + 'content' => 'This is a note' + ); + $object = $this->objectsService->createObject( $fields ); + $found = $this->objectsService->getObject( 'https://example.com/note/2' ); + $this->assertNull( $found ); + } + + public function testItUpdatesObject() + { + $fields = array( + 'id' => 'https://example.com/notes/1', + 'type' => 'Note', + 'content' => 'This is a note' + ); + $createTime = self::getNow(); + $object = $this->objectsService->createObject( $fields ); + $update = array( 'content' => 'This note has been updated' ); + $updateTime = self::getNow(); + $this->objectsService->updateObject( 'https://example.com/notes/1', $update ); + $expected = new ArrayDataSet( array( + 'objects' => array( + array( + 'id' => 1, + 'created' => $createTime, + 'lastUpdated' => $updateTime + ), + ), + 'fields' => array( + array( + 'id' => 1, + 'object_id' => 1, + 'name' => 'id', + 'value' => 'https://example.com/notes/1', + 'created' => $createTime, + 'lastUpdated' => $createTime, + 'targetObject_id' => null, + ), + array( + 'id' => 2, + 'object_id' => 1, + 'name' => 'type', + 'value' => 'Note', + 'created' => $createTime, + 'lastUpdated' => $createTime, + 'targetObject_id' => null, + ), + array( + 'id' => 3, + 'object_id' => 1, + 'name' => 'content', + 'value' => 'This note has been updated', + 'created' => $createTime, + 'lastUpdated' => $updateTime, + 'targetObject_id' => null, + ), + ), + ) ); + $expectedObjectsTable = $expected->getTable('objects'); + $expectedFieldsTable = $expected->getTable('fields'); + $objectsQueryTable = $this->getConnection()->createQueryTable( + 'objects', 'SELECT * FROM objects' + ); + $fieldsQueryTable = $this->getConnection()->createQueryTable( + 'fields', 'SELECT * FROM fields' + ); + $this->assertTablesEqual( $expectedObjectsTable, $objectsQueryTable ); + $this->assertTablesEqual( $expectedFieldsTable, $fieldsQueryTable ); + } + + public function testItUpdatesObjectFieldToNewObject() + { + } + + public function testItUpdatedObjectFieldArray() + { + } + + public function testItDeletesObjectField() + { + } } ?>