diff --git a/plugins/adamhall/adamhall.php b/plugins/adamhall/adamhall.php new file mode 100644 index 0000000..edc177a --- /dev/null +++ b/plugins/adamhall/adamhall.php @@ -0,0 +1,29 @@ + 'onTwigLoaded', + 'onMetaLoaded' => 'onMetaLoaded' + ); + } + + public function onTwigLoaded() + { + $this->addEditorJS('/adamhall/js/adamhall.js'); + } + + public function onMetaLoaded($meta) + { + $meta = $meta->getData(); + + # do something with the fields: + $myTabInformation = $meta['mytab']; + } +} \ No newline at end of file diff --git a/plugins/adamhall/adamhall.yaml b/plugins/adamhall/adamhall.yaml new file mode 100644 index 0000000..c2ad275 --- /dev/null +++ b/plugins/adamhall/adamhall.yaml @@ -0,0 +1,15 @@ +name: Adam Hall Plugin +version: 1.0.0 +description: Plugin for Adam Hall that integrates Custom Fields +author: Sebastian Schürmanns +homepage: http://trendschau.net +licence: Owned by Adam Hall + +metatabs: + adamhall: + fields: + myfield: + type: customfields + label: Simple Custom Field + description: Please add some custom fields + data: array \ No newline at end of file diff --git a/plugins/adamhall/js/adamhall.js b/plugins/adamhall/js/adamhall.js new file mode 100644 index 0000000..357e61e --- /dev/null +++ b/plugins/adamhall/js/adamhall.js @@ -0,0 +1,26 @@ +Vue.component('tab-adamhall', { + props: ['saved', 'errors', 'formdata', 'schema'], + template: '
' + + '' + + '' + + '
Saved successfully
' + + '
Please correct the errors above
' + + '
' + + '
', + methods: { + selectComponent: function(field) + { + return 'component-'+field.type; + }, + saveInput: function() + { + this.$emit('saveform'); + }, + } +}) diff --git a/system/Controllers/MetaApiController.php b/system/Controllers/MetaApiController.php index 4cfbd82..520bbd8 100644 --- a/system/Controllers/MetaApiController.php +++ b/system/Controllers/MetaApiController.php @@ -122,6 +122,28 @@ class MetaApiController extends ContentController { $metascheme[$tabname][$fieldname] = true; $metadata[$tabname][$fieldname] = isset($pagemeta[$tabname][$fieldname]) ? $pagemeta[$tabname][$fieldname] : null; + + # special treatment for customfields + if(isset($fielddefinitions['type']) && ($fielddefinitions['type'] == 'customfields' ) ) + { + # loop through the customdata + foreach($metadata[$tabname][$fieldname] as $key => $value) + { + # and make sure that arrays are transformed back into strings + if(isset($value['value']) && is_array($value['value'])) + { + $valuestring = implode('\n',$value['value']); + $metadata[$tabname][$fieldname][$key]['value'] = $valuestring; + } + } + /* + echo 'fielddefinition:
';
+					print_r($fielddefinitions);
+					echo '
metadata:
';
+					print_r($pagemeta[$tabname][$fieldname]);
+					die();
+					*/
+				}
 			}
 		}
 
@@ -208,6 +230,21 @@ class MetaApiController extends ContentController
 				{
 					$errors[$tab][$fieldName] = $result[$fieldName][0];
 				}
+
+				# special treatment for customfields 
+				if($fieldDefinition && isset($fieldDefinition['type']) && ($fieldDefinition['type'] == 'customfields' ) && isset($fieldDefinition['data']) && ($fieldDefinition['data'] == 'array' )  )
+				{
+					foreach($fieldValue as $key => $valuePair)
+					{
+						if(isset($valuePair['value']))
+						{
+							$arrayValues = explode(PHP_EOL,$valuePair['value']);
+							echo '
';
+							print_r($arrayValues);
+						}
+					}
+					die();
+				}	
 			}
 		}
 
diff --git a/system/Models/Validation.php b/system/Models/Validation.php
index 0391abe..972c347 100644
--- a/system/Models/Validation.php
+++ b/system/Models/Validation.php
@@ -63,6 +63,23 @@ class Validation
 			return true;
 		}, 'contains one or more invalid ip-adress');
 
