diff --git a/administrator/components/com_admin/sql/updates/mysql/3.8.0-2017-07-13.sql b/administrator/components/com_admin/sql/updates/mysql/3.8.0-2017-07-13.sql new file mode 100644 index 0000000000000..6878001cd38f9 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.8.0-2017-07-13.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(479, 0, 'plg_fields_subform', 'plugin', 'subform', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.8.0-2017-07-13.sql b/administrator/components/com_admin/sql/updates/postgresql/3.8.0-2017-07-13.sql new file mode 100644 index 0000000000000..36a4d97443329 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.8.0-2017-07-13.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(479, 0, 'plg_fields_subform', 'plugin', 'subform', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-13.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-13.sql new file mode 100644 index 0000000000000..9c66a71f75168 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-13.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(479, 0, 'plg_fields_subform', 'plugin', 'subform', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_fields/libraries/fieldsplugin.php b/administrator/components/com_fields/libraries/fieldsplugin.php index b545a791a93c1..aeb627c866cde 100644 --- a/administrator/components/com_fields/libraries/fieldsplugin.php +++ b/administrator/components/com_fields/libraries/fieldsplugin.php @@ -220,11 +220,32 @@ public function onCustomFieldsPrepareDom($field, DOMElement $parent, JForm $form * @since 3.7.0 */ public function onContentPrepareForm(JForm $form, $data) + { + $path = $this->getFormPath($form, $data); + if ($path === null) + { + return; + } + // Load the specific plugin parameters + $form->load(file_get_contents($path), true, '/form/*'); + } + + /** + * Returns the path of the XML definition file for the field parameters + * + * @param JForm $form The form + * @param stdClass $data The data + * + * @return string + * + * @since __DEPLOY_VERSION__ + */ + protected function getFormPath(JForm $form, $data) { // Check if the field form is calling us if (strpos($form->getName(), 'com_fields.field') !== 0) { - return; + return null; } // Ensure it is an object @@ -241,7 +262,7 @@ public function onContentPrepareForm(JForm $form, $data) // Not us if (!$this->isTypeSupported($type)) { - return; + return null; } $path = JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name . '/params/' . $type . '.xml'; @@ -249,11 +270,9 @@ public function onContentPrepareForm(JForm $form, $data) // Check if params file exists if (!file_exists($path)) { - return; + return null; } - - // Load the specific plugin parameters - $form->load(file_get_contents($path), true, '/form/*'); + return $path; } /** diff --git a/administrator/components/com_fields/models/fields/subformtype.php b/administrator/components/com_fields/models/fields/subformtype.php new file mode 100644 index 0000000000000..d59c1c6ef41ee --- /dev/null +++ b/administrator/components/com_fields/models/fields/subformtype.php @@ -0,0 +1,57 @@ +text, $b->text); + } + ); + + return $options; + } +} diff --git a/administrator/language/en-GB/en-GB.plg_fields_subform.ini b/administrator/language/en-GB/en-GB.plg_fields_subform.ini new file mode 100644 index 0000000000000..9987d21a3e799 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_fields_subform.ini @@ -0,0 +1,16 @@ +; Joomla! Project +; Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_SUBFORM="Fields - Subform" +PLG_FIELDS_SUBFORM_XML_DESCRIPTION="This plugin lets you create new fields of type 'subform' in any extensions where custom fields are supported." +PLG_FIELDS_SUBFORM_LABEL="Subform (%s)" +PLG_FIELDS_SUBFORM_PARAMS_OPTIONS_LABEL="Fields" +PLG_FIELDS_SUBFORM_PARAMS_OPTIONS_DESC="The fields of the subform." +PLG_FIELDS_SUBFORM_PARAMS_REPEAT_LABEL="Repeatable" +PLG_FIELDS_SUBFORM_PARAMS_REPEAT_DESC="Whether this subform shall be repeatable." +PLG_FIELDS_SUBFORM_PARAMS_RENDER_VALUES_LABEL="Render values" +PLG_FIELDS_SUBFORM_PARAMS_RENDER_VALUES_DESC="Do you want the custom field plugin to render the values of this subforms fields? Rendering is, for example, unneeded if your subform only contains 'text' fields, because text values does't change when being rendered. But when you e.g. have a 'media' field, the unrendered value will be the url to that media, the rendered value will be a HTML <img>-tag, for example. If you create your own layout override, where you can take care of the unrendered value, you should always disable rendering, as rendering always comes at a cost of performance." +PLG_FIELDS_SUBFORM_PARAMS_OPTIONS_NAME_LABEL="Name" +PLG_FIELDS_SUBFORM_PARAMS_OPTIONS_NAME_DESC="The name to identify the field." diff --git a/administrator/language/en-GB/en-GB.plg_fields_subform.sys.ini b/administrator/language/en-GB/en-GB.plg_fields_subform.sys.ini new file mode 100644 index 0000000000000..53a7cc0430dec --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_fields_subform.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_SUBFORM="Fields - Subform" +PLG_FIELDS_SUBFORM_XML_DESCRIPTION="This plugin lets you create new fields of type 'subform' in any extensions where custom fields are supported." diff --git a/installation/sql/mysql/joomla.sql b/installation/sql/mysql/joomla.sql index 9c5d6ca57481d..5da90f1d1bf06 100644 --- a/installation/sql/mysql/joomla.sql +++ b/installation/sql/mysql/joomla.sql @@ -667,6 +667,7 @@ INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `elem (492, 0, 'plg_privacy_message', 'plugin', 'message', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (494, 0, 'plg_captcha_recaptcha_invisible', 'plugin', 'recaptcha_invisible', 'captcha', 0, 0, 1, 0, '', '{"public_key":"","private_key":"","theme":"clean"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(495, 0, 'plg_fields_subform', 'plugin', 'subform', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (503, 0, 'beez3', 'template', 'beez3', '', 0, 1, 1, 0, '', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (504, 0, 'hathor', 'template', 'hathor', '', 1, 1, 1, 0, '', '{"showSiteName":"0","colourChoice":"0","boldText":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (506, 0, 'protostar', 'template', 'protostar', '', 0, 1, 1, 0, '', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), diff --git a/installation/sql/postgresql/joomla.sql b/installation/sql/postgresql/joomla.sql index 58b3530ac4b38..e8096e249319f 100644 --- a/installation/sql/postgresql/joomla.sql +++ b/installation/sql/postgresql/joomla.sql @@ -680,6 +680,7 @@ INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "elem (492, 0, 'plg_privacy_message', 'plugin', 'message', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (494, 0, 'plg_captcha_recaptcha_invisible', 'plugin', 'recaptcha_invisible', 'captcha', 0, 0, 1, 0, '', '{"public_key":"","private_key":"","theme":"clean"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(495, 0, 'plg_fields_subform', 'plugin', 'subform', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (503, 0, 'beez3', 'template', 'beez3', '', 0, 1, 1, 0, '', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (504, 0, 'hathor', 'template', 'hathor', '', 1, 1, 1, 0, '', '{"showSiteName":"0","colourChoice":"0","boldText":"0"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (506, 0, 'protostar', 'template', 'protostar', '', 0, 1, 1, 0, '', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), diff --git a/installation/sql/sqlazure/joomla.sql b/installation/sql/sqlazure/joomla.sql index 02717e9663390..a5776351030a3 100644 --- a/installation/sql/sqlazure/joomla.sql +++ b/installation/sql/sqlazure/joomla.sql @@ -895,6 +895,7 @@ INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "elem (492, 0, 'plg_privacy_message', 'plugin', 'user', 'message', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (494, 0, 'plg_captcha_recaptcha_invisible', 'plugin', 'recaptcha_invisible', 'captcha', 0, 0, 1, 0, '', '{"public_key":"","private_key":"","theme":"clean"}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(495, 0, 'plg_fields_subform', 'plugin', 'subform', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), (503, 0, 'beez3', 'template', 'beez3', '', 0, 1, 1, 0, '', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (504, 0, 'hathor', 'template', 'hathor', '', 1, 1, 1, 0, '', '{"showSiteName":"0","colourChoice":"0","boldText":"0"}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (506, 0, 'protostar', 'template', 'protostar', '', 0, 1, 1, 0, '', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '1900-01-01 00:00:00', 0, 0), diff --git a/media/system/js/subform-repeatable.js b/media/system/js/subform-repeatable.js index 65965ede4666a..f5b80758d832b 100644 --- a/media/system/js/subform-repeatable.js +++ b/media/system/js/subform-repeatable.js @@ -1 +1 @@ -!function(R){"use strict";R.subformRepeatable=function(e,t){if(this.$container=R(e),this.$container.data("subformRepeatable"))return a;this.$container.data("subformRepeatable",a),this.options=R.extend({},R.subformRepeatable.defaults,t),this.template="",this.prepareTemplate(),this.$containerRows=this.options.rowsContainer?this.$container.find(this.options.rowsContainer):this.$container,this.lastRowNum=this.$containerRows.find(this.options.repeatableElement).length;var a=this;this.$container.on("click",this.options.btAdd,function(e){e.preventDefault();var t=R(this).parents(a.options.repeatableElement);t.length||(t=null),a.addRow(t)}),this.$container.on("click",this.options.btRemove,function(e){e.preventDefault();var t=R(this).parents(a.options.repeatableElement);a.removeRow(t)}),this.options.btMove&&this.$containerRows.sortable({items:this.options.repeatableElement,handle:this.options.btMove,tolerance:"pointer"}),this.$container.trigger("subform-ready")},R.subformRepeatable.prototype.prepareTemplate=function(){if(this.options.rowTemplateSelector)this.template=R.trim(this.$container.find(this.options.rowTemplateSelector).last().html())||"";else{var e=this.$container.find(this.options.repeatableElement).get(0),t=R(e).clone();try{this.clearScripts(t)}catch(e){window.console&&console.log(e)}this.template=t.prop("outerHTML")}},R.subformRepeatable.prototype.addRow=function(e){var t=this.$containerRows.find(this.options.repeatableElement).length;if(t>=this.options.maximum)return null;var a=R.parseHTML(this.template);e?R(e).after(a):this.$containerRows.append(a);var o=R(a);o.attr("data-new","true"),this.fixUniqueAttributes(o,t);try{this.fixScripts(o)}catch(e){window.console&&console.log(e)}return this.$container.trigger("subform-row-add",o),o},R.subformRepeatable.prototype.removeRow=function(e){this.$containerRows.find(this.options.repeatableElement).length<=this.options.minimum||(this.$container.trigger("subform-row-remove",e),e.remove())},R.subformRepeatable.prototype.fixUniqueAttributes=function(e,t,a,o){a=void 0===a?e.attr("data-group"):a,o=void 0===o?e.attr("data-base-name"):o,t=void 0===t?0:t;var i=Math.max(this.lastRowNum,t),r=o+i;this.lastRowNum=i+1,e.attr("data-group",r);for(var n=e.find("[name]"),s={},l=0,p=n.length;l
=this.options.maximum)return null;var a=y.parseHTML(this.template);e?y(e).after(a):this.$containerRows.append(a);var o=y(a);o.attr("data-new","true"),this.fixUniqueAttributes(o,t);try{this.fixScripts(o)}catch(e){window.console&&console.log(e)}return this.$container.trigger("subform-row-add",o),o},y.subformRepeatable.prototype.removeRow=function(e){this.$containerRows.find(this.options.repeatableElement).length<=this.options.minimum||(this.$container.trigger("subform-row-remove",e),e.remove())},y.subformRepeatable.prototype.fixUniqueAttributes=function(e,t,a,o){var i=void 0===a?e.attr("data-group"):a,r=void 0===o?e.attr("data-base-name"):o,n=void 0===t?0:t,s=Math.max(this.lastRowNum,n),l=r+s;this.lastRowNum=s+1,e.attr("data-group",l);for(var p=e.find("[name]"),f={},c=0,d=p.length;c';
+//foreach ($field->subfield_rows as $subfield_objects)
+//{
+// echo '
';
+/**
+ * This example maybe looks a bit odd, but the the idea is that you could use
+ * something like this:
+ *
+ *
+ * subfield_rows as $row): ?>
+ *
+ *
+ * This means you have better control over how the output of your subform fields
+ * really is because you don't rely on the rendered values of the subform fields
+ * themselves.
+ */
diff --git a/plugins/system/fields/fields.php b/plugins/system/fields/fields.php
index 9838578360769..5a23072f0f8df 100644
--- a/plugins/system/fields/fields.php
+++ b/plugins/system/fields/fields.php
@@ -140,6 +140,12 @@ public function onContentAfterSave($context, $item, $isNew, $data = array())
$value = json_encode($value);
}
+ // JSON encode the value if it is an array
+ if (is_array($value))
+ {
+ $value = json_encode($value);
+ }
+
// Setting the value for the field and the item
$model->setFieldValue($field->id, $item->id, $value);
}
+ * Image: image->value; ?>
+ * etc...
+ *