public function marshall() { $ctx = $this->getContext(); $access = $ctx->getStreamAccess(); $component = $this->getToMarshall(); try { $asInstanceOf = $this->getAsInstanceOf(); $bean = new Bean($component, false, $asInstanceOf); // -- Component Instantiation. $ctorArgs = $bean->getConstructorParameters(); $ctorArgsCount = count($ctorArgs); $phpArgs = new PhpArgumentCollection(); if ($ctorArgsCount > 0) { $poppedVarNames = $ctx->popFromVariableStack($ctorArgsCount); for ($i = 0; $i < $ctorArgsCount; $i++) { $phpArgs[] = new PhpArgument(new PhpVariable($poppedVarNames[$i])); } } $componentVarName = $this->getVariableName(); $componentVarName = empty($componentVarName) === true ? $ctx->generateVariableName($component) : $componentVarName; $access->writeVariable($componentVarName); $access->writeEquals($ctx->mustFormatOutput()); $access->writeInstantiation(empty($asInstanceOf) === true ? get_class($component) : $asInstanceOf, $phpArgs); $access->writeSemicolon($ctx->mustFormatOutput()); // -- Call to setters (that are not involved in the component construction). $setters = $bean->getSetters(true); $settersCount = count($setters); if ($settersCount > 0) { $poppedVarNames = $ctx->popFromVariableStack($settersCount); for ($i = 0; $i < $settersCount; $i++) { $phpArgs = new PhpArgumentCollection(); $phpArgs[] = new PhpArgument(new PhpVariable($poppedVarNames[$i])); $access->writeMethodCall($componentVarName, $setters[$i]->getName(), $phpArgs); $access->writeSemicolon($ctx->mustFormatOutput()); } } $ctx->pushOnVariableStack($componentVarName); } catch (BeanException $e) { $msg = "The given QtiComponent to be marshalled into PHP source code is not a strict bean."; throw new PhpMarshallingException($msg, PhpMarshallingException::RUNTIME, $e); } }
public function testPropertyButNoSetter() { $mock = new SimpleBean('Name', 'Car'); $bean = new Bean($mock); $this->setExpectedException('\\qtism\\common\\beans\\BeanException', "The bean has no public setter for a 'noGetter' property."); $setter = $bean->getSetter('noGetter', BeanException::NO_METHOD); }
/** * Save the PhpDocument to a specific location. * * @param string $url A URL (Uniform Resource Locator) describing where to save the document. * @throws PhpStorageException If an error occurs while saving. */ public function save($url) { $stack = new SplStack(); $stack->push($this->getDocumentComponent()); // 1st/2nd pass marker. $marker = array(); try { // marshalling context. $stream = new MemoryStream(); $stream->open(); $streamAccess = new PhpStreamAccess($stream); $streamAccess->writeOpeningTag(); $ctx = new PhpMarshallingContext($streamAccess); $ctx->setFormatOutput(true); while (count($stack) > 0) { $component = $stack->pop(); $isMarked = in_array($component, $marker, true); if ($isMarked === false && $component instanceof QtiComponent) { // -- QtiComponent node, 1st pass. // Mark as explored. array_push($marker, $component); // Ask for a 2nd pass. $stack->push($component); // Let's look at the Bean properties and ask for a future exploration. $bean = new Bean($component, false, self::getBaseImplementation($component)); $ctorGetters = $bean->getConstructorGetters(); $bodyGetters = $bean->getGetters(true); $getters = array_reverse(array_merge($bodyGetters->getArrayCopy(), $ctorGetters->getArrayCopy())); foreach ($getters as $getter) { $stack->push(call_user_func(array($component, $getter->getName()))); } } else { if ($isMarked === false && ($component instanceof AbstractCollection && !$component instanceof Coords)) { // AbstractCollection node, 1st pass. // Mark as explored. array_push($marker, $component); // Ask for a 2nd pass. $stack->push($component); // Explore all values of the collection please! $values = array_reverse($component->getArrayCopy()); foreach ($values as $val) { $stack->push($val); } } else { if ($isMarked === true && $component instanceof QtiComponent) { // QtiComponent, 2nd pass. $marshaller = new PhpQtiComponentMarshaller($ctx, $component); $marshaller->setAsInstanceOf(self::getBaseImplementation($component)); if ($component === $this->getDocumentComponent()) { $marshaller->setVariableName('rootcomponent'); } $marshaller->marshall(); } else { if ($component instanceof QtiDatatype) { // Leaf node QtiDataType. $marshaller = new PhpQtiDatatypeMarshaller($ctx, $component); $marshaller->marshall(); } else { if ($isMarked === true && $component instanceof AbstractCollection) { // AbstractCollection, 2nd pass. $marshaller = new PhpCollectionMarshaller($ctx, $component); $marshaller->marshall(); } else { if (PhpUtils::isScalar($component) === true) { // Leaf node (QtiDatatype or PHP scalar (including the null value)). $marshaller = new PhpScalarMarshaller($ctx, $component); $marshaller->marshall(); } else { if (is_array($component) === true) { // Leaf node array. $marshaller = new PhpArrayMarshaller($ctx, $component); $marshaller->marshall(); } else { $msg = "Datatype '" . gettype($component) . "' cannot be handled by the PhpDocument::save() method."; throw new PhpStorageException($msg); } } } } } } } } file_put_contents($url, $stream->getBinary()); } catch (StreamAccessException $e) { $msg = "An error occured while writing the PHP source code stream."; throw new PhpStorageException($msg, 0, $e); } }
public function testHasSetterByBeanProperty() { $mock = new StrictBean('Mickael', 'Dundie', 'black', true); $bean = new Bean($mock); $property = $bean->getProperty('firstName'); $this->assertTrue($bean->hasSetter($property) !== false); }