/** * View for <param type="private" class="cbpaidParamsExt" method="data">... * * @param string $value Stored Data of Model Value associated with the element * @param ParamsInterface $pluginParams Main settigns parameters of the plugin * @param string $name Name attribute * @param CBSimpleXMLElement $param This XML node * @param string $control_name Name of the control * @param string $control_name_name css id-encode of the names of the controls surrounding this node * @param boolean $view TRUE: view, FALSE: edit * @param cbpaidTable $modelOfData Data of the Model corresponding to this View * @param cbpaidTable[] $modelOfDataRows Displayed Rows if it is a table * @param int $modelOfDataRowsNumber Total Number of rows * @return null|string */ public function data($value, &$pluginParams, $name, &$param, $control_name, $control_name_name, $view, &$modelOfData, &$modelOfDataRows, &$modelOfDataRowsNumber) { global $_CB_database; $data = $param->getElementByPath('data'); if ($data) { $dataTable = $data->attributes('table'); if (!$dataTable) { if (is_object($modelOfData) && $modelOfData instanceof TableInterface) { $dataTable = $modelOfData->getTableName(); } elseif (is_object($modelOfData) && isset($modelOfData->_tbl)) { $dataTable = $modelOfData->_tbl; } else { $dataTable = null; } } $xmlsql = new XmlQuery($_CB_database, $dataTable, $pluginParams); $xmlsql->setExternalDataTypeValues('modelofdata', $modelOfData); $xmlsql->process_orderby($data->getElementByPath('orderby')); // <data><orderby><field> fields $xmlsql->process_fields($param); // <data><rows><field> fields $xmlsql->process_where($data->getElementByPath('where')); // <data><where><column> fields $value = $xmlsql->queryloadResult(); // get the value if ($view) { if ($value === null) { $value = $param->attributes('default'); } return htmlspecialchars($value); } else { return '<input name="' . $control_name_name . '" type="text" id="' . $control_name_name . '" value="' . htmlspecialchars($value) . '"' . $this->_title($param) . ' />'; } } return null; }
/** * Parse the ticks to plot * @access private * * @param SimpleXMLElement $el <ticks type="function" name="nameofJSfunction" /> * @param callback $callBacks * @return array */ function _plot_parseTickFormatter( &$el, &$callBacks ) { global $_CB_database; $names_values = array(); if ( $el ) { $type = $el->attributes( 'type' ); $data = $el->getElementByPath( 'field' ); if ( ($type == 'append' ) && $data ) { $dataTable = $data->attributes( 'table' ); if ( ! $dataTable ) { $dataTable = null; } $xmlsql = new XmlQuery( $_CB_database, $dataTable, $this->_pluginParams ); $xmlsql->setExternalDataTypeValues( 'modelofdata', $this->_modelOfData[0] ); $xmlsql->process_data( $data ); $textToAppend = $xmlsql->queryloadResult( $data ); // get the records if ( $textToAppend ) { $names_values = new PlotJsonFormatter( 'function(val, axis) { return val.toFixed(axis.tickDecimals)+" ' . addslashes( CBTxt::T( $textToAppend ) ) . '"; }' ); } } else { $callBacksNew = $callBacks; unset( $callBacksNew[$el->getName()] ); $names_values = $this->xml2arr( $el, $callBacksNew ); } } return $names_values; }
/** * Saves the CB plugin view after an edit view form submit * * @param array $options * @param array $actionPath * @param array $keyValues * @param array $parametersValues * @param SimpleXMLElement $viewModel * @param TableInterface $data * @param RegistryEditController $params * @param string $mode * @param string $dataModelType * @param PluginTable $plugin * @param SimpleXMLElement $dataModel * @param RegistryInterface $pluginParams * @param string $cbprevstate * @param int $ui * @return null|string NULL: ok, STRING: error */ protected function savePluginView($options, $actionPath, $keyValues, $parametersValues, $viewModel, $data, $params, &$mode, $dataModelType, $plugin, $dataModel, $pluginParams, $cbprevstate, $ui) { global $_CB_framework; new cbTabs(false, 2, -1, false); // prevents output of CB tabs js code until we are done with drawing (or redirecting) $resultingMsg = null; cbSpoofCheck('plugin'); $postArray = $this->input->getNamespaceRegistry('post')->asArray(); // List of variables to exclude from the $postArray: $exclude = array('option', 'cid', 'cbprevstate', cbSpoofField()); foreach ($actionPath as $k => $v) { $exclude[] = $k; } // Remove the exclude variables from the $postArray before being used in the below cases: foreach ($exclude as $v) { if (isset($postArray[$v])) { unset($postArray[$v]); } } // Fix multi-selects and multi-checkboxes arrays to |*|-delimited strings: $postArray = $this->recursiveMultiSelectFix($postArray); foreach ($postArray as $key => $value) { if (property_exists($data, $key)) { $postArray[$key] = is_array($value) ? json_encode($value) : $value; } } $errorMsg = null; switch ($dataModelType) { case 'sql:row': if ($ui == 2) { if (true !== ($error = RegistryEditView::validateAndBindPost($params, $postArray))) { $errorMsg = $error; break; } if (!$data->bind($postArray)) { $errorMsg = $data->getError(); break; } } else { RegistryEditView::setFieldsListArrayValues(true); $fields = $params->draw(null, null, null, null, null, null, false, 'param', 'fieldsListArray'); // New CB2.0 way for bind(): foreach ($fields as $key => $value) { if (property_exists($data, $key)) { $data->{$key} = is_array($value) ? json_encode($value) : $value; } } } if (!$data->check()) { $errorMsg = $data->getError(); break; } $dataModelKey = $data->getKeyName(); $dataModelValueOld = $data->{$dataModelKey}; if ($mode == 'savecopy') { if (!$data->canCopy($data)) { $errorMsg = $data->getError(); break; } if (!$data->copy($data)) { $errorMsg = $data->getError(); break; } } else { if (!$data->store()) { $errorMsg = $data->getError(); break; } } $dataModelValue = $data->{$dataModelKey}; // Id changed; be sure to update the url encase of redirect: if (count($keyValues) == 1) { $urlKeys = array_keys($keyValues); $urlDataKey = $urlKeys[0]; if ($mode == 'savenew') { unset($actionPath[$urlDataKey]); } elseif ($dataModelValue != $dataModelValueOld) { $actionPath[$urlDataKey] = $dataModelValue; } } if ($data->hasFeature('checkout')) { /** @var \CBLib\Database\Table\CheckedOrderedTable $data */ $data->checkin(); } $this->savePluginViewOrder($data, $viewModel); $resultingMsg = $data->cbResultOfStore(); break; case 'sql:field': // <data name="params" type="sql:field" table="#__cbsubs_config" class="cbpaidConfig" key="id" value="1" valuetype="sql:int" /> $dataModelName = $dataModel->attributes('name'); $dataModelKey = $dataModel->attributes('key'); $dataModelValue = $dataModel->attributes('value'); if ($ui == 2) { if (true !== ($error = RegistryEditView::validateAndBindPost($params, $postArray))) { $errorMsg = $error; break; } } $rawParams = array(); $rawParams[$dataModelName] = json_encode($postArray); $xmlsql = new XmlQuery($this->db, null, $pluginParams); $xmlsql->process_data($dataModel); if ($dataModelValue) { $result = $xmlsql->queryUpdate($rawParams); } else { $result = $xmlsql->queryInsert($rawParams, $dataModelKey); } if (!$result) { $errorMsg = $xmlsql->getErrorMsg(); } break; case 'parameters': if ($ui == 2) { if (true !== ($error = RegistryEditView::validateAndBindPost($params, $postArray))) { $errorMsg = $error; break; } } $rawParams = array(); $rawParams['params'] = json_encode($postArray); // $plugin = new PluginTable( $this->_db ); // $plugin->load( $pluginId ); if (!$plugin->bind($rawParams)) { $errorMsg = $plugin->getError(); break; } if (!$plugin->check()) { $errorMsg = $plugin->getError(); break; } if (!$plugin->store()) { $errorMsg = $plugin->getError(); break; } $plugin->checkin(); $plugin->updateOrder("type='" . $plugin->getDbo()->getEscaped($plugin->type) . "' AND ordering > -10000 AND ordering < 10000 "); $resultingMsg = $plugin->cbResultOfStore(); break; case 'class': if ($ui == 2) { if (true !== ($error = RegistryEditView::validateAndBindPost($params, $postArray))) { $errorMsg = $error; break; } } if (!$data->bind($postArray)) { $errorMsg = $data->getError(); break; } if (!$data->check()) { $errorMsg = $data->getError(); break; } if (!$data->store()) { $errorMsg = $data->getError(); break; } if ($data->hasFeature('checkout')) { /** @var \CBLib\Database\Table\CheckedOrderedTable $data */ $data->checkin(); } $this->savePluginViewOrder($data, $viewModel); $resultingMsg = $data->cbResultOfStore(); break; case 'sql:multiplerows': default: echo 'Save error: showview data type: ' . $dataModelType . ' not implemented !'; exit; break; } if ($ui == 2) { $url = 'index.php?option=' . $options['option'] . '&view=' . $options['view']; if ($options['view'] == 'editPlugin') { $url .= '&cid=' . $options['pluginid']; } $url = $_CB_framework->backendUrl($url); } else { $url = 'index.php'; if (count($options) > 0) { $fixOptions = array(); foreach ($options as $k => $v) { $fixOptions[$k] = $k . '=' . urlencode($v); } $url .= '?' . implode('&', $fixOptions); } } if (isset($data->title)) { $dataItem = CBTxt::T($data->title); } elseif (isset($data->name)) { $dataItem = CBTxt::T($data->name); } else { $dataItem = null; } if ($errorMsg) { if (in_array($mode, array('save', 'savenew', 'savecopy'))) { $mode = 'apply'; } $msg = CBTxt::T('FAILED_TO_SAVE_LABEL_ITEM_BECAUSE_ERROR', 'Failed to save [label] [item] because: [error]', array('[label]' => $viewModel->attributes('label'), '[item]' => $dataItem, '[error]' => $errorMsg)); $msgType = 'error'; } else { $msg = CBTxt::T('SUCCESSFULLY_SAVED_LABEL_ITEM', 'Successfully saved [label] [item]', array('[label]' => $viewModel->attributes('label'), '[item]' => $dataItem)); $msgType = 'message'; } switch ($mode) { case 'apply': case 'savenew': case 'savecopy': unset($actionPath['view']); foreach ($actionPath as $k => $v) { if ($v !== '') { $url .= '&' . $k . '=' . $v; } } foreach ($parametersValues as $k => $v) { $url .= '&' . $k . '=' . $v; } if ($cbprevstate) { $url .= '&cbprevstate=' . $cbprevstate; } break; case 'save': if ($cbprevstate) { $prevUrl = base64_decode($cbprevstate); // $parametersValues[] = "'" . base64_encode( implode( '&', $cbprevstate ) ) . "'"; if (!preg_match('$[:/]$', $prevUrl)) { $prevUrl = str_replace('&pluginid=', '&cid=', $prevUrl); if ($ui == 2) { $url = $_CB_framework->backendUrl('index.php?' . $prevUrl); } else { $url = 'index.php?' . $prevUrl; } } } break; } if ($resultingMsg) { if ($ui != 2) { return $resultingMsg; // in frontend, for now, don't redirect here: think this is right ! } else { // If not an apply then change it to an apply so we can redisplay the view with the resulting message above it: if (in_array($mode, array('save', 'savenew', 'savecopy'))) { $mode = 'apply'; } echo $resultingMsg; } } else { if ($ui != 2) { return null; // in frontend, for now, don't redirect here: think this is right ! // $url = cbUnHtmlspecialchars( cbSef( $url ) ); } if ($mode == 'apply' && $errorMsg) { $_CB_framework->enqueueMessage($msg, $msgType); } else { cbRedirect($ui == 2 ? $url : cbSef(htmlspecialchars($url), false), $msg, $msgType); } } return null; }
/** * Prepares the XML-SQL Query * * @param boolean $allFields * @return XmlQuery */ protected function &_prepareXmlSqlQuery($allFields = true) { $xmlsql = new XmlQuery($this->_db, $this->table, $this->_pluginParams); if ($allFields === false) { // in case of complex where, we might still need the joins and AS values: foreach ($this->_filterPossibilitesArray as $value) { // <filters><filter> (preprocessed xml above) if (!$this->isValueEmpty($value['internalvalue'])) { /** @var SimpleXMLElement[] $value */ $where = $value['xml']->getElementByPath('data/where'); /** @var array $value */ if ($where) { $allFields = true; break; } } } } if ($allFields) { $xmlsql->process_fields($this->listFieldsRows); // <fields><field> fields // now check for orderings : if ($this->listFieldsRows) { foreach ($this->listFieldsRows->children() as $field) { /** @var $field SimpleXMLElement */ $orderinggroups = $field->getElementByPath('orderinggroups'); /** @var $orderinggroups SimpleXMLElement|null */ if ($orderinggroups) { foreach ($orderinggroups->children() as $group) { /** @var $group SimpleXMLElement */ if ($group->getName() == 'ordering') { if (count($group->children()) > 0) { $xmlsql->process_field($group); } } } } } } } else { if ($this->listFieldsRows) { $fieldsToProcess = array(); if ($this->search) { // search string defined: we need to process the corresponding fields: foreach ($this->quicksearchfields->children() as $searchField) { /** @var $searchField SimpleXMLElement */ if ($searchField->getName() == 'field') { $searchFieldName = $searchField->attributes('name'); if ($searchFieldName) { $fieldsToProcess[$searchFieldName] = true; } } } } if ($this->orderby) { // orderby string defined: we need to process the corresponding fields: foreach ($this->orderbyfields->children() as $orderField) { /** @var SimpleXMLElement $orderField */ if ($orderField->getName() == 'field') { $orderFieldName = $orderField->attributes('name'); if ($orderFieldName) { $fieldsToProcess[$orderFieldName] = true; } } elseif ($orderField->getName() == 'ordergroup') { foreach ($orderField->children() as $orderGroup) { if ($orderGroup->getName() == 'field') { $orderFieldName = $orderGroup->attributes('name'); if ($orderFieldName) { $fieldsToProcess[$orderFieldName] = true; } } } } } } foreach ($this->_filterPossibilitesArray as $value) { // <filters><filter> (preprocessed xml above) if (!$this->isValueEmpty($value['internalvalue'])) { // filtering defined, need to process field: if (is_array($value['valuefield'])) { foreach ($value['valuefield'] as $valueField) { $fieldsToProcess[$valueField] = true; } } else { $fieldsToProcess[$value['valuefield']] = true; } } } foreach (array_keys($fieldsToProcess) as $fName) { $selectField = $this->listFieldsRows->getChildByNameAttr('field', 'name', $fName); if ($selectField) { $xmlsql->process_field($selectField); } else { // trying to assume it's in the main table... // most times it's ok: no error: trigger_error( sprintf( 'TableBrowser: Notice: trying to select field '%s' which is not in the fields list at main level.', $fName ), E_USER_NOTICE ); } } } } $xmlsql->process_orderby($this->orderbyfields, $this->orderby); // <orderby><field> fields $xmlsql->process_search_string($this->quicksearchfields, $this->search); // <quicksearch><field> fields $xmlsql->process_where($this->whereColumns); // <where><column> fields $xmlsql->process_groupby($this->groupbyfields); // <groupby><field> fields foreach ($this->_filterPossibilitesArray as $value) { // <filters><filter> (preprocessed xml above) if (!$this->isValueEmpty($value['internalvalue'])) { $this->_filtered = true; if ($value['valuetype']) { $valueType = $value['valuetype']; } else { if (strpos($value['basetype'], ':') === false) { $valueType = 'xml:' . $value['basetype']; } else { $valueType = $value['basetype']; } } $xmlsql->process_filter($value['xml'], $value, $valueType); /* $where = $value['xml']->getElementByPath( 'data/where'); if ( $where ) { $saveReverse = $xmlsql->setReverse( true ); // $Tdata = $value['xml']->getElementByPath( 'data/where'); // $xmlsql->process_data( $Tdata ); $xmlsql->process_where( $where, $value ); $xmlsql->setReverse( $saveReverse ); } else { $joinkeys = $value['xml']->getElementByPath( 'data/joinkeys'); if ( $joinkeys ) { $data = $value['xml']->getElementByPath( 'data'); $xmlsql->changeJoinType( $data->attributes( 'name' ), $joinkeys->attributes( 'type' ) ); } else { $xmlsql->addWhere( $value['valuefield'], $value['operator'], $value['internalvalue'], $valueType ); } } */ } } return $xmlsql; }
/** * Loads the rows of menu * * @param SimpleXMLElement $child */ protected function _loadMenuRows(&$child) { if ($child->getName() == 'menu') { $listFieldsRows = $child->getElementByPath('fields'); $menuName = $child->attributes('name'); $this->rows[$menuName] = new Table(); if ($listFieldsRows) { foreach ($listFieldsRows->children() as $field) { /** @var $field SimpleXMLElement */ if ($field->attributes('type') == 'private') { $name = $field->attributes('name'); // $className = $field->attributes( 'class' ); // $methodName = $field->attributes( 'method' ); $value = $field->attributes('value'); $content = $value; // it will be called at rendering time: /* if ( $className && $methodName && class_exists( $className ) ) { $obj = new $className( $this->_db ); //TBD: implement the singleton similarly/calling _form_private if ( method_exists( $obj, $methodName ) ) { /* $row = $this->_modelOfData[0]; //TBD: checked.... foreach (get_object_vars($obj) as $key => $v) { if( substr( $key, 0, 1 ) != '_' ) { // internal attributes of an object are ignored if (isset($row->$key)) { $obj->$key = $row->$key; } } } * $content = $obj->$methodName( $value, $this->_pluginParams ); //TBD: pluginParams should be available by the method params() of $obj, not as function parameter } else { $content = 'Missing method ' . $methodName; } } else { $content = 'Missing class, or method in xml'; } */ $this->rows[$menuName]->{$name} = $content; } else { $xmlsql = new XmlQuery($this->_db, null, $this->_pluginParams); $xmlsql->process_field($field); $obj = null; if ($xmlsql->queryLoadObject($obj)) { // get the resulting object foreach (get_object_vars($obj) as $k => $v) { if (substr($k, 0, 1) != '_') { // internal attributes of an object are ignored $this->rows[$menuName]->{$k} = $v; } } // } else { // error in query... } } } } } }