/** * Execute export * * @return string * */ public function ___buildExport() { $form = $this->wire('modules')->get('InputfieldForm'); $form->action = './'; $form->method = 'post'; $exportFields = $this->wire('input')->post('export_fields'); if (empty($exportFields)) { $f = $this->wire('modules')->get('InputfieldSelectMultiple'); $f->attr('id+name', 'export_fields'); $f->label = $this->_('Select the fields that you want to export'); $f->icon = 'copy'; $maxName = 0; $maxLabel = 0; $numFields = 0; foreach ($this->wire('fields') as $field) { if (strlen($field->name) > $maxName) { $maxName = strlen($field->name); } $label = $field->getLabel(); if (strlen($label) > $maxLabel) { $maxLabel = strlen($label); } $numFields++; } $fieldName = $this->_('NAME'); $fieldLabel = $this->_('LABEL'); $fieldType = $this->_('TYPE'); $label = $fieldName . ' ' . str_repeat('.', $maxName - strlen($fieldName) + 3) . ' ' . $fieldLabel . str_repeat('.', $maxLabel - strlen($fieldLabel) + 3) . ' ' . $fieldType; $f->addOption(0, $label, array('disabled' => 'disabled')); foreach ($this->wire('fields') as $field) { $fieldLabel = $field->getLabel(); $label = $field->name . ' ' . str_repeat('.', $maxName - strlen($field->name) + 3) . ' ' . $fieldLabel . str_repeat('.', $maxLabel - strlen($fieldLabel) + 3) . ' ' . str_replace('Fieldtype', '', $field->type); $f->addOption($field->name, $label); } $f->notes = $this->_('Shift+Click to select multiple in sequence. Ctrl+Click (or Cmd+Click) to select multiple individually. Ctrl+A (or Cmd+A) to select all.'); $f->attr('size', $numFields + 1); $form->add($f); $f = $this->wire('modules')->get('InputfieldSubmit'); $f->attr('name', 'submit_export'); $f->attr('value', $this->_x('Export', 'button')); $form->add($f); } else { $form = $this->wire('modules')->get('InputfieldForm'); $f = $this->wire('modules')->get('InputfieldTextarea'); $f->attr('id+name', 'export_data'); $f->label = $this->_('Export Data'); $f->description = $this->_('Copy and paste this data into the "Import" box of another installation.'); $f->notes = $this->_('Click anywhere in the box to select all export data. Once selected, copy the data with CTRL-C or CMD-C.'); $f->attr('value', wireEncodeJSON($this->getExportData($exportFields), true, true)); $form->add($f); $f = $this->wire('modules')->get('InputfieldButton'); $f->href = './'; $f->value = $this->_x('Ok', 'button'); $form->add($f); } return $form; }
/** * Overridden from WireSaveableItems to retain keys with 0 values and remove defaults we don't need saved * */ protected function encodeData(array $value) { if (isset($value['collapsed']) && $value['collapsed'] === 0) { unset($value['collapsed']); } if (isset($value['columnWidth']) && (empty($value['columnWidth']) || $value['columnWidth'] == 100)) { unset($value['columnWidth']); } return wireEncodeJSON($value, 0); }
/** * Given an export data array, import it back to the class and return what happened * * @param array $data * * @return array Returns array( * [property_name] => array( * * // old value (in string comparison format) * 'old' => 'old value', * * // new value (in string comparison format) * 'new' => 'new value', * * // error message (string) or messages (array) * 'error' => 'error message or blank if no error' , * ) * */ public function setImportData(array $data) { $changes = array(); $data['errors'] = array(); $_data = $this->getExportData(); // compare old data to new data to determine what's changed foreach ($data as $key => $value) { if ($key == 'errors') { continue; } $data['errors'][$key] = ''; $old = isset($_data[$key]) ? $_data[$key] : ''; if (is_array($old)) { $old = wireEncodeJSON($old, true); } $new = is_array($value) ? wireEncodeJSON($value, true) : $value; if ($old === $new || empty($old) && empty($new) || (string) $old === (string) $new) { continue; } $changes[$key] = array('old' => $old, 'new' => $new, 'error' => ''); } // prep data for actual import if (!empty($data['type']) && (string) $this->type != $data['type']) { $this->type = $this->wire('fieldtypes')->get($data['type']); } if (!$this->type) { $this->type = $this->wire('fieldtypes')->get('FieldtypeText'); } $data = $this->type->importConfigData($this, $data); // populate import data foreach ($changes as $key => $change) { $this->errors('clear all'); $this->set($key, $data[$key]); if (!empty($data['errors'][$key])) { $error = $data['errors'][$key]; // just in case they switched it to an array of multiple errors, convert back to string if (is_array($error)) { $error = implode(" \n", $error); } } else { $error = $this->errors('last'); } $changes[$key]['error'] = $error ? $error : ''; } $this->errors('clear all'); return $changes; }
/** * Encode the 'data' portion of the table. * * This is a front-end to wireEncodeJSON so that it can be overridden if needed. * */ protected function encodeData(array $value) { return wireEncodeJSON($value); }
/** * Given a module class name and an array of configuration data, save it for the module * * @param string|Module $className * @param array $configData * @return bool True on success * @throws WireException * */ public function ___saveModuleConfigData($className, array $configData) { if (is_object($className)) { $className = $className->className(); } if (!($id = $this->moduleIDs[$className])) { throw new WireException("Unable to find ID for Module '{$className}'"); } $this->configData[$id] = $configData; $json = count($configData) ? wireEncodeJSON($configData, true) : ''; $database = $this->wire('database'); $query = $database->prepare("UPDATE modules SET data=:data WHERE id=:id"); // QA $query->bindValue(":data", $json, PDO::PARAM_STR); $query->bindValue(":id", (int) $id, PDO::PARAM_INT); $result = $query->execute(); return $result; }
/** * Given an array of export data, import it to the given template * * @param Template $template * @param array $data * @return bool True if successful, false if not * @return array Returns array( * [property_name] => array( * 'old' => 'old value', // old value (in string comparison format) * 'new' => 'new value', // new value (in string comparison format) * 'error' => 'error message or blank if no error' // error message (string) or messages (array) * ) * */ public function ___setImportData(Template $template, array $data) { $template->set('_importMode', true); $fieldgroupData = array(); $changes = array(); $_data = $this->getExportData($template); if (isset($data['fieldgroupFields'])) { $fieldgroupData['fields'] = $data['fieldgroupFields']; } if (isset($data['fieldgroupContexts'])) { $fieldgroupData['contexts'] = $data['fieldgroupContexts']; } unset($data['fieldgroupFields'], $data['fieldgroupContexts'], $data['id']); foreach ($data as $key => $value) { if ($key == 'fieldgroups_id' && !ctype_digit("{$value}")) { $fieldgroup = $this->wire('fieldgroups')->get($value); if (!$fieldgroup) { $fieldgroup = new Fieldgroup(); $fieldgroup->name = $value; } $oldValue = $template->fieldgroup ? $template->fieldgroup->name : ''; $newValue = $fieldgroup->name; $error = ''; try { $template->setFieldgroup($fieldgroup); } catch (Exception $e) { $error = $e->getMessage(); } if ($oldValue != $fieldgroup->name) { if (!$fieldgroup->id) { $newValue = "+{$newValue}"; } $changes['fieldgroups_id'] = array('old' => $template->fieldgroup->name, 'new' => $newValue, 'error' => $error); } } $template->errors("clear"); $oldValue = isset($_data[$key]) ? $_data[$key] : ''; $newValue = $value; if (is_array($oldValue)) { $oldValue = wireEncodeJSON($oldValue, true, false); } else { if (is_object($oldValue)) { $oldValue = (string) $oldValue; } } if (is_array($newValue)) { $newValue = wireEncodeJSON($newValue, true, false); } else { if (is_object($newValue)) { $newValue = (string) $newValue; } } // everything else if ($oldValue == $newValue || empty($oldValue) && empty($newValue)) { // no change needed } else { // changed try { $template->set($key, $value); if ($key == 'roles') { $template->getRoles(); } // forces reload of roles (and resulting error messages) $error = $template->errors("clear"); } catch (Exception $e) { $error = array($e->getMessage()); } $changes[$key] = array('old' => $oldValue, 'new' => $newValue, 'error' => count($error) ? $error : array()); } } if (count($fieldgroupData)) { $_changes = $template->fieldgroup->setImportData($fieldgroupData); if ($_changes['fields']['new'] != $_changes['fields']['old']) { $changes['fieldgroupFields'] = $_changes['fields']; } if ($_changes['contexts']['new'] != $_changes['contexts']['old']) { $changes['fieldgroupContexts'] = $_changes['contexts']; } } $template->errors('clear'); $template->set('_importMode', false); return $changes; }
/** * Given a module class name and an array of configuration data, save it for the module * * @param string|Module $className * @param array $configData * @return bool True on success * */ public function ___saveModuleConfigData($className, array $configData) { if (is_object($className)) { $className = $className->className(); } if (!($id = $this->moduleIDs[$className])) { throw new WireException("Unable to find ID for Module '{$className}'"); } $json = count($configData) ? wireEncodeJSON($configData, true) : ''; return $this->fuel('db')->query("UPDATE modules SET data='" . $this->fuel('db')->escape_string($json) . "' WHERE id={$id}"); }
/** * Given an export data array, import it back to the class and return what happened * * Changes are not committed until the item is saved * * @param Fieldgroup $fieldgroup * @param array $data * @return array Returns array( * [property_name] => array( * 'old' => 'old value', // old value, always a string * 'new' => 'new value', // new value, always a string * 'error' => 'error message or blank if no error' * ) * @throws WireException if given invalid data * */ public function ___setImportData(Fieldgroup $fieldgroup, array $data) { $return = array('fields' => array('old' => '', 'new' => '', 'error' => array()), 'contexts' => array('old' => '', 'new' => '', 'error' => array())); $fieldgroup->setTrackChanges(true); $fieldgroup->errors("clear"); $_data = $this->getExportData($fieldgroup); $rmFields = array(); if (isset($data['fields'])) { // field data $old = "\n" . implode("\n", $_data['fields']) . "\n"; $new = "\n" . implode("\n", $data['fields']) . "\n"; if ($old !== $new) { $return['fields']['old'] = $old; $return['fields']['new'] = $new; // figure out which fields should be removed foreach ($fieldgroup as $field) { $fieldNames[$field->name] = $field->name; if (!in_array($field->name, $data['fields'])) { $fieldgroup->remove($field); $label = "-{$field->name}"; $return['fields']['new'] .= $label . "\n"; $rmFields[] = $field->name; } } // figure out which fields should be added foreach ($data['fields'] as $name) { $field = $this->wire('fields')->get($name); if (in_array($name, $rmFields)) { continue; } if (!$field) { $error = sprintf($this->_('Unable to find field: %s'), $name); $return['fields']['error'][] = $error; $label = str_replace("\n{$name}\n", "\n?{$name}\n", $return['fields']['new']); $return['fields']['new'] = $label; continue; } if (!$fieldgroup->hasField($field)) { $label = str_replace("\n{$field->name}\n", "\n+{$field->name}\n", $return['fields']['new']); $return['fields']['new'] = $label; $fieldgroup->add($field); } else { $field = $fieldgroup->getField($field->name, true); // in context $fieldgroup->add($field); $label = str_replace("\n{$field->name}\n", "\n{$field->name}\n", $return['fields']['new']); $return['fields']['new'] = $label; } } } $return['fields']['new'] = trim($return['fields']['new']); $return['fields']['old'] = trim($return['fields']['old']); } if (isset($data['contexts'])) { // context data foreach ($data['contexts'] as $key => $value) { // remove items where they are both empty if (empty($value) && empty($_data['contexts'][$key])) { unset($data['contexts'][$key], $_data['contexts'][$key]); } } foreach ($_data['contexts'] as $key => $value) { // remove items where they are both empty if (empty($value) && empty($data['contexts'][$key])) { unset($data['contexts'][$key], $_data['contexts'][$key]); } } $old = wireEncodeJSON($_data['contexts'], true, true); $new = wireEncodeJSON($data['contexts'], true, true); if ($old !== $new) { $return['contexts']['old'] = trim($old); $return['contexts']['new'] = trim($new); foreach ($data['contexts'] as $name => $context) { $field = $fieldgroup->getField($name, true); // in context if (!$field) { if (!empty($context)) { $return['contexts']['error'][] = sprintf($this->_('Unable to find field to set field context: %s'), $name); } continue; } $id = $field->id; $fieldContexts = $fieldgroup->getFieldContextArray(); if (isset($fieldContexts[$id]) || !empty($context)) { $fieldgroup->setFieldContextArray($id, $context); $fieldgroup->trackChange('fieldContexts'); } } } } // other data foreach ($data as $key => $value) { if ($key == 'fields' || $key == 'contexts') { continue; } $old = isset($_data[$key]) ? $_data[$key] : null; if (is_array($old)) { $old = wireEncodeJSON($old, true, false); } $new = is_array($value) ? wireEncodeJSON($value, true, false) : $value; if ($old == $new) { continue; } $fieldgroup->set($key, $value); $error = (string) $fieldgroup->errors("first clear"); $return[$key] = array('old' => $old, 'new' => $value, 'error' => $error); } if (count($rmFields)) { $return['fields']['error'][] = sprintf($this->_('Warning, all data in these field(s) will be permanently deleted (please confirm): %s'), implode(', ', $rmFields)); } $fieldgroup->errors('clear'); return $return; }
/** * Overridden from WireSaveableItems to retain specific keys * */ protected function encodeData(array $value) { return wireEncodeJSON($value, array('slashUrls')); }
/** * Given a module class name and an array of configuration data, save it for the module * * @param string|Module $className * @param array $configData * @return bool True on success * @throws WireException * */ public function ___saveModuleConfigData($className, array $configData) { if (is_object($className)) { $className = $className->className(); } if (!($id = $this->moduleIDs[$className])) { throw new WireException("Unable to find ID for Module '{$className}'"); } // ensure original duplicates info is retained and validate that it is still current $configData = $this->duplicates()->getDuplicatesConfigData($className, $configData); $this->configData[$id] = $configData; $json = count($configData) ? wireEncodeJSON($configData, true) : ''; $database = $this->wire('database'); $query = $database->prepare("UPDATE modules SET data=:data WHERE id=:id", "modules.saveModuleConfigData({$className})"); // QA $query->bindValue(":data", $json, PDO::PARAM_STR); $query->bindValue(":id", (int) $id, PDO::PARAM_INT); $result = $query->execute(); $this->log("Saved module '{$className}' config data"); return $result; }
/** * Render the required javascript 'config' variable for the document <head> * * @return string * */ public function renderJSConfig() { $config = $this->wire('config'); $jsConfig = $config->js(); $jsConfig['debug'] = $config->debug; $jsConfig['urls'] = array('root' => $config->urls->root, 'admin' => $config->urls->admin, 'modules' => $config->urls->modules, 'core' => $config->urls->core, 'files' => $config->urls->files, 'templates' => $config->urls->templates, 'adminTemplates' => $config->urls->adminTemplates); return "var config = " . wireEncodeJSON($jsConfig, true, $config->debug); }
/** * Execute export * * @return string * */ public function ___buildExport() { $form = $this->wire('modules')->get('InputfieldForm'); $form->action = './'; $form->method = 'post'; $exportTemplates = $this->wire('input')->post('export_templates'); if (empty($exportTemplates)) { $f = $this->wire('modules')->get('InputfieldSelectMultiple'); $f->attr('id+name', 'export_templates'); $f->label = $this->_('Select the templates that you want to export'); $f->icon = 'copy'; $maxName = 0; $maxLabel = 0; $numTemplates = 0; foreach ($this->wire('templates') as $template) { if (strlen($template->name) > $maxName) { $maxName = strlen($template->name); } $label = $template->getLabel(); if (strlen($label) > $maxLabel) { $maxLabel = strlen($label); } $numTemplates++; } $templateName = $this->_('NAME') . ' '; $templateLabel = $this->_('LABEL') . ' '; $numFields = $this->_('FIELDS') . ' '; $modified = $this->_('MODIFIED'); $label = $templateName . ' ' . str_repeat('.', $maxName - strlen($templateName) + 10) . ' ' . $templateLabel . str_repeat('.', $maxLabel - strlen($templateLabel) + 10) . ' ' . str_pad($numFields, 13, '.') . ' ' . $modified; $f->addOption(0, $label, array('disabled' => 'disabled')); foreach ($this->wire('templates') as $template) { //if(!is_object($template->fieldgroup)) $this->error("Template: $template has no fieldgroup"); $templateName = $template->name . ' '; $templateLabel = $template->getLabel() . ' '; if ($templateLabel == $templateName) { $templateLabel = ''; } $numFields = count($template->fieldgroup) . ' '; $modified = $template->modified ? wireRelativeTimeStr($template->modified) : ''; $label = $templateName . str_repeat('.', $maxName - strlen($templateName) + 10) . ' ' . $templateLabel . str_repeat('.', $maxLabel - strlen($templateLabel) + 10) . ' ' . str_pad($numFields, 13, '.') . ' ' . $modified; $f->addOption($template->name, $label); } $f->notes = $this->_('Shift+Click to select multiple in sequence. Ctrl+Click (or Cmd+Click) to select multiple individually. Ctrl+A (or Cmd+A) to select all.'); $f->attr('size', $numTemplates + 1); $form->add($f); $f = $this->wire('modules')->get('InputfieldSubmit'); $f->attr('name', 'submit_export'); $f->attr('value', $this->_x('Export', 'button')); $form->add($f); } else { $form = $this->wire('modules')->get('InputfieldForm'); $f = $this->wire('modules')->get('InputfieldTextarea'); $f->attr('id+name', 'export_data'); $f->label = $this->_('Export Data'); $f->description = $this->_('Copy and paste this data into the "Import" box of another installation.'); $f->notes = $this->_('Click anywhere in the box to select all export data. Once selected, copy the data with CTRL-C or CMD-C.'); $f->attr('value', wireEncodeJSON($this->getExportData($exportTemplates), true, true)); $form->add($f); $f = $this->wire('modules')->get('InputfieldButton'); $f->href = './'; $f->value = $this->_x('Ok', 'button'); $form->add($f); } return $form; }
/** * Overridden from WireSaveableItems to retain keys with 0 values * */ protected function encodeData(array $value) { if (isset($value['collapsed']) && $value['collapsed'] === 0) { unset($value['collapsed']); } return wireEncodeJSON($value, 0); }