name = $name; $this->values = collect($values); $this->lang_tags = collect(); $this->oldValues = collect($values); $this->schema = (new Server) ->schema('attributetypes',$name); /* # Should this attribute be hidden if ($server->isAttrHidden($this->name)) $this->forcehide = true; # Should this attribute value be read only if ($server->isAttrReadOnly($this->name)) $this->readonly = true; # Should this attribute value be unique if ($server->isAttrUnique($this->name)) $this->unique = true; */ } public function __get(string $key): mixed { return match ($key) { // List all the attributes 'attributes' => $this->attributes(), // Can this attribute have more values 'can_addvalues' => $this->schema && (! $this->schema->is_single_value) && ((! $this->max_values_count) || ($this->values->count() < $this->max_values_count)), // Schema attribute description 'description' => $this->schema ? $this->schema->{$key} : NULL, // Attribute hints 'hints' => $this->hints(), // Can this attribute be edited 'is_editable' => $this->schema ? $this->schema->{$key} : NULL, // Is this an internal attribute 'is_internal' => isset($this->{$key}) && $this->{$key}, // Is this attribute the RDN 'is_rdn' => $this->is_rdn, // We prefer the name as per the schema if it exists 'name' => $this->schema ? $this->schema->{$key} : $this->{$key}, // Attribute name in lower case 'name_lc' => strtolower($this->name), // Old Values 'old_values' => $this->oldValues, // Attribute values 'values' => $this->values, // Required by Object Classes 'required_by' => $this->schema?->required_by_object_classes ?: collect(), // Used in Object Classes 'used_in' => $this->schema?->used_in_object_classes ?: collect(), default => throw new \Exception('Unknown key:' . $key), }; } public function __set(string $key,mixed $values): void { switch ($key) { case 'value': $this->values = collect($values); break; default: } } public function __toString(): string { return $this->name; } public function addValue(string $value): void { $this->values->push($value); } public function current(): mixed { return $this->values->get($this->counter); } public function next(): void { $this->counter++; } public function key(): mixed { return $this->counter; } public function valid(): bool { return $this->values->has($this->counter); } public function rewind(): void { $this->counter = 0; } public function count(): int { return $this->values->count(); } public function offsetExists(mixed $offset): bool { return ! is_null($this->values->has($offset)); } public function offsetGet(mixed $offset): mixed { return $this->values->get($offset); } public function offsetSet(mixed $offset, mixed $value): void { // We cannot set new values using array syntax } public function offsetUnset(mixed $offset): void { // We cannot clear values using array syntax } /** * Return the hints about this attribute, ie: RDN, Required, etc * * @return array */ public function hints(): array { $result = collect(); // Is this Attribute an RDN if ($this->is_rdn) $result->put(__('rdn'),__('This attribute is required for the RDN')); // If this attribute name is an alias for the schema attribute name // @todo // objectClasses requiring this attribute // eg: $result->put('required','Required by objectClasses: a,b'); if ($this->required_by->count()) $result->put(__('required'),sprintf('%s: %s',__('Required Attribute by ObjectClass(es)'),$this->required_by->join(','))); // This attribute has language tags if ($this->lang_tags->count()) $result->put(__('language tags'),sprintf('%s: %d',__('This Attribute has Language Tags'),$this->lang_tags->count())); return $result->toArray(); } /** * Determine if this attribute has changes * * @return bool */ public function isDirty(): bool { return ($this->oldValues->count() !== $this->values->count()) || ($this->values->diff($this->oldValues)->count() !== 0); } public function oldValues(array $array): void { $this->oldValues = collect($array); } /** * Display the attribute value * * @param bool $edit Render an edit form * @param bool $old Use old value * @param bool $new Enable adding values * @return View */ public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE): View { return view('components.attribute') ->with('o',$this) ->with('edit',$edit) ->with('old',$old) ->with('new',$new); } public function render_item_old(int $key): ?string { return Arr::get($this->old_values,$key); } public function render_item_new(int $key): ?string { return Arr::get($this->values,$key); } /** * If this attribute has RFC3866 Language Tags, this will enable those values to be captured * * @param string $tag * @param array $value * @return void */ public function setLangTag(string $tag,array $value): void { $this->lang_tags->put($tag,$value); } public function setRDN(): void { $this->is_rdn = TRUE; } }