From 77242cc50f49a471f7b7337265004bd859cf42da Mon Sep 17 00:00:00 2001 From: Ilija Studen Date: Mon, 16 Nov 2015 10:25:28 +0100 Subject: [PATCH] Add TypeInterface::serialize() functionality --- src/Builder/BaseTypeClassBuilder.php | 73 ++++++++++++++++++- src/Type.php | 28 +++++++ src/TypeInterface.php | 15 ++++ test/src/CodeBuilderTest.php | 16 ++++ .../src/Fixtures/Writers/WritersStructure.php | 2 +- 5 files changed, 129 insertions(+), 5 deletions(-) diff --git a/src/Builder/BaseTypeClassBuilder.php b/src/Builder/BaseTypeClassBuilder.php index dd28be8..7406c34 100644 --- a/src/Builder/BaseTypeClassBuilder.php +++ b/src/Builder/BaseTypeClassBuilder.php @@ -133,15 +133,13 @@ public function buildType(TypeInterface $type) foreach ($fields as $field) { if ($field instanceof ScalarField && $field->getShouldBeAddedToModel() && $field->getName() != 'id') { - $camelized_field_name = Inflector::classify($field->getName()); - $result[] = ''; $result[] = ' /**'; $result[] = ' * Return value of ' . $field->getName() . ' field'; $result[] = ' *'; $result[] = ' * @return ' . $field->getNativeType(); $result[] = ' */'; - $result[] = ' public function get' . $camelized_field_name . '()'; + $result[] = ' public function ' . $this->getGetterName($field->getName()) . '()'; $result[] = ' {'; $result[] = ' return $this->getFieldValue(' . var_export($field->getName(), true) . ');'; $result[] = ' }'; @@ -152,7 +150,7 @@ public function buildType(TypeInterface $type) $result[] = ' * @param ' . $field->getNativeType() . ' $value'; $result[] = ' * @return $this'; $result[] = ' */'; - $result[] = ' public function &set' . $camelized_field_name . '($value)'; + $result[] = ' public function &' . $this->getSetterName($field->getName()) . '($value)'; $result[] = ' {'; $result[] = ' $this->setFieldValue(' . var_export($field->getName(), true) . ', $value);'; $result[] = ''; @@ -207,6 +205,7 @@ public function buildType(TypeInterface $type) $result[] = ' return $this;'; $result[] = ' }'; + $this->buildJsonSerialize($type->getSerialize(), ' ', $result); $this->buildCompositeFieldMethods($type->getFields(), ' ', $result); $this->buildValidate($type->getFields(), ' ', $result); @@ -238,6 +237,35 @@ public function buildCompositeFieldMethods($fields, $indent, array &$result) } } + /** + * Build JSON serialize method, if we need to serialize extra fields + * + * @param array $serialize + * @param string $indent + * @param array $result + */ + public function buildJsonSerialize(array $serialize, $indent, array &$result) + { + if (count($serialize)) { + $result[] = ''; + $result[] = $indent . '/**'; + $result[] = $indent . ' * Prepare object properties so they can be serialized to JSON'; + $result[] = $indent . ' *'; + $result[] = $indent . ' * @return array'; + $result[] = $indent . ' */'; + $result[] = $indent . 'public function jsonSerialize()'; + $result[] = $indent . '{'; + $result[] = $indent . ' return array_merge(parent::jsonSerialize(), ['; + + foreach ($serialize as $field) { + $result[] = $indent . ' ' . var_export($field, true) . ' => $this->' . $this->getGetterName($field) . '(), '; + } + + $result[] = $indent . ' ]);'; + $result[] = $indent . '}'; + } + } + /** * @param FieldInterface[] $fields * @param string $indent @@ -351,4 +379,41 @@ private function buildValidatePresenceAndUniquenessLine($field_name, array $cont return '$validator->presentAndUnique(' . implode(', ', $field_names) . ');'; } + + /** + * @var array + */ + private $getter_names = [], $setter_names = []; + + /** + * @param string $field_name + * @return string + */ + private function getGetterName($field_name) + { + if (empty($this->getter_names[$field_name])) { + $camelized_field_name = Inflector::classify($field_name); + + $this->getter_names[$field_name] = "get{$camelized_field_name}"; + $this->setter_names[$field_name] = "set{$camelized_field_name}"; + } + + return $this->getter_names[$field_name]; + } + + /** + * @param string $field_name + * @return string + */ + private function getSetterName($field_name) + { + if (empty($this->setter_names[$field_name])) { + $camelized_field_name = Inflector::classify($field_name); + + $this->getter_names[$field_name] = "get{$camelized_field_name}"; + $this->setter_names[$field_name] = "set{$camelized_field_name}"; + } + + return $this->setter_names[$field_name]; + } } \ No newline at end of file diff --git a/src/Type.php b/src/Type.php index 082f0a9..acadfdc 100644 --- a/src/Type.php +++ b/src/Type.php @@ -577,4 +577,32 @@ public function &orderBy($order_by) return $this; } + + /** + * @var array + */ + private $serialize = []; + + /** + * Return a list of additional fields that will be included during object serialization + * + * @return array + */ + public function getSerialize() + { + return $this->serialize; + } + + /** + * Set a list of fields that will be included during object serialization + * + * @param string ...$fields + * @return $this + */ + public function &serialize(...$fields) + { + $this->serialize = $fields; + + return $this; + } } diff --git a/src/TypeInterface.php b/src/TypeInterface.php index ab7ae7d..72b735e 100644 --- a/src/TypeInterface.php +++ b/src/TypeInterface.php @@ -210,4 +210,19 @@ public function getOrderBy(); * @return $this */ public function &orderBy($order_by); + + /** + * Return a list of additional fields that will be included during object serialization + * + * @return array + */ + public function getSerialize(); + + /** + * Set a list of fields that will be included during object serialization + * + * @param string ...$fields + * @return $this + */ + public function &serialize(...$fields); } diff --git a/test/src/CodeBuilderTest.php b/test/src/CodeBuilderTest.php index 04b2523..7b54e3f 100644 --- a/test/src/CodeBuilderTest.php +++ b/test/src/CodeBuilderTest.php @@ -2,6 +2,7 @@ namespace ActiveCollab\DatabaseStructure\Test; +use ActiveCollab\DatabaseConnection\Test\Fixture\Writer; use ActiveCollab\DatabaseStructure\Structure; use ActiveCollab\DatabaseStructure\Test\Fixtures\Writers\WritersStructure; use ReflectionClass; @@ -271,4 +272,19 @@ public function testChaptersOrderBy() $this->assertCount(1, $order_by); $this->assertEquals('position', $order_by[0]); } + + /** + * Test if JSON serialize is properly defined in writer class + */ + public function testJsonSerializeIsDefinedInBookClass() + { + $json_serialize = $this->base_writer_reflection->getMethod('jsonSerialize'); + $this->assertEquals($this->base_writer_reflection->getName(), $json_serialize->getDeclaringClass()->getName()); + + $json_serialize = $this->base_book_reflection->getMethod('jsonSerialize'); + $this->assertEquals('ActiveCollab\DatabaseObject\Object', $json_serialize->getDeclaringClass()->getName()); + + $json_serialize = $this->base_chapter_reflection->getMethod('jsonSerialize'); + $this->assertEquals('ActiveCollab\DatabaseObject\Object', $json_serialize->getDeclaringClass()->getName()); + } } \ No newline at end of file diff --git a/test/src/Fixtures/Writers/WritersStructure.php b/test/src/Fixtures/Writers/WritersStructure.php index 1a80b15..9faebdb 100644 --- a/test/src/Fixtures/Writers/WritersStructure.php +++ b/test/src/Fixtures/Writers/WritersStructure.php @@ -26,7 +26,7 @@ public function configure() new Index('birthday'), ])->addAssociations([ new HasManyAssociation('books'), - ])->orderBy('name'); + ])->orderBy('name')->serialize('name', 'birthday'); $this->addType('books')->addFields([ (new NameField('title', '', true))->required()->unique('writer_id'),