diff options
| author | Philipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de> | 2024-09-24 10:53:31 +0200 |
|---|---|---|
| committer | Philipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de> | 2024-09-24 10:53:31 +0200 |
| commit | 4459dd7917f4d1c34f40bb68f0e991e9c3d53e4c (patch) | |
| tree | 5c07151ae61276d334e88f6309c30d439a85c12e /lib/classes/Icon.class.php | |
| parent | da0022e5c1abbf9825ae76debaabdff7e8623bb4 (diff) | |
| parent | 97a188592c679890a25c37ab78463add76a52ff7 (diff) | |
Merge branch 'main' into issue-3911issue-3911
Diffstat (limited to 'lib/classes/Icon.class.php')
| -rw-r--r-- | lib/classes/Icon.class.php | 392 |
1 files changed, 0 insertions, 392 deletions
diff --git a/lib/classes/Icon.class.php b/lib/classes/Icon.class.php deleted file mode 100644 index ca0b9e0..0000000 --- a/lib/classes/Icon.class.php +++ /dev/null @@ -1,392 +0,0 @@ -<?php -/** - * Icon class is used to create icon objects which can be rendered as - * svg. Output will be html. Optionally, the icon can be rendered - * as a css background. - * - * @author Jan-Hendrik Willms <tleilax+studip@gmail.com> - * @copyright Stud.IP Core Group - * @license GPL2 or any later version - * @since 3.2 - */ -class Icon -{ - const SVG = 1; - const CSS_BACKGROUND = 4; - const INPUT = 256; - - const DEFAULT_SIZE = 16; - const DEFAULT_COLOR = 'blue'; - const DEFAULT_ROLE = 'clickable'; - - const ROLE_INFO = 'info'; - const ROLE_CLICKABLE = 'clickable'; - const ROLE_ACCEPT = 'accept'; - const ROLE_STATUS_GREEN = 'status-green'; - const ROLE_INACTIVE = 'inactive'; - const ROLE_NAVIGATION = 'navigation'; - const ROLE_NEW = 'new'; - const ROLE_ATTENTION = 'attention'; - const ROLE_STATUS_RED = 'status-red'; - const ROLE_INFO_ALT = 'info_alt'; - const ROLE_SORT = 'sort'; - const ROLE_STATUS_YELLOW = 'status-yellow'; - - - protected $shape; - protected $role; - protected $attributes = []; - - - /** - * This is the magical Role to Color mapping. - */ - private static $roles_to_colors = [ - self::ROLE_INFO => 'black', - self::ROLE_CLICKABLE => 'blue', - self::ROLE_ACCEPT => 'green', - self::ROLE_STATUS_GREEN => 'green', - self::ROLE_INACTIVE => 'grey', - self::ROLE_NAVIGATION => 'blue', - self::ROLE_NEW => 'red', - self::ROLE_ATTENTION => 'red', - self::ROLE_STATUS_RED => 'red', - self::ROLE_INFO_ALT => 'white', - self::ROLE_SORT => 'blue', - self::ROLE_STATUS_YELLOW => 'yellow' - ]; - - // return the color associated to a role - private static function roleToColor($role) - { - if (!isset(self::$roles_to_colors[$role])) { - throw new \InvalidArgumentException('Unknown role: "' . $role . '"'); - } - return self::$roles_to_colors[$role]; - } - - // return the roles! associated to a color - public static function colorToRoles($color) - { - static $colors_to_roles; - - if (!$colors_to_roles) { - foreach (self::$roles_to_colors as $r => $c) { - $colors_to_roles[$c][] = $r; - } - } - - if (!isset($colors_to_roles[$color])) { - throw new \InvalidArgumentException('Unknown color: "' . $color . '"'); - } - - return $colors_to_roles[$color]; - } - - /** - * Create a new Icon object. - * - * This is just a factory method. You could easily just call the - * constructor instead. - * - * @param String $shape Shape of the icon, may contain a mixed definition - * like 'seminar' - * @param String $role Role of the icon, defaults to Icon::DEFAULT_ROLE - * @param Array $attributes Additional attributes like 'title'; - * only use semantic ones describing - * this icon regardless of its later - * rendering in a view - * @return Icon object - */ - public static function create($shape, $role = Icon::DEFAULT_ROLE, $attributes = []) - { - // $role may be omitted - if (is_array($role)) { - $attributes = $role; - $role = Icon::DEFAULT_ROLE; - } - - return new self($shape, $role, $attributes); - } - - /** - * Constructor of the object. - * - * @param String $shape Shape of the icon, may contain a mixed definition - * like 'seminar' - * @param String $role Role of the icon, defaults to Icon::DEFAULT_ROLE - * @param Array $attributes Additional attributes like 'title'; - * only use semantic ones describing - * this icon regardless of its later - * rendering in a view - */ - public function __construct($shape, $role = Icon::DEFAULT_ROLE, array $attributes = []) - { - - // only defined roles - if (!isset(self::$roles_to_colors[$role])) { - throw new \InvalidArgumentException('Creating an Icon without proper role: "' . $role . '"'); - } - - // only semantic attributes - if ($non_semantic = array_filter(array_keys($attributes), function ($attr) { - return !in_array($attr, ['title']); - })) { - // DEPRECATED - // TODO starting with the v3.6 the following line should - // be enabled to prevent non-semantic attributes in this position - # throw new \InvalidArgumentException('Creating an Icon with non-semantic attributes:' . json_encode($non_semantic)); - } - - $this->shape = $shape; - $this->role = $role; - $this->attributes = $attributes; - } - - /** - * Returns the `shape` -- the string describing the shape of this instance. - * @return String the shape of this Icon - */ - public function getShape() - { - return $this->shapeToPath($this->shape); - } - - /** - * Returns the `role` -- the string describing the role of this instance. - * @return String the role of this Icon - */ - public function getRole() - { - return $this->role; - } - - /** - * Returns the semantic `attributes` of this instance, e.g. the title of this Icon - * @return Array the semantic attribiutes of the Icon - */ - public function getAttributes() - { - return $this->attributes; - } - - /** - * Returns whether this icon intends to signal attention. - * - * @todo This is currently just a heuristic based on the associated icon - * role. Although this is sufficient for the current requirements, - * it could probably in a better, more suitable way. - * - * @return bool - * @since Stud.IP 5.0 - */ - public function signalsAttention() - { - return $this->roleToColor($this->role) === 'red'; - } - - /** - * Function to be called whenever the object is converted to - * string. Internally the same as calling Icon::asImg - * - * @return String representation - */ - public function __toString() - { - return $this->asImg(); - } - - /** - * Renders the icon inside an img html tag. - * - * @param int $size Optional; Defines the dimension in px of the rendered icon; FALSE prevents any - * width or height attributes - * @param Array $view_attributes Optional; Additional attributes to pass - * into the rendered output - * @return String containing the html representation for the icon. - */ - public function asImg($size = null, $view_attributes = []) - { - if (is_array($size)) { - list($view_attributes, $size) = [$size, null]; - } - return sprintf( - '<img %s>', - arrayToHtmlAttributes( - $this->prepareHTMLAttributes($size, $view_attributes) - ) - ); - } - - /** - * Renders the icon inside an input html tag. - * - * @param int $size Optional; Defines the dimension in px of the rendered icon; FALSE prevents any - * width or height attributes - * @param Array $view_attributes Optional; Additional attributes to pass - * into the rendered output - * @return String containing the html representation for the icon. - */ - public function asInput($size = null, $view_attributes = []) - { - if (is_array($size)) { - list($view_attributes, $size) = [$size, null]; - } - return sprintf( - '<input type="image" %s>', - arrayToHtmlAttributes( - $this->prepareHTMLAttributes($size, $view_attributes) - ) - ); - } - - /** - * Renders the icon as a set of css background rules. - * - * @param int $size Optional; Defines the size in px of the rendered icon - * @return String containing the html representation for css backgrounds - */ - public function asCSS($size = null) - { - if (self::isStatic($this->shape)) { - return sprintf( - 'background-image:url(%1$s);background-size:%2$upx %2$upx;', - $this->shapeToPath($this->shape), - $this->get_size($size) - ); - } - - return sprintf( - 'background-image:url(%1$s);background-size:%2$upx %2$upx;', - $this->get_asset_svg(), - $this->get_size($size) - ); - } - - /** - * Returns a path to the SVG matching the icon. - * - * @return String containing the html representation for css backgrounds - */ - public function asImagePath() - { - return $this->prepareHTMLAttributes(false, [])['src']; - } - - /** - * Returns a new Icon with a changed shape - * @param mixed $shape New value of `shape` - * @return Icon A new Icon with a new `shape` - */ - public function copyWithShape($shape) - { - $clone = clone $this; - $clone->shape = $shape; - return $clone; - } - - /** - * Returns a new Icon with a changed role - * @param mixed $role New value of `role` - * @return Icon A new Icon with a new `role` - */ - public function copyWithRole($role) - { - $clone = clone $this; - $clone->role = $role; - return $clone; - } - - /** - * Returns a new Icon with new attributes - * @param mixed $attributes New value of `attributes` - * @return Icon A new Icon with a new `attributes` - */ - public function copyWithAttributes($attributes) - { - $clone = clone $this; - $clone->attributes = $attributes; - return $clone; - } - - /** - * Prepares the html attributes for use assembling HTML attributes - * from given shape, role, size, semantic and view attributes - * - * @param int $size Size of the icon - * @param array $attributes Additional attributes - * @return Array containing the merged attributes - */ - private function prepareHTMLAttributes($size, $attributes) - { - $dimensions = []; - if ($size !== false) { - $size = $this->get_size($size); - $dimensions = ['width' => $size, 'height' => $size]; - } - - $result = array_merge($this->attributes, $attributes, $dimensions, [ - 'src' => self::isStatic($this->shape) ? $this->shape : $this->get_asset_svg(), - ]); - - if (!isset($result['alt']) && !isset($result['title'])) { - //Add an empty alt attribute to prevent screen readers from - //reading the URL of the icon: - $result['alt'] = ''; - } - - $classNames = 'icon-role-' . $this->role; - - if (!self::isStatic($this->shape)) { - $classNames .= ' icon-shape-' . $this->shape; - } - - $result['class'] = isset($result['class']) ? $result['class'] . ' ' . $classNames : $classNames; - - return $result; - } - - /** - * Get the correct asset for an SVG icon. - * - * @return String containing the url of the corresponding asset - */ - protected function get_asset_svg() - { - return Assets::url('images/icons/' . self::roleToColor($this->role) . '/' . $this->shapeToPath($this->shape) . '.svg'); - } - - /** - * Get the size of the icon. If a size was passed as a parameter and - * inside the attributes array during icon construction, the size from - * the attributes will be used. - * - * @param int $size size of the icon - * @return int Size of the icon in pixels - */ - protected function get_size($size) - { - $size = $size ?: Icon::DEFAULT_SIZE; - if (isset($this->attributes['size'])) { - $parts = explode('@', $this->attributes['size'], 2); - $size = $parts[0]; - $temp = $parts[1] ?? null; - unset($this->attributes['size']); - } - return (int)$size; - } - - // an icon is static if it starts with 'http' - private static function isStatic($shape) - { - return mb_strpos($shape, 'http') === 0; - } - - // transforms a shape w/ possible additions (`shape`) to a path `(addition/)?shape` - private function shapeToPath() - { - return self::isStatic($this->shape) - ? $this->shape : - join('/', array_reverse(explode('+', preg_replace('/\.svg$/', '', $this->shape)))); - } -} |
