@param null|string|array $slugs
@param null|string|array $attributeIds
@param null|string|array $values meta values
@param null|string|array $locales

@return AttributeAvQuery
480088
protected static function queryAttributeAvs($slugs = null, $attributeIds = null, $values = null, $locales = null)
    {
        if (!is_array($slugs) && $slugs !== null) {
            $slugs = array($slugs);
        }

        if (!is_array($attributeIds) && $attributeIds !== null) {
            $attributeIds = array($attributeIds);
        }

        if (!is_array($values) && $values !== null) {
            $values = array($values);
        }

        if (!is_array($locales) && $locales !== null) {
            $locales = array($locales);
        }

        $query = AttributeAvQuery::create();

        if ($attributeIds !== null) {
            $query->filterByAttributeId($attributeIds, Criteria::IN);
        }

        self::addJoinAttributeTypeAvMeta($query);
        self::addJoinAttributeAttributeType($query);
        self::addJoinAttributeType($query);

        if ($locales !== null) {
            $query->addJoinCondition(
                'attribute_type_av_meta',
                "`attribute_type_av_meta`.`LOCALE` IN (" . self::formatStringsForIn($locales) . ")"
            );
        }

        if ($values !== null) {
            $query->addJoinCondition(
                'attribute_type_av_meta',
                "`attribute_type_av_meta`.`VALUE` IN (" . self::formatStringsForIn($values) . ")"
            );
        }

        if ($slugs !== null) {
            $query->addJoinCondition(
                'attribute_type',
                "`attribute_type`.`SLUG` IN (" . self::formatStringsForIn($slugs) . ")"
            );
        }

        return $query;
    }
823256
public function createAttributeValue(Attribute $attribute, $value, $locale)
    {
        $attributeValue = $this->attributeValueRepository->createNew();
        $attributeValue->setAttribute($attribute);
        $this->entityManager->persist($attributeValue);
        $attribute->addValue($attributeValue);
        $this->setOrCreateAttributeValueTranslation($attributeValue, $value, $locale);

        return $attributeValue;
    }
198108
private function setVarStartHandler(array $attrs): void
    {
        if (empty($attrs['name'])) {
            throw new DomainException('REPORT ERROR var: The attribute "name" is missing or not set in the XML file');
        }

        $name  = $attrs['name'];
        $value = $attrs['value'];
        $match = [];
        // Current GEDCOM record strings
        if ($value === '@ID') {
            if (preg_match('/0 @(.+)@/', $this->gedrec, $match)) {
                $value = $match[1];
            }
        } elseif ($value === '@fact') {
            $value = $this->fact;
        } elseif ($value === '@desc') {
            $value = $this->desc;
        } elseif ($value === '@generation') {
            $value = (string) $this->generation;
        } elseif (preg_match("/@(\w+)/", $value, $match)) {
            $gmatch = [];
            if (preg_match("/\d $match[1] (.+)/", $this->gedrec, $gmatch)) {
                $value = str_replace('@', '', trim($gmatch[1]));
            }
        }
        if (preg_match("/\\$(\w+)/", $name, $match)) {
            $name = $this->vars["'" . $match[1] . "'"]['id'];
        }
        $count = preg_match_all("/\\$(\w+)/", $value, $match, PREG_SET_ORDER);
        $i     = 0;
        while ($i < $count) {
            $t     = $this->vars[$match[$i][1]]['id'];
            $value = preg_replace('/\$' . $match[$i][1] . '/', $t, $value, 1);
            $i++;
        }
        if (preg_match('/^I18N::number\((.+)\)$/', $value, $match)) {
            $value = I18N::number((int) $match[1]);
        } elseif (preg_match('/^I18N::translate\(\'(.+)\'\)$/', $value, $match)) {
            $value = I18N::translate($match[1]);
        } elseif (preg_match('/^I18N::translateContext\(\'(.+)\', *\'(.+)\'\)$/', $value, $match)) {
            $value = I18N::translateContext($match[1], $match[2]);
        }

        // Arithmetic functions
        if (preg_match("/(\d+)\s*([\-\+\*\/])\s*(\d+)/", $value, $match)) {
            // Create an expression language with the functions used by our reports.
            $expression_provider  = new ReportExpressionLanguageProvider();
            $expression_cache     = new NullAdapter();
            $expression_language  = new ExpressionLanguage($expression_cache, [$expression_provider]);

            $value = (string) $expression_language->evaluate($value);
        }

        if (strpos($value, '@') !== false) {
            $value = '';
        }
        $this->vars[$name]['id'] = $value;
    }
258712
public function getAttributes(array $attribute_names = [], array $types = [])
    {
        $attribute_map = [];

        if (empty($attribute_names)) {
            $attribute_map = $this->attribute_map->getItems();
        } else {
            foreach ($attribute_names as $attribute_name) {
                $attribute_map[$attribute_name] = $this->getAttribute($attribute_name);
            }
        }

        if (!empty($types)) {
            $attribute_map = array_filter(
                $attribute_map,
                function ($attribute) use ($types) {
                    return in_array(get_class($attribute), $types);
                }
            );
        }

        return new AttributeMap($attribute_map);
    }
1021420
public static function findBySlug($slug, $locale = null)
    {
        /** @var \Dimsav\Translatable\Translatable $model */
        $model = (new static);

        /** @var SluggableTrait $translationModel */
        $translationModel = $model->getTranslationModelName();
        $parentKey        = $model->getRelationKey();

        $translationInstance = $translationModel::findBySlug($slug, $locale);

        if (empty($translationInstance)) return null;

        return static::find($translationInstance->{$parentKey});
    }
