<?php require_once 'htmlelements.class.php'; /** * ====================================================================== * * RENDERER FOR ADNINLTE template https://adminlte.io * DOCS: https://adminlte.io/docs/3.2/ * https://adminlte.io/themes/v3/index3.html * * ====================================================================== * * @author Axel */ class renderadminlte { var $aPresets=[ 'bgcolor'=>[ 'description'=>'background colors', 'group'=>'styling', 'values'=>[ // https://adminlte.io/themes/v3/pages/UI/general.html ''=>'no value', 'indigo'=>'indigo', 'lightblue'=>'', 'navy'=>'', 'purple'=>'', 'fuchsia'=>'', 'pink'=>'', 'maroon'=>'', 'orange'=>'', 'lime'=>'', 'teal'=>'', 'olive'=>'', 'black'=>'black', 'dark'=>'dark gray', 'gray'=>'gray', 'light'=>'light gray', ] ], 'type'=>[ 'description'=>'type or status like info/ warning/ danger to define a color', 'group'=>'styling', 'values'=>[ ''=>'no value', 'danger'=>'red', 'info'=>'aqua', 'primary'=>'blue', 'secondary'=>'gray', 'success'=>'green', 'warning'=>'yellow', 'dark'=>'dark gray', 'gray'=>'gray', ] ], 'shadow'=>[ 'description'=>'use a shadow', 'group'=>'styling', 'values'=>[ ''=>'no value', 'none'=>'none', 'small'=>'small', 'regular'=>'regular', 'large'=>'large' ] ], 'size'=>[ 'description'=>'set a size', 'group'=>'styling', 'values'=>[ ''=>'no value', 'lg'=>'', 'sm'=>'', 'xs'=>'', 'flat'=>'', ] ], 'variant'=>[ 'description'=>'coloring style', 'group'=>'styling', 'values'=>[ ''=>'no value', 'outline'=>'small stripe on top', 'solid'=>'full filled widget', 'gradient'=>'full filled with gradient', ] ], 'visibility'=>[ 'description'=>'', 'group'=>'customizing', 'values'=>[ ''=>'no value', '0'=>'hide', '1'=>'show', ] ], // for keys: state 'windowstate'=>[ 'description'=>'state of a resizable widget', 'group'=>'customizing', 'values'=>[ ''=>'no value', 'collapsed'=>'header only', 'maximized'=>'full window', ] ], // for keys: dismissable 'yesno'=>[ 'description'=>'', 'group'=>'customizing', 'values'=>[ ''=>'no value', '0'=>'no', '1'=>'yes', ] ], ]; var $_aValueMappings=[ 'shadow'=>[ 'default' => '', 'none' => 'shadow-none', 'small' => 'shadow-small', 'regular' => 'shadow', 'large' => 'shadow-lg', ] ]; var $_aElements=[]; /** * instance of htmlelements * @var object */ var $_oHtml=false; // ---------------------------------------------------------------------- // // CONSTRUCTOR // // ---------------------------------------------------------------------- public function __construct() { $this->_oHtml=new htmlelements(); $this->_initElements(); return true; } // ---------------------------------------------------------------------- // // PRIVATE FUNCTIONS // // ---------------------------------------------------------------------- /** * verify if an item has a correct value * it returns false if a key is not defined to be checked * it returns true if it was validated successfully * it dies with an errror, if a value check failed * * @param string $sType type; key in $_aValidItems; one of bgcolor|color|type|size * @param string $sValue value to check * @param string $sReferrer optional: method that called this function */ protected function _DELETE_ME___checkValue($sType, $sValue, $sReferrer=false){ if (!$sValue || !array_key_exists($sType, $this->_aValidItems)){ return false; } if(array_search($sValue, $this->_aValidItems[$sType])===false){ echo "ERROR: ".($sReferrer ? $sReferrer.' - ' : '')."value [$sValue] is not a valid for type [$sType]; it must be one of ".implode("|", $this->_aValidItems[$sType]).'<br>'; } return true; } /** * used in cosntructor * initialize all element definitions */ protected function _initElements(){ $this->_aElements=[ // ------------------------------------------------------------ 'alert'=>[ 'label'=>'Alert', 'description'=>'Colored box with title and a text', 'method'=>'getAlert', 'params'=>[ 'type' => ['select'=>$this->aPresets['type'], 'example_value'=>'warning'], 'dismissible' => ['select'=>$this->aPresets['yesno'], 'example_value'=>''], 'title' => [ 'description'=>'Title in a bit bigger font', 'group'=>'content', 'example_value'=>'Alert title' ], 'text' => [ 'description'=>'Message text', 'group'=>'content', 'example_value'=>'I am a message. Read me, please.' ], ] ], // ------------------------------------------------------------ 'badge'=>[ 'label'=>'Badge', 'description'=>'Tiny additional info; mostly as counter', 'method'=>'getBadge', 'params'=>[ 'type' => ['select'=>$this->aPresets['type'], 'example_value'=>'danger'], 'bgcolor' => ['select'=>$this->aPresets['bgcolor'], 'example_value'=>''], 'class' => [ 'group'=>'styling', 'description'=>'optional: css classes', 'example_value'=>'' ], 'id' => [ 'group'=>'customizing', 'description'=>'optional: id attribute', 'example_value'=>'' ], 'title' => [ 'group'=>'content', 'description'=>'optional: title attribute for mouseover', 'example_value'=>'Errors: 5' ], 'text' => [ 'group'=>'content', 'description'=>'Text or value in the badge', 'example_value'=>'5' ], ] ], // ------------------------------------------------------------ 'button'=>[ 'label'=>'Button', 'description'=>'Buttons<br>In this component you can add other parmeter keys too - these will be added as attributes in the button tag.', 'method'=>'getButton', 'params'=>[ 'type' => ['select'=>$this->aPresets['type'], 'example_value'=>'primary'], 'size' => ['select'=>$this->aPresets['size'], 'example_value'=>''], 'class' => [ 'group'=>'styling', 'description'=>'optional: css classes', 'example_value'=>'' ], 'text' => [ 'group'=>'content', 'description'=>'Text/ html code on the button', 'example_value'=>'Click me' ], ] ], // ------------------------------------------------------------ 'callout'=>[ 'label'=>'Callout', 'description'=>'Kind of infobox', 'method'=>'getCallout', 'params'=>[ 'type' => ['select'=>$this->aPresets['type'], 'example_value'=>'danger'], 'class' => [ 'group'=>'styling', 'description'=>'optional: css classes', 'example_value'=>'' ], 'title' => [ 'group'=>'content', 'description'=>'Title in a bit bigger font', 'example_value'=>'I am a callout' ], 'text' => [ 'group'=>'content', 'description'=>'Message text', 'example_value'=>'Here is some description to whatever.' ], ] ], // ------------------------------------------------------------ 'card'=>[ 'label'=>'Card', 'description'=>'Content box with header, text, footer', 'method'=>'getCard', 'params'=>[ 'type' => ['select'=>$this->aPresets['type'], 'example_value'=>'primary'], 'variant' => ['select'=>$this->aPresets['variant'], 'example_value'=>'outline'], 'class' => [ 'group'=>'styling', 'description'=>'optional: css classes', 'example_value'=>'' ], 'state' => [ 'group'=>'customizing', 'select'=>$this->aPresets['windowstate'], 'example_value'=>'' ], 'tb-collapse' => ['description'=>'show minus symbol as collapse button', 'select'=>$this->aPresets['visibility'], 'example_value'=>''], 'tb-expand' => ['description'=>'show plus symbol to expand card', 'select'=>$this->aPresets['visibility'], 'example_value'=>''], 'tb-maximize' => ['description'=>'show maximize button for fullscreen', 'select'=>$this->aPresets['visibility'], 'example_value'=>''], 'tb-minimize' => ['description'=>'show minimize button to minimize', 'select'=>$this->aPresets['visibility'], 'example_value'=>''], 'tb-remove' => ['description'=>'show cross symbol to remove card', 'select'=>$this->aPresets['visibility'], 'example_value'=>''], 'title' => [ 'group'=>'content', 'description'=>'Title in the top row', 'example_value'=>'I am a card' ], 'tools' => [ 'group'=>'content', 'description'=>'Html code for the top right', 'example_value'=>'' ], 'text' => [ 'group'=>'content', 'description'=>'Main content', 'example_value'=>'Here is some beautiful content.' ], 'footer' => [ 'group'=>'content', 'description'=>'optional: footer content', 'example_value'=>'Footer' ], ] ], // ------------------------------------------------------------ 'infobox'=>[ 'label'=>'Info box', 'description'=>'Box with icon to highlight a single value; optional with a progress bar', 'method'=>'getInfobox', 'params'=>[ 'type'=>['select'=>$this->aPresets['type'], 'example_value'=>''], 'iconbg'=>['select'=>$this->aPresets['type'], 'example_value'=>'info'], 'shadow'=>['select'=>$this->aPresets['shadow'], 'example_value'=>''], 'icon'=>[ 'group'=>'content', 'description'=>'css class for an icon', 'example_value'=>'far fa-thumbs-up' ], 'text'=>[ 'group'=>'content', 'description'=>'short information text', 'example_value'=>'Likes' ], 'number'=>[ 'group'=>'content', 'description'=>'a number to highlight', 'example_value'=>"41,410" ], 'progressvalue'=>[ 'group'=>'content', 'description'=>'optional: progress value 0..100 to draw a progress bar', 'example_value'=>70 ], 'progresstext'=>[ 'group'=>'content', 'description'=>'optional: text below progress bar', 'example_value'=>'70% Increase in 30 Days' ] ] ], // ------------------------------------------------------------ 'smallbox'=>[ 'label'=>'Small box', 'description'=>'Solid colored box to highlight a single value; optional with a link', 'method'=>'getSmallbox', 'params'=>[ 'type'=>['select'=>$this->aPresets['type'], 'example_value'=>'info'], 'shadow'=>['select'=>$this->aPresets['shadow'], 'example_value'=>''], 'icon'=>['group'=>'content', 'description'=>'css class for an icon', 'example_value'=>'fas fa-shopping-cart'], 'text'=>['group'=>'content', 'description'=>'short information text', 'example_value'=>'New orders'], 'number'=>['group'=>'content', 'description'=>'a number to highlight', 'example_value'=>"150"], 'url'=>['group'=>'content', 'description'=>'optional: url to set a link on the bottom', 'example_value'=>'#'], 'linktext'=>['group'=>'content', 'optional: description'=>'linktext', 'example_value'=>'More info'] ] ], ]; } /** * helper function: a shortcut for $this->_oHtml->getTag * @param string $sTag name of html tag * @param array $aAttributes array of its attributes */ protected function _tag($sTag, $aAttributes, $sContent=false){ if ($sContent){ $aAttributes['label']=(isset($aAttributes['label']) ? $aAttributes['label'] : '') . $sContent; } return $this->_oHtml->getTag($sTag, $aAttributes); } // ---------------------------------------------------------------------- // // PUBLIC FUNCTIONS AdminLTE 3.2 // // ---------------------------------------------------------------------- /** * render a page by using template * @param string $stemplate html template with placeholders * @param array $aReplace key = what to replace .. value = new value */ public function render($sTemplate, $aReplace){ return str_replace( array_keys($aReplace), array_values($aReplace), $sTemplate ); } /** * add a wrapper: wrap some content into a tag * * @param string $sContent html content inside * @return string */ public function addWrapper($sTag, $aOptions, $sContent){ $aOptions['label']=$sContent; return $this->_tag($sTag, $aOptions)."\n"; } // ---------------------------------------------------------------------- // // PUBLIC FUNCTIONS :: NAVIGATION // // ---------------------------------------------------------------------- /** * get a single navigation item on top bar * * @param array $aLink Array of html attributes; key children can contain subitems * @param integer $iLevel Menu level; 1=top bar; 2=pupup menu with subitems * @return string */ public function getNavItem($aLink, $iLevel=1){ static $iCounter; if(!isset($iCounter)){ $iCounter=0; } // special menu entry: horizontal bar (label is "-") if($aLink['label']=='-'){ return '<div class="dropdown-divider"></div>'; } $aChildren=isset($aLink['children']) && is_array($aLink['children']) && count($aLink['children']) ? $aLink['children'] : false; $aLink['class']='nav-link' . (isset($aLink['class']) ? ' '.$aLink['class'] : '') . ($aChildren ? ' dropdown-toggle' : '') ; if($aChildren){ $iCounter++; $sNavId="navbarDropdown".$iCounter; $aLink=array_merge($aLink,[ 'id'=>$sNavId, 'role'=>"button", 'data-toggle'=>"dropdown", 'aria-haspopup'=>"true", 'aria-expanded'=>"false", ]); unset($aLink['children']); // remove from html attributes to draw } $sReturn=$this->_tag('a', $aLink)."\n"; if($aChildren){ $iLevel++; $sReturn.=$this->addWrapper( 'div', [ 'aria-labelledby'=> $sNavId, 'class'=>'dropdown-menu' ], $this->getNavItems($aChildren, $iLevel) )."\n"; $iLevel--; } if($iLevel==1){ $sLiClass='nav-item'.($aChildren ? ' dropdown' : ''); $sReturn=$this->addWrapper( 'li', ['class'=>$sLiClass], $sReturn ); } return $sReturn; } /** * get a navigation item for top bar * */ public function getNavItems($aLinks, $iLevel=1){ $sReturn=''; if (!$aLinks || !is_array($aLinks) || !count($aLinks)){ return false; } foreach($aLinks as $aLink){ $sReturn.=$this->getNavItem($aLink, $iLevel); } return $sReturn; } /** * get a top left navigation for a top navigation bar * * @example * <code> * $aTopnav=[ * ['href'=>'/index.php', 'label'=>'MyHome' , 'class'=>'bg-gray'], * ['href'=>'#', 'label'=>'Contact'], * ['href'=>'#', 'label'=>'Help', * 'children'=>[ * ['href'=>'#', 'label'=>'FAQ'], * ['label'=>'-'], * ['href'=>'#', 'label'=>'Support'], * ] * ] * ]; * echo '<nav class="main-header navbar navbar-expand navbar-white navbar-light">' * .$renderAdminLTE->getTopNavigation($aTopnav) * .'</nav>' * </code> * * @param array $aNavitems array of navigation items/ tree * @param array $aUlOptions array of html attrubutes for wrapping UL tag * @return string */ public function getTopNavigation($aNavItems, $aUlOptions=['class'=>'navbar-nav']){ array_unshift($aNavItems, ['class'=>'nav-link', 'data-widget'=>'pushmenu', 'href'=>'#', 'role'=>'button', 'label'=>'<i class="fas fa-bars"></i>']); return $this->addWrapper('ul', $aUlOptions, $this->getNavItems($aNavItems)); } // ---------------------------------------------------------------------- /** * get a navigation items for sidebar * @param array $aLinks list of link items */ public function getNavi2Items($aLinks){ $sReturn=''; if (!$aLinks || !is_array($aLinks) || !count($aLinks)){ return false; } foreach($aLinks as $aLink){ // to render active or open links: $aLink['class']='nav-link' . (isset($aLink['class']) ? ' '.$aLink['class'] : ''); $aChildren=isset($aLink['children']) ? $aLink['children'] : false; $aLiClass='nav-item' . ($aChildren && strstr($aLink['class'], 'active') ? ' menu-open' : ''); $sSubmenu=''; if($aChildren){ unset($aLink['children']); $aLink['label'].='<i class="right fas fa-angle-left"></i>'; $sSubmenu.=$this->getSidebarNavigation($aChildren, ['class'=>'nav nav-treeview']); } $aLink['label']=$this->addWrapper('p', [], $aLink['label']); $sReturn.=$this->addWrapper( 'li', ['class'=>$aLiClass], $this->_tag('a', $aLink).$sSubmenu )."\n"; } return $sReturn; } /** * */ public function getSidebarNavigation($aNavItems, $aUlOptions=[ 'class'=>'nav nav-pills nav-sidebar flex-column nav-flat_ nav-child-indent', 'data-widget'=>'treeview', 'role'=>'menu', 'data-accordion'=>'false' ]) { return $this->addWrapper( 'ul', $aUlOptions, $this->getNavi2Items($aNavItems) )."\n"; } // ---------------------------------------------------------------------- // // PUBLIC FUNCTIONS :: CONTENT - BASIC FUNCTIONS // // ---------------------------------------------------------------------- /** * add page row * * @param string $sContent html content inside * @return string */ public function addRow($sContent){ return $this->addWrapper('div', ['class'=>'row'], $sContent); } /** * add page column * * @param string $sContent html content inside * @param integer $iCols column width; 12 = full width * @param string $sFloat css value for float attribute; default=false * @return string */ public function addCol($sContent, $iCols=6, $sFloat=false){ return $this->addWrapper('div', ['class'=>'col-md-'.$iCols, 'style'=>'float:'.$sFloat], $sContent); } // ---------------------------------------------------------------------- // // PUBLIC FUNCTIONS :: CONTENT - WIDGET HELPERS // // ---------------------------------------------------------------------- /** * get a list of all defined components that can be rendered * @param {bool} $bSendData flag: send including subkeys of the hash; default: false (keys only) * @return {array} */ public function getComponents($bSendData=false){ return $bSendData ? $this->_aElements : array_keys($this->_aElements) ; } /** * get data of a component * @param {string} $sComponent id of the component * @return {array} */ public function getComponent($sComponent){ if(!isset($this->_aElements[$sComponent])){ return false; } $aReturn=array_merge(['id'=>$sComponent], $this->_aElements[$sComponent]); unset($aReturn['params']); return $aReturn; } /** * get parameter keys of a component * @param {string} $sComponent id of the component * @param {bool} $bSendData flag: send including subkeys of the hash; default: false (keys only) * @return {array} */ public function getComponentParamkeys($sComponent, $bSendData=false){ if(!isset($this->_aElements[$sComponent])){ return false; } $aKeys=array_keys($this->_aElements[$sComponent]['params']); if(!$bSendData){ return $aKeys; } $aReturn=[]; foreach($aKeys as $sKey){ $aReturn[$sKey]=$this->getComponentParamkey($sComponent, $sKey); } // $aReturn=$this->_aElements[$sComponent]['params']; return $aReturn; } /** * get information a parameter keys of a component * @param {string} $sComponent id of the component * @param {string} $sKey key in the options array * @return {array} */ public function getComponentParamkey($sComponent, $sKey){ if(!isset($this->_aElements[$sComponent]['params'][$sKey])){ return false; } $aReturn=$this->_aElements[$sComponent]['params'][$sKey]; // get description from a preset if(!isset($aReturn['description']) && isset($aReturn['select']['description'])){ $aReturn['description']=$aReturn['select']['description']; } if(!isset($aReturn['group']) && isset($aReturn['select']['group'])){ $aReturn['group']=$aReturn['select']['group']; } return $aReturn; } /** * get a flat list of valid parameters for a key in a component * @param {string} $sComponent id of the component * @param {string} $sKey key in the options array * @return {array} */ public function getValidParamValues($sComponent, $sKey){ $aOptionkey=$this->getComponentParamkey($sComponent, $sKey); if(!$aOptionkey || !isset($aOptionkey['select']['values'])){ return false; } return array_keys($aOptionkey['select']['values']); } // ---------------------------------------------------------------------- /** * helper: add a css value with prefix * this handles option keys in get[COMPONENT] methods * if a value is set then this function returns a space + prefix (param 2) + value * @param {string} $sValue option value * @param {string} $sPrefix prefix in front of css value * @return {string} */ protected function _addClassValue($sValue, $sPrefix=''){ return $sValue ? ' '.$sPrefix.$sValue : ''; } /** * helper function for get[COMPONENTNAME] methods: * ensure that all wanted keys exist in an array. Non existing keys will be added with value false * @return array */ protected function _ensureOptions($sComponent, $aOptions=[]){ $aParams=$this->getComponentParamkeys($sComponent, 0); if(!$aParams){ $aOptions['_infos'][]="Warning: no definition was found for component $sComponent."; return $aOptions; } foreach ($aParams as $sKey){ if(!isset($aOptions) || !isset($aOptions[$sKey])){ $aOptions[$sKey]=false; if(!isset($aOptions['_infos'])){ $aOptions['_infos']=[]; } $aOptions['_infos'][]="added missing key: $sKey"; } // $aParamdata $aValidvalues=$this->getValidParamValues($sComponent, $sKey); if($aValidvalues){ if(array_search($aOptions[$sKey], $aValidvalues)===false){ echo "ERROR: [".$sComponent."] value "".$aOptions[$sKey]."" is not a valid for param key [".$sKey."]; it must be one of ".implode("|", $aValidvalues).'<br>'; } } // $this->_checkValue($sKey, $aOptions[$sKey], __METHOD__); } // echo '<pre>' . print_r($aOptions, 1) . '</pre>'; return $aOptions; } // ---------------------------------------------------------------------- // // PUBLIC FUNCTIONS :: CONTENT - WIDGETS // // ---------------------------------------------------------------------- /** * return a alert box * https://adminlte.io/themes/v3/pages/UI/general.html * * @param type $aOptions hash with keys for all options * - type - one of [none]|danger|info|primary|success|warning * - dismissible - if dismissible - one of true|false; default: false * - title * - text * @return string */ public function getAlert($aOptions){ $aOptions=$this->_ensureOptions('alert', $aOptions); $aAlertIcons=[ 'danger'=>'icon fas fa-ban', 'info'=>'icon fas fa-info', 'warning'=>'icon fas fa-exclamation-triangle', 'success'=>'icon fas fa-check', ]; $aElement=[ 'class'=>'alert' . $this->_addClassValue($aOptions['type'], 'alert-') . $this->_addClassValue($aOptions['dismissible'], 'alert-') , 'label'=>'' . ($aOptions['dismissible'] ? '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' : '') . $this->_tag('h5', [ 'label'=> '' .(isset($aAlertIcons[$aOptions['type']]) ? '<i class="'.$aAlertIcons[$aOptions['type']].'"></i> ' : '') .$aOptions['title'] ]) .$aOptions['text'] ]; return $this->_tag('div', $aElement); } /** * get html code for a badge * * Examples * <span class="badge badge-danger navbar-badge">3</span> * <span title="3 New Messages" class="badge badge-warning">3</span> * <span class="right badge badge-danger">New</span> * <span class="badge badge-danger float-right">$350</span> * * @param array $aOptions hash with keys for all options * - bgcolor - background color (without prefix "bg") * - class - css class * - id - optional: id attribute * - text - visible text * - title - optional: title attribute * - type - one of [none]|danger|dark|info|primary|secondary|success|warning */ public function getBadge($aOptions){ $aOptions=$this->_ensureOptions('badge', $aOptions); $aElement=[]; $aElement['class']='badge' . $this->_addClassValue($aOptions['class'], '') . $this->_addClassValue($aOptions['type'], 'badge-') . $this->_addClassValue($aOptions['bgcolor'], 'bg-') ; if ($aOptions['id']){ $aElement['id']=$aOptions['id']; } $aElement['title']=$aOptions['title']; $aElement['label']=$aOptions['text']; return $this->_tag('span', $aElement); } /** * Get a button. * You can use any other key that are not named here. Those keys will be rendered * as additional html attributes without modification. * https://adminlte.io/themes/v3/pages/UI/buttons.html * * <button type="button" class="btn btn-block btn-default">Default</button> * @param type $aOptions hash with keys for all options * - type - one of [none]|danger|dark|info|primary|secondary|success|warning * - size - one of [none]|lg|sm|xs|flat * - class - any css class for customizing, eg. "disabled" * - icon - not supported yet * - text - text on button * @return string */ public function getButton($aOptions){ $aOptions=$this->_ensureOptions('button', $aOptions); $aElement=$aOptions; $aElement['class']='btn' . $this->_addClassValue($aOptions['type'], 'btn-') . $this->_addClassValue($aOptions['size'], 'btn-') . $this->_addClassValue($aOptions['class'], '') ; $aElement['label']=$aOptions['text'] ? $aOptions['text'] : ' '; foreach(['_infos', 'type', 'size', 'icon', 'text'] as $sDeleteKey){ unset($aElement[$sDeleteKey]); } return $this->_tag('button', $aElement); } /** * get a callout (box with coloered left border; has type, title + text) * https://adminlte.io/themes/v3/pages/UI/general.html * * @param type $aOptions hash with keys for all options * >> styling * - type - one of [none]|danger|dark|info|primary|secondary|success|warning * - class - optional css class * * >> texts/ html content * - title - text: title of the card * - text - text: content of the card * @return string */ public function getCallout($aOptions){ $aOptions=$this->_ensureOptions('callout', $aOptions); $sClass='callout' . $this->_addClassValue($aOptions['type'], 'callout-') . $this->_addClassValue($aOptions['class'], '') ; return $this->addWrapper( 'div', ['class'=>$sClass], ($aOptions['title'] ? $this->_tag('h5', ['label'=>$aOptions['title']]) : '') .($aOptions['text'] ? $this->_tag('p', ['label'=>$aOptions['text']]) : '') ); } /** * get a card * https://adminlte.io/docs/3.2/components/cards.html * https://adminlte.io/docs/3.2/javascript/card-widget.html * * @param type $aOptions hash with keys for all options * >> styling * - variant: "default" - titlebar is colored * "outline" - a small stripe on top border is colored * "solid" - whole card is colored * "gradient" - whole card is colored with a gradient * - type - one of [none]|danger|dark|info|primary|secondary|success|warning * - class - any css class for customizing, eg. "disabled" * - state - one of [none]|collapsed|maximized * * >> toolbar icons - set to true to show it; default: none of it is visible * - tb-collapse * - tb-expand it is added automatically if you set 'state'=>'collapsed' * - tb-maximize * - tb-minimize it is added automatically if you set 'state'=>'maximized' * - tb-remove * * >> texts/ html content * - title - text: title of the card * - tools - text: titlebar top right elements * - text - text: content of the card * - footer - text: footer of the card * @return string */ public function getCard($aOptions){ $aOptions=$this->_ensureOptions('card', $aOptions); // css class prefixes based on "variant" value $aVariants=[ 'default' => 'card-', 'outline' => 'card-outline card-', 'solid' => 'bg-', 'gradient' => 'bg-gradient-', ]; // window states: css class and toolbar buttons to add $aStates=[ 'collapsed'=>[ 'class'=>'collapsed-card', 'tool'=>'tb-expand'], 'maximized'=>[ 'class'=>'maximized-card', 'tool'=>'tb-minimize'], ]; $aTools=[ 'tb-collapse'=>'<button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>', 'tb-expand'=>'<button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-plus"></i></button>', 'tb-maximize'=>'<button type="button" class="btn btn-tool" data-card-widget="maximize"><i class="fas fa-expand"></i></button>', 'tb-minimize'=>'<button type="button" class="btn btn-tool" data-card-widget="maximize"><i class="fas fa-compress"></i></button>', 'tb-remove'=>'<button type="button" class="btn btn-tool" data-card-widget="remove"><i class="fas fa-times"></i></button>', ]; // print_r($aOptions); $sVariantPrefix=$aVariants[$aOptions['variant']] ? $aVariants[$aOptions['variant']] : $aVariants['default']; $sClass='card' . $this->_addClassValue($aOptions['type'], $sVariantPrefix) . $this->_addClassValue($aOptions['class'], '') ; // check window state foreach($aStates as $sStatus=>$aStatus){ if($aOptions['state']===$sStatus){ $sClass.=' '.$aStatus['class']; $aOptions[$aStatus['tool']]=1; } } // add toolbar buttons - from given options or by window state foreach($aTools as $sTool=>$sHtml){ $aOptions['tools'].=($aOptions[$sTool] ? $sHtml : ''); } // build parts of the card $sCardHeader=$this->addWrapper('div', ['class'=>'card-header'], $this->_tag('h3', ['class'=>'card-title', 'label'=>$aOptions['title']]) . ($aOptions['tools'] ? $this->_tag('div', ['class'=>'card-tools', 'label'=>$aOptions['tools']]) : '') ); $sCardBody=$this->_tag('div', ['class'=>'card-body', 'label'=>$aOptions['text']]); $sCardFooter=$aOptions['footer'] ? $this->_tag('div', ['class'=>'card-footer', 'label'=>$aOptions['footer']]) : ''; // merge all return $this->addWrapper('div', ['class'=>$sClass], $sCardHeader.$sCardBody.$sCardFooter); } /** * return an info-box: * A colored box with large icon, text and a value. * https://adminlte.io/docs/3.2/components/boxes.html * * @param type $aOptions hash with keys for all options * styling: * - type - color of the box; one of [none]|danger|dark|info|primary|secondary|success|warning * - iconbg - background color or type of icon; use it for default type (type="") * - shadow - size of shadow; one of [none] (=default: between small and regular)|none|small|regular|large * * content * - icon - icon class * - text - information text * - number - value (comes in bold text) * - progressvalue - integer: progress bar; range: 0..100 * - progresstext - text below progress bar * @return string */ public function getInfobox($aOptions){ $aOptions=$this->_ensureOptions('infobox', $aOptions); // print_r($aOptions); $sClass='info-box' . $this->_addClassValue($aOptions['type'], 'bg-') . $this->_addClassValue($aOptions['class'], '') .($aOptions['shadow'] && isset($this->_aValueMappings['shadow'][$aOptions['shadow']]) ? ' '.$this->_aValueMappings['shadow'][$aOptions['shadow']] : '') ; // build parts $sIcon=$aOptions['icon'] ? $this->addWrapper("span", [ 'class'=>'info-box-icon'.($aOptions['iconbg'] ? ' bg-'.$aOptions['iconbg'] : '') ], $this->_tag('i',['class'=>$aOptions['icon']])) : '' ; $sContent=$this->addWrapper("div", ['class'=>'info-box-content'], '' . ($aOptions['text'] ? $this->_tag('span', ['class'=>'info-box-text', 'label'=>$aOptions['text']]) : '') . ($aOptions['number'] ? $this->_tag('span', ['class'=>'info-box-number', 'label'=>$aOptions['number']]) : '') . ($aOptions['progressvalue']!==false && $aOptions['progressvalue']!=='' ? $this->addWrapper('div', ['class'=>'progress'], $this->_tag('div', ['class'=>'progress-bar'. ($aOptions['iconbg'] ? ' bg-'.$aOptions['iconbg'] : ''), 'style'=>'width: '.(int)$aOptions['progressvalue'].'%' ]) ) . ($aOptions['progresstext'] ? $this->_tag('span', ['class'=>'progress-description', 'label'=>$aOptions['progresstext']]) : '' ) : '' ) ); // merge all return $this->_tag('div', ['class'=>$sClass], $sIcon.$sContent); } /** * return an info-box: * A colored box with large icon, text and a value. * https://adminlte.io/docs/3.2/components/boxes.html * https://adminlte.io/themes/v3/pages/widgets.html * * @param type $aOptions hash with keys for all options * styling: * - type - color of the box; one of [none]|danger|dark|info|primary|secondary|success|warning * content * - icon - icon class for icon on the right * - text - information text * - number - value (comes in bold text) * - url - integer: progress bar; range: 0..100 * - linktext- text below progress bar * @return string */ public function getSmallbox($aOptions){ $aOptions=$this->_ensureOptions('smallbox', $aOptions); $aShadows=[ 'default' => '', 'none' => 'shadow-none', 'small' => 'shadow-small', 'regular' => 'shadow', 'large' => 'shadow-lg', ]; // print_r($aOptions); $sClass='small-box' . $this->_addClassValue($aOptions['type'], 'bg-') .($aOptions['shadow'] && isset($this->_aValueMappings['shadow'][$aOptions['shadow']]) ? ' '.$this->_aValueMappings['shadow'][$aOptions['shadow']] : '') ; // build parts $sContent=$this->addWrapper("div", ['class'=>'inner'], '' . ($aOptions['number'] ? $this->_tag('h3', ['label'=>$aOptions['number']]) : '') . ($aOptions['text'] ? $this->_tag('p', ['class'=>'info-box-text', 'label'=>$aOptions['text']]) : '') ); $sIcon=$aOptions['icon'] ? $this->addWrapper("div", ['class'=>'icon'], $this->_tag('i',['class'=>$aOptions['icon']])) : '' ; $sFooter=($aOptions['url'] ? $this->addWrapper("a", [ 'class'=>'small-box-footer', 'href'=>$aOptions['url'], ], '' . ($aOptions['linktext'] ? $aOptions['linktext'] : $aOptions['url']) . ' ' . $this->_tag('i',['class'=>'fas fa-arrow-circle-right']) ) : '' ); // merge all return $this->_tag('div', ['class'=>$sClass], $sContent.$sIcon.$sFooter); } /* <div class="info-box"> <span class="info-box-icon bg-info"><i class="far fa-bookmark"></i></span> <div class="info-box-content"> <span class="info-box-text">Bookmarks</span> <span class="info-box-number">41,410</span> <div class="progress"> <div class="progress-bar bg-info" style="width: 70%"></div> </div> <span class="progress-description"> 70% Increase in 30 Days </span> </div> </div> <div class="info-box bg-success"> <span class="info-box-icon"><i class="far fa-thumbs-up"></i></span> <div class="info-box-content"> <span class="info-box-text">Likes</span> <span class="info-box-number">41,410</span> <div class="progress"> <div class="progress-bar" style="width: 70%"></div> </div> <span class="progress-description"> 70% Increase in 30 Days </span> </div> </div> */ }