diff --git a/public_html/deployment/classes/htmlguielements.class.php b/public_html/deployment/classes/htmlguielements.class.php index 03cc3d1a95fa6f1da7a6e9507660588c0d71de61..a05a4e50754a80466a46458af9a207bb664c0a5c 100644 --- a/public_html/deployment/classes/htmlguielements.class.php +++ b/public_html/deployment/classes/htmlguielements.class.php @@ -1,7 +1,8 @@ <?php /** * html gui elements - * for bootstrap 3 + * for bootstrap 3..5 + * * CI SERVER GUI * * $oHtml=new htmlguielements(); @@ -9,220 +10,236 @@ * echo $oHtml->getBox('error', 'errormessage'); * echo $oHtml->getIcon('fa-pencil'); * - * echo $oHtml->getLink(array( + * echo $oHtml->getLink([ * 'href'=>'https://www.axel-hahn.de', * 'class'=>'btn btn-primary', * 'icon'=>'fa-close', * 'label'=>'linked text', - * )); + * ]); * * echo $oHtml->getTabs( - * array( + * [ * '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{ - - var $aCfg=array( - 'buttons'=>array( +class htmlguielements +{ + + /** + * Configuration array with icons + * @var array + */ + var $aCfg = [ + 'buttons' => [ // bootstrap defaults - 'primary'=>array('class'=>'btn-primary', 'icon'=>''), - 'success'=>array('class'=>'btn-success', 'icon'=>''), - 'info'=>array('class'=>'btn-info', 'icon'=>''), - 'warning'=>array('class'=>'btn-warning', 'icon'=>''), - 'danger'=>array('class'=>'btn-danger', 'icon'=>''), + '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'=>array('class'=>'btn-danger', 'icon'=>'fa-solid fa-times'), - 'error'=>array('class'=>'btn-danger', 'icon'=>'fa-solid fa-bolt'), - 'ok'=>array('class'=>'btn-primary', 'icon'=>'fa-solid fa-check'), - + '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'=>array('class'=>''), - 'build'=>array('class'=>''), - 'cleanup'=>array('class'=>''), - 'deploy'=>array('class'=>'', 'icon'=>'fa-solid fa-forward'), - 'new'=>array('class'=>'', 'icon'=>'fa-regular fa-star'), - 'overview'=>array('class'=>''), - 'phase'=>array('class'=>'', 'icon'=>'fa-solid fa-chevron-right'), - 'rollback'=>array('class'=>'', 'icon'=>'fa-solid fa-forward'), - 'setup'=>array('class'=>''), - - ), - 'icons'=>array( - - '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' => ['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-chevron-up', - 'box-down'=>'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', - ), - ); - - public function __construct() { - return true; + '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-chevron-up', + 'box-down' => '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 + * Add an html attribute if the attribute exists as a key * @param string $sAttribute html attribute to add - * @param string $aData item array + * @param array $aData item array * @param string $sDefault use default if key does not exists * @return string */ - public function addAttributeFromKey($sAttribute, $aData, $sDefault=''){ - return (isset($aData[$sAttribute]) - ? $this->addAttribute($sAttribute, $aData[$sAttribute]) - : $this->addAttribute($sAttribute, $sDefault) - ); + 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 + * 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($sAttribute, $sValue){ - return ($sValue ? ' '.$sAttribute.'="'.$sValue.'"' : '' ); + public function addAttribute(string $sAttribute, string $sValue): string + { + return ($sValue ? ' ' . $sAttribute . '="' . $sValue . '"' : ''); } - + /** - * get html attributes as string from all keys of given hash + * Get html attributes as string from all keys of given hash * * @param array $aItem * @return string */ - public function addAllAttributes($aItem){ - $sReturn=''; - foreach (array_keys($aItem) as $sKey){ - $sReturn.=$this->addAttributeFromKey($sKey, $aItem); + 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 + * Get html code for icon; glypphicons and font-awesome is supported * * @param string $sLabel label of icon * @return string */ - public function getIcon($sLabel){ - if(!$sLabel){ + public function getIcon(string $sLabel): string + { + if (!$sLabel) { return ''; } - $sPrefix=( strpos($sLabel, 'fa-')===0 ? 'fa' : ''); - // if(!$sPrefix){ - if(isset($this->aCfg['icons'][$sLabel])){ + if (isset($this->aCfg['icons'][$sLabel])) { return $this->getIconByType($sLabel); } - return '<i'.$this->addAttribute('class', ($sPrefix ? $sPrefix . ' ' : '').$sLabel).'></i> '; + return '<i' . $this->addAttribute('class', $sLabel) . '></i> '; } + /** - * get html code for icon; glypphicons and font-awesome is supported + * Get html code for icon * * @param string $sLabel label of icon * @return string */ - public function getIconClass($sLabel){ - if(!$sLabel){ + public function getIconClass(string $sLabel): string + { + if (!$sLabel) { return ''; } - if(isset($this->aCfg['icons'][$sLabel])){ + if (isset($this->aCfg['icons'][$sLabel])) { return $this->aCfg['icons'][$sLabel]; } - $sPrefix=( strpos($sLabel, 'fa-')===0 ? 'fa' : ''); - return ($sPrefix ? $sPrefix . ' ' : '').$sLabel; + return $sLabel; } - + /** - * get a default icon from config + * Get a default icon from config + * * @param string $sType icon type - * @return array + * @return string */ - public function getIconByType($sType){ + public function getIconByType(string $sType): string + { return (isset($this->aCfg['icons'][$sType]) ? $this->getIcon($this->aCfg['icons'][$sType]) : '' @@ -230,53 +247,55 @@ class htmlguielements{ } /** - * get html code for icon; glypphicons and font-awesome is supported + * 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($aItem){ - - $sHref=$this->addAttributeFromKey('href', $aItem, '#'); - $sLabel=(isset($aItem['icon']) ? $this->getIcon($aItem['icon']): '') - .(isset($aItem['label']) ? $aItem['label'] : ''); - - foreach(array('href', 'icon', 'label') as $sKey){ - if (isset($aItem[$sKey])){ + 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>'; + + $sReturn = '<a' . $sHref; + $sReturn .= $this->addAllAttributes($aItem); + $sReturn .= '>' + . $sLabel + . '</a>'; return $sReturn; } - + /** - * add default css classes and colors based on $aItem['type'] and the + * 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($aItem){ - $aReturn=$aItem; - if (isset($this->aCfg['buttons'][$aItem['type']])){ - $sClass=$this->aCfg['buttons'][$aItem['type']]['class']; - $aReturn['class'].=$sClass ? ' '.$sClass : ''; - + 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']] - : '' + $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']] + : '' ) ); } @@ -285,28 +304,29 @@ class htmlguielements{ /** - * get html code for icon; glypphicons and font-awesome is supported + * 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(array('class', 'icon') as $sKey){ - if (!isset($aItem[$sKey])){ - $aItem[$sKey]=''; + public function getLinkButton($aItem) + { + foreach (['class', 'icon'] as $sKey) { + if (!isset($aItem[$sKey])) { + $aItem[$sKey] = ''; } } - - if (isset($aItem['type'])){ - $aItem=$this->_getButtonattributesByType($aItem); + + 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; + $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); @@ -317,71 +337,26 @@ class htmlguielements{ // ---------------------------------------------------------------------- /** - * get html code of a div around a message + * 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($sWarnlevel, $sMessage) { - $aCfg = array( - "error" => array("class" => "alert alert-danger", "prefix" => t("error")), - "success" => array("class" => "alert alert-success", "prefix" => t("success")), - "info" => array("class" => "alert alert-info", "prefix" => t("info")), - "warning" => array("class" => "alert alert-warning", "prefix" => t("warning")), - ); + 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 tabs with content - * - * @staticvar int $iCounter internal counter for tabs ans content - * @param array $aTabData tab data; key is the tab label; value the content of its tab - * @return string - */ - public function getNav__UNUSED($aTabData){ - $sTabs=''; - $sContent=''; - - static $iCounter=0; - $iTab=0; - - if (!is_array($aTabData) || !count($aTabData)){ - return false; - } - $sNavType=$aTabData['options']['type']; // "tabs" or "pills" - $sNavCss='nav nav-'.$sNavType; - if (isset($aTabData['options']['stacked']) && $aTabData['options']['stacked']){ - $sNavCss.=' nav-stacked'; + $sMessage = '<strong>' . $this->getIcon('sign-' . $sWarnlevel) . $aCfg[$sWarnlevel]["prefix"] . '</strong> ' . $sMessage; } - if (isset($aTabData['options']['justified']) && $aTabData['options']['justified']){ - $sNavCss.=' nav-justified'; - } - $sNavType=$aTabData['options']['justified']; - foreach ($aTabData['tabs'] as $sTabLabel=>$sTabContent){ - $iCounter++; - $iTab++; - $sId="tab-generated-$iCounter"; - $sTabs.= ($iTab==1 ? '<li class="active"' : '<li') - . ' role="presentation">' - . '<a href="#'.$sId.'" data-toggle="tab">' . $sTabLabel . '</a></li>' - ; - $sContent.='<div class="tab-pane' - .($iTab==1 ? ' active' : '') - .'" id="'.$sId.'">' - .$sTabContent - .'</div>' - ; - } - return '<div class="tabbable">' - . '<ul class="'.$sNavCss.'">'. $sTabs.'</ul>' - . '<div class="tab-content">'.$sContent.'</div>' - . '</div>'; + return '<div' . $this->addAttribute('class', $sClass) . '>' . $sMessage . '</div>'; } /** @@ -390,28 +365,29 @@ class htmlguielements{ * @param array $aTabledata array with subkeys "header" and "body" * @return string */ - public function getTable($aTabledata) { - $sTHead=''; - $sTBody=''; - if (isset($aTabledata['body'])){ - foreach ($aTabledata['body'] as $aRow){ - $sTBody.='<tr>'; - foreach ($aRow as $sItem){ - $sTBody.='<td>'.$sItem.'</td>'; + 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>'; + $sTBody .= '</tr>'; } } - if (isset($aTabledata['header'])){ - foreach ($aTabledata['header'] as $sItem){ - $sTHead.='<th>'.$sItem.'</th>'; + 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>' - ; + . ($sTHead ? '<thead>' . $sTHead . '</thead>' : '') + . ($sTBody ? '<tbody>' . $sTBody . '</tbody>' : '') + . '</table>' + ; } - + }