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: '', + 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: '' + '' + '', 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: '' + - ' ' + '' + '' + + '' + '' + '' + '' + - '' + - '' + - '' + - '' + + '' + + '' + + '' + + '' + 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 }}' + + '' + '' + + '' + + '', + 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: '{{ fielderrors }}' + + '{{ description|translate }}' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '