{@inheritDoc}
return object value associated with input key
501791
@Override
    public Object get(Object key) {
        if (INSTALL_KERNEL_INIT_CODE.equals(key))
            return initValidate();
        if (INSTALL_KERNEL_INIT_ERROR_MESSAGE.equals(key) ||
            RUNTIME_INSTALL_DIR.equals(key))
            return data.get(key);
        if (installKernelMap == null) {
            throw new RuntimeException(getMessage("MAPBASED_ERROR_KERNEL_NOT_INIT"));
        }
        return installKernelMap.get(key);
    }
1018365
private function __key($key)
    {
        if ($key instanceof AnObjectHandlable) {
            $key = $key->getHandle();
        } elseif (gettype($key) == 'object') {
            $key = spl_object_hash($key);
        }

        return $key;
    }
377053
public function input($key = null, $default = null)
    {
        $input = $this->getInputSource()->all() + $this->query->all();

        return array_get($input, $key, $default);
    }
571853
public static function set(& $object, $key, $value)
    {
        if (static::isArray($object))
            $object[$key] = $value;

        if (static::isObject($object))
            $object->$key = $value;

        return $object;
    }
30778
public static function getObjectFieldValue($object, $field)
    {
        $op = $value = null;

        $pos = strpos($field, '(');
        if (false !== $pos) {
            list ($op, $field) = explode('(', $field, 2);
            $field = rtrim($field, ')');
        }

        if (isset($object[$field])) {
            $value = $object[$field];
        } else {
            $accessors = array('', 'get', 'is');

            foreach ($accessors as $accessor) {
                $accessor .= $field;

                if (!method_exists($object, $accessor)) {
                    continue;
                }

                $value = $object->{$accessor}();
                break;
            }
        }

        if ($op) {
            $function = 'filter' . ucfirst(strtolower($op));
            if (method_exists(static::class, $function)) {
                $value = static::$function($value);
            }
        }

        return $value;
    }
1240668
public function getObjectValue($object, $name)
    {
        if (is_object($object) && isset($object->$name) && !method_exists($object, $name)) {
            return $object->$name;
        }

        // If its a nested value like meta[user[phone]]
        if (strpos($name, '[') > 0) {
            $nested = explode('[', str_replace(']', '', $name));
            $final = $object;
            foreach ($nested as $property) {
                if (!empty($property) && isset($final->{$property})) {
                    $final = $final->{$property};
                } elseif (is_object($final) && is_null($final->{$property})) {
                    $final = '';
                }
            }

            return $final;
        }

        return '';
    }
997147
public function prepare($input)
    {
        foreach ($input as $key => $record) {
            $this->setFieldOriginalValue($key);
            $input[$key] = $this->prepareValue($key, $record);
        }

        return $input;
    }
320793
public function getInputValue($key = null, $default = null)
    {
        $input = $this->getInputSource()->all() + $this->query->all();

        return ArrayHelper::get($input, $key, $default);
    }
455664
public function getAttribute($key)
    {
        $value = parent::getAttribute($key);

        foreach (static::$getter_manipulators as $manipulator) {
            $value = $manipulator($this, $key, $value);
        }

        return $value;
    }
283014
public function input($key = null, $default = null)
    {
        $input = $this->getInputSource();

        return $this->inputSift($input, $key, $default);
    }
788799
public function set($key, Input $input): self
    {
        if (!$input->isValid()) {
            return $this;
        }

        $value = $input->value();

        $this->mapOfValues[$key] = $value;

        return $this;
    }
525615
protected function objectForKey($key)
    {
        /**
         * Fixes https://github.com/silverstripe/silverstripe-framework/issues/8332
         *
         * Due to historic reasons, the default (empty) value for this field is 'unchanged', even though
         * the field is usually integer on the database side.
         * MySQL handles that gracefully and returns an empty result in that case,
         * whereas some other databases (e.g. PostgreSQL) do not support comparison
         * of numeric types with string values, issuing a database error.
         *
         * This fix is not ideal, but supposed to keep backward compatibility for SS4.
         *
         * In 5.0 this method to be removed and NULL should be used instead of 'unchanged' (or an empty array. to be decided).
         * In 5.0 this class to be refactored so that $this->value is always an array of values (or null)
         */
        if ($this->getKeyField() === 'ID' && $key === 'unchanged') {
            $key = null;
        } elseif (is_string($key)) {
            $key = preg_split('/\s*,\s*/', trim($key));
        }

        return parent::objectForKey($key);
    }
