We overwrite the field attribute to add our hidden fields, as this
formfield can contain multiple values.

@param array $properties
@return DBHTMLText
967246
public function Field($properties = array())
    {
        $value = '';
        $titleArray = array();
        $idArray = array();
        $items = $this->getItems();
        $emptyTitle = _t('SilverStripe\\Forms\\DropdownField.CHOOSE', '(Choose)', 'start value of a dropdown');

        if ($items && count($items)) {
            foreach ($items as $item) {
                $idArray[] = $item->ID;
                $titleArray[] = ($item instanceof ViewableData)
                    ? $item->obj($this->getLabelField())->forTemplate()
                    : Convert::raw2xml($item->{$this->getLabelField()});
            }

            $title = implode(", ", $titleArray);
            sort($idArray);
            $value = implode(",", $idArray);
        } else {
            $title = $emptyTitle;
        }

        $dataUrlTree = '';
        if ($this->form) {
            $dataUrlTree = $this->Link('tree');
            if (!empty($idArray)) {
                $dataUrlTree = Controller::join_links($dataUrlTree, '?forceValue=' . implode(',', $idArray));
            }
        }
        $properties = array_merge(
            $properties,
            array(
                'Title' => $title,
                'EmptyTitle' => $emptyTitle,
                'Link' => $dataUrlTree,
                'Value' => $value
            )
        );
        return FormField::Field($properties);
    }
84358
public function setProperties(array $properties): self
    {
        // check all keys and values are non-empty strings
        $this->properties = [];
        foreach ($properties as $key => $value) {
            assert(is_scalar($key) === true && strlen((string)$key) > 0);
            assert(is_string($value) === true && strlen($value) > 0);
            $this->properties[(string)$key] = (string)$value;
        }

        return $this;
    }
56648
protected function attributesFromProperties(array $properties): array
    {
        // First, we'll only keep the entities that are part of the Entity's
        // attributes
        $managedProperties = $this->getManagedProperties();

        $properties = array_only($properties, $managedProperties);

        // If the entity does not uses the attributes array to store
        // part of its attributes, we'll directly return the properties
        if (!$this->entityMap->usesAttributesArray()) {
            return $properties;
        }

        $arrayName = $this->entityMap->getAttributesArrayName();

        if (!array_key_exists($arrayName, $properties)) {
            throw new MappingException("Property $arrayName not set on object of type ".$this->getEntityClass());
        }

        if (!is_array($properties[$arrayName])) {
            throw new MappingException("Property $arrayName should be an array.");
        }

        $attributes = $properties[$arrayName];

        unset($properties[$arrayName]);

        return $properties + $attributes;
    }
765954
public function setProperties(array $properties) {
		foreach ($this->properties as $prop) {
			$prop->setParent(null);
		}

		$this->properties->clear();

		foreach ($properties as $prop) {
			$this->setProperty($prop);
		}

		return $this;
	}
561439
public function SmallFieldHolder($properties = array())
    {
        $context = $this;

        if (count($properties)) {
            $context = $this->customise($properties);
        }

        return $context->renderWith($this->getSmallFieldHolderTemplates());
    }
675161
public function Field($properties = array())
    {
        $source = ArrayLib::flatten($this->getSource());
        $values = $this->getValueArray();

        // Get selected values
        $mapped = [];
        foreach ($values as $value) {
            if (isset($source[$value])) {
                $mapped[] = Convert::raw2xml($source[$value]);
            }
        }

        // Don't check if string arguments are matching against the source,
        // as they might be generated HTML diff views instead of the actual values
        if ($this->value && is_string($this->value) && empty($mapped)) {
            $mapped[] = Convert::raw2xml(trim($this->value));
            $values = [];
        }

        if ($mapped) {
            $attrValue = implode(', ', array_values($mapped));
            $inputValue = implode(', ', array_values($values));
        } else {
            $attrValue = '<i>(' . _t('SilverStripe\\Forms\\FormField.NONE', 'none') . ')</i>';
            $inputValue = '';
        }

        $properties = array_merge($properties, array(
            'AttrValue' => DBField::create_field('HTMLFragment', $attrValue),
            'InputValue' => $inputValue
        ));

        return parent::Field($properties);
    }
700230
public function setFieldsPropertyValues($property,$values){
		$i=0;
		if(\is_array($values)===false){
			$values=\array_fill(0, $this->count(),$values);
		}
		foreach ($values as $value){
			$c=$this->content[$i++];
			if(isset($c)){
				$df=$c->getDataField();
				$df->setProperty($property,$value);
			}
			else{
				return $this;
			}
		}
		return $this;
	}
849677
public static function getNameFromArray(array $properties)
    {
        if (!Helpers::isKeyExists($properties, 'name')
            || empty($fieldName = Helpers::removeNonEnglishChars($properties['name']))
        ) {
            throw new Exception("The field 'name' was not provided!");
        }

        return $fieldName;
    }
770008
public function FieldHolder($properties = array())
    {
        if ($this->content instanceof ViewableData) {
            $context = $this->content;

            if ($properties) {
                $context = $context->customise($properties);
            }

            return $context->forTemplate();
        }

        return $this->content;
    }
