/** * Determines the value for the element in the form view * * @param array $data form data * @param int $repeatCounter when repeating joinded groups we need to know what part of the array to access * @param array $opts options * * @return string value */ public function getValue($data, $repeatCounter = 0, $opts = array()) { // @TODO rename $this->defaults to $this->values if (!isset($this->defaults)) { $this->defaults = array(); } if (!array_key_exists($repeatCounter, $this->defaults)) { $groupModel = $this->getGroup(); $group = $groupModel->getGroup(); $joinid = $this->isJoin() ? $this->getJoinModel()->getJoin()->id : $group->join_id; $formModel = $this->getFormModel(); $element = $this->getElement(); /** * $$$rob - if no search form data submitted for the search element then the default * selection was being applied instead * otherwise get the default value so if we don't find the element's value in $data we fall back on this value */ $value = JArrayHelper::getValue($opts, 'use_default', true) == false ? '' : $this->getDefaultValue($data); $name = $this->getFullName(false, true, false); $rawname = $name . '_raw'; if ($groupModel->isJoin() || $this->isJoin()) { $nameKey = 'join.' . $joinid . '.' . $name; $rawNameKey = 'join.' . $joinid . '.' . $rawname; // $$$ rob 22/02/2011 this test barfed on fileuploads which weren't repeating // if ($groupModel->canRepeat() || !$this->isJoin()) { if ($groupModel->canRepeat()) { $v = FArrayHelper::getNestedValue($data, $nameKey . '.' . $repeatCounter, null); if (is_null($v)) { $v = FArrayHelper::getNestedValue($data, $rawNameKey . '.' . $repeatCounter, null); } if (!is_null($v)) { $value = $v; } } else { $v = FArrayHelper::getNestedValue($data, $nameKey, null); if (is_null($v)) { $v = FArrayHelper::getNestedValue($data, $rawNameKey, null); } if (!is_null($v)) { $value = $v; } /* $$$ rob if you have 2 tbl joins, one repeating and one not * the none repeating one's values will be an array of duplicate values * but we only want the first value */ if (is_array($value) && !$this->isJoin()) { $value = array_shift($value); } } } else { if ($groupModel->canRepeat()) { // Repeat group NO join $thisname = $name; if (!array_key_exists($name, $data)) { $thisname = $rawname; } if (array_key_exists($thisname, $data)) { if (is_array($data[$thisname])) { // Occurs on form submission for fields at least $a = $data[$thisname]; } else { // Occurs when getting from the db $a = json_decode($data[$thisname]); } $value = JArrayHelper::getValue($a, $repeatCounter, $value); } } else { $value = !is_array($data) ? $data : JArrayHelper::getValue($data, $name, JArrayHelper::getValue($data, $rawname, $value)); } } if (!is_array($value)) { $value = array($value); } /*@TODO perhaps we should change this to $element->value and store $element->default as the actual default value *stops this getting called from form validation code as it messes up repeated/join group validations */ if (array_key_exists('runplugins', $opts) && $opts['runplugins'] == 1) { FabrikWorker::getPluginManager()->runPlugins('onGetElementDefault', $formModel, 'form', $this); } $this->defaults[$repeatCounter] = $value; } return $this->defaults[$repeatCounter]; }
/** * Load the actual validation plugins that the element uses * * @return array plugins */ public function getPlugins() { $item = $this->getItem(); $plugins = (array) FArrayHelper::getNestedValue($item->params, 'validations.plugin', array()); $published = (array) FArrayHelper::getNestedValue($item->params, 'validations.plugin_published', array()); $icons = (array) FArrayHelper::getNestedValue($item->params, 'validations.show_icon', array()); $in = (array) FArrayHelper::getNestedValue($item->params, 'validations.validate_in', array()); $on = (array) FArrayHelper::getNestedValue($item->params, 'validations.validation_on', array()); $return = array(); for ($i = 0; $i < count($plugins); $i++) { $o = new stdClass(); $o->plugin = $plugins[$i]; $o->published = FArrayHelper::getValue($published, $i, 1); $o->show_icon = FArrayHelper::getValue($icons, $i, 1); $o->validate_in = FArrayHelper::getValue($in, $i, 'both'); $o->validation_on = FArrayHelper::getValue($on, $i, 'both'); $return[] = $o; } return $return; }
/** * Load the actual validation plugins that the element uses * * @return array plugins */ public function getPlugins() { $item = $this->getItem(); $plugins = FArrayHelper::getNestedValue($item->params, 'validations.plugin', array()); return $plugins; }
/** * When rendered as a multi-select / checkbox getValue() returns the id for the x-ref table. * This method gets the ids for the records in the x-ref target table. * * @param array $data Form data * @param int $repeatCounter Repeat group counter * * @return array|boolean Array of ids if found, else return false. */ protected function multiOptionTargetIds($data, $repeatCounter = 0) { $displayType = $this->getDisplayType(); if ($displayType == 'checkbox' || $displayType == 'multilist') { $idname = $this->getFullName(true, false) . '_id'; $formModel = $this->getFormModel(); if ($this->isJoin() && !$formModel->hasErrors()) { // Only add repeatCounter if group model repeating - otherwise we only ever select one checkbox. if ($this->getGroupModel()->canRepeat()) { $idname .= '.' . $repeatCounter; } $default = (array) FArrayHelper::getNestedValue($data, $idname, 'not found'); return $default; } } return false; }
/** * Draws the html form element * * @param array $data to preopulate element with * @param int $repeatCounter repeat group counter * * @return string elements html */ public function render($data, $repeatCounter = 0) { // For repetaing groups we need to unset this where each time the element is rendered unset($this->_autocomplete_where); if ($this->isJoin()) { $this->hasSubElements = true; } $params = $this->getParams(); $formModel = $this->getForm(); $groupModel = $this->getGroup(); $element = $this->getElement(); $aGroupRepeats[$element->group_id] = $groupModel->canRepeat(); $displayType = $params->get('database_join_display_type', 'dropdown'); $db = $this->getDb(); if (!$db) { JError::raiseWarning(JText::sprintf('PLG_ELEMENT_DBJOIN_DB_CONN_ERR', $element->name)); return ''; } if (isset($formModel->_aJoinGroupIds[$groupModel->getId()])) { $joinId = $formModel->_aJoinGroupIds[$groupModel->getId()]; $joinGroupId = $groupModel->getId(); } else { $joinId = ''; $joinGroupId = ''; } $default = (array) $this->getValue($data, $repeatCounter); $tmp = $this->_getOptions($data, $repeatCounter); $w = new FabrikWorker(); foreach ($default as &$d) { $d = $w->parseMessageForPlaceHolder($d); } $thisElName = $this->getHTMLName($repeatCounter); // Get the default label for the drop down (use in read only templates) $defaultLabel = ''; $defaultValue = ''; foreach ($tmp as $obj) { if ($obj->value == JArrayHelper::getValue($default, 0, '')) { $defaultValue = $obj->value; $defaultLabel = $obj->text; break; } } $id = $this->getHTMLId($repeatCounter); // $$$ rob 24/05/2011 - add options per row $options_per_row = intval($params->get('dbjoin_options_per_row', 0)); $html = array(); // $$$ hugh - still need to check $this->isEditable(), as content plugin sets it to false, // as no point rendering editable view for {fabrik view=element ...} in an article. if (!$formModel->isEditable() || !$this->isEditable()) { // $$$ rob 19/03/2012 uncommented line below - needed for checkbox rendering $obj = JArrayHelper::toObject($data); $defaultLabel = $this->renderListData($default, $obj); if ($defaultLabel === $params->get('database_join_noselectionlabel', JText::_('COM_FABRIK_PLEASE_SELECT'))) { // No point showing 'please select' for read only $defaultLabel = ''; } if ($params->get('databasejoin_readonly_link') == 1) { $popupformid = (int) $params->get('databasejoin_popupform'); if ($popupformid !== 0) { $query = $db->getQuery(true); $query->select('id')->from('#__{package}_lists')->where('form_id =' . $popupformid); $db->setQuery($query); $listid = $db->loadResult(); $url = 'index.php?option=com_fabrik&view=details&formid=' . $popupformid . '&listid =' . $listid . '&rowid=' . $defaultValue; $defaultLabel = '<a href="' . JRoute::_($url) . '">' . $defaultLabel . '</a>'; } } $html[] = $defaultLabel; } else { // $$$rob should be canUse() otherwise if user set to view but not use the dd was shown if ($this->canUse()) { $idname = $this->getFullName(false, true, false) . '_id'; $attribs = 'class="fabrikinput inputbox" size="1"'; /*if user can access the drop down*/ switch ($displayType) { case 'dropdown': default: $html[] = JHTML::_('select.genericlist', $tmp, $thisElName, $attribs, 'value', 'text', $default, $id); break; case 'radio': // $$$ rob 24/05/2011 - always set one value as selected for radio button if none already set if ($defaultValue == '' && !empty($tmp)) { $defaultValue = $tmp[0]->value; } // $$$ rob 24/05/2011 - add options per row $options_per_row = intval($params->get('dbjoin_options_per_row', 0)); $html[] = '<div class="fabrikSubElementContainer" id="' . $id . '">'; $html[] = FabrikHelperHTML::aList($displayType, $tmp, $thisElName, $attribs . ' id="' . $id . '"', $defaultValue, 'value', 'text', $options_per_row); break; case 'checkbox': $defaults = $formModel->failedValidation() ? $default : explode(GROUPSPLITTER, JArrayHelper::getValue($data, $idname)); $html[] = '<div class="fabrikSubElementContainer" id="' . $id . '">'; $rawname = $this->getFullName(false, true, false) . '_raw'; $html[] = FabrikHelperHTML::aList($displayType, $tmp, $thisElName, $attribs . ' id="' . $id . '"', $defaults, 'value', 'text', $options_per_row, $this->isEditable()); if ($this->isJoin() && $this->isEditable()) { $join = $this->getJoin(); $joinidsName = 'join[' . $join->id . '][' . $join->table_join . '___id]'; if ($groupModel->canRepeat()) { $joinidsName .= '[' . $repeatCounter . '][]'; $joinids = FArrayHelper::getNestedValue($data, 'join.' . $joinId . '.' . $rawname . '.' . $repeatCounter, 'not found'); } else { $joinidsName .= '[]'; $joinids = explode(GROUPSPLITTER, JArrayHelper::getValue($data, $rawname)); } $tmpids = array(); foreach ($tmp as $obj) { $o = new stdClass(); $o->text = $obj->text; if (in_array($obj->value, $defaults)) { $index = array_search($obj->value, $defaults); $o->value = JArrayHelper::getValue($joinids, $index); } else { $o->value = 0; } $tmpids[] = $o; } $html[] = '<div class="fabrikHide">'; $attribs = 'class="fabrikinput inputbox" size="1" id="' . $id . '"'; $html[] = FabrikHelperHTML::aList($displayType, $tmpids, $joinidsName, $attribs, $joinids, 'value', 'text', $options_per_row, $this->isEditable()); $html[] = '</div>'; } $defaultLabel = implode("\n", $html); break; case 'multilist': $defaults = $formModel->failedValidation() ? $default : explode(GROUPSPLITTER, JArrayHelper::getValue($data, $idname)); if ($this->isEditable()) { $multiSize = (int) $params->get('dbjoin_multilist_size', 6); $attribs = 'class="fabrikinput inputbox" size="' . $multiSize . '" multiple="true"'; $html[] = JHTML::_('select.genericlist', $tmp, $thisElName, $attribs, 'value', 'text', $defaults, $id); } else { $attribs = 'class="fabrikinput inputbox" size="1" id="' . $id . '"'; $html[] = FabrikHelperHTML::aList($displayType, $tmp, $thisElName, $attribs, $defaults, 'value', 'text', $options_per_row, $this->isEditable()); } $defaultLabel = implode("\n", $html); break; case 'auto-complete': // Get the LABEL from the form's data. $label = (array) $this->getValue($data, $repeatCounter, array('valueFormat' => 'label')); // $$$ rob 18/06/2012 if form submitted with errors - reshowing the auto-complete wont have access to the submitted values label if ($formModel->hasErrors()) { $label = (array) $this->getLabelForValue($label[0], $label[0], $repeatCounter); } $autoCompleteName = str_replace('[]', '', $thisElName) . '-auto-complete'; $html[] = '<input type="text" size="' . $params->get('dbjoin_autocomplete_size', '20') . '" name="' . $autoCompleteName . '" id="' . $id . '-auto-complete" value="' . JArrayHelper::getValue($label, 0) . '" class="fabrikinput inputbox autocomplete-trigger"/>'; // $$$ rob - class property required when cloning repeat groups - don't remove $html[] = '<input type="hidden" class="fabrikinput" size="20" name="' . $thisElName . '" id="' . $id . '" value="' . JArrayHelper::getValue($default, 0, '') . '"/>'; break; } if ($params->get('fabrikdatabasejoin_frontend_select') && $this->isEditable()) { JText::script('PLG_ELEMENT_DBJOIN_SELECT'); $html[] = '<a href="#" class="toggle-selectoption" title="' . JText::_('COM_FABRIK_SELECT') . '">' . FabrikHelperHTML::image('search.png', 'form', @$this->tmpl, array('alt' => JText::_('COM_FABRIK_SELECT'))) . '</a>'; } if ($params->get('fabrikdatabasejoin_frontend_add') && $this->isEditable()) { JText::script('PLG_ELEMENT_DBJOIN_ADD'); $html[] = '<a href="#" title="' . JText::_('COM_FABRIK_ADD') . '" class="toggle-addoption">'; $html[] = FabrikHelperHTML::image('action_add.png', 'form', @$this->tmpl, array('alt' => JText::_('COM_FABRIK_SELECT'))) . '</a>'; } $html[] = $displayType == 'radio' ? '</div>' : ''; } elseif ($this->canView()) { $html[] = $this->renderListData($default, JArrayHelper::toObject($data)); } } if ($params->get('join_desc_column', '') !== '') { $html[] = '<div class="dbjoin-description">'; $opts = $this->_getOptionVals($data, $repeatCounter); for ($i = 0; $i < count($opts); $i++) { $opt = $opts[$i]; $display = $opt->value == $default ? '' : 'none'; $c = $i + 1; $html[] = '<div style="display:' . $display . '" class="notice description-' . $c . '">' . $opt->description . '</div>'; } $html[] = '</div>'; } return implode("\n", $html); }
/** * Determines the value for the element in the form view * * @param array $data form data * @param int $repeatCounter when repeating joinded groups we need to know what part of the array to access * @param array $opts options * * @return string value */ public function getValue($data, $repeatCounter = 0, $opts = array()) { $data = (array) $data; if (!isset($this->defaults)) { $this->defaults = array(); } /* * $$$ rob 20/08/2012 - added $data to serialized key * Seems that db join _getOptionVals() _autocomplete_where is getting run a couple of times with key and labels being passed in */ $valueKey = $repeatCounter . serialize($opts) . serialize($data); if (!array_key_exists($valueKey, $this->defaults)) { $value = ''; $groupModel = $this->getGroupModel(); $group = $groupModel->getGroup(); $joinid = $this->isJoin() ? $this->getJoinModel()->getJoin()->id : $group->join_id; $formModel = $this->getForm(); $element = $this->getElement(); // $$$rob - if no search form data submitted for the checkbox search element then the default // selecton was being applied instead $value = JArrayHelper::getValue($opts, 'use_default', true) == false ? '' : $this->getDefaultValue($data); $name = $this->getValueFullName($opts); // $name could already be in _raw format - so get inverse name e.g. with or without raw $rawname = JString::substr($name, -4) === '_raw' ? JString::substr($name, 0, -4) : $name . '_raw'; if ($groupModel->isJoin() || $this->isJoin()) { $nameKey = 'join.' . $joinid . '.' . $name; $rawNameKey = 'join.' . $joinid . '.' . $rawname; if ($groupModel->canRepeat()) { $v = FArrayHelper::getNestedValue($data, $nameKey . '.' . $repeatCounter, null); if (is_null($v)) { $v = FArrayHelper::getNestedValue($data, $rawNameKey . '.' . $repeatCounter, null); } if (!is_null($v)) { $value = $v; } } else { $v = FArrayHelper::getNestedValue($data, $nameKey, null); if (is_null($v)) { $v = FArrayHelper::getNestedValue($data, $rawNameKey, null); } if (!is_null($v)) { $value = $v; } if (is_array($value) && (array_key_exists(0, $value) && is_array($value[0]))) { // Fix for http://fabrikar.com/forums/showthread.php?t=23568&page=2 $value = $value[0]; } } } else { if ($groupModel->canRepeat()) { // Can repeat NO join if (array_key_exists($name, $data)) { // Occurs on form submission for fields at least : occurs when getting from the db $a = is_array($data[$name]) ? $a = $data[$name] : FabrikWorker::JSONtoData($data[$name], true); $value = JArrayHelper::getValue($a, $repeatCounter, $value); } elseif (array_key_exists($rawname, $data)) { // Occurs on form submission for fields at least : occurs when getting from the db $a = is_array($data[$rawname]) ? $a = $data[$rawname] : FabrikWorker::JSONtoData($data[$rawname], true); $value = JArrayHelper::getValue($a, $repeatCounter, $value); } } else { if (array_key_exists($name, $data)) { // Put this back in for radio button after failed validation not picking up previously selected option $value = $data[$name]; } elseif (array_key_exists($rawname, $data)) { $value = $data[$rawname]; } } } if ($value === '') { // Query string for joined data $value = JArrayHelper::getValue($data, $name); } /** * $$$ hugh -- added this so we are consistent in what we return, otherwise uninitialized values, * i.e. if you've added a checkbox element to a form with existing data, don't get set, and causes * issues with methods that call getValue(). */ if (!isset($value)) { $value = ''; } // $$$ corner case where you have a form and a list for the same table on the same page // and the list is being filtered with table___name[value]=foo on the query string. if (is_array($value) && array_key_exists('value', $value)) { $value = $value['value']; } $element->default = $value; $formModel = $this->getForm(); // Stops this getting called from form validation code as it messes up repeated/join group validations if (array_key_exists('runplugins', $opts) && $opts['runplugins'] == 1) { FabrikWorker::getPluginManager()->runPlugins('onGetElementDefault', $formModel, 'form', $this); } if (is_string($element->default)) { // $$$ rob changed to false below as when saving encrypted data a stored valued of 62 // Was being returned as [62], then [[62]] etc. $element->default = FabrikWorker::JSONtoData($element->default, false); } $this->defaults[$valueKey] = $element->default; } return $this->defaults[$valueKey]; }
/** * Update the form models data with data from CURL request * * @param Joomla\Registry\Registry $params Parameters * @param array $responseBody Response body * @param array $data Data returned from CURL request * * @return void */ protected function updateFormModelData($params, $responseBody, $data) { $w = new FabrikWorker(); $dataMap = $params->get('put_include_list', ''); $include = $w->parseMessageForPlaceholder($dataMap, $responseBody, true); $formModel = $this->getModel(); if (FabrikWorker::isJSON($include)) { $include = json_decode($include); $keys = $include->put_key; $values = $include->put_value; $defaults = $include->put_value; for ($i = 0; $i < count($keys); $i++) { $key = $keys[$i]; $default = $defaults[$i]; $localKey = FabrikString::safeColNameToArrayKey($values[$i]); $remoteData = FArrayHelper::getNestedValue($data, $key, $default, true); if (!is_null($remoteData)) { $formModel->_data[$localKey] = $remoteData; } } } }