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);
     }
 }
Пример #2
0
 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);
     }
 }
Пример #4
0
 public function testHasSetterByBeanProperty()
 {
     $mock = new StrictBean('Mickael', 'Dundie', 'black', true);
     $bean = new Bean($mock);
     $property = $bean->getProperty('firstName');
     $this->assertTrue($bean->hasSetter($property) !== false);
 }