/** * Test constructor. * * @test * @covers \Bairwell\Hydrator\CachedProperty::__construct * @covers \Bairwell\Hydrator\CachedProperty::getName * @covers \Bairwell\Hydrator\CachedProperty::setName * @covers \Bairwell\Hydrator\CachedProperty::getClassName * @covers \Bairwell\Hydrator\CachedProperty::setClassName */ public function testConstructor() { $from = new \Bairwell\Hydrator\Annotations\From(); /* @var AsBase $AsBase */ $AsBase = $this->getMockForAbstractClass('\\Bairwell\\Hydrator\\Annotations\\AsBase'); $sut = new CachedProperty('testClass', 'testingName', $from); $this->assertEquals('testClass', $sut->getClassName()); $this->assertEquals('testingName', $sut->getName()); $this->assertSame($from, $sut->getFrom()); $this->assertFalse($sut->hasCastAs()); $sut = new CachedProperty('test2Class', 'testing2Name', $from, \ReflectionProperty::IS_PUBLIC, $AsBase); $this->assertEquals('test2Class', $sut->getClassName()); $this->assertEquals('testing2Name', $sut->getName()); $this->assertSame($from, $sut->getFrom()); $this->assertTrue($sut->hasCastAs()); $this->assertSame($AsBase, $sut->getCastAs()); $this->assertSame($sut, $sut->setName('jeff')); $this->assertEquals('jeff', $sut->getName()); $this->assertSame($sut, $sut->setClassName('thingy')); $this->assertEquals('thingy', $sut->getClassName()); }
/** * Add a property onto our list. * * @param \Bairwell\Hydrator\CachedProperty $value The property we are adding/stacking. * * @return CachedClass * * @throws \TypeError If class of property does not match this class. */ public function add(CachedProperty $value) : self { $offset = $value->getName(); if (false === isset($this->properties[$offset])) { $this->properties[$offset] = []; } $this->properties[$offset][] = $value; return $this; }
/** * Hydrate a single property. * * @param CachedProperty $property The property we are hydrating. * @param object $object The object we are injecting into (reference). * @param Sources $sources The hydration sources. * @param Conditionals $conditionals The conditions to run. * @param FailureList $failureList Our current list of failure reasons (reference). * * @return object The object after we have injected into it. * @throws \TypeError If not passed an object. */ public function hydrateSingleProperty(CachedProperty $property, $object, Sources $sources, Conditionals $conditionals, FailureList &$failureList) { if (false === is_object($object)) { throw new \TypeError('HydrateSingleProperty must be passed an ' . 'object as $object: got ' . gettype($object)); } $propertyName = $property->getName(); $className = $property->getClassName(); // double check our data just in case things have changed from the cached version. $from = $property->getFrom(); $annotationSources = $this->validateSources($from->sources, $className . '::$' . $propertyName, $sources); $annotationConditions = $this->validateConditions($from->conditions, $className . '::$' . $propertyName, $conditionals); $fromField = $from->field; if (true === empty($fromField)) { $fromField = $propertyName; } // now to check the conditions are okay for hydration. foreach ($annotationConditions as $annotationCondition) { if (false === call_user_func($conditionals[$annotationCondition])) { return $object; } } $currentValue = null; foreach ($annotationSources as $annotationSource) { if (null !== $this->logger) { $this->logger->debug('Attempting to hydrate {className}.{propertyName} from {annotationSource}.{fromField} : Current value "{currentValue}"', ['className' => $className, 'propertyName' => $propertyName, 'annotationSource' => $annotationSource, 'fromField' => $fromField, 'currentValue' => (string) $currentValue]); } $currentValue = $this->hydrateSinglePropertyViaSource($currentValue, $sources[$annotationSource], $annotationSource, $fromField, $property, $failureList); } //end foreach if (null !== $currentValue) { $this->logger->debug('Setting value of {className}.{propertyName} : {type}', ['className' => $className, 'propertyName' => $propertyName, 'type' => gettype($currentValue)]); // only use reflection if necessary. if (true === $property->isPublic()) { $object->{$propertyName} = $currentValue; } else { $reflectedProperty = new \ReflectionProperty(get_class($object), $propertyName); $reflectedProperty->setAccessible(true); $reflectedProperty->setValue($object, $currentValue); } } else { $this->logger->debug('No change in value for {className}.{propertyName}', ['className' => $className, 'propertyName' => $propertyName]); } //end if return $object; }