432598
public function getPrimaryKeyValue()
    {
        //
        $key = static::getPrimaryKey();

        //
        return $key
            && isset($this->{$key})
            ? $this->{$key}
            : null;
    }
273751
public function Get($Key = NULL, $Default = NULL) {
      if ($Key === NULL)
         return $this->GetRequestArguments (self::INPUT_GET);
      else
         return $this->GetValueFrom(self::INPUT_GET, $Key, $Default);
   }
814955
public function getAllValues($input, $options = []) {
		// reset values
		$this->values = [];
		// sort fields
		$fields = $this->sortFieldsForProcessing($this->fields);
		// inject tenant #
		if (!empty($this->collection_object->primary_model->tenant)) {
			$this->values[$this->collection_object->primary_model->tenant_column] = \Tenant::id();
		}
		// if we delete we only allow pk and optimistic lock
		$allowed = [];
		if (!empty($options['validate_for_delete'])) {
			$allowed = $this->collection_object->data['pk'];
			if ($this->collection_object->primary_model->optimistic_lock) {
				$allowed[] = $this->collection_object->primary_model->optimistic_lock_column;
			}
		}
		// see if we have a change in entry fields
		$changed_field = [
			'parent' => null,
			'detail' => null,
			'subdetail' => null
		];
		if (!empty($this->misc_settings['__form_onchange_field_values_key']) && count($this->misc_settings['__form_onchange_field_values_key']) == 1) {
			if (isset($fields[$this->misc_settings['__form_onchange_field_values_key'][0]])) {
				$changed_field['parent'] = $this->misc_settings['__form_onchange_field_values_key'][0];
			}
		}
		// process json_contains
		foreach ($fields as $k => $v) {
			if (empty($v['options']['json_contains'])) continue;
			$value = array_key_get($input, $v['options']['values_key']);
			if (is_json($value)) {
				$value = json_decode($value, true);
				foreach ($v['options']['json_contains'] as $k2 => $v2) {
					array_key_set($input, $v2, $value[$k2] ?? null);
				}
			} else if (empty($value)) {
				foreach ($v['options']['json_contains'] as $k2 => $v2) {
					array_key_set($input, $v2, null);
				}
			}
		}
		// process fields
		foreach ($fields as $k => $v) {
			// skip certain values
			if (!empty($options['only_columns']) && !in_array($k, $options['only_columns'])) continue;
			if (!empty($allowed) && !in_array($k, $allowed)) continue;
			// default data type
			if (empty($v['options']['type'])) {
				$v['options']['type'] = 'varchar';
			}
			// get value
			$input = array_merge_hard($input, $this->values);
			$value = array_key_get($input, $v['options']['values_key']);
			$error_name = $v['options']['error_name'];
			// multiple column
			if (!empty($v['options']['multiple_column'])) {
				// todo - validate
				$value = $this->generateMultipleColumns($value, $error_name, array_merge($input, $this->values), null, $v);
			} else {
				$temp = $this->validateDataTypesSingleValue($k, $v, $value, $error_name);
				if (empty($temp['flag_error'])) {
					if (empty($temp[$k]) && !empty($temp[$k . '_is_serial'])) {
						// we do not create empty serial keys
						continue;
					} else {
						$value = $temp[$k];
					}
				}
			}
			// persistent
			if ($this->values_loaded && !empty($this->misc_settings['persistent']['fields'][$k])) {
				if (is_null($value)) {
					$value = $this->original_values[$k];
				} else if ($this->misc_settings['persistent']['fields'][$k] === 'if_set' && empty($this->original_values[$k])) {
					// we allow value change
				} else if ($value !== $this->original_values[$k]) {
					$this->error('danger', 'You are trying to change persistent field!', $error_name);
				}
			}
			$v['options']['error_name_no_field'] = $error_name;
			// default
			$default = null;
			if (array_key_exists('default', $v['options'])) {
				array_key_set($this->values, $v['options']['values_key'], $value);
				$default = $this->processDefaultValue($k, $v['options']['default'], null, $this->values, false, $changed_field, $v);
				if (!isset($value) && $this->canProcessDefaultValue($value, $v, $v['options']['default'])) {
					$value = $default;
				} else {
					$temp = array_key_get($this->values, $v['options']['values_key']);
					if ($temp !== $value) {
						$value = $temp;
					}
				}
			}
			// put into values
			array_key_set($this->values, $v['options']['values_key'], $value);
			// options_model validation
			if (isset($value) && !empty($v['options']['options_model']) && empty($v['options']['options_manual_validation'])) {
				$this->checkOptionsModel($v['options'], $value, $error_name, array_merge($input, $this->values));
			}
			// options validation
			if (isset($value) && !empty($v['options']['options']) && empty($v['options']['options_manual_validation'])) {
				$temp_value = is_array($value) ? $value : [$value];
				foreach ($temp_value as $k54 => $v54) {
					$key = is_scalar($v54) ? $v54 : $k54;
					if (empty($v['options']['options'][$key])) {
						$this->error('danger', \Object\Content\Messages::INVALID_VALUES, $error_name);
					}
				}
			}
		}
		// check optimistic lock
		if ($this->values_loaded && $this->collection_object->primary_model->optimistic_lock && !in_array($this->initiator_class, ['report', 'list', 'import']) && empty($this->options['skip_optimistic_lock'])) {
			if (($this->values[$this->collection_object->primary_model->optimistic_lock_column] ?? '') !== $this->original_values[$this->collection_object->primary_model->optimistic_lock_column]) {
				$this->error('danger', \Object\Content\Messages::OPTIMISTIC_LOCK);
			}
		}
		// we do not process details if only_columns is set
		if (!empty($options['only_columns'])) goto processAllValues;
		// process details & subdetails
		if (empty($options['validate_for_delete']) && !empty($this->detail_fields)) {
			foreach ($this->detail_fields as $k => $v) {
				$this->values[$k] = []; // a must
				$details = $input[$k] ?? [];
				// 1 to 1
				if (!empty($v['options']['details_11'])) {
					$details = [$details];
				}
				// sort fields
				$fields = $this->sortFieldsForProcessing($v['elements'], $v['options']);
				// if we have custom data processor
				if (!empty($v['options']['details_process_widget_data'])) {
					$widget_model = \Factory::model($k, true);
					$v['validate_required'] = $options['validate_required'] ?? false;
					$this->values[$k] = $widget_model->formProcessWidgetData($this, [$k], $details, $this->values, $fields, $v);
					continue;
				}
				// start processing of keys
				$detail_key_holder = [];
				$this->generateDetailsPrimaryKey($detail_key_holder, 'reset', $this->values, [$k], $v);
				// autoincrement
				$autoincrement_details = [];
				if (!empty($v['options']['details_autoincrement']) && empty($v['options']['details_11'])) {
					// set it to 0
					foreach ($v['options']['details_autoincrement'] as $v72) {
						$autoincrement_details[$v72] = 0;
					}
					// find maximums in original values
					if (!empty($this->original_values[$k])) {
						foreach ($this->original_values[$k] as $k71 => $v71) {
							foreach ($v['options']['details_autoincrement'] as $v72) {
								if ($v71[$v72] > $autoincrement_details[$v72]) {
									$autoincrement_details[$v72] = $v71[$v72];
								}
							}
						}
					}
					// find maximum in new values
					if (!empty($details)) {
						foreach ($details as $k71 => $v71) {
							foreach ($v['options']['details_autoincrement'] as $v72) {
								if (!empty($v71[$v72]) && intval($v71[$v72]) > $autoincrement_details[$v72]) {
									$autoincrement_details[$v72] = $v71[$v72];
								}
							}
						}
					}
				}
				// process details one by one
				foreach ($details as $k2 => $v2) {
					// see if we have a change in a detail
					$changed_field_details = $changed_field;
					if (!empty($this->misc_settings['__form_onchange_field_values_key'])) {
						$temp_count = count($this->misc_settings['__form_onchange_field_values_key']);
						if ($this->misc_settings['__form_onchange_field_values_key'][0] == $k && ($temp_count == 2 || $temp_count == 3)) {
							if (!empty($v['options']['details_11'])) {
								$changed_field_details['detail'] = $this->misc_settings['__form_onchange_field_values_key'][1];
							} else if ($this->misc_settings['__form_onchange_field_values_key'][1] . '' == $k2 . '') {
								$changed_field_details['detail'] = $this->misc_settings['__form_onchange_field_values_key'][2];
							}
						}
					}
					// change detected
					$flag_change_detected = false;
					// put pk into detail
					$detail = $detail_key_holder['parent_pks'];
					// process json_contains
					foreach ($fields as $k3 => $v3) {
						if (empty($v3['options']['json_contains'])) continue;
						// get value, grab from neighbouring values first
						$value = $v2[$k3] ?? null;
						if (is_json($value)) {
							$value = json_decode($value, true);
							foreach ($v3['options']['json_contains'] as $k31 => $v31) {
								$v2[$v31] = $value[$k31] ?? null;
							}
						} else if (empty($value)) {
							foreach ($v3['options']['json_contains'] as $k31 => $v31) {
								$detail[$v31] = $v2[$v31] = null;
							}
						}
					}
					// process pk
					$this->generateDetailsPrimaryKey($detail_key_holder, 'pk', $v2, [$k], $v);
					$error_name = $detail_key_holder['error_name'];
					$k2 = $detail_key_holder['pk'];
					// process fields
					foreach ($fields as $k3 => $v3) {
						// skip buttons and links
						if (in_array(($v3['options']['method'] ?? ''), ['button', 'button2', 'submit', 'a'])) continue;
						// default data type
						if (empty($v3['options']['type'])) {
							$v3['options']['type'] = 'varchar';
						}
						// get value, grab from neighbouring values first
						$value = $detail[$k3] ?? $v2[$k3] ?? null;
						// validate data type
						if (!empty($v3['options']['multiple_column'])) {
							if (!empty($value)) {
								$value = $this->generateMultipleColumns($value, $error_name, $detail, [$k], $v3);
							} else {
								$value = null;
							}
						} else {
							$temp = $this->validateDataTypesSingleValue($k3, $v3, $value, "{$error_name}[{$k3}]");
							if (empty($temp['flag_error'])) {
								if (empty($temp[$k3]) && !empty($temp[$k3 . '_is_serial'])) {
									// we do not create empty serial keys
									continue;
								} else {
									$value = $temp[$k3];
								}
							}
						}
						// persistent
						if (!empty($v['options']['details_11'])) {
							$detail_access_key = [$k];
						} else {
							$detail_access_key = [$k, $k2];
						}
						$original_values = array_key_get($this->original_values, array_merge($detail_access_key, [$k3]));
						if ($this->values_loaded && !empty($this->misc_settings['persistent']['details'][$k][$k3]) && isset($original_values)) {
							// todo: handle if_set
							if (is_null($value)) {
								$value = $original_values;
							} else if ($value !== $original_values) {
								$this->error('danger', 'You are trying to change persistent field!', "{$error_name}[{$k3}]");
							}
						}
						$v3['options']['error_name_no_field'] = $error_name;
						// default
						$default = null;
						if (array_key_exists('default', $v3['options'])) {
							$detail[$k3] = $value;
							$default = $this->processDefaultValue($k3, $v3['options']['default'], null, $detail, false, $changed_field_details, $v3);
							if (!isset($value) && $this->canProcessDefaultValue($value, $v3)) {
								$value = $default;
							} else if ($detail[$k3] !== $value) {
								$value = $detail[$k3];
							}
						}
						// see if we changed the value but not autoincrement
						if (isset($value) && $value !== $default && !isset($autoincrement_details[$k3])) {
							$flag_change_detected = true;
						}
						// options_model validation
						if (isset($value) && !empty($v3['options']['options_model']) && empty($v3['options']['options_manual_validation'])) {
							$this->checkOptionsModel($v3['options'], $value, "{$error_name}[{$k3}]", array_merge($v2, $detail));
						}
						// options validation
						if (isset($value) && !empty($v3['options']['options']) && empty($v3['options']['options_manual_validation'])) {
							$temp_value = is_array($value) ? $value : [$value];
							foreach ($temp_value as $v54) {
								if (empty($v3['options']['options'][$v54])) {
									$this->error('danger', \Object\Content\Messages::INVALID_VALUES, "{$error_name}[{$k3}]");
								}
							}
						}
						$detail[$k3] = $value;
					}
					// process subdetails, first to detect change
					if (!empty($v['subdetails'])) {
						foreach ($v['subdetails'] as $k0 => $v0) {
							// make empty array
							$detail[$k0] = [];
							// sort fields
							$subdetail_fields = $this->sortFieldsForProcessing($v0['elements']);
							// if we have custom data processor
							if (!empty($v0['options']['details_process_widget_data'])) {
								$widget_model = \Factory::model($k0, true);
								$v0['validate_required'] = $options['validate_required'] ?? false;
								$detail[$k0] = $widget_model->formProcessWidgetData($this, [$k, $k2, $k0], $v2[$k0] ?? [], $detail, $subdetail_fields, $v0);
								// change detected
								if (!empty($detail[$k0])) {
									$flag_change_detected = true;
								}
								continue;
							}
							// start processing of keys
							$subdetail_key_holder = [];
							$this->generateDetailsPrimaryKey($subdetail_key_holder, 'reset', $detail, [$k, $k2, $k0], $v0);
							// go through data
							if (!empty($v0['options']['details_11'])) {
								$subdetail_data = [$v2[$k0] ?? []];
							} else {
								$subdetail_data = $v2[$k0] ?? [];
							}
							// handle auto increment
							$autoincrement_subdetails = [];
							if (!empty($v0['options']['details_autoincrement']) && empty($v0['options']['details_11'])) {
								foreach ($v0['options']['details_autoincrement'] as $v72) {
									$autoincrement_subdetails[$v72] = 0;
								}
								// find maximum in new values
								if (!empty($subdetail_data)) {
									foreach ($subdetail_data as $k71 => $v71) {
										foreach ($v0['options']['details_autoincrement'] as $v72) {
											if (!empty($v71[$v72]) && intval($v71[$v72]) > $autoincrement_subdetails[$v72]) {
												$autoincrement_subdetails[$v72] = $v71[$v72];
											}
										}
									}
								}
							}
							if (!empty($subdetail_data)) {
								foreach ($subdetail_data as $k5 => $v5) {
									$flag_subdetail_change_detected = false;
									// put pk into detail
									$subdetail = $subdetail_key_holder['parent_pks'];
									// process json_contains
									foreach ($subdetail_fields as $k30 => $v30) {
										if (empty($v30['options']['json_contains'])) continue;
										// get value, grab from neighbouring values first
										$value = $v5[$k30] ?? null;
										if (is_json($value)) {
											$value = json_decode($value, true);
											foreach ($v30['options']['json_contains'] as $k31 => $v31) {
												$v5[$v31] = $value[$k31] ?? null;
											}
										} else if (empty($value)) {
											foreach ($v30['options']['json_contains'] as $k31 => $v31) {
												$subdetail[$v31] = $v5[$v31] = null;
											}
										}
									}
									// process pk
									$this->generateDetailsPrimaryKey($subdetail_key_holder, 'pk', $v5, [$k, $k2, $k0], $v0);
									$subdetail_error_name = $subdetail_key_holder['error_name'];
									$k5 = $subdetail_key_holder['pk'];
									// process fields
									foreach ($subdetail_fields as $k6 => $v6) {
										// default data type
										if (empty($v6['options']['type'])) {
											$v6['options']['type'] = 'varchar';
										}
										// get value
										$value = $v5[$k6] ?? null;
										// validate data type
										$temp = $this->validateDataTypesSingleValue($k6, $v6, $value, "{$subdetail_error_name}[{$k6}]");
										if (empty($temp['flag_error'])) {
											if (empty($temp[$k6]) && !empty($temp[$k6 . '_is_serial'])) {
												// we do not create empty serial keys
												continue;
											} else {
												$value = $temp[$k6];
											}
										}
										// persistent
										if (!empty($v0['options']['details_11'])) {
											$subdetail_access_key = array_merge($detail_access_key, [$k0]);
										} else {
											$subdetail_access_key = array_merge($detail_access_key, [$k0, $k5]);
										}
										$original_values = array_key_get($this->original_values, array_merge($subdetail_access_key, [$k6]));
										if ($this->values_loaded && !empty($this->misc_settings['persistent']['subdetails'][$k][$k0][$k6]) && isset($original_values)) {
											// todo: handle if_set
											if (is_null($value)) {
												$value = $original_values;
											} else if ($value !== $original_values) {
												$this->error('danger', 'You are trying to change persistent field!', "{$subdetail_error_name}[{$k3}]");
											}
										}
										// default
										$default = null;
										if (array_key_exists('default', $v6['options'])) {
											$default = $this->processDefaultValue($k6, $v6['options']['default'], $value, $subdetail, false);
											if (strpos($v6['options']['default'], 'static::') !== false || is_null($value)) {
												$value = $default;
											}
										}
										// see if we changed the value
										if (!is_null($value) && $value !== $default) {
											$flag_subdetail_change_detected = true;
										}
										$subdetail[$k6] = $value;
									}
									// if we have a change
									if ($flag_subdetail_change_detected) {
										$flag_change_detected = true;
										if (!empty($v0['options']['details_11'])) {
											$detail[$k0] = $subdetail;
										} else {
											// autoincrement
											if (!empty($autoincrement_subdetails)) {
												foreach ($autoincrement_subdetails as $k71 => $v71) {
													if (empty($subdetail[$k71])) {
														$subdetail[$k71] = $v71 + 1;
														$autoincrement_subdetails[$k71]++;
													}
												}
											}
											$detail[$k0][$k5] = $subdetail;
										}
									}
								}
							}
						}
					}
					// if we have changes we puth them into values
					if ($flag_change_detected) {
						// 1 to 1
						if (!empty($v['options']['details_11'])) {
							$this->values[$k] = $detail;
						} else { // 1 to M
							// autoincrement
							if (!empty($autoincrement_details)) {
								foreach ($autoincrement_details as $k71 => $v71) {
									if (empty($detail[$k71])) {
										$detail[$k71] = $v71 + 1;
										$autoincrement_details[$k71]++;
									}
								}
							}
							$this->values[$k][$k2] = $detail;
						}
					}
				}
			}
			// we need to process not set details
			foreach ($input as $k => $v) {
				if (is_string($k) && $k[0] == '\\' && !in_array($k, array_keys($this->fields)) && !in_array($k, array_keys($this->detail_fields))) {
					$this->values[$k] = $input[$k];
				}
			}
		}
processAllValues:
		$this->triggerMethod('processAllValues');
		// debug
		//print_r2($this->values);
	}
348602
public static function result($object, $property)
    {
        $value = static::get($object, $property);

        if (static::isFunction($value)) {
            static::associate($value, $object);
            return $value();
        }

        return $value;
    }
3295
public static function object_get($object, $key, $default = null)
    {
        if (\is_null($key) || trim($key) === '') {
            return $object;
        }

        foreach (explode('.', $key) as $segment) {
            if (! \is_object($object) || ! isset($object->{$segment})) {
                return self::value($default);
            }

            $object = $object->{$segment};
        }

        return $object;
    }