/** * Create a params object based on a XML dom node. * * @param DOMElement $node * * @return stdClass */ public static function nodeParams($node) { $params = $node->getElementsByTagName('params'); $return = new stdClass(); $i = 0; foreach ($params as $param) { // Avoid nested descendants when asking for group params if ($i > 0) { continue; } $i++; if ($param->hasAttributes()) { foreach ($param->attributes as $attr) { $name = $attr->nodeName; $value = (string) $attr->nodeValue; if (FabrikWorker::isJSON($value)) { $value = json_decode($value); } $return->{$name} = $value; } } } return $return; }
/** * Manipulates posted form data for insertion into database * * @param mixed $val this elements posted form data * @param array $data posted form data * * @return mixed */ public function storeDatabaseFormat($val, $data) { if (is_array($val)) { // Ensure that array is incremental numeric key -otherwise json_encode turns it into an object $val = array_values($val); } if (is_array($val) || is_object($val)) { return json_encode($val); } else { /* * $$$ hugh - nastyish hack to try and make sure we consistently save as JSON, * for instance in CSV import, if data is just a single option value like 2, * instead of ["2"], we have been saving it as just that value, rather than a single * item JSON array. */ if (isset($val)) { // We know it's not an array or an object, so lets see if it's a string // which doesn't contain ", [ or ] if (!preg_match('#["\\[\\]]#', $val)) { // No ", [ or ], so lets see if wrapping it up in JSON array format // produces valid JSON $json_val = '["' . $val . '"]'; if (FabrikWorker::isJSON($json_val)) { // Looks like we we have a valid JSON array, so return that return $json_val; } else { // Give up and just store whatever it was we got! return $val; } } else { // Contains ", [ or ], so wtf, hope it's json return $val; } } else { return ''; } } }
/** * Format JSON data */ protected function implodeJSON(&$v, $k, $sepchar) { if (!FabrikString::isRawName($k) && FabrikWorker::isJSON($v)) { $v = FabrikWorker::JSONtoData($v, true); $v = implode($sepchar, $v); } }
/** * Shows the data formatted for the list view * * @param string $data elements data * @param object &$thisRow all the data in the lists current row * * @return string formatted value */ public function renderListData($data, &$thisRow) { $params = $this->getParams(); $groupModel = $this->getGroupModel(); $labeldata = array(); if (!$groupModel->isJoin() && $groupModel->canRepeat()) { $opts = $this->_getOptionVals(); $name = $this->getFullName(false, true, false) . '_raw'; // If coming from fabrikemail plugin $thisRow is empty if (isset($thisRow->{$name})) { $data = $thisRow->{$name}; } if (!is_array($data)) { $data = json_decode($data, true); } foreach ($data as $d) { foreach ($opts as $opt) { if ($opt->value == $d) { $labeldata[] = $opt->text; break; } } } } else { // $$$ hugh - $data may already be JSON encoded, so we don't want to double-encode. if (!FabrikWorker::isJSON($data)) { $labeldata = (array) $data; } else { // $$$ hugh - yeah, I know, kinda silly to decode right before we encode, // should really refactor so encoding goes in this if/else structure! $labeldata = (array) json_decode($data); } foreach ($labeldata as &$l) { $l = $this->getLabelForValue($l, $l); } } $data = json_encode($labeldata); // $$$ rob add links and icons done in parent::renderListData(); return parent::renderListData($data, $thisRow); }
/** * Trigger called when a row is stored. * If we are creating a new record, and the element was set to readonly * then insert the users data into the record to be stored * * @param array &$data Data to store * @param int $repeatCounter Repeat group index * * @return bool If false, data should not be added. */ public function onStoreRow(&$data, $repeatCounter = 0) { if (!parent::onStoreRow($data, $repeatCounter)) { return false; } // $$$ hugh - if importing a CSV, just use the data as is if ($this->getListModel()->importingCSV) { return true; } $input = $this->app->input; // $$$ hugh - special case, if we have just run the fabrikjuser plugin, we need to // use the 'newuserid' as set by the plugin. $newUserId = $input->getInt('newuserid', 0); if (!empty($newUserId)) { $newUserIdElement = $input->get('newuserid_element', ''); $thisFullName = $this->getFullName(true, false); if ($newUserIdElement == $thisFullName) { return true; } } $element = $this->getElement(); $params = $this->getParams(); /* * After a failed validation, if readonly for ACL's, it may be JSON, and urlencoded, like ["94"] */ $data[$element->name] = is_array($data[$element->name]) ? $data[$element->name][0] : $data[$element->name]; $data[$element->name] = html_entity_decode($data[$element->name]); if (FabrikWorker::isJSON($data[$element->name])) { $data[$element->name] = FabrikWorker::JSONtoData($data[$element->name], true); } $data[$element->name] = is_array($data[$element->name]) ? $data[$element->name][0] : $data[$element->name]; /** * $$$ hugh - special case for social plugins (like CB plugin). If plugin sets * fabrik.plugin.profile_id, and 'user_use_social_plugin_profile' param is set, * and we are creating a new row, then use the session data as the user ID. * This allows user B to view a table in a CB profile for user A, do an "Add", * and have the user element set to user A's ID. */ // TODO - make this table/form specific, but not so easy to do in CB plugin if ((int) $params->get('user_use_social_plugin_profile', 0)) { //if ($input->getString('rowid', '', 'string') == '' && $input->get('task') !== 'doimport') if ($input->getString('rowid', '', 'string') == '' && !$this->getListModel()->importingCSV) { $session = JFactory::getSession(); if ($session->has('fabrik.plugin.profile_id')) { $data[$element->name] = $session->get('fabrik.plugin.profile_id'); $data[$element->name . '_raw'] = $data[$element->name]; // $session->clear('fabrik.plugin.profile_id'); return true; } } } // $$$ rob also check we aren't importing from CSV - if we are ignore //if ($input->getString('rowid', '', 'string') == '' && $input->get('task') !== 'doimport') if ($input->getString('rowid', '', 'string') == '' && !$this->getListModel()->importingCSV) { // $$$ rob if we cant use the element or its hidden force the use of current logged in user if (!$this->canUse() || $this->getElement()->hidden == 1) { $data[$element->name] = $this->user->get('id'); $data[$element->name . '_raw'] = $data[$element->name]; } } else { if ($this->updateOnEdit()) { $data[$element->name] = $this->user->get('id'); $data[$element->name . '_raw'] = $data[$element->name]; // Set the formDataWithTableName so any plugins (like email) pick it up with getProcessData() $thisFullName = $this->getFullName(true, false); $formModel = $this->getFormModel(); $groupModel = $this->getGroupModel(); if ($groupModel->canRepeat()) { $formModel->formDataWithTableName[$thisFullName][$repeatCounter] = array($data[$element->name]); $formModel->formDataWithTableName[$thisFullName . '_raw'][$repeatCounter] = array($data[$element->name]); } else { $formModel->formDataWithTableName[$thisFullName] = array($data[$element->name]); $formModel->formDataWithTableName[$thisFullName . '_raw'] = array($data[$element->name]); } // $$$ hugh - need to add to updatedByPlugin() in order to override write access settings. // This allows us to still 'update on edit' when element is write access controlled. if (!$this->canUse()) { $this->getFormModel()->updatedByPlugin($thisFullName, $this->user->get('id')); } } else { if ($this->getListModel()->importingCSV) { $formData = $this->getFormModel()->formData; $userId = FArrayHelper::getValue($formData, $element->name, ''); if (!empty($userId) && !is_numeric($userId)) { $user = JFactory::getUser($userId); $newUserId = $user->get('id'); if (empty($newUserId) && FabrikWorker::isEmail($userId)) { $db = $this->_db; $query = $db->getQuery(true)->select($db->qn('id'))->from($db->qn('#__users'))->where($db->qn('email') . ' = ' . $db-- > q($userId)); $db->setQuery($query, 0, 1); $newUserId = (int) $db->loadResult(); } $data[$element->name] = $newUserId; } } } } return true; }
/** * Checks if filter option values are in json format * if so explode those values into new options * * @param array &$rows filter options * * @return null */ protected function unmergeFilterSplits(&$rows) { /* * takes rows which may be in format : * * [0] => stdClass Object ( [text] => ["1"] [value] => ["1"] ) and converts them into [0] => JObject Object ( [_errors:protected] => Array ( ) [value] => 1 [text] => 1 [disable] => ) */ $allvalues = array(); foreach ($rows as $row) { $allvalues[] = $row->value; } $c = count($rows) - 1; for ($j = $c; $j >= 0; $j--) { $vals = FabrikWorker::JSONtoData($rows[$j]->value, true); $txt = FabrikWorker::JSONtoData($rows[$j]->text, true); if (is_array($vals)) { $found = false; for ($i = 0; $i < count($vals); $i++) { $vals2 = FabrikWorker::JSONtoData($vals[$i], true); $txt2 = FabrikWorker::JSONtoData(JArrayHelper::getValue($txt, $i), true); for ($jj = 0; $jj < count($vals2); $jj++) { if (!in_array($vals2[$jj], $allvalues)) { $found = true; $allvalues[] = $vals2[$jj]; $rows[] = JHTML::_('select.option', $vals2[$jj], $txt2[$jj]); } } } /* if ($found) { // $$$ rob 01/08/2011 - caused empty list in advanced search on dropdown element unset($rows[$j]); } */ if (FabrikWorker::isJSON($rows[$j])) { // $$$ rob 01/10/2012 - if not unset then you could get json values in standard dd filter (checkbox) unset($rows[$j]); } } if (count($vals) > 1) { unset($rows[$j]); } } }
/** * 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; } } } }
/** * Trigger called when a row is deleted * * @param array $groups Grouped data of rows to delete * * @return void */ public function onDeleteRows($groups) { // Cant delete files from unpublished elements if (!$this->canUse()) { return; } $db = $this->getListModel()->getDb(); require_once COM_FABRIK_FRONTEND . '/helpers/uploader.php'; $params = $this->getParams(); if ($params->get('upload_delete_image', false)) { jimport('joomla.filesystem.file'); $elName = $this->getFullName(true, false); $name = $this->getElement()->name; foreach ($groups as $rows) { foreach ($rows as $row) { if (array_key_exists($elName . '_raw', $row)) { if ($this->isJoin()) { $join = $this->getJoinModel()->getJoin(); $query = $db->getQuery(true); $query->select('*')->from($db->qn($join->table_join))->where($db->qn('parent_id') . ' = ' . $db->q($row->__pk_val)); $db->setQuery($query); $imageRows = $db->loadObjectList('id'); if (!empty($imageRows)) { foreach ($imageRows as $imageRow) { $this->deleteFile($imageRow->{$name}); } $query->clear(); $query->delete($db->qn($join->table_join))->where($db->qn('id') . ' IN (' . implode(', ', array_keys($imageRows)) . ')'); $db->setQuery($query); $logMsg = 'onDeleteRows Delete records query: ' . $db->getQuery() . '; user = '******'id'); JLog::add($logMsg, JLog::WARNING, 'com_fabrik.element.fileupload'); $db->execute(); } } else { $files = $row->{$elName . '_raw'}; if (FabrikWorker::isJSON($files)) { $files = FabrikWorker::JSONtoData($files, true); } else { $files = explode(GROUPSPLITTER, $files); } foreach ($files as $filename) { $this->deleteFile(trim($filename)); } } } } } } }