/** * @covers \NObjects\Reflection\ReflectionClass */ public function testGetAncestorPrivatePropertiesReturnsPropertyNameOnlyOnce() { $fixture = new Fake\PotpourriChildChildChild(); $this->object = new ReflectionClass($fixture); $results = $this->object->getAncestorPrivateProperties(); $this->assertCount(2, $results); $this->assertCount(1, array_filter($results, function ($elem) { /** @var \ReflectionProperty $elem */ return $elem->getName() == 'privProp'; }), 'Ancestor private property privProp not in collection'); $this->assertCount(1, array_filter($results, function ($elem) { /** @var \ReflectionProperty $elem */ return $elem->getName() == 'childPrivProp'; }), 'Ancestor private property childPrivProp not in collection'); }
/** * Return object as an associative array (property & value pair). * * @param callable $valueClosure * @return array */ public function toArray($valueClosure = null) { $refl = new ReflectionClass($this); // Collect properties from this class as well as private property names from parents // which may have accessor methods. $props = array_unique(array_merge($refl->getProperties(), $refl->getAncestorPrivateProperties())); // adding support for public properties foreach ($this as $k => $v) { $props[] = (object) array('name' => $k, 'value' => $v); } $array = array(); foreach ($props as $rp) { $func = $this->_getAccessorMethod($rp->name); // skip properties that start with an _ // skip functions that don't exist if ($rp->name[0] == '_' || !method_exists($this, $func) && !isset($this->{$rp->name})) { continue; } // if public use temp object and don't cache if ($rp instanceof \ReflectionProperty) { if ($rp->isPublic()) { $val = $rp->getValue($this); } else { $val = $this->{$func}(); } } else { $val = $rp->value; } $base = __CLASS__; switch (true) { // is NObjects\Object instance case $val instanceof $base: $array[$rp->name] = $val->toArray($valueClosure); break; // intercept array types (ArrayObject, Collection) and convert $val to array // intercept array types (ArrayObject, Collection) and convert $val to array case method_exists($val, 'toArray'): $val = $val->toArray(); break; case $val instanceof \ArrayObject: $val = $val->getArrayCopy(); break; default: $array[$rp->name] = self::valueClosure($valueClosure, $val); break; } // do extra work when $val is an array if (is_array($val)) { foreach ($val as $k => $v) { if ($v instanceof $base) { $val[$k] = $v->toArray($valueClosure); } else { if (\NObjects\Validate::isAssociativeArray($v)) { $newObj = new \NObjects\Object($v); $val[$k] = $newObj->toArray($valueClosure); } else { $val[$k] = self::valueClosure($valueClosure, $v); } } } $array[$rp->name] = $val; } } return $array; }