Resolve a belongs to association

@param string $attr   attribute
@param mixed  $values values to use

@return association
343919
private function _resolveBelongsTo($attr, $values)
    {
        $cls = get_called_class();
        if (!array_key_exists($cls, self::$_belongs_to)
            || !array_key_exists($attr, self::$_belongs_to[$cls])
        ) {
            return null;
        }

        $configs       = self::$_belongs_to[$cls][$attr];
        $belongs_cls   = is_array($configs) && array_key_exists("class_name",  $configs) ? $configs["class_name"]  : ucfirst($attr);
        $belongs_key   = is_array($configs) && array_key_exists("foreign_key", $configs) ? $configs["foreign_key"] : strtolower($belongs_cls)."_id";
        $primary_key   = is_array($configs) && array_key_exists("primary_key", $configs) ? $configs["primary_key"] : "id";
        $value         = $values[$belongs_key];

        if (array_key_exists($attr, $this->_belongs_cache) && $this->_belongs_cache[$attr] && $this->_belongs_cache[$attr]->$primary_key == $value) {
            return $this->_belongs_cache[$attr];
        }

        $obj = $belongs_cls::first(array($primary_key => $value));

        if ($obj) {
            $this->_belongs_cache[$attr] = $obj;
        }
        return $obj;
    }
8792
public function setAttribute($attribute, $value){
        if($attribute === 'table'){
            $this->_table = $value;
        }
        elseif($attribute === 'pk'){
            $this->_pk = $value;
        }
        elseif($attribute === 'relations'){
            $this->_relations = $value;
        }
        
        return $this;
    }
239995
private function _resolveCollection($attr, $values)
    {
        $cls = get_called_class();

        if (!array_key_exists($cls, self::$_has_many_maps)) {
            return null;
        }

        $maps = array_values(self::$_has_many_maps[$cls]);
        if (!in_array($attr, $maps)) {
            return null;
        }

        if (!$values || !is_array($values) || sizeof($values)<1 || !is_object($values[0])) {
            return null;
        }

        $this->_has_many_ids = array();

        foreach ($values as $value) {
            $klass = get_class($value);
            $this->push($value);
            $id = $value->get($klass::getPK());
            if ($id) {
                array_push($this->_has_many_ids, $id);
            }
        }
        return $this->_has_many_ids;
    }
209537
private function _resolveHasOne($attr, $value)
    {
        $cls = get_called_class();
        if (!array_key_exists($cls, self::$_has_one)
            || !array_key_exists($attr, self::$_has_one[$cls])
        ) {
            return null;
        }

        if (array_key_exists($attr, $this->_has_one_cache) && $this->_has_one_cache[$attr]) {
            return $this->_has_one_cache[$attr];
        }

        $configs       = self::$_has_one[$cls][$attr];
        $has_one_cls   = is_array($configs) && array_key_exists("class_name", $configs)  ? $configs["class_name"]  : ucfirst(preg_replace('/s$/', "", $attr));
        $this_key      = is_array($configs) && array_key_exists("foreign_key", $configs) ? $configs["foreign_key"] : (self::isIgnoringCase() ? strtolower($cls)."_id" : $cls."_id");
        $obj           = $has_one_cls::first(array($this_key=>$value));

        if ($obj) {
            $this->_has_one_cache[$attr] = $obj;
        }
        return $obj;
    }
430852
public function attr($name, $value = null)
    {
        $attrs = (array) $this->getAttribute('attribs');

        if ($value === null) {
            return isset($attrs[$name]) ? $attrs[$name] : null;
        }

        $attrs[$name] = $value;

        $this->setAttribute('attribs', $attrs);

        return $this;
    }
984655
private function deleteFiles($attr)
    {
        $base = $this->getSavePath($attr);
        /* @var $model ActiveRecord */
        $model = $this->owner;
        if ($model->isNewRecord) {
            $value = $model->{$attr};
        } else {
            $value = $model->oldAttributes[$attr];
        }
        $file = $base . $value;

        if (is_file($file)) {
            unlink($file);
        }
    }
74149
public function resolve($resource, $attribute = null)
    {
        $attribute = $attribute ?? $this->attribute;

        $value = $resource->{$attribute} ?? null;

        $value = is_object($value) || is_array($value) ? $value : json_decode($value);

        $fields = $this->fields->whereInstanceOf(Resolvable::class)->reduce(function ($values, $field) {
            return $values->map(function ($row) use ($field) {
                $key = $field->attribute;
                $cb = $field->resolveCallback;

                if (isset($row->{$key})) {
                    $row->{$key} = $cb ? call_user_func($cb, $row->{$key}) : $row->{$key};
                }

                if (property_exists($field, 'computeCallback') && $field->computeCallback) {
                    $row->{$key} = call_user_func($field->computeCallback, $row);
                }

                return $row;
            });
        }, collect($value));

        if (!$this->resolveCallback) {
            $this->resolveCallback = function () use ($fields) {
                return $fields->toArray();
            };
        }

        $this->withMeta(['fields' => $this->fields]);

        parent::resolve($resource, $attribute);
    }
