Skip to content
Snippets Groups Projects
htmlguielements.class.php 13.34 KiB
<?php
/**
 * html gui elements
 * for bootstrap 3..5
 * 
 * CI SERVER GUI
 *
 * $oHtml=new htmlguielements();
 * 
 * echo $oHtml->getBox('error', 'errormessage');
 * echo $oHtml->getIcon('fa-pencil');
 * 
 * echo $oHtml->getLink([
 *     'href'=>'https://www.axel-hahn.de',
 *     'class'=>'btn btn-primary',
 *     'icon'=>'fa-close',
 *     'label'=>'linked text',
 * ]);
 * 
 * echo $oHtml->getTabs(
 *     [
 *         'tab 1'=>'Inhalt #1',
 *         'tab 2'=>'Inhalt #2',
 *     ]
 * );
 * 
 * 
 * @author hahn
 * 
 * 2024-08-23  v1.1  Axel Hahn  php8 only; added variable types; short array syntax; remove unneeded methods
 */
class htmlguielements
{

    /**
     * Configuration array with icons
     * @var array
     */
    var $aCfg = [
        'buttons' => [
            // bootstrap defaults
            'primary' => ['class' => 'btn-primary', 'icon' => ''],
            'success' => ['class' => 'btn-success', 'icon' => ''],
            'info' => ['class' => 'btn-info', 'icon' => ''],
            'warning' => ['class' => 'btn-warning', 'icon' => ''],
            'danger' => ['class' => 'btn-danger', 'icon' => ''],

            // custom buttons
            'close' => ['class' => 'btn-danger', 'icon' => 'fa-solid fa-times'],
            'error' => ['class' => 'btn-danger', 'icon' => 'fa-solid fa-bolt'],
            'ok' => ['class' => 'btn-primary', 'icon' => 'fa-solid fa-check'],

            // deploy actions and buttons
            'accept' => ['class' => ''],
            'build' => ['class' => ''],
            'cleanup' => ['class' => ''],
            'deploy' => ['class' => '', 'icon' => 'fa-solid fa-forward'],
            'new' => ['class' => '', 'icon' => 'fa-regular fa-star'],
            'overview' => ['class' => ''],
            'phase' => ['class' => '', 'icon' => 'fa-solid fa-chevron-right'],
            'rollback' => ['class' => '', 'icon' => 'fa-solid fa-forward'],
            'setup' => ['class' => ''],

        ],
        'icons' => [

            'menu' => 'fa-solid fa-chevron-right',
            'valuestore' => 'fa-solid fa-tags',
            'overview' => 'fa-solid fa-list',
            'project' => 'fa-solid fa-book',
            'project-home' => 'fa-solid fa-home',
            'projects' => 'fa-regular fa-folder',
            'actions' => 'fa-solid fa-check',

            'actionlog' => 'fa-solid fa-list-ul',
            // 'accept'=>'fa-solid fa-forward',
            'accept' => 'fa-solid fa-check',
            'build' => 'fa-solid fa-box-open',
            'checklang' => 'fa-solid fa-check',
            'cleanup' => 'fa-solid fa-broom',
            'close' => 'fa-solid fa-times',
            'delete' => 'fa-solid fa-trash',
            'deploy' => 'fa-solid fa-forward',
            'deploy-configfile' => 'fa-regular fa-file-code',
            'deploy-rollout-plugin' => 'fa-solid fa-plug',
            'filter' => 'fa-solid fa-filter',
            'foreman' => 'fa-solid fa-hard-hat',
            'gotop' => 'fa-solid fa-arrow-up',
            'help' => 'fa-solid fa-life-ring',
            'login' => 'fa-solid fa-right-to-bracket',
            'new' => 'fa-regular fa-star',
            // 'phase' => 'fa-solid fa-chevron-right',
            'poweroff' => 'fa-solid fa-power-off',
            'refresh' => 'fa-solid fa-sync',
            'rollback' => 'fa-solid fa-forward',
            'setup' => 'fa-solid fa-cog',
            'time' => 'fa-regular fa-clock',
            'waiting' => 'fa-solid fa-clock',
            'user' => 'fa-solid fa-user',
            'user-profile' => 'fa-regular fa-id-card',
            'user-group' => 'fa-regular fa-bookmark',
            'user-permission' => 'fa-solid fa-caret-right',

            'workflow' => 'fa-solid fa-angle-double-right',
            'repository' => 'fa-solid fa-database',
            'phase' => 'fa-solid fa-flag',
            'package' => 'fa-solid fa-cubes',
            'version' => 'fa-solid fa-tag',
            'list' => 'fa-solid fa-list',
            'raw-data' => 'fa-regular fa-file',
            'method' => 'fa-solid fa-cogs',
            'url' => 'fa-solid fa-globe-americas',

            'back' => 'fa-solid fa-chevron-left',

            'branch' => 'fa-solid fa-bookmark',
            'calendar' => 'fa-regular fa-calendar',
            'comment' => 'fa-regular fa-comment',
            'revision' => 'fa-solid fa-tag',

            'link-extern' => 'fa-solid fa-globe-americas',

            'host' => 'fa-regular fa-hdd',
            'hostgroup' => 'fa-solid fa-sitemap',
            'file-any' => 'fa-regular fa-file',
            'file-archive' => 'fa-regular fa-file-archive',
            'file-code' => 'fa-regular fa-file-code',
            'file-meta' => 'fa-regular fa-file',
            'file-template' => 'fa-regular fa-file-alt',
            'file-target' => 'fa-solid fa-file-upload',
            'replace' => 'fa-solid fa-random',

            'box-up' => 'fa-solid fa-chevron-up',
            'box-down' => 'fa-solid fa-chevron-down',

            'sign-info' => 'fa-solid fa-info',
            'sign-warning' => 'fa-solid fa-exclamation',
            'sign-error' => 'fa-solid fa-bolt',
            'sign-ok' => 'fa-solid fa-check',
            'sign-success' => 'fa-solid fa-check',
        ],
    ];

