file = $file; try { // @todo Load in the proper attribute objects and objectclass objects // @todo Make sure we have a structural objectclass, or make the template invalid $this->template = json_decode($td->get($file),null,512,JSON_OBJECT_AS_ARRAY|JSON_THROW_ON_ERROR); } catch (\JsonException $e) { $this->invalid = TRUE; $this->reason = $e->getMessage(); } } public function __get(string $key): mixed { return match ($key) { 'attributes' => collect(Arr::get($this->template,$key))->keys(), 'enabled' => Arr::get($this->template,$key,FALSE) && (! $this->invalid), 'icon','regexp','title' => Arr::get($this->template,$key), 'name' => Str::replaceEnd('.json','',$this->file), 'objectclasses' => collect(Arr::get($this->template,$key)), 'order' => collect(Arr::get($this->template,'attributes'))->map(fn($item)=>$item['order']), default => throw new \Exception('Unknown key: '.$key), }; } public function __isset(string $key): bool { return array_key_exists($key,$this->template); } private function autofill() { /* autoFill:string string is a literal string, and may contain many fields like %attr|start-end/flags|additionalcontrolchar% to substitute values read from other fields. |start-end is optional, but must be present if the k flag is used. /flags is optional. |additionalcontrolchar is optional. flags may be: T: Read display text from selection item (drop-down list), otherwise, read the value of the field For fields that aren't selection items, /T shouldn't be used, and the field value will always be read. k: Tokenize: If the "k" flag is not given: A |start-end instruction will perform a sub-string operation upon the value of the attr, passing character positions start-end through. start can be 0 for first character, or any other integer. end can be 0 for last character, or any other integer for a specific position. If the "k" flag is given: The string read will be split into fields, using : as a delimiter "start" indicates which field number to pass through. K: The string read will be split into fields, using ' ' as a delimiter "start" indicates which field number to pass through. If additionalcontrolchar is given, it will be used as delimiter (e.g. this allows for splitting e-mail addresses into domain and domain-local part). l: Make the result lower case. U: Make the result upper case. A: Remap special characters to their corresponding ASCII value */ if (! preg_match('/;/',$arg)) { system_message(array( 'title'=>_('Problem with autoFill() in template'), 'body'=>sprintf('%s (%s)',_('There is only 1 argument, when there should be two'),$attribute->getName(false)), 'type'=>'warn')); return; } list($attr,$string) = preg_split('(([^,]+);(.*))',$arg,-1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); preg_match_all('/%(\w+)(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?(?:\|(.))?%/U',$string,$matchall); //print"
";print_r($matchall); //0 = highlevel match, 1 = attr, 2 = subst, 3 = mod, 4 = delimiter if (! isset($attribute->js['autoFill'])) $attribute->js['autoFill'] = ''; $formula = $string; $formula = preg_replace('/^([^%])/','\'$1',$formula); $formula = preg_replace('/([^%])$/','$1\'',$formula); # Check that our attributes match our schema attributes. foreach ($matchall[1] as $index => $checkattr) { $sattr = $this->getServer()->getSchemaAttribute($checkattr); # If the attribute is the same as in the XML file, then dont need to do anything. if (! $sattr || ! strcasecmp($sattr->getName(),$checkattr)) continue; $formula = preg_replace("/$checkattr/",$sattr->getName(),$formula); $matchall[1][$index] = $sattr->getName(); } $elem_id = 0; foreach ($matchall[0] as $index => $null) { $match_attr = strtolower($matchall[1][$index]); $match_subst = $matchall[2][$index]; $match_mod = $matchall[3][$index]; $match_delim = $matchall[4][$index]; $substrarray = array(); if (! isset($varcount[$match_attr])) $varcount[$match_attr] = 0; else $varcount[$match_attr]++; $js_match_attr = $match_attr; $match_attr = $js_match_attr.'xx'.$varcount[$match_attr]; $formula = preg_replace('/%'.$js_match_attr.'([|\/%])/i','%'.$match_attr.'$1',$formula,1); $attribute->js['autoFill'] .= sprintf(" var %s;\n",$match_attr); $attribute->js['autoFill'] .= sprintf( " var elem$elem_id = document.getElementById(pre+'%s'+suf);\n". " if (!elem$elem_id) return;\n", $js_match_attr); if (strstr($match_mod,'T')) { $attribute->js['autoFill'] .= sprintf(" %s = elem$elem_id.options[elem$elem_id.selectedIndex].text;\n", $match_attr); } else { $attribute->js['autoFill'] .= sprintf(" %s = elem$elem_id.value;\n",$match_attr); } $elem_id++; if (strstr($match_mod,'k')) { preg_match_all('/([0-9]+)/',trim($match_subst),$substrarray); if (isset($substrarray[1][0])) { $tok_idx = $substrarray[1][0]; } else { $tok_idx = '0'; } $attribute->js['autoFill'] .= sprintf(" %s = %s.split(':')[%s];\n",$match_attr,$match_attr,$tok_idx); } elseif (strstr($match_mod,'K')) { preg_match_all('/([0-9]+)/',trim($match_subst),$substrarray); if (isset($substrarray[1][0])) { $tok_idx = $substrarray[1][0]; } else { $tok_idx = '0'; } if ($match_delim == '') { $delimiter = ' '; } else { $delimiter = preg_quote($match_delim); } $attribute->js['autoFill'] .= sprintf(" %s = %s.split('%s')[%s];\n",$match_attr,$match_attr,$delimiter,$tok_idx); } else { preg_match_all('/([0-9]*)-([0-9]*)/',trim($match_subst),$substrarray); if ((isset($substrarray[1][0]) && $substrarray[1][0]) || (isset($substrarray[2][0]) && $substrarray[2][0])) { $attribute->js['autoFill'] .= sprintf(" %s = %s.substr(%s,%s);\n", $match_attr,$match_attr, $substrarray[1][0] ? $substrarray[1][0] : '0', $substrarray[2][0] ? $substrarray[2][0] : sprintf('%s.length',$match_attr)); } } if (strstr($match_mod,'l')) { $attribute->js['autoFill'] .= sprintf(" %s = %s.toLowerCase();\n",$match_attr,$match_attr); } if (strstr($match_mod,'U')) { $attribute->js['autoFill'] .= sprintf(" %s = %s.toUpperCase();\n",$match_attr,$match_attr); } if (strstr($match_mod,'A')) { $attribute->js['autoFill'] .= sprintf(" %s = toAscii(%s);\n",$match_attr,$match_attr); } # Matchfor only entry without modifiers. $formula = preg_replace('/^%('.$match_attr.')%$/U','$1 + \'\'',$formula); # Matchfor only entry with modifiers. $formula = preg_replace('/^%('.$match_attr.')(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?(?:\|(.))?%$/U','$1 + \'\'',$formula); # Matchfor begining entry. $formula = preg_replace('/^%('.$match_attr.')(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?(?:\|(.))?%/U','$1 + \'',$formula); # Matchfor ending entry. $formula = preg_replace('/%('.$match_attr.')(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?(?:\|(.))?%$/U','\' + $1 ',$formula); # Match for entries not at begin/end. $formula = preg_replace('/%('.$match_attr.')(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?(?:\|(.))?%/U','\' + $1 + \'',$formula); $attribute->js['autoFill'] .= "\n"; } $attribute->js['autoFill'] .= sprintf(" fillRec(pre+'%s'+suf, %s); // %s\n",strtolower($attr),$formula,$string); $attribute->js['autoFill'] .= "\n"; } }