1340091
public function attr($name, $value = null){
        if(is_null($value)){
            return $this->getAttributeValue($name);
        }else{
            return $this->setAttribute($name, $value);
        }
    }
522116
public static function fromAttributeValues(AttributeValue ...$values): self
    {
        $attribs = array_map(
            function (AttributeValue $value) {
                return $value->toAttribute();
            }, $values);
        return new self(...$attribs);
    }
114915
private function _checkAndReturnBelongs($attr, $values)
    {
        $cls = get_called_class();
        if (array_key_exists($cls, self::$_belongs_to)
            && array_key_exists($attr, self::$_belongs_to[$cls])
        ) {
            return $this->_resolveBelongsTo($attr, $values);
        }
    }
1299162
public function allCategoryValues($values, $attribute = null)
    {
        $model = new $this->owner->modelClass();

        return $this->anyCategoryValues($values, $attribute)->andHaving(new Expression('COUNT(*) = ' . count($model->filterCategoryValues($values))));
    }
1050421
protected function resolveAttribute($resource, $attribute)
    {
        $this->setResourceId(data_get($resource, 'id'));
        return parent::resolveAttribute($resource, $attribute);
    }
275811
public function deleteAttribute($attr) {
        $url = "entities/{$this->_id}/attrs/$attr";

        if ($this->_type) {
            $url .= "?type={$this->_type}";
        }

        return $this->_orion->delete($url);
    }
1220135
protected function getAttrAlias(Attr $attr) {
		//check if join is already created
		$stringPath = $attr->getStringPath();
		if (array_key_exists($stringPath, $this->joins))
			return [$this->joins[$stringPath]->getAlias(), $this->joins[$stringPath]->getProfile()];
		
		//
		$path = $attr->getPath();
		$current = $this->profile;
		$parent = null;
		
		for ($i = 0; $i < count($path); $i++) {
			//build join name
			$joinPath = array_slice($path, 0, $i + 1);
			$name = implode('__', $joinPath);
			
			//check association
			if (!$current->hasAssociation($path[$i]))
				throw new \RuntimeException(sprintf("Association '%s' not found in class %s", $path[$i], $current->getReflectionClass()->getName()));
			
			//build join instance
			$association = $current->getAssociation($path[$i]);
			$related = Profiler::getClassProfile($association->getEntityClass());
			
			if (!array_key_exists($name, $this->joins))
				$this->joins[$name] = new Join($association, $related, $this->getJoinAlias(), $parent);
			
			//prepare next iteration
			$current = $related;
			$parent = $name;
		}
		
		return [$this->joins[$parent]->getAlias(), $this->joins[$parent]->getProfile()];
	}
693493
protected function add_autovalues(&$attrs)
    {
        if (empty($this->prop['autovalues'])) {
            return;
        }

        $attrvals = array();
        foreach ($attrs as $k => $v) {
            $attrvals['{'.$k.'}'] = is_array($v) ? $v[0] : $v;
        }

        foreach ((array)$this->prop['autovalues'] as $lf => $templ) {
            if (empty($attrs[$lf])) {
                if (strpos($templ, '(') !== false) {
                    // replace {attr} placeholders with (escaped!) attribute values to be safely eval'd
                    $code = preg_replace('/\{\w+\}/', '', strtr($templ, array_map('addslashes', $attrvals)));
                    $res  = false;

                    try {
                        $res = eval("return ($code);");
                    }
                    catch (ParseError $e) {
                        // ignore
                    }

                    if ($res === false) {
                        rcube::raise_error(array(
                            'code' => 505, 'file' => __FILE__, 'line' => __LINE__,
                            'message' => "Expression parse error on: ($code)"), true, false);
                        continue;
                    }

                    $attrs[$lf] = $res;
                }
                else {
                    // replace {attr} placeholders with concrete attribute values
                    $attrs[$lf] = preg_replace('/\{\w+\}/', '', strtr($templ, $attrvals));
                }
            }
        }
    }
610375
public function setModelDefaults($attr, $value = null)
    {
        if (is_array($attr))
            $this->modelDefaults = array_merge($this->modelDefaults, $attr);
        else
            $this->modelDefaults[$attr] = $value;

        return $this;
    }
461287
public function attr($attribute, $value)
    {
        $this->setOption(self::OPTION_METHOD, "attr");
        $this->setOption(self::OPTION_ATTR, $attribute);
        $this->setOption(self::OPTION_VALUE, $value);

        return $this;
    }