+		Validator::addRule('customfields', function($field, $value, array $params, array $fields) use ($user)
+		{
+			foreach($value as $customfield)
+			{
+				if(!isset($customfield['key']) OR empty($customfield['key']) OR (preg_match('/^([a-z0-9])+$/i', $customfield['key']) == false) )
+				{
+		        	return false;
+		        }
+
+				if (!isset($customfield['value']) OR empty($customfield['value']) OR ( $customfield['value'] != strip_tags($customfield['value']) ) )
+				{
+					return false;
+				}
+			}
+			return true;
+		}, 'contains one or more invalid values');
+
 		Validator::addRule('checkPassword', function($field, $value, array $params, array $fields) use ($user)
 		{
 			$userdata = $user->getUser($fields['username']);
@@ -459,6 +476,10 @@ class Validation
 				$v->rule('lengthMax', $fieldName, 1000);
 				$v->rule('image_types', $fieldName);
 				break;
+			case "customfields":
+				$v->rule('array', $fieldName);
+				$v->rule('customfields', $fieldName);
+				break;			
 			default:
 				$v->rule('lengthMax', $fieldName, 1000);
 				$v->rule('regex', $fieldName, '/^[\pL0-9_ \-]*$/u');
diff --git a/system/author/css/style.css b/system/author/css/style.css
index 20c86e8..7f115df 100644
--- a/system/author/css/style.css
+++ b/system/author/css/style.css
@@ -128,6 +128,9 @@ input.upload{
   opacity: 0;
 }
 
+/* fix wrong text-align/family */
+input, textarea, button {font-family: arial, sans-serif}
+
 /****************************
 *  	download-commponent		*
 ****************************/
@@ -1280,6 +1283,16 @@ span.error{
 	background: #70c1b3;
 }
 
+/********************
+*	Customfields	*
+********************/
+
+.customkey{
+	width: 29%;
+}
+.customvalue{
+	width: 60%;
+}
 
 /********************
 *	UPDATE-BANNER	*
diff --git a/system/author/js/vue-blox.js b/system/author/js/vue-blox.js
index cd979d7..704c950 100644
--- a/system/author/js/vue-blox.js
+++ b/system/author/js/vue-blox.js
@@ -1248,13 +1248,13 @@ const definitionComponent = Vue.component('definition-component', {
 	template: '
' + '
' + '' + - '
' + + '
' + '' + '' + - '' + - '' + - '' + - '
' + + '' + + '' + + '' + + '
' + '
' + '' + '
' + diff --git a/system/author/js/vue-meta.js b/system/author/js/vue-meta.js index bbfeb1e..b909d8f 100644 --- a/system/author/js/vue-meta.js +++ b/system/author/js/vue-meta.js @@ -332,6 +332,7 @@ Vue.component('component-checkboxlist', { '' + '{{ errors[name] }}' + '{{ description|translate }}' + + '' + '
', methods: { update: function($event, value, optionvalue, name) @@ -373,6 +374,92 @@ Vue.component('component-radio', { }, }) +Vue.component('component-customfields', { + props: ['class', 'id', 'description', 'readonly', 'required', 'disabled', 'options', 'label', 'name', 'type', 'value', 'errors'], + data: function () { + return { + fielderrors: false, + fielddetails: {}, + } + }, + + template: '
' + + '' + + '
{{ fielderrors }}
' + + '
{{ description|translate }}
' + + '
' + + '' + + '
' + + '' + + '' + + '
' + + '' + + '
', + mounted: function(){ + + if(this.value === null) + { + this.value = [{}]; + } + }, + methods: { + update: function(value, name) + { + FormBus.$emit('forminput', {'name': name, 'value': value}); + }, + updatePairKey: function(index,event) + { + this.value[index].key = event.target.value; + + var regex = /^[a-z0-9]+$/i; + if(regex.test(event.target.value)) + { + this.fielderrors = false; + delete this.value[index].keyerror; + this.update(this.value,this.name); + } + else + { + this.value[index].keyerror = 'red'; + this.fielderrors = 'Only alphanumeric for keys allowed'; + } + }, + updatePairValue: function(index, event) + { + this.value[index].value = event.target.value; + + var regex = /<.*(?=>)/gm; + if(event.target.value == '' || regex.test(event.target.value)) + { + this.value[index].valueerror = 'red'; + this.fielderrors = 'No empty values or html tags are allowed'; + } + else + { + this.fielderrors = false; + delete this.value[index].valueerror; + this.update(this.value,this.name); + } + }, + addField: function() + { + for(object in this.value) + { + if(Object.keys(this.value[object]).length === 0) + { + return; + } + } + + this.value.push({}); + }, + deleteField: function(index) + { + this.value.splice(index,1); + }, + }, +}) + Vue.component('tab-meta', { props: ['saved', 'errors', 'formdata', 'schema'], template: '
' + @@ -473,9 +560,18 @@ let meta = new Vue({ } }); + /* update single value or array + this.$set(this.someObject, 'b', 2) */ FormBus.$on('forminput', formdata => { this.$set(this.formData[this.currentTab], formdata.name, formdata.value); }); + + /* update values that are objects + this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 }) */ + + FormBus.$on('forminputobject', formdata => { + this.formData[this.currentTab][formdata.name] = Object.assign({}, this.formData[this.currentTab][formdata.name], formdata.value); + }); }, methods: { saveForm: function()