148593
public function findRecordIdForSlugFromCmsTable($slug, $locale = null, $limitToLanguage = false)
    {
        /** @var CmsModel|SluggableTrait $this */

        $existing = DB::table(static::$slugsTable)
            ->select([ static::$slugsEntryKey . ' as entry' ])
            ->where(static::$slugsModuleKey, $this->getModuleNumber())
            ->where(static::$slugsColumn, $slug);

        if ($locale || $limitToLanguage) {

            if ($locale) {
                $existing->where(static::$slugsLanguageKey, $this->lookUpLanguageIdForLocale($locale));
            } else {
                $existing->where(static::$slugsLanguageKey, $this->storeSlugForLanguageId());
            }
        }

        $existing = $existing->orderBy('id', 'asc')
                             ->limit(1)
                             ->first();

        if (empty($existing)) return null;

        return $existing->entry;
    }
993746
public function updateAttributes(array $attrs) {
        $url = "entities/{$this->_id}/attrs";

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

        $updateEntity = new ContextFactory($attrs);
        return $this->_orion->patch($url, $updateEntity);
    }
673292
protected function augmentDatabaseRequireTable($localisedTable, $fields, $indexes)
    {
        DB::require_table($localisedTable, $fields, $indexes, false);
    }
1340547
private function languageCompareAgainstSupportedLocales(array $aggregatedValues)
    {
        foreach ($aggregatedValues as $locale => $attributes) {
            if ('*' === $locale) {
                continue;
            }

            $localeParts = explode('-', $locale);
            if (2 !== count($localeParts)) {
                continue;
            }

            $language = $localeParts[0];

            if (in_array($language, $this->supportedLocales, true)) {
                return new NegotiatedValue($language, $attributes);
            }
        }

        return null;
    }
473538
public function allLanguageValues($values, $attribute = null)
    {
        $model = new $this->owner->modelClass();

        return $this->anyLanguageValues($values, $attribute)->andHaving(new Expression('COUNT(*) = ' . count($model->filterLanguageValues($values))));
    }
1244940
public function fill(array $attributes) {
        $locales = Locale\get_locales();

        foreach($locales as $locale => $options)
            if( in_array($locale, array_keys($attributes)) )
                $this->translations[$locale] = array_pull($attributes, $locale);

        return parent::fill($attributes);
    }
1023317
public function getItems($attributes, $values, $firstonly = false)
	{
		$attributes = (array) $attributes;
		$values     = (array) $values;

		// Filter by language if not set
		if (($key = array_search('language', $attributes)) === false)
		{
			if ($this->get('language_filter'))
			{
				$attributes[] = 'language';
				$values[]     = array($this->get('language'), '*');
			}
		}
		elseif ($values[$key] === null)
		{
			unset($attributes[$key]);
			unset($values[$key]);
		}

		// Filter by access level if not set
		if (($key = array_search('access', $attributes)) === false)
		{
			$attributes[] = 'access';
			$values[]     = $this->get('access');
		}
		elseif ($values[$key] === null)
		{
			unset($attributes[$key]);
			unset($values[$key]);
		}

		return parent::getItems($attributes, $values, $firstonly);
	}
1190822
protected function createAttachRecords($ids, array $attributes)
    {
        $records = [];

        $timed = in_array($this->createdAt(), $this->pivotColumns);

        // To create the attachment records, we will simply spin through the IDs given
        // and create a new record to insert for each ID. Each ID may actually be a
        // key in the array, with extra attributes to be placed in other columns.
        foreach ($ids as $key => $value) {
            $records[] = $this->attacher($key, $value, $attributes, $timed);
        }

        return $records;
    }
313672
private function retrieveAttributeValueTranslationByLocale(AttributeValue $attributeValue, $locale)
    {
        foreach ($attributeValue->getTranslations() as $attributeValueTranslation) {
            if ($attributeValueTranslation->getLocale() === $locale) {
                return $attributeValueTranslation;
            }
        }

        return null;
    }
903211
public function valuesFor($attributeNames)
	{
		$filter = array();

		foreach ($attributeNames as $name)
			$filter[$name] = $this->$name;

		return $filter;
	}
1031627
private function getSlugParts(int $categoryId, string $locale): array
    {
        $category = $this->repo->getCategoriesPlain()->where('id', $categoryId)->first();
        $slugParts = [];

        if (!$category) {
            // Try to fetch from DB
            $category = Category::find($categoryId);

            if (!$category) {
                return [];
            }

            $category = [
                'id'        => $category->id,
                'parent_id' => $category->parent_id,
                'slugs'     => $category->translations->pluck('slug', 'locale')->toArray(),
            ];
        }

        $slugParts[] = array_get($category, 'slugs.' . $locale);

        if (isset($category['parent_id']) && $category['parent_id']) {
            $slugParts = array_merge($slugParts, $this->getSlugParts($category['parent_id'], $locale));
        }

        return $slugParts;
    }
764065
public function count(array $locales = null,  array $filters = null)
    {
        $query = TransUnitQuery::create()
            ->select('Id')
            ->distinct()
        ;

        $this->addTransUnitFilters($query, $filters);
        $this->addTranslationFilter($query, $locales, $filters);

        return $query->count($this->getConnection());
    }