diff --git a/admin/helpers/compiler/c_Fields.php b/admin/helpers/compiler/c_Fields.php index 16a8a2efa..43ba892a0 100644 --- a/admin/helpers/compiler/c_Fields.php +++ b/admin/helpers/compiler/c_Fields.php @@ -1,5 +1,4 @@ placeholders['###View###'] = ucfirst($viewName); $this->placeholders['[[[view]]]'] = $this->placeholders['###view###']; $this->placeholders['[[[VIEW]]]'] = $this->placeholders['###VIEW###']; - $this->placeholders['[[[View]]]'] = $this->placeholders['###View###']; + $this->placeholders['[[[View]]]'] = $this->placeholders['###View###']; $this->placeholders['###views###'] = $listViewName; $this->placeholders['###VIEWS###'] = strtoupper($listViewName); $this->placeholders['###Views###'] = ucfirst($listViewName); @@ -413,10 +412,11 @@ class Fields extends Structure $this->accessBuilder[$viewName] = $viewName; } // set the read only - $readOnly = ""; + $readOnlyXML = array(); if ($view['settings']->type == 2) { - $readOnly = "\t\t\t" . 'readonly="true"' . PHP_EOL."\t\t\t" . 'disabled="true"'; + $readOnlyXML['readonly'] = true; + $readOnlyXML['disabled'] = true; } // main lang prefix $langView = $this->langPrefix . '_' . $this->placeholders['###VIEW###']; @@ -460,7 +460,7 @@ class Fields extends Structure $this->langContent[$this->lang][$langView . '_VERSION_LABEL'] = "Revision"; $this->langContent[$this->lang][$langView . '_VERSION_DESC'] = "A count of the number of times this " . $view['settings']->name_single . " has been revised."; $this->langContent[$this->lang][$langView . '_SAVE_WARNING'] = "Alias already existed so a number was added at the end. You can re-edit the " . $view['settings']->name_single . " to customise the alias."; - + // check if the same field is added multiple times foreach ($view['settings']->fields as $field) { @@ -468,220 +468,277 @@ class Fields extends Structure $this->setUniqueNameKeeper($field, $view['settings']->type, $name, $viewName); } // start adding dynamc fields - $dynamcfields = ''; + $dynamicFieldsXML = array(); $spacerCounter = 'a'; // set the custom table key $dbkey = 'g'; // TODO we should add the global and local view switch if field for front end foreach ($view['settings']->fields as $field) { - $dynamcfields .= $this->setDynamicField($field, $view, $view['settings']->type, $langView, $viewName, $listViewName, $spacerCounter, $this->placeholders, $dbkey, true); + $dynamicFieldsXML[] = $this->setDynamicField($field, $view, $view['settings']->type, $langView, $viewName, $listViewName, $spacerCounter, $this->placeholders, $dbkey, true); } - // set the defautl fields - $fieldSet = array(); - $fieldSet[] = '
'; - $fieldSet[] = "\t\t"; - $fieldSet[] = "\t\t"; + // set the default fields + $XML = new simpleXMLElement(''); + $fieldSetXML = $XML->addChild('fieldset'); + $fieldSetXML->addAttribute('name', 'details'); + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " Default Fields."); + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " Id Field. Type: Text (joomla)"); // if id is not set if (!isset($this->fieldsNames[$viewName]['id'])) { - $fieldSet[] = "\t\t 'id', + 'type' => 'text', + 'class' => 'readonly', + 'label' => 'JGLOBAL_FIELD_ID_LABEL', + 'description' => 'JGLOBAL_FIELD_ID_DESC', + 'size' => 10, + 'default' => 0 + ); + $fieldXML = $fieldSetXML->addChild('field'); + $this->xmlAddAttributes($fieldXML, $attributes); } // if created is not set if (!isset($this->fieldsNames[$viewName]['created'])) { - $fieldSet[] = "\t\t"; - $fieldSet[] = "\t\t 'created', + 'type' => 'calendar', + 'label' => $langView . '_CREATED_DATE_LABEL', + 'description' => $langView . '_CREATED_DATE_DESC', + 'size' => 22, + 'format' => '%Y-%m-%d %H:%M:%S', + 'filter' => 'user_utc' + ); + $attributes = array_merge($attributes, $readOnlyXML); + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " Date Created Field. Type: Calendar (joomla)"); + $fieldXML = $fieldSetXML->addChild('field'); + $this->xmlAddAttributes($fieldXML, $attributes); } // if created_by is not set if (!isset($this->fieldsNames[$viewName]['created_by'])) { - $fieldSet[] = "\t\t"; - $fieldSet[] = "\t\t 'created_by', + 'type' => 'user', + 'label' => $langView . '_CREATED_BY_LABEL', + 'description' => $langView . '_CREATED_BY_DESC', + ); + $attributes = array_merge($attributes, $readOnlyXML); + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " User Created Field. Type: User (joomla)"); + $fieldXML = $fieldSetXML->addChild('field'); + $this->xmlAddAttributes($fieldXML, $attributes); } // if published is not set if (!isset($this->fieldsNames[$viewName]['published'])) { - $fieldSet[] = "\t\t"; - $fieldSet[] = "\t\t'; - $fieldSet[] = "\t\t\t"; - $fieldSet[] = "\t\t\t"; - $fieldSet[] = "\t\t\t"; - $fieldSet[] = "\t\t\t"; - $fieldSet[] = "\t\t"; + $attributes = array( + 'name' => 'published', + 'type' => 'list', + 'label' => 'JSTATUS' + ); + $attributes = array_merge($attributes, $readOnlyXML); + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " Published Field. Type: List (joomla)"); + $fieldXML = $fieldSetXML->addChild('field'); + $this->xmlAddAttributes($fieldXML, $attributes); + foreach (array('JPUBLISHED' => 1, 'JUNPUBLISHED' => 0, 'JARCHIVED' => 2, 'JTRASHED' => -2) as $text => $value) + { + $optionXML = $fieldXML->addChild('option'); + $optionXML->addAttribute('value', $value); + $optionXML[] = $text; + } } // if modified is not set if (!isset($this->fieldsNames[$viewName]['modified'])) { - $fieldSet[] = "\t\t"; - $fieldSet[] = "\t\t" . ''; + $attributes = array( + 'name' => 'modified', + 'type' => 'calendar', + 'class' => 'readonly', + 'label' => $langView . '_MODIFIED_DATE_LABEL', + 'description' => $langView . '_MODIFIED_DATE_DESC', + 'size' => 22, + 'readonly' => "true", + 'format' => '%Y-%m-%d %H:%M:%S', + 'filter' => 'user_utc' + ); + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " Date Modified Field. Type: Calendar (joomla)"); + $fieldXML = $fieldSetXML->addChild('field'); + $this->xmlAddAttributes($fieldXML, $attributes); } // if modified_by is not set if (!isset($this->fieldsNames[$viewName]['modified_by'])) { - $fieldSet[] = "\t\t"; - $fieldSet[] = "\t\t" . ' 'modified_by', + 'type' => 'user', + 'label' => $langView . '_MODIFIED_BY_LABEL', + 'description' => $langView . '_MODIFIED_BY_DESC', + 'class' => 'readonly', + 'readonly' => 'true', + 'filter' => 'unset' + ); + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " User Modified Field. Type: User (joomla)"); + $fieldXML = $fieldSetXML->addChild('field'); + $this->xmlAddAttributes($fieldXML, $attributes); } // check if view has access if (isset($this->accessBuilder[$viewName]) && ComponentbuilderHelper::checkString($this->accessBuilder[$viewName]) && !isset($this->fieldsNames[$viewName]['access'])) { - $fieldSet[] = "\t\t"; - $fieldSet[] = "\t\t" . ' 'access', + 'type' => 'accesslevel', + 'label' => 'JFIELD_ACCESS_LABEL', + 'description' => 'JFIELD_ACCESS_DESC', + 'default' => 1, + 'required' => "false" + ); + $attributes = array_merge($attributes, $readOnlyXML); + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " Access Field. Type: Accesslevel (joomla)"); + $fieldXML = $fieldSetXML->addChild('field'); + $this->xmlAddAttributes($fieldXML, $attributes); } // if ordering is not set if (!isset($this->fieldsNames[$viewName]['ordering'])) { - $fieldSet[] = "\t\t"; - $fieldSet[] = "\t\t 'ordering', + 'type' => 'number', + 'class' => 'inputbox validate-ordering', + 'label' => $langView . '_ORDERING_LABEL', + 'description' => '', + 'default' => 0, + 'size' => 6, + 'required' => "false" + ); + $attributes = array_merge($attributes, $readOnlyXML); + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " Ordering Field. Type: Numbers (joomla)"); + $fieldXML = $fieldSetXML->addChild('field'); + $this->xmlAddAttributes($fieldXML, $attributes); } // if version is not set if (!isset($this->fieldsNames[$viewName]['version'])) { - $fieldSet[] = "\t\t"; - $fieldSet[] = "\t\t 'version', + 'type' => 'text', + 'class' => 'readonly', + 'label' => $langView . '_VERSION_LABEL', + 'description' => $langView . '_VERSION_DESC', + 'size' => 6, + 'readonly' => "true", + 'filter' => 'unset' + ); + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " Version Field. Type: Text (joomla)"); + $fieldXML = $fieldSetXML->addChild('field'); + $this->xmlAddAttributes($fieldXML, $attributes); } // check if metadata is added to this view if (isset($this->metadataBuilder[$viewName]) && ComponentbuilderHelper::checkString($this->metadataBuilder[$viewName])) { // metakey - $fieldSet[] = "\t\t"; - $fieldSet[] = "\t\t 'metakey', + 'type' => 'textarea', + 'label' => 'JFIELD_META_KEYWORDS_LABEL', + 'description' => 'JFIELD_META_KEYWORDS_DESC', + 'rows' => 3, + 'cols' => 30 + ); + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " Metakey Field. Type: Textarea (joomla)"); + $fieldXML = $fieldSetXML->addChild('field'); + $this->xmlAddAttributes($fieldXML, $attributes); // metadesc - $fieldSet[] = "\t\t"; - $fieldSet[] = "\t\txmlComment($fieldSetXML, $this->setLine(__LINE__) . " Metadesc Field. Type: Textarea (joomla)"); + $fieldXML = $fieldSetXML->addChild('field'); + $this->xmlAddAttributes($fieldXML, $attributes); } // load the dynamic fields now - if (ComponentbuilderHelper::checkString($dynamcfields)) + if (count($dynamicFieldsXML)) { - $fieldSet[] = "\t\t" . $dynamcfields; + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " Dynamic Fields."); + foreach ($dynamicFieldsXML as $dynamicfield) + { + $this->xmlAppend($fieldSetXML, $dynamicfield); + } } - // close fieldset - $fieldSet[] = "\t
"; // check if metadata is added to this view if (isset($this->metadataBuilder[$viewName]) && ComponentbuilderHelper::checkString($this->metadataBuilder[$viewName])) { - $fieldSet[] = PHP_EOL."\t"; - $fieldSet[] = "\t'; - $fieldSet[] = "\t\t" . '
'; + $this->xmlComment($fieldSetXML, $this->setLine(__LINE__) . " Metadata Fields"); + $fieldsXML = $fieldSetXML->addChild('fields'); + $fieldsXML->addAttribute('name', 'metadata'); + $fieldsXML->addAttribute('label', 'JGLOBAL_FIELDSET_METADATA_OPTIONS'); + $fieldsFieldSetXML = $fieldsXML->addChild('fieldset'); + $fieldsFieldSetXML->addAttribute('name', 'vdmmetadata'); + $fieldsFieldSetXML->addAttribute('label', 'JGLOBAL_FIELDSET_METADATA_OPTIONS'); // robots - $fieldSet[] = "\t\t\t"; - $fieldSet[] = "\t\t\t" . ''; - $fieldSet[] = "\t\t\t\t" . ''; - $fieldSet[] = "\t\t\t\t" . ''; - $fieldSet[] = "\t\t\t\t" . ''; - $fieldSet[] = "\t\t\t\t" . ''; - $fieldSet[] = "\t\t\t\t" . ''; - $fieldSet[] = "\t\t\t" . ''; + $this->xmlComment($fieldsFieldSetXML, $this->setLine(__LINE__) . " Robots Field. Type: List (joomla)"); + $robots = $fieldsFieldSetXML->addChild('field'); + $attributes = array( + 'name' => 'robots', + 'type' => 'list', + 'label' => 'JFIELD_METADATA_ROBOTS_LABEL', + 'description' => 'JFIELD_METADATA_ROBOTS_DESC' + ); + $this->xmlAddAttributes($robots, $attributes); + $options = array( + 'JGLOBAL_USE_GLOBAL' => '', + 'JGLOBAL_INDEX_FOLLOW' => 'index, follow', + 'JGLOBAL_NOINDEX_FOLLOW' => 'noindex, follow', + 'JGLOBAL_INDEX_NOFOLLOW' => 'index, nofollow', + 'JGLOBAL_NOINDEX_NOFOLLOW' => 'noindex, nofollow', + ); + foreach ($options as $text => $value) + { + $option = $robots->addChild('option'); + $option->addAttribute('value', $value); + $option[] = $text; + } // author - $fieldSet[] = "\t\t\t"; - $fieldSet[] = "\t\t\t" . 'xmlComment($fieldsFieldSetXML, $this->setLine(__LINE__) . " Author Field. Type: Text (joomla)"); + $author = $fieldsFieldSetXML->addChild('field'); + $attributes = array( + 'name' => 'author', + 'type' => 'text', + 'label' => 'JAUTHOR', + 'description' => 'JFIELD_METADATA_AUTHOR_DESC', + 'size' => 20 + ); + $this->xmlAddAttributes($author, $attributes); // rights - $fieldSet[] = "\t\t\t"; - $fieldSet[] = "\t\t\t" . 'xmlComment($fieldsFieldSetXML, $this->setLine(__LINE__) . " Rights Field. Type: Textarea (joomla)"); + $rights = $fieldsFieldSetXML->addChild('field'); + $attributes = array( + 'name' => 'rights', + 'type' => 'textarea', + 'label' => 'JFIELD_META_RIGHTS_LABEL', + 'description' => 'JFIELD_META_RIGHTS_DESC', + 'required' => 'false', + 'filter' => 'string', + 'cols' => 30, + 'rows' => 2 + ); + $this->xmlAddAttributes($rights, $attributes); } // just to be safe, lets clear the view placeholders $this->clearFromPlaceHolders('view'); - // retunr the set - return implode(PHP_EOL, $fieldSet); + // return the set + return $this->xmlPrettyPrint($XML, 'fieldset'); } return ''; } - + /** * set Field Names - * + * * @param string $view View the field belongs to * @param string $name The name of the field * - * + * */ public function setFieldsNames(&$view, &$name) { @@ -690,7 +747,7 @@ class Fields extends Structure /** * set Dynamic field - * + * * @param array $field The field data * @param array $view The view data * @param int $viewType The view type @@ -702,21 +759,20 @@ class Fields extends Structure * @param string $dbkey The the custom table key * @param boolean $build The switch to set the build option * - * @return string The complete field in xml - * + * @return SimpleXMLElement The complete field in xml + * */ public function setDynamicField(&$field, &$view, &$viewType, &$langView, &$viewName, &$listViewName, &$spacerCounter, &$placeholders, &$dbkey, $build) { if (isset($field['settings']) && ComponentbuilderHelper::checkObject($field['settings'])) { - // reset some values + // reset some values $name = ComponentbuilderHelper::safeString($field['settings']->name); $typeName = ComponentbuilderHelper::safeString($field['settings']->type_name); $multiple = false; $langLabel = ''; - $taber = ''; $fieldSet = ''; - $fieldAttributes = array(); + $fieldAttributes = array(); // set field attributes $fieldAttributes = $this->setFieldAttributes($field, $viewType, $name, $typeName, $multiple, $langLabel, $langView, $spacerCounter, $listViewName, $viewName, $placeholders); // check if values were set @@ -724,13 +780,13 @@ class Fields extends Structure { // set the array of field names $this->setFieldsNames($viewName,$fieldAttributes['name']); - + if ($this->defaultField($typeName, 'option')) { //reset options array $optionArray = array(); // now add to the field set - $fieldSet .= $this->setField('option', $taber, $fieldAttributes, $name, $typeName, $langView, $viewName, $listViewName, $placeholders, $optionArray); + $xmlElement = $this->setField('option', $fieldAttributes, $name, $typeName, $langView, $viewName, $listViewName, $placeholders, $optionArray); if ($build) { // set builders @@ -745,7 +801,7 @@ class Fields extends Structure $this->setBuilders($langLabel, $langView, $viewName, $listViewName, $name, $view, $field, $typeName, $multiple); } // now add to the field set - $fieldSet .= $this->setField('plain', $taber, $fieldAttributes, $name, $typeName, $langView, $viewName, $listViewName, $placeholders, $optionArray); + $xmlElement = $this->setField('plain', $fieldAttributes, $name, $typeName, $langView, $viewName, $listViewName, $placeholders, $optionArray); } elseif ($this->defaultField($typeName, 'spacer')) { @@ -765,7 +821,7 @@ class Fields extends Structure $this->setLayoutBuilder($viewName, $tabName, $name, $field); } // now add to the field set - $fieldSet .= $this->setField('spacer', $taber, $fieldAttributes, $name, $typeName, $langView, $viewName, $listViewName, $placeholders, $optionArray); + $xmlElement = $this->setField('spacer', $fieldAttributes, $name, $typeName, $langView, $viewName, $listViewName, $placeholders, $optionArray); // increment spacer counter if ($typeName === 'spacer') { @@ -783,7 +839,7 @@ class Fields extends Structure $this->setBuilders($langLabel, $langView, $viewName, $listViewName, $name, $view, $field, $typeName, $multiple, false); } // now add to the field set - $fieldSet .= $this->setField('special', $taber, $fieldAttributes, $name, $typeName, $langView, $viewName, $listViewName, $placeholders, $optionArray); + $xmlElement = $this->setField('special', $fieldAttributes, $name, $typeName, $langView, $viewName, $listViewName, $placeholders, $optionArray); } } elseif (ComponentbuilderHelper::checkArray($fieldAttributes['custom'])) @@ -801,56 +857,56 @@ class Fields extends Structure $this->setBuilders($langLabel, $langView, $viewName, $listViewName, $name, $view, $field, $typeName, $multiple, $custom); } // now add to the field set - $fieldSet .= $this->setField('custom', $taber, $fieldAttributes, $name, $typeName, $langView, $viewName, $listViewName, $placeholders, $optionArray, $custom); + $xmlElement = $this->setField('custom', $fieldAttributes, $name, $typeName, $langView, $viewName, $listViewName, $placeholders, $optionArray, $custom); } } - return $fieldSet; + return $xmlElement; } - return ''; + return false; } /** * set a field - * - * @param string $setType The set of fields type - * @param string $taber The tabs to add in layout - * @param array $fieldAttributes The field values - * @param string $name The field name - * @param string $typeName The field type - * @param string $langView The language string of the view - * @param string $viewName The singel view name - * @param string $listViewName The list view name - * @param array $placeholders The place holder and replace values - * @param string $optionArray The option bucket array used to set the field options if needed. - * @param arra $custom Used when field is from config * - * @return string The field in xml - * + * @param string $setType The set of fields type + * @param array $fieldAttributes The field values + * @param string $name The field name + * @param string $typeName The field type + * @param string $langView The language string of the view + * @param string $viewName The single view name + * @param string $listViewName The list view name + * @param array $placeholders The place holder and replace values + * @param string $optionArray The option bucket array used to set the field options if needed. + * @param array $custom Used when field is from config + * + * @return SimpleXMLElement The field in xml + * */ - private function setField($setType, $taber, &$fieldAttributes, &$name, &$typeName, &$langView, &$viewName, &$listViewName, $placeholders, &$optionArray, $custom = null) + private function setField($setType, &$fieldAttributes, &$name, &$typeName, &$langView, &$viewName, &$listViewName, $placeholders, &$optionArray, $custom = null) { - $fieldSet = ''; + $field = new stdClass(); if ($setType === 'option') { // now add to the field set - $fieldSet .= PHP_EOL."\t" . $taber . "\t"; - $fieldSet .= PHP_EOL."\t" . $taber . "\tfieldXML = new SimpleXMLElement(''); + $field->comment = $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (joomla)"; + foreach ($fieldAttributes as $property => $value) { if ($property != 'option') { - $fieldSet .= PHP_EOL."\t\t" . $taber . "\t" . $property . '="' . $value . '"'; + $field->fieldXML->addAttribute($property, $value); } elseif ($property === 'option') { - $optionSet = ''; + $this->xmlComment($field->fieldXML, $this->setLine(__LINE__) . " Option Set."); if (strpos($value, ',') !== false) { // mulitpal options $options = explode(',', $value); foreach ($options as $option) { + $optionXML = $field->fieldXML->addChild('option'); if (strpos($option, '|') !== false) { // has other value then text @@ -859,7 +915,7 @@ class Fields extends Structure // add to lang array $this->langContent[$this->lang][$langValue] = $t; // no add to option set - $optionSet .= PHP_EOL."\t" . $taber . "\t\t" . ''; + $optionXML->addAttribute('value', $v); $optionArray[$v] = $langValue; } else @@ -869,14 +925,16 @@ class Fields extends Structure // add to lang array $this->langContent[$this->lang][$langValue] = $option; // no add to option set - $optionSet .= PHP_EOL."\t\t" . $taber . "\t" . ''; + $optionXML->addAttribute('value', $option); $optionArray[$option] = $langValue; } + $optionXML[] = $langValue; } } else { // one option + $optionXML = $field->fieldXML->addChild('option'); if (strpos($value, '|') !== false) { // has other value then text @@ -885,7 +943,7 @@ class Fields extends Structure // add to lang array $this->langContent[$this->lang][$langValue] = $t; // no add to option set - $optionSet .= PHP_EOL."\t\t" . $taber . "\t" . ''; + $optionXML->addAttribute('value', $v); $optionArray[$v] = $langValue; } else @@ -895,58 +953,45 @@ class Fields extends Structure // add to lang array $this->langContent[$this->lang][$langValue] = $value; // no add to option set - $optionSet .= PHP_EOL."\t\t" . $taber . "\t" . ''; + $optionXML->addAttribute('value', $value); $optionArray[$value] = $langValue; } + $optionXML[] = $langValue; } } } - if (ComponentbuilderHelper::checkString($optionSet)) + if (!$field->fieldXML->count()) { - $fieldSet .= '>'; - $fieldSet .= PHP_EOL."\t\t\t" . $taber . ""; - $fieldSet .= $optionSet; - $fieldSet .= PHP_EOL."\t\t" . $taber . ""; - } - elseif ($typeName === 'sql') - { - $optionArray = false; - $fieldSet .= PHP_EOL."\t\t" . $taber . "/>"; - } - else - { - $optionArray = false; - $fieldSet .= PHP_EOL."\t\t\t" . $taber . ""; - $fieldSet .= PHP_EOL."\t\t" . $taber . "/>"; + $this->xmlComment($field->fieldXML, $this->setLine(__LINE__) . " No Manual Options Were Added In Field Settings."); } } elseif ($setType === 'plain') { // now add to the field set - $fieldSet .= PHP_EOL."\t\t" . $taber . ""; - $fieldSet .= PHP_EOL."\t\t" . $taber . "fieldXML = new SimpleXMLElement(''); + $field->comment = $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (joomla)"; + foreach ($fieldAttributes as $property => $value) { if ($property != 'option') { - $fieldSet .= PHP_EOL."\t\t" . $taber . "\t" . $property . '="' . $value . '"'; + $field->fieldXML->addAttribute($property, $value); } } - $fieldSet .= PHP_EOL."\t\t" . $taber . "/>"; } elseif ($setType === 'spacer') { // now add to the field set - $fieldSet .= PHP_EOL."\t\t"; - $fieldSet .= PHP_EOL."\t\tfieldXML = new SimpleXMLElement(''); + $field->comment = $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". A None Database Field. (joomla)"; + foreach ($fieldAttributes as $property => $value) { if ($property != 'option') { - $fieldSet .= " " . $property . '="' . $value . '"'; + $field->fieldXML->addAttribute($property, $value); } } - $fieldSet .= " />"; } elseif ($setType === 'special') { @@ -954,19 +999,24 @@ class Fields extends Structure if ($typeName === 'repeatable') { // now add to the field set - $fieldSet .= PHP_EOL."\t\t"; - $fieldSet .= PHP_EOL."\t\tfieldXML = new SimpleXMLElement(''); + $field->comment = $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (depreciated)"; + foreach ($fieldAttributes as $property => $value) { if ($property != 'fields') { - $fieldSet .= PHP_EOL."\t\t\t" . $property . '="' . $value . '"'; + $field->fieldXML->addAttribute($property, $value); } } - $fieldSet .= ">"; - $fieldSet .= PHP_EOL."\t\t\t" . ''; - $fieldSet .= PHP_EOL."\t\t\t\t" . '"; - $fieldSet .= PHP_EOL."\t\t\t"; - $fieldSet .= PHP_EOL."\t\t"; } - // set the subform fields (it is a repeatable without the modal) + // set the subform fields (it is a repeatable without the modal) elseif ($typeName === 'subform') { // now add to the field set - $fieldSet .= PHP_EOL."\t\t"; - $fieldSet .= PHP_EOL."\t\tfieldXML = new SimpleXMLElement(''); + $field->comment = $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (joomla)"; + // add all properties foreach ($fieldAttributes as $property => $value) { if ($property != 'fields' && $property != 'formsource') { - $fieldSet .= PHP_EOL."\t\t\t" . $property . '="' . $value . '"'; + $field->fieldXML->addAttribute($property, $value); } } // if we detect formsource we do not add the form if (isset($fieldAttributes['formsource']) && ComponentbuilderHelper::checkString($fieldAttributes['formsource'])) { - $fieldSet .= PHP_EOL."\t\t\tformsource". '="' . $fieldAttributes['formsource'] . '"'; - $fieldSet .= PHP_EOL."\t\t />"; + $field->fieldXML->addAttribute('formsource', $fieldAttributes['formsource']); } + // add the form else { - $fieldSet .= ">"; - $fieldSet .= PHP_EOL."\t\t\t" . '"; - $fieldSet .= PHP_EOL."\t\t"; } } } elseif ($setType === 'custom') { // now add to the field set - $fieldSet .= PHP_EOL."\t\t" . $taber . ""; - $fieldSet .= PHP_EOL."\t\t" . $taber . "fieldXML = new SimpleXMLElement(''); + $field->comment = $this->setLine(__LINE__) . " " . ComponentbuilderHelper::safeString($name, 'F') . " Field. Type: " . ComponentbuilderHelper::safeString($typeName, 'F') . ". (custom)"; foreach ($fieldAttributes as $property => $value) { if ($property != 'option') { - $fieldSet .= PHP_EOL."\t\t" . $taber . "\t" . $property . '="' . $value . '"'; + $field->fieldXML->addAttribute($property, $value); } } - $fieldSet .= PHP_EOL."\t\t" . $taber . "/>"; // incase the field is in the config and has not been set if ('config' === $viewName && 'configs' === $listViewName) { @@ -1160,19 +1206,19 @@ class Fields extends Structure $this->setCustomFieldTypeFile($data, $listViewName, $viewName); } } - return $fieldSet; + return $field; } /** * set the layout builder - * + * * @param string $viewName The single edit view code name - * @param string $tabName The tab code name - * @param string $name The field code name - * @param array $field The field details + * @param string $tabName The tab code name + * @param string $name The field code name + * @param array $field The field details * * @return void - * + * */ public function setLayoutBuilder(&$viewName,&$tabName,&$name,&$field) { @@ -1191,7 +1237,7 @@ class Fields extends Structure } else { - $this->zeroOrderFix[$viewName][(int) $field['tab']]++; + $this->zeroOrderFix[$viewName][(int) $field['tab']] ++; } $field['order_edit'] = $this->zeroOrderFix[$viewName][(int) $field['tab']]; } @@ -1215,7 +1261,7 @@ class Fields extends Structure $this->movedPublishingFields[$viewName][$name] = $name; } } - elseif ($tabName === 'publishing' || $tabName === 'Publishing' ) + elseif ($tabName === 'publishing' || $tabName === 'Publishing') { if (!in_array($name, $this->defaultFields)) { @@ -1253,14 +1299,14 @@ class Fields extends Structure /** * build the site field data needed - * - * @param string $view The single edit view code name - * @param string $field The field name - * @param string $set The decoding set this field belongs to - * @param string $type The field type + * + * @param string $view The single edit view code name + * @param string $field The field name + * @param string $set The decoding set this field belongs to + * @param string $type The field type * * @return void - * + * */ public function buildSiteFieldData($view, $field, $set, $type) { @@ -1286,7 +1332,7 @@ class Fields extends Structure /** * set field attributes - * + * * @param array $field The field data * @param int $viewType The view type * @param string $name The field name @@ -1301,11 +1347,11 @@ class Fields extends Structure * @param boolean $repeatable The repeatable field switch * * @return array The field attributes - * + * */ private function setFieldAttributes(&$field, &$viewType, &$name, &$typeName, &$multiple, &$langLabel, $langView, &$spacerCounter, $listViewName, $viewName, $placeholders, $repeatable = false) { - // reset array` + // reset array $fieldAttributes = array(); $setCustom = false; // setup joomla default fields @@ -1537,7 +1583,7 @@ class Fields extends Structure // check if translatable if (ComponentbuilderHelper::checkString($xmlValue) && isset($property['translatable']) && $property['translatable'] == 1) { - // update lable if field use multiple times + // update label if field use multiple times if ($property['name'] === 'label') { if (isset($fieldAttributes['name']) && isset($this->uniqueNames[$viewName]['names'][$fieldAttributes['name']])) @@ -1631,14 +1677,14 @@ class Fields extends Structure /** * Keep track of the field names, to see if it used multiple times - * + * * @param array $field The field data * @param string $typeName The field type * @param string $name The field name * @param string $viewName The singel view name * * @return void - * + * */ protected function setUniqueNameKeeper(&$field, &$typeName, &$name, $viewName) { @@ -1690,15 +1736,15 @@ class Fields extends Structure } } } - + /** * Count how many times the same field is used per view - * + * * @param string $name The name of the field * @param string $view The name of the view * * @return void - * + * */ protected function setUniqueNameCounter($name, $view) { @@ -1717,15 +1763,15 @@ class Fields extends Structure $this->uniqueNames[$view]['counter'][$name]++; return; } - + /** * Naming each field with an unique name - * + * * @param string $name The name of the field * @param string $view The name of the view * * @return string the name - * + * */ protected function uniqueName($name, $view) { @@ -1746,10 +1792,10 @@ class Fields extends Structure return $name; } - + /** * set Builders - * + * * @param string $langLabel The language string for field label * @param string $langView The language string of the view * @param string $viewName The singel view name @@ -1763,7 +1809,7 @@ class Fields extends Structure * @param boolean $options The options switch * * @return void - * + * */ public function setBuilders($langLabel, $langView, $viewName, $listViewName, $name, $view, $field, $typeName, $multiple, $custom = false, $options = false) { @@ -1793,21 +1839,21 @@ class Fields extends Structure // don't use these as index or uniqe keys $textKeys = array('TEXT', 'TINYTEXT', 'MEDIUMTEXT', 'LONGTEXT', 'BLOB', 'TINYBLOB', 'MEDIUMBLOB', 'LONGBLOB'); // build the query values - $this->queryBuilder[$viewName][$name]['type'] = $field['settings']->datatype; - if (!in_array($field['settings']->datatype, $textKeys)) + $this->queryBuilder[$viewName][$name]['type'] = $field['settings']->datatype; + if (!in_array($field['settings']->datatype, $textKeys)) { - $this->queryBuilder[$viewName][$name]['lenght'] = $field['settings']->datalenght; - $this->queryBuilder[$viewName][$name]['lenght_other'] = $field['settings']->datalenght_other; - $this->queryBuilder[$viewName][$name]['default'] = $field['settings']->datadefault; - $this->queryBuilder[$viewName][$name]['other'] = $field['settings']->datadefault_other; - } - else - { - $this->queryBuilder[$viewName][$name]['default'] = 'EMPTY'; - } + $this->queryBuilder[$viewName][$name]['lenght'] = $field['settings']->datalenght; + $this->queryBuilder[$viewName][$name]['lenght_other'] = $field['settings']->datalenght_other; + $this->queryBuilder[$viewName][$name]['default'] = $field['settings']->datadefault; + $this->queryBuilder[$viewName][$name]['other'] = $field['settings']->datadefault_other; + } + else + { + $this->queryBuilder[$viewName][$name]['default'] = 'EMPTY'; + } // to identify the field - $this->queryBuilder[$viewName][$name]['ID'] = $field['settings']->id; - $this->queryBuilder[$viewName][$name]['null_switch'] = $field['settings']->null_switch; + $this->queryBuilder[$viewName][$name]['ID'] = $field['settings']->id; + $this->queryBuilder[$viewName][$name]['null_switch'] = $field['settings']->null_switch; // set index types if ($field['settings']->indexes == 1 && !in_array($field['settings']->datatype, $textKeys)) { @@ -2024,7 +2070,7 @@ class Fields extends Structure $this->getItemsMethodListStringFixBuilder[$viewName][] = array('name' => $name, 'type' => $typeName, 'translation' => false, 'custom' => $custom, 'method' => $field['settings']->store); } } - + // if subform the values must revert to array if ('subform' === $typeName) { @@ -2037,7 +2083,7 @@ class Fields extends Structure $this->getItemsMethodEximportStringFixBuilder[$viewName][] = array('name' => $name, 'type' => $typeName, 'translation' => false, 'custom' => $custom, 'method' => $field['settings']->store); } // check if field should be added to uikit - $this->buildSiteFieldData($viewName, $name, 'uikit', $typeName); + $this->buildSiteFieldData($viewName, $name, 'uikit', $typeName); // load the selection translation fix if (ComponentbuilderHelper::checkArray($options) && (isset($field['list']) && $field['list'] == 1) && $typeName != 'repeatable' && $typeName != 'subform') { @@ -2073,7 +2119,7 @@ class Fields extends Structure } $this->setLayoutBuilder($viewName, $tabName, $name, $field); } - + public function setCustomFieldTypeFile($data, $viewName_list, $viewName_single) { // make sure it is not already been build @@ -2081,11 +2127,11 @@ class Fields extends Structure { // first build the custom field type file $target = array('admin' => 'customfield'); - $this->buildDynamique($target,'field'.$data['custom']['extends'],$data['custom']['type']); + $this->buildDynamique($target,'field'.$data['custom']['extends'], $data['custom']['type']); // set tab and break replacements $tabBreak = array( - '\t' => "\t", - '\n' => PHP_EOL + '\t' => "\t", + '\n' => PHP_EOL ); // make field dynamic $replace = array( @@ -2149,7 +2195,7 @@ class Fields extends Structure } else { - $phpxCode .= PHP_EOL."\t\t".$this->setPlaceholders($code, $tabBreak); + $phpxCode .= PHP_EOL . "\t\t" . $this->setPlaceholders($code, $tabBreak); } } } @@ -2194,15 +2240,15 @@ class Fields extends Structure /** * default Fields - * + * * @param string $type The field type * @param boolean $option The field grouping * * @return boolean if the field was found - * + * */ public function defaultField($type, $option = 'default') - { + { // list of default fields // https://docs.joomla.org/Form_field $defaults = array( @@ -2244,4 +2290,121 @@ class Fields extends Structure return false; } + /** + * xmlComment + * + * @param SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param string $comment The comment to inject + * + * @return null + * + */ + public function xmlComment(&$xml, $comment) + { + $domXML = dom_import_simplexml($xml); + $domComment = new DOMComment($comment); + $nodeTarget = $domXML->ownerDocument->importNode($domComment, true); + $domXML->appendChild($nodeTarget); + $xml = simplexml_import_dom($domXML); + } + + /** + * xmlAddAttributes + * + * @param SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param array $attributes The attributes to apply to the XML element + * + * @return null + * + */ + public function xmlAddAttributes(&$xml, $attributes = array()) + { + foreach ($attributes as $key => $value) + { + $xml->addAttribute($key, $value); + } + } + + /** + * xmlAppend + * + * @param SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param mixed $node A SimpleXMLElement node to append to the XML element reference, or a stdClass object containing a comment attribute to be injected before the XML node and a fieldXML attribute containing a SimpleXMLElement + * + * @return null + * + */ + public function xmlAppend(&$xml, $node) + { + if (!$node) + { // element was not returned + return; + } + switch (get_class($node)) + { + case 'stdClass': + if (property_exists($node, 'comment')) + { + $this->xmlComment($xml, $node->comment); + } + if (property_exists($node, 'fieldXML')) + { + $this->xmlAppend($xml, $node->fieldXML); + } + break; + case 'SimpleXMLElement': + $domXML = dom_import_simplexml($xml); + $domNode = dom_import_simplexml($node); + $domXML->appendChild($domXML->ownerDocument->importNode($domNode, true)); + $xml = simplexml_import_dom($domXML); + break; + } + } + + /** + * xmlPrettyPrint + * + * @param SimpleXMLElement $xml The XML element containing a node to be output + * @param string $nodename node name of the input xml element to print out. this is done to omit the ownerDocument; + $dom->formatOutput = true; + $xmlString = $dom->saveXML($dom->getElementsByTagName($nodename)->item(0)); + $tidy = new Tidy(); + $tidy->parseString($xmlString,array('indent'=>true,'indent-spaces'=>8,'input-xml'=>true,'output-xml'=>true,'indent-attributes'=>true,'wrap-attributes'=>true,'wrap'=>false)); + $tidy->cleanRepair(); + return $this->xmlIndent((string)$tidy,' ',8,true,false); + } + + /** + * xmlIndent + * + * @param string $string The XML input + * @param string $char Character or characters to use as the repeated indent + * @param integer $depth number of times to repeat the indent character + * @param boolean $skipfirst Skip the first line of the input. + * @param boolean $skiplast Skip the last line of the input; + * + * @return string XML output + * + */ + public function xmlIndent($string,$char=' ',$depth=0,$skipfirst=false,$skiplast=false) + { + $output = array(); + $lines = explode("\n",$string); + $first = true; + $last = count($lines)-1; + foreach($lines as $i=>$line) + { + $output[] = (($first&&$skipfirst)||$i===$last&&$skiplast)?$line:str_repeat($char,$depth).$line; + $first = false; + } + return implode("\n",$output); + } + } diff --git a/admin/helpers/compiler/e_Interpretation.php b/admin/helpers/compiler/e_Interpretation.php index 9374bc27e..3e6b844fe 100644 --- a/admin/helpers/compiler/e_Interpretation.php +++ b/admin/helpers/compiler/e_Interpretation.php @@ -1653,13 +1653,19 @@ class Interpretation extends Fields public function setCustomViewFieldUikitChecker(&$get, $checker, $string, $code, $tab = '') { $fieldUikit = ''; + $runplugins = false; foreach ($checker as $field => $array) { if (strpos($get['selection']['select'], $field) !== false) { // build decoder string - $fieldUikit .= PHP_EOL."\t".$tab."\t//".$this->setLine(__LINE__)." Make sure the content prepare plugins fire on ".$field." (TODO)"; - $fieldUikit .= PHP_EOL."\t".$tab."\t".$string."->".$field." = JHtml::_('content.prepare',".$string."->".$field.");"; + if(!$runplugins) { + $runplugins = PHP_EOL.$tab."\t//".$this->setLine(__LINE__)." Load the JEvent Dispatcher"; + $runplugins .= PHP_EOL.$tab."\tJPluginHelper::importPlugin('content');"; + $runplugins .= PHP_EOL.$tab."\t".'$this->_dispatcher = JEventDispatcher::getInstance();'; + } + $fieldUikit .= PHP_EOL."\t".$tab."\t//".$this->setLine(__LINE__)." Make sure the content prepare plugins fire on ".$field; + $fieldUikit .= PHP_EOL."\t".$tab."\t".'$this->_dispatcher->trigger("onContentPrepare",array($this->_context,&'.$string.'->'.$field.',$item->params));'; // only load for uikit version 2 (TODO) we may need to add another check here if (2 == $this->uikit || 1 == $this->uikit) { @@ -1668,6 +1674,9 @@ class Interpretation extends Fields } } } + // load dispatcher + $this->JEventDispatcher = array('###DISPATCHER###' => ($runplugins?:'')); + // return UIKIT fix return $fieldUikit; } @@ -2123,6 +2132,8 @@ class Interpretation extends Fields $getItem .= PHP_EOL."\t".$tab."\t\treturn false;"; } $getItem .= PHP_EOL."\t".$tab."\t}"; + // dispatcher placholder + $getItem .= "###DISPATCHER###"; if (ComponentbuilderHelper::checkArray($get->main_get)) { $asBucket = array(); @@ -2203,7 +2214,8 @@ class Interpretation extends Fields $getItem .= PHP_EOL.PHP_EOL."\t".$tab."\t//".$this->setLine(__LINE__)." set data object to item."; $getItem .= PHP_EOL."\t".$tab."\t\$this->_item[\$pk] = \$data;"; } - return $getItem; + // check if the dispather should be added + return str_replace(array_keys($this->JEventDispatcher), array_values($this->JEventDispatcher), $getItem); } return PHP_EOL."\t".$tab."\t//".$this->setLine(__LINE__)."add your custom code here."; } @@ -2526,6 +2538,8 @@ class Interpretation extends Fields $methods .= PHP_EOL.PHP_EOL."\t\t//".$this->setLine(__LINE__)." check if there was data returned"; $methods .= PHP_EOL."\t\tif (\$db->getNumRows())"; $methods .= PHP_EOL."\t\t{"; + // set dispatcher placeholder + $methods .= "###DISPATCHER###"; // set decoding of needed fields if (isset($this->siteFieldData['decode'][$default['code']][$get['key']][$default['as']])) { @@ -2629,13 +2643,15 @@ class Interpretation extends Fields $script .= PHP_EOL."\t\t//".$this->setLine(__LINE__)." Get the encryption object."; $script .= PHP_EOL."\t\t\$advanced = new FOFEncryptAes(\$advancedkey, 256);".PHP_EOL; } - $methods = str_replace('###CRYPT###',$script,$methods); + $methods = str_replace('###CRYPT###', $script, $methods); } } + // insure the crypt placeholder is removed $methods = str_replace('###CRYPT###','',$methods); } } - return $methods.PHP_EOL; + // check if the dispatcher must be set + return str_replace(array_keys($this->JEventDispatcher), array_values($this->JEventDispatcher), $methods).PHP_EOL; } public function setCustomViewMethodDefaults($get,$code) @@ -2734,6 +2750,7 @@ class Interpretation extends Fields $getItem .= PHP_EOL.PHP_EOL."\t\t//".$this->setLine(__LINE__)." Convert the parameter fields into objects."; $getItem .= PHP_EOL."\t\tif (".$Component."Helper::checkArray(\$items))"; $getItem .= PHP_EOL."\t\t{"; + $getItem .= "###DISPATCHER###"; $getItem .= PHP_EOL."\t\t\tforeach (\$items as \$nr => &\$item)"; $getItem .= PHP_EOL."\t\t\t{"; $getItem .= PHP_EOL."\t\t\t\t//".$this->setLine(__LINE__)." Always create a slug for sef URL's"; @@ -2773,6 +2790,8 @@ class Interpretation extends Fields $asBucket[] = $main_get['as']; } } + // check if we should load the dispatcher + $getItem = str_replace(array_keys($this->JEventDispatcher), array_values($this->JEventDispatcher), $getItem); // setup Globals $getItem .= $this->setCustomViewGlobals($get->global,'$item',$asBucket,"\t\t"); // setup the custom gets that returns multipal values