diff --git a/library/Businessprocess/Web/Component/ActionBar.php b/library/Businessprocess/Web/Component/ActionBar.php new file mode 100644 index 0000000..0a71df0 --- /dev/null +++ b/library/Businessprocess/Web/Component/ActionBar.php @@ -0,0 +1,10 @@ + 'action-bar'); +} \ No newline at end of file diff --git a/library/Businessprocess/Web/Component/Attribute.php b/library/Businessprocess/Web/Component/Attribute.php new file mode 100644 index 0000000..dfabd00 --- /dev/null +++ b/library/Businessprocess/Web/Component/Attribute.php @@ -0,0 +1,98 @@ +name = $name; + $this->value = $value; + } + + /** + * @param $name + * @param $value + * @return static + */ + public static function create($name, $value) + { + return new static($name, $value); + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * @return string + */ + public function render() + { + return sprintf( + '%s="%s"', + $this->renderName(), + $this->renderValue() + ); + } + + /** + * @return string + */ + public function renderName() + { + return static::escapeName($this->name); + } + + /** + * @return string + */ + public function renderValue() + { + return static::escapeValue($this->value); + } + + /** + * @param $name + * @return string + */ + public static function escapeName($name) + { + // TODO: escape + return (string) $name; + } + + /** + * @param $value + * @return string + */ + public static function escapeValue($value) + { + // TODO: escape + return (string) $value; + } +} diff --git a/library/Businessprocess/Web/Component/Attributes.php b/library/Businessprocess/Web/Component/Attributes.php new file mode 100644 index 0000000..1c073b7 --- /dev/null +++ b/library/Businessprocess/Web/Component/Attributes.php @@ -0,0 +1,158 @@ +attributes = array(); + if (empty($attributes)) { + return; + } + + foreach ($attributes as $key => $value) { + if ($value instanceof Attribute) { + $this->addAttribute($value); + } elseif (is_string($key)) { + $this->add($key, $value); + } elseif (is_array($value) && count($value) === 2) { + $this->add(array_shift($value), array_shift($value)); + } + } + } + + /** + * @param Attribute[] $attributes + * @return static + */ + public static function create(array $attributes = null) + { + return new static($attributes); + } + + /** + * @param Attributes|array|null $attributes + * @return static + */ + public static function wantAttributes($attributes) + { + if ($attributes instanceof Attributes) { + return $attributes; + } else { + $self = new static(); + if (is_array($attributes)) { + foreach ($attributes as $k => $v) { + $self->add($k, $v); + } + + return $self; + + } elseif ($attributes !== null) { + throw new IcingaException( + 'Attributes, Array or Null expected, got %s', + $self->getPhpTypeName($attributes) + ); + } + return $self; + } + } + + /** + * @return Attribute[] + */ + public function attributes() + { + return $this->attributes; + } + + /** + * @param Attribute|string $attribute + * @param string|array $value + * @return $this + */ + public function add($attribute, $value = null) + { + if ($attribute instanceof static) { + foreach ($attribute as $a) { + $this->add($a); + } + + return $this; + } elseif ($attribute instanceof Attribute) { + return $this->addAttribute($attribute); + } else { + return $this->addAttribute(Attribute::create($attribute, $value)); + } + } + + /** + * @param Attribute|string $attribute + * @param string|array $value + * @return $this + */ + public function set($attribute, $value = null) + { + if ($attribute instanceof static) { + foreach ($attribute as $a) { + $this->setAttribute($a); + } + + return $this; + } else if ($attribute instanceof Attribute) { + return $this->setAttribute($attribute); + } else { + return $this->setAttribute(new Attribute($attribute, $value)); + } + } + + /** + * @param Attribute $attribute + * @return $this + */ + public function addAttribute(Attribute $attribute) + { + $name = $attribute->getName(); + if (array_key_exists($name, $this->attributes)) { + $this->attributes[$name]->addValue($attribute->getValue()); + } else { + $this->attributes[$name] = $attribute; + } + + return $this; + } + + /** + * @param Attribute $attribute + * @return $this + */ + public function setAttribute(Attribute $attribute) + { + $name = $attribute->getName(); + $this->attributes[$name] = $attribute; + return $this; + } + + /** + * @inheritdoc + */ + public function render() + { + if (empty($this->attributes)) { + return ''; + } + + return ' ' . implode(' ', $this->attributes); + } +} \ No newline at end of file diff --git a/library/Businessprocess/Web/Component/Component.php b/library/Businessprocess/Web/Component/Component.php new file mode 100644 index 0000000..fb7d873 --- /dev/null +++ b/library/Businessprocess/Web/Component/Component.php @@ -0,0 +1,134 @@ +view = $view; + return $this; + } + + /** + * @return View + */ + public function view() + { + if ($this->view === null) { + $this->view = $this->discoveredView(); + } + return $this->view; + } + + /** + * @return View + */ + protected function discoveredView() + { + if (self::$discoveredView === null) { + $viewRenderer = Icinga::app()->getViewRenderer(); + if ($viewRenderer->view === null) { + $viewRenderer->initView(); + } + + self::$discoveredView = $viewRenderer->view; + } + + return self::$discoveredView; + } + + /** + * @return string + */ + abstract function render(); + + public function wantHtml($any, $separator = '') + { + if ($any instanceof Component) { + return $any; + } elseif (is_string($any)) { + return $this->view()->escape($any); + } elseif (is_array($any)) { + $safe = array(); + foreach ($any as $el) { + $safe .= $this->wantHtml($el); + } + + return implode($separator, $safe); + } else { + // TODO: Should we add a dedicated Exception class? + throw new IcingaException( + 'String, Web Component or Array of such expected, got "%s"', + $this->getPhpTypeName($any) + ); + } + } + + public function getPhpTypeName($any) + { + if (is_object($any)) { + return get_class($any); + } else { + return gettype($any); + } + } + + /** + * @param Exception|string $error + * @return string + */ + protected function renderError($error) + { + if ($error instanceof Exception) { + $file = preg_split('/[\/\\\]/', $error->getFile(), -1, PREG_SPLIT_NO_EMPTY); + $file = array_pop($file); + $msg = sprintf( + '%s (%s:%d)', + $error->getMessage(), + $file, + $error->getLine() + ); + } elseif (is_string($error)) { + $msg = $error; + } else { + $msg = 'Got an invalid error'; + } + + + + + $view = $this->view(); + return sprintf( + $view->translate('ERROR: %s'), + $view->escape($msg) + ); + } + + /** + * @return string + */ + public function __toString() + { + try { + return $this->render(); + } catch (Exception $e) { + return $this->renderError($e); + } + } +} \ No newline at end of file diff --git a/library/Businessprocess/Web/Component/Container.php b/library/Businessprocess/Web/Component/Container.php new file mode 100644 index 0000000..b4d90d4 --- /dev/null +++ b/library/Businessprocess/Web/Component/Container.php @@ -0,0 +1,144 @@ +addContent($content); + + if ($this->attributes === null) { + $this->attributes = Attributes::wantAttributes($attributes); + } else { + $this->attributes = Attributes::wantAttributes($this->attributes); + } + if ($tag !== null) { + $this->tag = $tag; + } + } + + /** + * @param Component|array|string $content + * @param Attributes|array $attributes + * @param string $tag + * + * @return static + */ + public static function create($content = array(), $attributes = null, $tag = null) + { + return new static($content, $attributes, $tag); + } + + /** + * @return Attributes + */ + public function attributes() + { + return $this->attributes; + } + + /** + * @see addContent() + * @param Component|array|string $content + * @return $this + */ + public function add($content) + { + return $this->addContent($content); + } + + /** + * @param Component|array|string $content + * @return $this + */ + public function addContent($content) + { + if (is_array($content)) { + foreach ($content as $c) { + $this->addContent($c); + } + } + + $htmlOrComponent = $this->wantHtml($content); + if (strlen($htmlOrComponent)) { + $this->content[] = $htmlOrComponent; + } + + return $this; + } + + /** + * @param Component|array|string $content + * @return $this + */ + public function setContent($content) + { + $this->content = array(); + $this->addContent($content); + + return $this; + } + + /** + * @return string + */ + public function renderContent() + { + return implode($this->separator, $this->content); + } + + /** + * @inheritdoc + */ + public function render() + { + return $this->renderContainerFor($this->renderContent()); + } + + /** + * @inheritdoc + */ + public function renderError($error) + { + // TODO: eventually add class="error" + return $this->renderContainerFor( + parent::renderError($error) + ); + } + + /** + * @param $content + * @return string + */ + protected function renderContainerFor($content) + { + return sprintf( + '<%s%s>%s', + $this->tag, + $this->attributes->render(), + $content, + $this->tag + ); + } +} \ No newline at end of file diff --git a/library/Businessprocess/Web/Component/Link.php b/library/Businessprocess/Web/Component/Link.php new file mode 100644 index 0000000..fa9e2fc --- /dev/null +++ b/library/Businessprocess/Web/Component/Link.php @@ -0,0 +1,76 @@ +text = $text; + if ($url instanceof Url) { + if ($urlParams !== null) { + $url->addParams($urlParams); + } + + $link->url = $url; + } else { + $link->url = Url::fromPath($url, $urlParams); + } + $link->attributes = new Attributes($attributes); + + return $link; + } + + /** + * @return string + */ + public function getRenderedText() + { + return $this->view()->escape((string) $this->text); + } + + /** + * @return Url + */ + public function getUrl() + { + return $this->url; + } + + /** + * @inheritdoc + */ + public function render() + { + return sprintf( + '%s', + $this->getUrl(), + $this->attributes->render(), + $this->getRenderedText() + ); + } +} \ No newline at end of file