예제 #1
0
 /**
  * ><p>**Note:** for use by MacroCall.
  *
  * @param string $name
  * @return false|null|string
  * @throws ComponentException
  */
 public function getParameterType($name)
 {
     $param = $this->getParameter($name);
     if (isset($param)) {
         $p = type::getIdOf($param->props->type);
         if ($p === false) {
             $s = join('</kbd>, <kbd>', type::getAllNames());
             throw new ComponentException($this, "The <kbd>{$name}</kbd> parameter has an invalid type: <kbd>{$param->props->type}</kbd>.<p>Expected values: <kbd>{$s}</kbd>.");
         }
         return $p;
     }
     return null;
 }
예제 #2
0
 function render()
 {
     // Validate defaultParam's value.
     $def = $this->getDefaultParam();
     if (!empty($def)) {
         if (!$this->props->defines($def)) {
             throw new ComponentException($this, "Invalid value for <kbd>defaultParam</kbd> on <b>&lt;{$this->props->macro}></b>; parameter <kbd>{$def}</kbd> does not exist");
         }
         // Move children to default parameter.
         if ($this->hasChildren()) {
             $type = $this->props->getTypeOf($def);
             if ($type != type::content && $type != type::metadata) {
                 throw new ComponentException($this, sprintf("The macro's default parameter <kbd>{$def}</kbd> can't hold content because its type is <kbd>%s</kbd>.", type::getNameOf($type)));
             }
             $param = new Metadata($this->context, ucfirst($def), $type);
             $this->props->set($def, $param);
             $param->attachTo($this);
             $param->setChildren($this->getChildren());
         }
     } elseif ($this->hasChildren()) {
         throw new ComponentException($this, 'You may not specify content for this tag because it has no default property');
     }
     parent::render();
 }
예제 #3
0
 /**
  * Converts a value that will be assigned to a property into a type compatible with that
  * property.
  * >**Note:** you should call {@see validate()} before calling this method, as the later does not
  * validate its input.
  *
  * @param string $type The property type.
  * @param mixed  $v    The value to be converted.
  * @return bool|float|int|null|string|\Traversable
  */
 public static function typecast($type, $v)
 {
     if (isset($v) && $v !== '') {
         switch ($type) {
             case type::bool:
                 return type::toBoolean($v);
             case type::id:
                 return $v;
             case type::number:
                 return is_float($v) ? floatval($v) : intval($v);
             case type::string:
                 return strval($v);
             case type::data:
                 if ($v instanceof \Iterator) {
                     return $v;
                 }
                 if ($v instanceof \IteratorAggregate) {
                     return $v->getIterator();
                 }
                 return $v;
         }
     }
     return $v;
 }
 /**
  * Returns the value converted to a the data type required by the specified property.
  *
  * @param string $name
  * @param mixed  $v
  * @return bool|float|int|null|string|\Traversable
  * @throws ComponentException
  */
 function typecastPropertyValue($name, $v)
 {
     if ($this->isScalar($name) && $this->isEnum($name)) {
         $this->validateEnum($name, $v);
     }
     $type = $this->getTypeOf($name);
     if ($type && !type::validate($type, $v)) {
         throw new ComponentException($this->component, sprintf("%s is not a valid value for the <kbd>{$name}</kbd> property, which is of type <kbd>%s</kbd>", is_scalar($v) ? sprintf("The %s<kbd>%s</kbd>", typeOf($v), var_export($v, true)) : sprintf("A value of PHP type <kbd>%s</kbd>", typeOf($v)), type::getNameOf($type)));
     }
     // A special case for content type properties:
     // Convert a content property specified as attribute=string to a format equivalent to the one generated by
     // <subtag>string</subtag>
     if ($type == type::content && is_string($v)) {
         $content = new Metadata($this->component->context, $name, type::metadata);
         $content->setChildren([Text::from($this->component->context, $v)]);
         return $content;
     }
     return type::typecast($type, $v);
 }