362822
public function buildField($properties = array())
    {
        if ($this->multiple) {
            $this->name .= '[]';
        }

        $source = $this->getSource();
        $options = array();

        if ($this->getHasEmptyDefault()) {
            $selected = ($this->value === '' || $this->value === null);
            $disabled = (in_array('', $this->disabledItems, true)) ? 'disabled' : false;

            $options[] = new ArrayData(array(
                'Value' => '',
                'Title' => $this->getEmptyString(),
                'Selected' => $selected,
                'Disabled' => $disabled
            ));
        }

        if ($source) {
            // We have an array of values
            if (is_array($this->value)) {
                // Loop through and figure out which values were selected.
                foreach ($source as $value => $title) {
                    $options[] = new ArrayData(array(
                        'Title' => $title,
                        'Value' => $value,
                        'Selected' => (in_array($value, $this->value) || in_array($value, $this->defaultItems)),
                        'Disabled' => $this->disabled || in_array($value, $this->disabledItems),
                    ));
                }
            } else {
                // Listbox was based a singlular value, so treat it like a dropdown.
                foreach ($source as $value => $title) {
                    $selected = false;
                    if ($value === '' && ($this->value === '' || $this->value === null)) {
                        $selected = true;
                    } else {
                        // check against value, fallback to a type check comparison when !value
                        if ($value) {
                            $selected = ($value == $this->value);
                        } else {
                            // Safety check against casting arrays as strings in PHP>5.4
                            if (!is_array($value) && !is_array($this->value)) {
                                $selected = ($value === $this->value) || (((string) $value) === ((string) $this->value));
                            } else {
                                $selected = ($value === $this->value);
                            }
                        }

                        $this->isSelected = $selected;
                    }

                    $disabled = false;
                    if (in_array($value, $this->disabledItems) && $title != $this->emptyString) {
                        $disabled = 'disabled';
                    }

                    $options[] = new ArrayData(array(
                        'Title' => $title,
                        'Value' => $value,
                        'Selected' => $selected,
                        'Disabled' => $disabled,
                    ));
                }
            }
        }


        $properties = array_merge($properties, array(
            'Options' => new ArrayList($options)
        ));

        return FormField::Field($properties);
    }
628319
public function addProperties($properties)
    {
        if (empty($properties) || !count((array)$properties)) {
            throw new \Exception('Empty properties given');
        }

        if (!is_array($properties) && !is_object($properties)) {
            throw new \Exception('Expected array or object');
        }

        foreach ($properties as $key => $property) {
            $this->addProperty($key, $property);
        }

        return $this;
    }
621194
protected function addFieldProperties(&$properties, array $fields, $withoutTimestamps, $withSoftDelete)
    {
        $primaryField = $this->getPrimaryField($fields);

        foreach ($fields as $field) {

            if ($field instanceof Field && $field != $primaryField) {
                if (!$withoutTimestamps && $field->isAutoManagedOnUpdate()) {
                    continue;
                }
                if ($withSoftDelete && $field->isAutoManagedOnDelete()) {
                    continue;
                }

                $this->addFieldType($properties, $field)
                    ->addFieldComment($properties, $field)
                    ->addFieldUnsigned($properties, $field)
                    ->addFieldNullable($properties, $field)
                    ->addFieldIndex($properties, $field)
                    ->addFieldUnique($properties, $field)
                    ->addFieldPropertyClousure($properties);
            }
        }

        return $this;
    }
536683
public function setProperties(array $properties) {
        if (!isset($properties[self::DATA_PROPERTY_REQUIRED])){
            $properties[self::DATA_PROPERTY_REQUIRED] = array();
        }
        if (!isset($properties[self::DATA_PROPERTY_DEFAULTS])){
            $properties[self::DATA_PROPERTY_DEFAULTS] = array();
        }
        $this->properties = $properties;
        return $this;
    }
56567
public function fillKeyField(array &$fields)
    {
        $model   = $this->config->getDataModel();
        $keyName = $model->getKeyName();

        //add the primary key field, which will be uneditable, but part of the data model
        if ($this->config->getType() === 'model' && !isset($fields[$keyName])) {
            $keyField         = $this->make($keyName, array('visible' => false));
            $fields[$keyName] = $keyField->getOptions();
        }
    }
495012
public function setDataTypeParams(array $properties)
    {
        if (Helpers::isKeyExists($properties, 'data-type-params')) {
            $this->methodParams = $this->getDataTypeParams((array) $properties['data-type-params']);
        }
		
        return $this;
    }
91188
public function setProperties(array $properties)
    {
        foreach ($properties as $propertyIdent => $propertyMetadata) {
            if (isset($this->properties[$propertyIdent])) {
                $this->properties[$propertyIdent] = array_replace_recursive(
                    $this->properties[$propertyIdent],
                    $propertyMetadata
                );
            } else {
                $this->properties[$propertyIdent] = $propertyMetadata;
            }
        }

        return $this;
    }
325532
public function FieldHolder($properties=array()) {
        $obj=($properties ? $this->customise($properties):$this);
        
        
        Requirements::css(CB_DIR.'/css/PackageViewField.css');
        Requirements::javascript(CB_DIR.'/javascript/PackageViewField.js');
        
        return $obj->renderWith($this->getFieldHolderTemplates());
    }