/** * renders one parameter and its children * * @param SimpleXMLElement $param The param to render * @param string $control_name The control name * @param cbTabs $tabs CB tab if applicable * @param string $viewType The view type ( 'view', 'param', 'depends': means: <param> tag => param, <field> tag => view ) * @param string $htmlFormatting The HTML formatting ( 'table', 'td', 'span', 'none', 'fieldsListArray' ) * @return string HTML */ function renderOneParamAndChildren( &$param, $control_name='params', $tabs=null, $viewType = 'depends', $htmlFormatting = 'table' ) { static $tabpaneCounter = 0; // level of tabs (for nested tabs) // static $tabpaneNames = array(); // names of the tabpanes of level [tabpaneCounter] for the tabpanetabs // Check if ACL authorizes to view and to use that element: if ( ( ! Access::authorised( $param ) ) && ( ! ( ( $param->getName() == 'if' ) && ( $param->attributes( 'type' ) == 'permission' ) ) ) ) { return null; } $html = array(); $viewMode = $param->attributes( 'mode' ); switch ( $viewMode ) { // case 'view': case 'show': $viewType = 'view'; break; // case 'param': case 'edit': $viewType = 'param'; break; default: break; } // treat any <attributes> below the tag to add attributes to the tag as needed: $this->extendParamAttributes( $param, $control_name, ( $viewType == 'view' ) ); switch ( $param->getName() ) { case 'param': $result = $this->renderParam( $param, $control_name, ( $viewType == 'view' ), $htmlFormatting ); $dynamic = ( ( ! ( $viewType == 'view' ) ) && ( $param->attributes( 'onchange' ) == 'evaluate' ) ); if ( $dynamic && ( $viewType == 'param' ) && ( $htmlFormatting != 'fieldsListArray' ) ) { $result[1] .= '<noscript><button type="submit" name="cbdoevalpostagain" value="" class="button cbregOnChange">' . CBTxt::Th("Change") . '</button></noscript>'; } if ( $result[1] || ( $viewType != 'view' ) || ( ! in_array( $param->attributes( 'hideblanktext' ), array( 'true', 'always' ) ) ) ) { $html[] = $this->_renderLine( $param, $result, $control_name, $htmlFormatting, true, ( $viewType == 'view' ) ); if ( $dynamic ) { $ifName = $this->_htmlId( $control_name, $param ); $this->_jsif[$ifName]['element'] = $param; $this->_jsif[$ifName]['control_name'] = $control_name; $this->_jsif[$ifName]['ifname'] = $ifName; $this->_jsif[$ifName]['onchange'] = $param->attributes( 'onchange' ); } } break; case 'params': $paramsName = $param->attributes( 'name' ); $paramsType = $param->attributes( 'type' ); if ( ( ( $paramsType == 'params' ) && $paramsName ) || ( $paramsType == 'pluginparams' ) ) { $repeat = ( $param->attributes( 'repeat' ) == 'true' ); $repeatOrdering = ( $param->attributes( 'repeatordering' ) != 'false' ); $repeatMax = (int) $param->attributes( 'repeatmax' ); if ( $control_name ) { $parent_cname = $control_name . '[' . $paramsName . ']'; } else { $parent_cname = $paramsName; } if ( $paramsType == 'params' ) { $valueObj = $this->_parseParamsColumn( $paramsName, $parent_cname ); } else { $valueObj = $this->_pluginParams; } $this->pushModelOfData( $valueObj ); if ( $repeat ) { $this->_jsrepeat = true; $valueArray = $valueObj->asArray(); if ( ! $valueArray ) { $valueArray = array( 0 => null ); } $result = $this->renderParam( $param, $control_name, ( $viewType == 'view' ), $htmlFormatting ); $return = null; foreach ( $valueArray as $index => $value ) { if ( $control_name ) { $child_cnam = $control_name . '[' . $paramsName . '][' . $index . ']'; } else { $child_cnam = $paramsName . '[' . $index . ']'; } // Grab child params from index: if ( $paramsType == 'params' ) { $valueObj = $this->_parseParamsColumn( $index, $child_cnam ); } else { $valueObj = $this->_pluginParams; } $this->pushModelOfData( $valueObj ); if ( in_array( $htmlFormatting, array( 'div', 'span', 'none' ) ) ) { $return .= '<div class="panel panel-default cbRepeatRow">' . '<div class="panel-body">'; if ( $repeatOrdering ) { $return .= '<div class="text-center cbRepeatRowSort">' . '<div class="cbRepeatRowMove fa fa-sort fa-block btn btn-default" title="' . htmlspecialchars( CBTxt::T( 'Click and drag to move this row.' ) ) . '"></div>' . '</div>'; } $return .= '<div class="cbRepeatRowParams">' . $this->renderAllParams( $param, $child_cnam, $tabs, $viewType, $htmlFormatting ) . '</div>' . '<div class="text-right cbRepeatRowIncrement">' . '<div class="cbRepeatRowAddRemove">' . '<div class="cbRepeatRowRemove fa fa-minus btn btn-danger" title="' . htmlspecialchars( CBTxt::T( 'Click to remove this row.' ) ) . '"></div>' . '<div class="cbRepeatRowAdd fa fa-plus btn btn-success" title="' . htmlspecialchars( CBTxt::T( 'Click to add new row.' ) ) . '"></div>' . '</div>' . '</div>' . '</div>' . '</div>'; } elseif ( in_array( $htmlFormatting, array( 'table', 'td' ) ) ) { $return .= '<table class="table table-bordered cbRepeatRow">' . '<tbody>' . '<tr>'; if ( $repeatOrdering ) { $return .= '<td class="text-center cbRepeatRowSort" style="width: 1%; vertical-align: middle;">' . '<div class="cbRepeatRowMove fa fa-sort btn btn-default" title="' . htmlspecialchars( CBTxt::T( 'Click and drag to move this row.' ) ) . '"></div>' . '</td>'; } $return .= '<td class="text-right cbRepeatRowParams">' . '<table class="table table-noborder">' . ( $htmlFormatting == 'td' ? '<tr>' : null ) . $this->renderAllParams( $param, $child_cnam, $tabs, $viewType, $htmlFormatting ) . ( $htmlFormatting == 'td' ? '<tr>' : null ) . '</table>' . '</td>' . '<td class="text-center cbRepeatRowIncrement" style="width: 10%; vertical-align: middle;">' . '<div class="cbRepeatRowRemove fa fa-minus btn btn-danger" title="' . htmlspecialchars( CBTxt::T( 'Click to remove this row.' ) ) . '"></div>' . '<div class="cbRepeatRowAdd fa fa-plus btn btn-success" title="' . htmlspecialchars( CBTxt::T( 'Click to add new row.' ) ) . '"></div>' . '</td>' . '</tr>' . '</tbody>' . '</table>'; } else { // Nothing; we need some formatting for the repeat usage } $this->popModelOfData(); } if ( $return ) { // Options parsing is pretty slow so lets shut it off by default: $repeatIgnore = 'option'; // Lets check if this repeat has any of its options being conditioned and if it is we need to allow them to parse (slow!): if ( $this->_jsif ) { foreach ( $this->_jsif as $ifCondition ) { if ( isset( $ifCondition['element']->option ) ) { if ( isset( $ifCondition['control_name'] ) && ( strpos( $ifCondition['control_name'], $paramsName ) !== false ) ) { $repeatIgnore = null; break; } elseif ( isset( $ifCondition['ifname'] ) && ( strpos( $ifCondition['ifname'], $paramsName ) !== false ) ) { $repeatIgnore = null; break; } elseif ( isset( $ifCondition['show'] ) && $ifCondition['show'] ) { foreach ( $ifCondition['show'] as $showCondition ) { if ( strpos( $showCondition, $paramsName ) !== false ) { $repeatIgnore = null; break; } } } elseif ( isset( $ifCondition['hide'] ) && $ifCondition['hide'] ) { foreach ( $ifCondition['hide'] as $hideCondition ) { if ( strpos( $hideCondition, $paramsName ) !== false ) { $repeatIgnore = null; break; } } } } } } $result[1] = '<div class="cbRepeat"' . ( ! $repeatOrdering ? ' data-cbrepeat-sortable="false"' : null ) . ( $repeatIgnore ? ' data-cbrepeat-ignore="' . htmlspecialchars( $repeatIgnore ) . '"' : null ) . ( $repeatMax ? ' data-cbrepeat-max="' . (int) $repeatMax . '"' : null ) . '>' . $return . '</div>'; } $html[] = $this->_renderLine( $param, $result, $control_name, $htmlFormatting, true, ( $viewType == 'view' ) ); } else { $html[] = $this->renderAllParams( $param, $parent_cname, $tabs, $viewType, $htmlFormatting ); } $this->popModelOfData(); } break; case 'field': $result = $this->renderParam( $param, $control_name, ( $viewType != 'param' ) ); $task = $param->attributes( 'task' ); $link = $param->attributes( 'link' ); $target = $param->attributes( 'target' ); $title = $param->attributes( 'title' ); if ( $title ) { $title = ' title="' . htmlspecialchars( CBTxt::T( $title ) ) . '"'; } else { $title = ''; } $class = $param->attributes( 'cssclasslink' ); if ( $class ) { $class = ' class="' . htmlspecialchars( $class ) . '"'; } else { $class = ''; } if ( $htmlFormatting != 'fieldsListArray' ) { if ( $link || $task ) { if ( $link ) { if ( $target == 'popup' ) { $linkhref = $this->_controllerView->drawUrl( $link, $param, $this->_modelOfData[0], $this->_modelOfData[0]->get( 'id' ), true, false ); //TODO NOT URGENT: hardcoded id column name 'id' $onclickJS = 'window.open(\'' . htmlspecialchars( cbUnHtmlspecialchars( $linkhref ) ) . '\', \'cbtablebrowserpopup\', \'status=no,toolbar=no,scrollbars=yes,titlebar=no,menubar=no,resizable=yes,width=640,height=480,directories=no,location=no\'); return false;'; $rowAttributes = ' onclick="' . $onclickJS . '"'; } else { $linkhref = $this->_controllerView->drawUrl( $link, $param, $this->_modelOfData[0], $this->_modelOfData[0]->get( 'id' ), true ); //TODO NOT URGENT: hardcoded id column name 'id' $rowAttributes = ( $target ? ' target="' . htmlspecialchars( $target ) . '"' : '' ); } } elseif ( $task ) { $linkhref = '#'; $onclickJS = "submitbutton( '" . addslashes( $task ) . "' );"; $rowAttributes = ' onclick="' . $onclickJS . '"'; } else { $linkhref = null; $rowAttributes = ''; } if ( $linkhref ) { $result[1] = '<a href="' . $linkhref .'"' . $title . $class . $rowAttributes . '>' . ( trim( $result[1] ) ? $result[1] : '---' ) . '</a>'; } else { $result[1] = '<span' . $title . $class . '>' . ( trim( $result[1] ) ? $result[1] : '---' ) . '</span>'; } } elseif ( $title ) { $result[1] = '<span' . $title . $class . '>' . $result[1] . '</span>'; } } $html[] = $this->_renderLine( $param, $result, $control_name, $htmlFormatting, false, ( $viewType == 'view' ) ); break; case 'fieldset': $htid = $this->_outputIdEqualHtmlId( $control_name, $param ); $legend = $param->attributes( 'label' ); $description = $param->attributes( 'description' ); $name = $param->attributes( 'name' ); $class = RegistryEditView::buildClasses( $param ); $fieldsethtml = '<fieldset' . ( $class ? ' class="' . htmlspecialchars( $class ) . '"' : ( $name ? ( ' class="cbFieldset cbfieldset_' . $name . '"' ) : '' ) ) . '>'; if ( $htmlFormatting == 'table' ) { $html[] = '<tr' . $htid . '><td colspan="3" width="100%">' . $fieldsethtml; } elseif ( $htmlFormatting == 'td' ) { $html[] = "\t\t\t<td" . $htid . ">" . $fieldsethtml; } elseif ( $htmlFormatting == 'span' ) { $html[] = '<div' . $htid . '>' . $fieldsethtml; } elseif ( $htmlFormatting == 'fieldsListArray' ) { // nothing } else { $html[] = '<fieldset' . $htid . ( $class ? ' class="' . htmlspecialchars( $class ) . '"' : ( $name ? ( ' class="cbFieldset cbfieldset_' . $name . '"' ) : '' ) ) . '>'; } if ( $legend && ( $htmlFormatting != 'fieldsListArray' ) ) { $html[] = '<legend' . ( $class ? ' class="' . htmlspecialchars( $class ) . '"' : '' ) . '>' . CBTxt::Th( $legend ) . '</legend>'; } if ( $htmlFormatting == 'table' ) { $html[] = '<table class="table table-noborder">'; if ( $description ) { $html[] = '<tr><td colspan="3" width="100%"><strong>' . CBTxt::Th( $description ) . '</strong></td></tr>'; } } elseif ( $htmlFormatting == 'td' ) { if ( $description ) { $html[] = '<td colspan="3" width="100%"><strong>' . CBTxt::Th( $description ) . '</strong></td>'; } } elseif ( $htmlFormatting == 'span' ) { if ( $description ) { $html[] = '<span class="cbLabelSpan">' . CBTxt::Th( $description ) . '</span> '; } $html[] = '<span class="cbFieldSpan">'; } elseif ( $htmlFormatting == 'fieldsListArray' ) { // nothing } else { if ( $description ) { $html[] = '<strong>' . CBTxt::Th( $description ) . '</strong>'; } } $html[] = $this->renderAllParams( $param, $control_name, $tabs, $viewType, $htmlFormatting ); if ( $htmlFormatting == 'table' ) { $html[] = "\n\t</table>"; $html[] = '</fieldset></td></tr>'; } elseif ( $htmlFormatting == 'td' ) { $html[] = '</fieldset></td>'; } elseif ( $htmlFormatting == 'span' ) { $html[] = '</span></fieldset></div>'; } elseif ( $htmlFormatting == 'fieldsListArray' ) { // nothing } else { $html[] = '</fieldset>'; } break; case 'fields': case 'status': $html[] = $this->renderAllParams( $param, $control_name, $tabs, $viewType, $htmlFormatting ); break; case 'if': $ifType = $param->attributes( 'type' ); if ( ( $ifType == 'showhide' ) && ( ! ( $viewType == 'view' ) ) ) { $ifName = $this->_htmlId( $control_name, $param ) . $param->attributes( 'operator' ) . $param->attributes( 'value' ). $param->attributes( 'valuetype' ); // $this->_jsif[$ifName] = array(); // $this->_jsif[$ifName]['show']= array(); // $this->_jsif[$ifName]['set'] = array(); if ( count( $param->children() ) > 0 ) { foreach ( $param->children() as $subParam ) { /** @var SimpleXMLElement $subParam */ $repeat = ( ( $subParam->getName() == 'params' ) && ( $subParam->attributes( 'repeat' ) == 'true' ) ); if ( in_array( $subParam->getName(), array( 'showview', 'params', 'fields', 'status', 'if' ) ) && ( ! $repeat ) ) { if ( $subParam->getName() == 'showview' ) { $viewName = $subParam->attributes( 'view' ); $viewModel = $this->_views->getChildByNameAttributes( 'view', array( 'ui' => 'admin', 'name' => $viewName ) ); if ( ! $viewModel ) { echo 'Extended renderAllParams:showview: View ' . $viewName . ' not defined in XML'; return false; } $children = $viewModel->children(); } else { $children = $subParam->children(); } if ( count( $children ) > 0 ) { if ( $subParam->getName() == 'params' ) { $paramsName = $subParam->attributes( 'name' ); if ( $control_name ) { $child_cnam = $control_name . '[' . $paramsName . ']'; } else { $child_cnam = $paramsName; } } else { $child_cnam = $control_name; } foreach ( $children as $vChild ) { /** @var SimpleXMLElement $vChild */ if ( ! in_array( $vChild->getName(), array( 'showview', 'if', 'else' ) ) ) { //TBD //FIXME: this avoids JS error but still shows sub-view ! recursive function needed here $this->_jsif[$ifName]['show'][] = $this->_htmlId( $child_cnam, $vChild ); } elseif ( $vChild->getName() == 'if' ) { foreach ( $vChild->children() as $vvChild ) { /** @var SimpleXMLElement $vvChild */ if ( ! in_array( $vvChild->getName(), array( 'showview', 'if', 'else', 'params', 'fields', 'status' ) ) ) { //TBD //FIXME: this avoids JS error but still shows sub-view ! recursive function needed here $this->_jsif[$ifName]['show'][] = $this->_htmlId( $child_cnam, $vvChild ); } elseif ( $vvChild->getName() == 'if' ) { foreach ( $vvChild->children() as $vvvChild ) { /** @var SimpleXMLElement $vvvChild */ if ( ! in_array( $vvvChild->getName(), array( 'showview', 'if', 'else', 'params', 'fields', 'status' ) ) ) { //TBD //FIXME: this avoids JS error but still shows sub-view ! recursive function needed here $this->_jsif[$ifName]['show'][] = $this->_htmlId( $child_cnam, $vvvChild ); } } } } } } } } elseif ( $subParam->getName() == 'else' ) { if ( $subParam->attributes( 'action' ) == 'set' ) { $correspondingParam = $param->getAnyChildByNameAttr( 'param', 'name', $subParam->attributes( 'name' ) ); if ( $correspondingParam ) { $this->_jsif[$ifName]['set'][] = $this->_htmlId( $control_name, $correspondingParam ) . '=' . $this->control_id( $control_name, $subParam->attributes( 'name' ) ) . '=' . $subParam->attributes( 'value' ); } else { echo 'No corresponding param to the else statement for name ' . $subParam->attributes( 'name' ) . ' !'; } } } else { $this->_jsif[$ifName]['show'][] = $this->_htmlId( $control_name, $subParam ); } } $this->_jsif[$ifName]['element'] = $param; $this->_jsif[$ifName]['control_name'] = $control_name; $this->_jsif[$ifName]['ifname'] = $this->_htmlId( $control_name, $param ); } $html[] = $this->renderAllParams( $param, $control_name, $tabs, $viewType, $htmlFormatting ); } elseif ( ( $ifType == 'condition' ) || ( $ifType == 'permission' ) || ( $viewType == 'view' ) ) { if ( $ifType == 'permission' ) { $showInside = Access::authorised( $param ); } else { $showInside = $this->_evalIf( $param ); } if ( $showInside ) { $then = $param->getChildByNameAttributes( 'then' ); if ( $then ) { $insideParamToRender = $then; } else { $insideParamToRender = $param; } } else { $insideParamToRender = $param->getChildByNameAttributes( 'else' ); if ( $insideParamToRender && $insideParamToRender->attributes( 'action' ) == 'set' ) { $correspondingParam = $param->getAnyChildByNameAttr( 'param', 'name', $insideParamToRender->attributes( 'name' ) ); if ( $correspondingParam ) { $this->_modelOfData[0]->set( $insideParamToRender->attributes( 'name' ), $insideParamToRender->attributes( 'value' )); $insideParamToRender = null; } else { echo 'No corresponding param to the else statement for name ' . $insideParamToRender->attributes( 'name' ) . ' !'; } } } if ( $insideParamToRender ) { $htmlElse = $this->renderAllParams( $insideParamToRender, $control_name, $tabs, $viewType, $htmlFormatting ); if ( $htmlElse != '' ) { $html[] = $htmlElse; } } } break; case 'else': break; // implemented in if above it case 'toolbarmenu': $newToolBarMenu = new SimpleXMLElement( '<?xml version="1.0" encoding="UTF-8"?><cbxml></cbxml>'); /** @var $toolbarMenu SimpleXMLElement */ /** @var $menu SimpleXMLElement */ foreach ( $param->children() as $menu ) { $menuLink = $menu->attributes( 'link' ); $menuAccess = true; $link = null; if ( $menuLink ) { $link = $this->_controllerView->drawUrl( $menuLink, $menu, $this->_modelOfData[0], null ); if ( ! $link ) { $menuAccess = false; } } if ( $menuAccess ) { /** @var $menu SimpleXMLElement */ $child = $newToolBarMenu->addChildWithAttr( 'menu', null, null, $menu->attributes() ); if ( $link ) { $child->addAttribute( 'urllink', $link ); } } } global $_CB_Backend_Menu; $_CB_Backend_Menu->menuItems[] = $newToolBarMenu; break; case 'grid': if ( $htmlFormatting != 'fieldsListArray' ) { $htid = $this->_outputIdEqualHtmlId( $control_name, $param ); if ( $htmlFormatting == 'table' ) { $html[] = '<tr' . $htid . '><td colspan="3" style="width: 100%;">'; } elseif ( $htmlFormatting == 'td' ) { $html[] = '<td' . $htid . '>'; } $fluid = ( $param->attributes( 'fluid' ) == 'true' ? true : false ); $html[] = '<div class="' . htmlspecialchars( RegistryEditView::buildClasses( $param, array( ( $fluid ? 'container-fluid' : 'container' ) ) ) ) . '">'; if ( $htmlFormatting == 'table' ) { $html[] = '<table class="table table-noborder">'; } } $html[] = $this->renderAllParams( $param, $control_name, $tabs, $viewType, $htmlFormatting ); if ( $htmlFormatting != 'fieldsListArray' ) { if ( $htmlFormatting == 'table' ) { $html[] = '</table>'; } $html[] = '</div>'; if ( $htmlFormatting == 'table' ) { $html[] = '</td></tr>'; } elseif ( $htmlFormatting == 'td' ) { $html[] = '</td>'; } } break; case 'gridrow': if ( $htmlFormatting != 'fieldsListArray' ) { $htid = $this->_outputIdEqualHtmlId( $control_name, $param ); if ( $htmlFormatting == 'table' ) { $html[] = '<tr' . $htid . '><td colspan="3" style="width: 100%;">'; } elseif ( $htmlFormatting == 'td' ) { $html[] = '<td' . $htid . '>'; } $html[] = '<div class="' . htmlspecialchars( RegistryEditView::buildClasses( $param, array( 'row' ) ) ) . '">'; } $html[] = $this->renderAllParams( $param, $control_name, $tabs, $viewType, $htmlFormatting ); if ( $htmlFormatting != 'fieldsListArray' ) { $html[] = '</div>'; if ( $htmlFormatting == 'table' ) { $html[] = '</td></tr>'; } elseif ( $htmlFormatting == 'td' ) { $html[] = '</td>'; } } break; case 'gridcol': if ( $htmlFormatting != 'fieldsListArray' ) { $classes = array(); $size = explode( ',', $param->attributes( 'size' ) ); $colSizes = array( 'xs', 'sm', 'md', 'lg' ); if ( count( $size ) > 1 ) for ( $i = 0; $i < 4; $i++ ) { if ( isset( $size[$i] ) && $size[$i] ) { $classes[] = 'col-' . $colSizes[$i] . '-' . (int) $size[$i]; } } elseif ( isset( $size[0] ) && $size[0] ) { $classes[] = 'col-sm-' . (int) $size[0]; } else { $classes[] = 'col-sm-12'; } $offset = explode( ',', $param->attributes( 'offset' ) ); if ( count( $offset ) > 1 ) for ( $i = 0; $i < 4; $i++ ) { if ( isset( $offset[$i] ) && $offset[$i] ) { $classes[] = 'col-' . $colSizes[$i] . '-offset-' . (int) $offset[$i]; } } elseif ( isset( $offset[0] ) && $offset[0] ) { $classes[] = 'col-sm-offset-' . (int) $offset[0]; } $push = explode( ',', $param->attributes( 'push' ) ); if ( count( $push ) > 1 ) for ( $i = 0; $i < 4; $i++ ) { if ( isset( $push[$i] ) && $push[$i] ) { $classes[] = 'col-' . $colSizes[$i] . '-push-' . (int) $push[$i]; } } elseif ( isset( $push[0] ) && $push[0] ) { $classes[] = 'col-sm-push-' . (int) $push[0]; } $pull = explode( ',', $param->attributes( 'pull' ) ); if ( count( $pull ) > 1 ) for ( $i = 0; $i < 4; $i++ ) { if ( isset( $pull[$i] ) && $pull[$i] ) { $classes[] = 'col-' . $colSizes[$i] . '-pull-' . (int) $pull[$i]; } } elseif ( isset( $pull[0] ) && $pull[0] ) { $classes[] = 'col-sm-pull-' . (int) $pull[0]; } $html[] = '<div class="' . htmlspecialchars( RegistryEditView::buildClasses( $param, $classes ) ) . '">'; if ( $htmlFormatting == 'table' ) { $html[] = '<table class="table table-noborder">'; } } $html[] = $this->renderAllParams( $param, $control_name, $tabs, $viewType, $htmlFormatting ); if ( $htmlFormatting != 'fieldsListArray' ) { if ( $htmlFormatting == 'table' ) { $html[] = '</table>'; } $html[] = '</div>'; } break; case 'tabpane': // first render all tabpanetabs (including nested tabpanes): $tabpaneCounter++; $this->tabpaneNames[$tabpaneCounter] = $param->attributes( 'name' ); $subhtml = $this->renderAllParams( $param, $control_name, $tabs, $viewType, $htmlFormatting ); unset( $this->tabpaneNames[$tabpaneCounter] ); $tabpaneCounter--; if ( $htmlFormatting != 'fieldsListArray' ) { // then puts them together: $htid = $this->_outputIdEqualHtmlId( $control_name, $param ); if ( $htmlFormatting == 'table' ) { $html[] = '<tr' . $htid . '><td colspan="3" style="width: 100%;">'; } elseif ( $htmlFormatting == 'td' ) { $html[] = '<td' . $htid . '>'; } $html[] = $tabs->startPane( $param->attributes( 'name' ) ); } $html[] = $subhtml; if ( $htmlFormatting != 'fieldsListArray' ) { $html[] = $tabs->endPane(); if ( $htmlFormatting == 'table' ) { $html[] = '</td></tr>'; } elseif ( $htmlFormatting == 'td' ) { $html[] = '</td>'; } } break; case 'tabpanetab': if ( $htmlFormatting != 'fieldsListArray' ) { $this->_i++; $idtab = $this->tabpaneNames[$tabpaneCounter] . $this->_i; $html[] = $tabs->startTab( $this->tabpaneNames[$tabpaneCounter], CBTxt::Th( $param->attributes( 'label' ) ), $idtab ); $tabTitle = $param->attributes( 'title' ); $tabDescription = $param->attributes( 'description' ); $tabResult = array( ( $tabTitle && $tabDescription ? CBTxt::Th( $tabTitle ) : '' ), '<strong>' . CBTxt::Th( ( $tabDescription ? $tabDescription : $tabTitle ) ) . '</strong>', null ); if ( $htmlFormatting == 'table' ) { $html[] = '<table class="table table-noborder">'; if ( $tabTitle || $tabDescription ) { $html[] = $this->_renderLine( $param, $tabResult, $control_name, $htmlFormatting, true, ( $viewType == 'view' ) ); } } elseif ( $htmlFormatting == 'div' ) { if ( $tabTitle || $tabDescription ) { $html[] = $this->_renderLine( $param, $tabResult, $control_name, $htmlFormatting, true, ( $viewType == 'view' ) ); } } } $html[] = $this->renderAllParams( $param, $control_name, $tabs, $viewType, $htmlFormatting ); if ( $htmlFormatting != 'fieldsListArray' ) { if ( $htmlFormatting == 'table' ) { $html[] = '</table>'; } $html[] = $tabs->endTab(); } break; case 'inherit': $from = $param->attributes( 'from' ); if ( $from ) { /** @var SimpleXMLElement[] $fromXml */ $fromXml = $param->xpath( $from ); if ( $fromXml && ( count( $fromXml ) > 0 ) ) { array_unshift( $this->_extenders, array( &$param ) ); foreach ( $fromXml as $fmx ) { $html[] = $this->renderAllParams( $fmx, $control_name, $tabs, $viewType, $htmlFormatting ); } } } break; case 'extend': $errorText = self::extendXMLnode( $param, $param, null, $this->_pluginObject, $this ); if ( $errorText ) { $html[] = $errorText; } break; /* * This is in future going to be the new implementation for inherit in CB as it auto-loads: could also be named "extends". case 'extends': $from = $param->attributes( 'from' ); if ( $from ) { $fromXml = cbpaidViewExtended::xpathWithAutoLoad( $param, $from ); // same as $fromXml = $param->xpath( $from ); if ( $fromXml && ( count( $fromXml ) > 0 ) ) { $param->{0} = 'inherit'; array_unshift( $this->_parent->_extenders, array( &$param ) ); foreach ( $fromXml as $fmx ) { $html[] = $this->_parent->renderAllParams( $fmx, $control_name, $tabs, $viewType, $htmlFormatting ); } } } break; */ case 'trigger': $isSaving = ( $htmlFormatting == 'fieldsListArray' ); $errorText = $this->triggerXML( $param, $this->_pluginObject, $this, $isSaving ); if ( $errorText ) { $html[] = $errorText; } break; case 'css': case 'js': case 'jquery': $fromFile = $param->attributes( 'file' ); if ( $fromFile ) { global $_CB_framework; $this->substituteName( $fromFile, true ); $fromFile = static::pathFromXML( $fromFile, $param, $this->_pluginObject, 'live' ); switch ( $param->getName() ) { case 'css': $_CB_framework->document->addHeadStyleSheet( $fromFile ); break; case 'js': $_CB_framework->document->addHeadScriptUrl( $fromFile ); break; case 'jquery': $_CB_framework->addJQueryPlugin( $param->attributes( 'name' ), $fromFile ); break; } } break; case 'menugroup': if ( $htmlFormatting != 'fieldsListArray' ) { $id = $this->_htmlId( $control_name, $param ); $tb = new Menu( $this->input, $param, $this->_options, $this->_pluginParams, $this->_types, $this->_actions, $this->_views, $this->_pluginObject, $this->_tabid, $this->_db, $this ); if ( $htmlFormatting == 'table' ) { $html[] = '<tr id="' . $id . '"><td colspan="3" style="width: 100%;">'; } elseif ( $htmlFormatting == 'td' ) { $html[] = '<td id="' . $id . '">'; } $html[] = $tb->draw(); if ( $htmlFormatting == 'table' ) { $html[] = '</td></tr>'; } elseif ( $htmlFormatting == 'td' ) { $html[] = '</td>'; } unset($tb); } break; case 'tablebrowser': if ( $htmlFormatting != 'fieldsListArray' ) { $id = $this->_htmlId( $control_name, $param ); $tb = new TableBrowser( $this->input, $param, $this->_options, $this->_pluginParams, $this->_types, $this->_actions, $this->_views, $this->_pluginObject, $this->_tabid, $this->_db, $this ); if ( $htmlFormatting == 'table' ) { $html[] = '<tr id="' . $id . '"><td colspan="3" style="width: 100%;">'; } elseif ( $htmlFormatting == 'td' ) { $html[] = '<td id="' . $id . '">'; } $html[] = $tb->draw( $viewType ); if ( $htmlFormatting == 'table' ) { $html[] = '</td></tr>'; } elseif ( $htmlFormatting == 'td' ) { $html[] = '</td>'; } unset($tb); } break; case 'showview': $name = $param->attributes( 'name' ); $viewName = $param->attributes( 'view' ); $showviewType = $param->attributes( 'type' ); $viewMode = $param->attributes( 'mode' ); $htmlFormattingView = $param->attributes( 'formatting' ); $tabbed = ( $htmlFormattingView == 'tab' ); if ( ( $htmlFormattingView == '' ) || $tabbed ) { $htmlFormattingView = $htmlFormatting; } switch ( $viewMode ) { // case 'view': case 'show': $viewType = 'view'; break; // case 'param': case 'edit': $viewType = 'param'; break; default: break; } // MODEL: load data to view: /** @var $dataModel SimpleXMLElement|null */ $dataModel = $param->getElementByPath( 'data' ); if ( $dataModel ) { if ( $name ) { if ( $control_name ) { $parent_cname = $control_name . '[' . $name . ']'; } else { $parent_cname = $name; } } else { $parent_cname = $control_name; } $dataModelType = $dataModel->attributes( 'type' ); switch ( $dataModelType ) { case 'sql:string': // <data name="params" type="sql:string" default="" /> $name = $param->attributes( 'name' ); $value = $this->get( $name, $param->attributes( 'default' ) ); $sqlParams = new Registry( $value ); $sqlParams->setNamespaceRegistry( 'parent', $this->getModelOfData() ); $data = $sqlParams; break; case 'sql:field': // <data name="params" type="sql:field" table="#__cbsubs_config" class="cbpaidConfig" key="id" value="1" valuetype="sql:int" /> global $_CB_database; $xmlsql = new XmlQuery( $_CB_database, null, $this->_pluginParams ); $xmlsql->process_data( $dataModel ); $sqlRow = $xmlsql->queryloadResult(); // get the resulting field if ( $sqlRow !== null ) { $sqlParams = new Registry( $sqlRow ); $sqlParams->setNamespaceRegistry( 'parent', $this->getModelOfData() ); $data = $sqlParams; } else { // echo 'ERROR'; // error in query... $data = null; } break; case 'parameters': // <data name="pluginparams" type="parameters" /> $data = $this->_pluginParams; break; default: $data = null; trigger_error( 'Extended renderAllParams:showview: Data model type ' . $dataModelType . ' is not implemented !', E_USER_NOTICE ); break; } } else { $parent_cname = $control_name; if ( $name && ( $showviewType == 'private' ) ) { $value = $this->get( $name, $param->attributes( 'default' ) ); $sqlParams = new Registry( $value ); $sqlParams->setNamespaceRegistry( 'parent', $this->getModelOfData() ); $data = $sqlParams; } else { // No data child found and not private type then use the current data model for params: $data = null; } } // VIEW: select view: if ( $viewName && ( ( ! $showviewType ) || ( $showviewType == 'view' ) ) ) { $this->substituteName( $viewName, false ); // $allViewsModels = $param->xpath( '/cbxml/views' ); // $param->xpath( '/cbxml/views[@test="haha"]' ); // $param->xpath( '/cbxml/views[1][@test="haha"]' ); // $param->xpath( '/cbxml/views[1]' ); // $param->xpath( '//views' ); // // $viewModel = $allViewsModels[0]->getChildByNameAttributes( 'view', array( 'ui' => 'admin', 'name' => $viewName ) ); // $allViewsModels = $param->xpath( '//views[test="haha"]/view[@name="' . $viewName . '"]' ); // $param->xpath( '../../../../../../../../views[test="haha"]/view[@name="' . $viewName . '"]' ); // $param->xpath( '/*/views[test="haha"]/*[@name="' . $viewName . '"]' ); // $param->xpath( '/cbxml/views[test="haha"]/view[@name="' . $viewName . '"]' ); // // $viewModel = $allViewsModels[0]; $viewModel = $this->_views->getChildByNameAttributes( 'view', array( 'ui' => 'admin', 'name' => $viewName ) ); if ( !$viewModel ) { if ( $param->attributes( 'mandatory' ) == 'false' ) { return null; } trigger_error( 'Extended renderAllParams:showview: View ' . $viewName . ' not defined in XML. ', E_USER_NOTICE ); return false; } if ( $data ) { $this->pushModelOfData( $data ); } if ( $tabbed ) { $this->_i++; $idtab = $this->tabpaneNames[$tabpaneCounter] . $this->_i; $html[] = $tabs->startTab( $idtab, CBTxt::Th( $viewModel->attributes( 'label' ) ), $idtab ); if ( $htmlFormattingView == 'table' ) { $html[] = '<table class="table table-noborder">'; } } $html[] = $this->renderAllParams( $viewModel, $parent_cname, $tabs, $viewType, $htmlFormattingView ); if ( $tabbed ) { if ( $htmlFormattingView == 'table' ) { $html[] = '</table>'; } $html[] = $tabs->endTab(); } if ( $data ) { $this->popModelOfData(); } } elseif ( $showviewType == 'xml' ) { // e.g.: <showview name="gateway_paymentstatus_information" mode="view" type="xml" file="processors/{payment_method}/edit.gateway" path="/*/views/view[@name="paymentstatusinformation"]" mandatory="false" /> $fromNode = $param->attributes( 'path' ); $fromFile = $param->attributes( 'file' ); $mandatory = $param->attributes( 'mandatory' ); if ( $fromNode && ( $fromFile !== null ) ) { $this->substituteName( $fromFile, true ); $this->substituteName( $fromNode, false ); if ( $fromFile !== '' ) { $fromFile = static::pathFromXML( $fromFile . '.xml', $param, $this->_pluginObject ); } if ( ( $fromFile === '' ) || is_readable( $fromFile ) ) { if ( $fromFile === '' ) { $fromRoot = $param; } else { $fromRoot = new SimpleXMLElement( $fromFile, LIBXML_NONET | ( defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0 ), true ); } /** @var SimpleXMLElement[] $viewModels */ $viewModels = $fromRoot->xpath( $fromNode ); if ( $viewModels && count( $viewModels ) ) { if ( $data ) { $this->pushModelOfData( $data ); } foreach ( $viewModels as $viewModel ) { if ( $tabbed ) { $this->_i++; $idtab = $this->tabpaneNames[$tabpaneCounter] . $this->_i; $html[] = $tabs->startTab( $idtab, CBTxt::Th( $viewModel->attributes( 'label' ) ), $idtab ); if ( $htmlFormattingView == 'table' ) { $html[] = '<table class="table table-noborder">'; } } $html[] = $this->renderAllParams( $viewModel, $parent_cname, $tabs, $viewType, $htmlFormattingView ); if ( $tabbed ) { if ( $htmlFormattingView == 'table' ) { $html[] = '</table>'; } $html[] = $tabs->endTab(); } } if ( $data ) { $this->popModelOfData(); } } elseif ( $mandatory == 'false' ) { return null; } else { trigger_error( 'Extended renderAllParams:showview: View ' . $viewName . ': file ' . $fromFile . ', path: ' . $fromNode . ' does not exist or is empty.', E_USER_NOTICE ); } } elseif ( $param->attributes( 'mandatory' ) == 'false' ) { return null; } else { trigger_error( 'Extended renderAllParams:showview: View ' . $viewName . ': file ' . $fromFile . ' does not exist or is not readable.', E_USER_NOTICE ); return false; } } } elseif ( $showviewType == 'plugins' ) { $groups = explode( ',', $param->attributes( 'groups' ) ); $action = $param->attributes( 'action' ); $path = $param->attributes( 'path' ); $this->substituteName( $action, false ); $this->substituteName( $path, false ); if ( $data ) { $this->pushModelOfData( $data ); } foreach ( $groups as $group ) { $matches = null; if ( preg_match( '/^([^\[]+)\[(.+)\]$/', $group, $matches ) ) { $classId = $matches[2]; $group = $matches[1]; } else { $classId = null; } global $_PLUGINS; $_PLUGINS->loadPluginGroup( $group, $classId, 0 ); $loadedPlugins = $_PLUGINS->getLoadedPluginGroup( $group ); foreach ( $loadedPlugins as /* $id => */ $plugin ) { $element = $_PLUGINS->loadPluginXML( 'action', $action, $plugin->id ); /** @var SimpleXMLElement[] $viewModels */ $viewModels = $element->xpath( $path ); if ( $viewModels && count( $viewModels ) ) { foreach ( $viewModels as $viewModel ) { if ( $tabbed ) { $this->_i++; $idtab = $this->tabpaneNames[$tabpaneCounter] . $this->_i; $tabTite = CBTxt::Th( $viewModel->attributes( 'label' ) ); if ( ! $tabTite ) { $tabTite = $plugin->name; } $html[] = $tabs->startTab( $idtab, $tabTite, $idtab ); if ( $htmlFormattingView == 'table' ) { $html[] = '<table class="table table-noborder">'; } } $html[] = $this->renderAllParams( $viewModel, $parent_cname, $tabs, $viewType, $htmlFormattingView ); if ( $tabbed ) { if ( $htmlFormattingView == 'table' ) { $html[] = '</table>'; } $html[] = $tabs->endTab(); } } } } } if ( $data ) { $this->popModelOfData(); } } elseif ( $showviewType == 'private' ) { $dataModelClass = $param->attributes( 'class' ); $methodName = $param->attributes( 'method' ); $dataKey = $param->attributes( 'key' ); if ( $dataModelClass && $methodName ) { if ( $data && $dataKey && isset( $data->$dataKey ) ) { $dataModelValue = $data->$dataKey; } elseif ( ! $dataKey ) { $dataModelValue = 0; } else { trigger_error( sprintf( "Missing key field %s in data", htmlspecialchars( $dataKey ) ), E_USER_NOTICE ); return null; } if ( strpos( $dataModelClass, '::' ) === false ) { if ( class_exists( $dataModelClass ) ) { /** @var $viewerClass TableInterface */ global $_CB_database; $viewerClass = new $dataModelClass( $_CB_database ); // normal clas="className" if ( $dataModelValue ) { $viewerClass->load( $dataModelValue ); } } else { trigger_error( "Missing private class " . htmlspecialchars( $dataModelClass ), E_USER_NOTICE ); return null; } } else { $dataModelSingleton = explode( '::', $dataModelClass ); // class object loader from singleton: class="loaderClass::loadStaticMethor" with 1 parameter, the key value. if ( is_callable( $dataModelSingleton ) ) { $rows = call_user_func_array( $dataModelSingleton, array( $dataModelValue ) ); $viewerClass = $rows[0]; } else { trigger_error( "Missing singleton class creator " . htmlspecialchars( $dataModelClass ), E_USER_NOTICE ); return null; } } if ( $viewerClass ) { if ( method_exists( $viewerClass, $methodName ) ) { /* $row = $this->_modelOfData[0]; //TBD: checked.... foreach (get_object_vars($data) as $key => $v) { if( substr( $key, 0, 1 ) != '_' ) { // internal attributes of an object are ignored if (isset($row->$key)) { $data->$key = $row->$key; } } } */ // this parameter is missing here ?: $control_name_name = $this->control_name( $control_name, $name ); $html[] = $viewerClass->$methodName( $param, $data, $this->_pluginParams, $parent_cname, $tabs, $viewType, $htmlFormattingView, $tabbed ); // shouldn't this be this? : $html[] = $viewerClass->$methodName( $value, $this->_pluginParams, $name, $node, $control_name, $control_name_name, $this->_view, $this->_modelOfData[0], $this->_modelOfDataRows, $this->_modelOfDataRowsNumber ); } else { trigger_error( "Missing private xml method " . htmlspecialchars( $methodName ), E_USER_NOTICE ); return null; } } else { trigger_error( "No data found !", E_USER_NOTICE ); return null; } } else { trigger_error( "Missing private class or method attributes in xml", E_USER_NOTICE ); return null; } } break; case 'hidden': if ( $viewType == 'view' ) { trigger_error( 'Type hidden in non-view mode not implemented in GUI.', E_USER_NOTICE ); } break; case 'comment': break; case 'extendxmlparser': $this->setExtendedViewParser( $param ); break; case 'extendparser': // old CBSubs GPL 3.0.0 case: ignore if not needed (but keep reference in case: $this->oldExtendParserNode = $param; break; case 'attributes': // Implemented above by ->extendParamAttributes break; default: if ( $this->_extendViewParser ) { $html[] = $this->_extendViewParser->renderAllParams( $param, $control_name, $tabs, $viewType, $htmlFormatting ); } else { echo 'Method to render XML view element ' . $param->getName() . ' is not implemented !'; } break; } return ( $htmlFormatting == 'fieldsListArray' ? $this->arrayValuesMerge( $html ) : implode( "\n", $html ) ); }