    /**
     * Constructor
     */
    public function __construct()
    {
        // nothing here
    }

    // ----------------------------------------------------------------------
    // helper function
    // ----------------------------------------------------------------------

    /**
     * Add an html attribute if the attribute exists as a key
     * @param string  $sAttribute  html attribute to add
     * @param array  $aData       item array
     * @param string  $sDefault    use default if key does not exists
     * @return string
     */
    public function addAttributeFromKey(string $sAttribute, array $aData, string $sDefault = ''): string
    {
        return (isset($aData[$sAttribute])
            ? $this->addAttribute($sAttribute, $aData[$sAttribute])
            : $this->addAttribute($sAttribute, $sDefault)
        );
    }

    /**
     * Add an html attribute if value is not empty
     * @param string  $sAttribute  html attribute to add
     * @param string  $sValue      value of attribute
     * @return string
     */
    public function addAttribute(string $sAttribute, string $sValue): string
    {
        return ($sValue ? ' ' . $sAttribute . '="' . $sValue . '"' : '');
    }

    /**
     * Get html attributes as string from all keys of given hash
     * 
     * @param array $aItem
     * @return string
     */
    public function addAllAttributes(array $aItem): string
    {
        $sReturn = '';
        foreach (array_keys($aItem) as $sKey) {
            $sReturn .= $this->addAttributeFromKey($sKey, $aItem);
        }
        return $sReturn;
    }

    // ----------------------------------------------------------------------
    // low level
    // ----------------------------------------------------------------------

    /**
     * Get html code for icon; glypphicons and font-awesome is supported
     * 
     * @param string $sLabel  label of icon
     * @return string
     */
    public function getIcon(string $sLabel): string
    {
        if (!$sLabel) {
            return '';
        }
        if (isset($this->aCfg['icons'][$sLabel])) {
            return $this->getIconByType($sLabel);
        }
        return '<i' . $this->addAttribute('class', $sLabel) . '></i> ';
    }

    /**
     * Get html code for icon
     * 
     * @param string $sLabel  label of icon
     * @return string
     */
    public function getIconClass(string $sLabel): string
    {
        if (!$sLabel) {
            return '';
        }
        if (isset($this->aCfg['icons'][$sLabel])) {
            return $this->aCfg['icons'][$sLabel];
        }
        return $sLabel;
    }

    /**
     * Get a default icon from config
     * 
     * @param string  $sType  icon type
     * @return string
     */
    public function getIconByType(string $sType): string
    {
        return (isset($this->aCfg['icons'][$sType])
            ? $this->getIcon($this->aCfg['icons'][$sType])
            : ''
        );
    }

    /**
     * Get html code for icon; glypphicons and font-awesome is supported
     * 
     * @param array $aItem  array with link attributes; href for target; "label" and "icon" 
     * @return string
     */
    public function getLink(array $aItem): string
    {

        $sHref = $this->addAttributeFromKey('href', $aItem, '#');
        $sLabel = (isset($aItem['icon']) ? $this->getIcon($aItem['icon']) : '')
            . (isset($aItem['label']) ? $aItem['label'] : '');

        foreach (['href', 'icon', 'label'] as $sKey) {
            if (isset($aItem[$sKey])) {
                unset($aItem[$sKey]);
            }
        }

        $sReturn = '<a' . $sHref;
        $sReturn .= $this->addAllAttributes($aItem);
        $sReturn .= '>'
            . $sLabel
            . '</a>';
        return $sReturn;
    }

    /**
     * Add default css classes and colors based on $aItem['type'] and the
     * local default settings in $this->aCfg
     * 
     * @param array  $aItem
     * @return array 
     */
    protected function _getButtonattributesByType(array $aItem): array
    {
        $aReturn = $aItem;
        if (isset($this->aCfg['buttons'][$aItem['type']])) {
            $sClass = $this->aCfg['buttons'][$aItem['type']]['class'];
            $aReturn['class'] .= $sClass ? ' ' . $sClass : '';

            // icon priority:
            // given in param --> icon in button config --> icon in icon config
            $aReturn['icon'] = $aReturn['icon'] ? $aReturn['icon'] :
                ($this->aCfg['buttons'][$aItem['type']]['icon']
                    ? $this->aCfg['buttons'][$aItem['type']]['icon']
                    : (
                        isset($this->aCfg['icons'][$aItem['type']])
                        ? $this->aCfg['icons'][$aItem['type']]
                        : ''
                    )
                );
        }
        return $aReturn;
    }


    /**
     * Get html code for a button like link
     * 
     * @param array $aItem  array with link attributes; href for target; "label" and "icon" 
     * @return string
     */
    public function getLinkButton($aItem)
    {
        foreach (['class', 'icon'] as $sKey) {
            if (!isset($aItem[$sKey])) {
                $aItem[$sKey] = '';
            }
        }

        if (isset($aItem['type'])) {
            $aItem = $this->_getButtonattributesByType($aItem);
            unset($aItem['type']);
        }
        // if not class "btn" was added: add "btn" 
        // if not class "btn-[something]" was added: add "btn-default" 
        $sClass = $aItem['class'];
        $sClass = (strstr($sClass, 'btn-') ? '' : 'btn-default ') . $sClass;
        $sClass = (strstr($sClass, 'btn ') ? '' : 'btn ') . $sClass;
        $aItem['class'] = $sClass;

        // $aItem['label'].=' -> '.$sClass;
        return $this->getLink($aItem);
    }

    // ----------------------------------------------------------------------
    // gui elements
    // ----------------------------------------------------------------------

    /**
     * Get html code of a div around a message
     * 
     * @param string $sWarnlevel one of error|success|info|warning to get a colored box
     * @param string $sMessage   message text
     * @return string
     */
    public function getBox(string $sWarnlevel, string $sMessage): string
    {
        $aCfg = [
            "error" => ["class" => "alert alert-danger", "prefix" => t("error")],
            "success" => ["class" => "alert alert-success", "prefix" => t("success")],
            "info" => ["class" => "alert alert-info", "prefix" => t("info")],
            "warning" => ["class" => "alert alert-warning", "prefix" => t("warning")],
            ];
        $sClass = "";
        if (isset($aCfg[$sWarnlevel])) {
            $sClass = $aCfg[$sWarnlevel]["class"];
            $sMessage = '<strong>' . $this->getIcon('sign-' . $sWarnlevel) . $aCfg[$sWarnlevel]["prefix"] . '</strong> ' . $sMessage;
        }
        return '<div' . $this->addAttribute('class', $sClass) . '>' . $sMessage . '</div>';
    }

    /**
     * get html code for a table
     * 
     * @param array $aTabledata  array with subkeys "header" and "body"
     * @return string
     */
    public function getTable(array $aTabledata): string
    {
        $sTHead = '';
        $sTBody = '';
        if (isset($aTabledata['body'])) {
            foreach ($aTabledata['body'] as $aRow) {
                $sTBody .= '<tr>';
                foreach ($aRow as $sItem) {
                    $sTBody .= '<td>' . $sItem . '</td>';
                }
                $sTBody .= '</tr>';
            }
        }
        if (isset($aTabledata['header'])) {
            foreach ($aTabledata['header'] as $sItem) {
                $sTHead .= '<th>' . $sItem . '</th>';
            }
        }
        return '<table class="table" style="width: auto;">'
            . ($sTHead ? '<thead>' . $sTHead . '</thead>' : '')
            . ($sTBody ? '<tbody>' . $sTBody . '</tbody>' : '')
            . '</table>'
        ;
    }

}