@param ITableStructure $structure
@param array           $array

@return ITableRow[]
@throws InvalidArgumentException
333156
private function buildNormalizedRows(ITableStructure $structure, array $array) : array
    {
        $columns           = $structure->getColumns();
        $columnNames       = $structure->getColumnNames();
        $componentNamesMap = [];

        foreach ($columns as $column) {
            $componentNames = $column->getComponentNames();
            sort($componentNames);
            $componentNamesMap[$column->getName()] = $componentNames;
        }

        sort($columnNames);
        $rows = [];

        foreach ($array as $rowData) {
            $rowColumns = array_keys($rowData);
            sort($rowColumns);

            if ($columnNames !== $rowColumns) {
                throw InvalidArgumentException::format(
                    'Invalid row array: expecting columns names to be (%s), (%s) given',
                    Debug::formatValues($columnNames), Debug::formatValues($rowColumns)
                );
            }

            foreach ($rowData as $columnName => $componentData) {
                $column = $columns[$columnName];

                if (!is_array($componentData)) {
                    if ($column->hasSingleComponent()) {
                        $component            = $column->getComponent();
                        $rowData[$columnName] = [$component->getName() => $componentData];
                    } else {
                        throw InvalidArgumentException::format(
                            'Invalid row array: expecting columns data for column %s to be array, %s given',
                            $columnName, Debug::getType($componentData)
                        );
                    }
                } else {
                    $componentNames = array_keys($componentData);
                    sort($componentNames);

                    if ($componentNames !== $componentNamesMap[$columnName]) {
                        throw InvalidArgumentException::format(
                            'Invalid row array: expecting columns data for column %s to have be array with keys (%s), (%s) given',
                            $columnName, Debug::formatValues($componentNamesMap[$columnName]), Debug::formatValues($componentNames)
                        );
                    }
                }
            }

            $rows[] = new TableRow($rowData);
        }

        return $rows;
    }
1240716
public function save( & $structure )
    {
        if ( is_object( $structure ) )
        {
            $section    = $structure->section;
            $settings   = (array) $structure->settings;
        }
        else if ( is_array( $structure ) )
        {
            $section    = $structure['section'];
            $settings   = (array) $structure['settings'];
        }
        else
        {
            return 0;
        }

        $rows   = 0;
        $set    = array();
        $rem    = array();
        $def    = $this->getDefinitions();
        $elems  = $def->getElements( $section );
        $fields = $def->getFieldsets( $section );

        if ( ! empty( $fields ) && ! empty( $settings ) )
        {
            foreach ( $fields as $name => $fieldset )
            {
                if ( isset( $settings[$name] ) )
                {
                    if ( $settings[$name] instanceof StructureAbstract )
                    {
                        $fieldsetSettings = $settings[$name]->settings;
                    }
                    else if ( is_array( $settings[$name] ) )
                    {
                        if ( array_key_exists( 'settings', $settings[$name] ) )
                        {
                            $fieldsetSettings = $settings[$name]['settings'];
                        }
                        else
                        {
                            $fieldsetSettings = $settings[$name];
                        }
                    }
                    else
                    {
                        continue;
                    }

                    $subSection = array(
                        'section'   => $fieldset,
                        'settings'  => $fieldsetSettings,
                    );

                    $rows += $this->save( $subSection );
                }
            }
        }

        if ( ! empty( $elems ) && ! empty( $settings ) )
        {
            foreach ( $elems as $name => $spec )
            {
                if ( isset( $settings[$name] ) )
                {
                    if ( is_scalar( $settings[$name] ) )
                    {
                        $set[$spec['key']] = array(
                            'value' => $settings[$name],
                            'type'  => empty( $spec['type'] )
                                    ? 'ini' : $spec['type'],
                        );
                    }
                    else
                    {
                        $rem[] = $spec['key'];
                        foreach ( $settings[$name] as $index => $value )
                        {
                            $set[$spec['key'] . '.' . $index] = array(
                                'value' => $value,
                                'type'  => empty( $spec['type'] )
                                        ? 'ini' : $spec['type'],
                            );
                        }
                    }
                }
                else
                {
                    $rem[] = $spec['key'];
                }
            }
        }

        $connection = $this->getDbAdapter()
                           ->getDriver()
                           ->getConnection();

        $connection->beginTransaction();

        try
        {
            if ( ! empty( $rem ) )
            {
                $delete = $this->sql()
                               ->delete()
                               ->where( $this->keysWhere( $rem ) );

                $result = $this->sql()
                               ->prepareStatementForSqlObject( $delete )
                               ->execute();

                $rows += $result->getAffectedRows();
            }

            foreach ( $set as $key => $spec )
            {
                $type  = $spec['type'];
                $value = $spec['value'];

                $update = $this->sql()
                               ->update()
                               ->set( array(
                                   'value'  => $value,
                               ) )
                               ->where( array(
                                   'key'    => $key,
                                   'type'   => $type,
                               ) );

                $result = $this->sql()
                               ->prepareStatementForSqlObject( $update )
                               ->execute();

                $updateRows = $result->getAffectedRows();

                if ( $updateRows )
                {
                    $rows += $updateRows;
                }
                else
                {
                    $insert = $this->sql()
                                   ->insert()
                                   ->values( array(
                                       'key'    => $key,
                                       'type'   => $type,
                                       'value'  => $value,
                                   ) );

                    $result = $this->sql()
                                   ->prepareStatementForSqlObject( $insert )
                                   ->execute();

                    $rows += $result->getAffectedRows();
                }
            }

            $connection->commit();
        }
        catch ( \Exception $ex )
        {
            $connection->rollback();
            throw $ex;
        }

        return $rows;
    }
1128693
public function push(array $array, $element): array
    {
        $elements = func_get_args();
        array_shift($elements);
        foreach ($elements as $element) {
            array_push($array, $element);
        }
        return $array;
    }
995542
private function prepareStructure($structure)
    {
        $newStructure = [];
        foreach ($structure as $path => $element) {
            $position = &$newStructure;
            foreach (explode('/', $path) as $part) {
                $position[$part] = [];
                $position = &$position[$part];
            }
            $position = strpos($path, DIRECTORY_SEPARATOR) === false ? [] : $position;
            $position = is_array($element) ? $this->prepareStructure($element) : (string) $element;
        }
        return $newStructure;
    }
1353313
public function save( &$structure )
    {
        if ( is_object( $structure ) )
        {
            $data = $structure;
        }
        else if ( is_array( $structure ) )
        {
            $data = (object) $structure;
        }
        else
        {
            return 0;
        }

        $result = 0;
        $rootId = isset( $data->rootId )        ? (int) $data->rootId   : null;
        $rules  = isset( $data->rules )         ? (array) $data->rules  : null;
        $extra  = isset( $data->extraContent )  ? $data->extraContent   : null;

        $result += $this->saveRules( $rootId ?: null, $rules );
        $result += $this->saveExtra( $rootId ?: null, $extra );
        return $result;
    }
1290980
private function createStructureNodes(\DOMDocument $dom, ElementStructure $structure)
    {
        $structureNode = $dom->createElement('structure');

        $idAttr = $dom->createAttribute('id');
        $idAttr->value = $structure->getId();
        $structureNode->appendChild($idAttr);

        $dsIdAttr = $dom->createAttribute('dsId');
        $dsIdAttr->value = $structure->getDsId();
        $structureNode->appendChild($dsIdAttr);

        $parentDsIdAttr = $dom->createAttribute('parentDsId');
        $parentDsIdAttr->value = $structure->getDsId();
        $structureNode->appendChild($parentDsIdAttr);

        $nameAttr = $dom->createAttribute('name');
        $nameAttr->value = $structure->getName();
        $structureNode->appendChild($nameAttr);

        $parentNameAttr = $dom->createAttribute('parentName');
        $parentNameAttr->value = $structure->getParentName();
        $structureNode->appendChild($parentNameAttr);

        foreach ($structure->getStructures() as $childStructure) {
            $structureNode->appendChild(
                $this->createStructureNodes($dom, $childStructure)
            );
        }

        foreach ($structure->getValues() as $value) {
            $valueNode = $dom->createElement('value');

            $idAttr = $dom->createAttribute('id');
            $idAttr->value = $value->getId();
            $valueNode->appendChild($idAttr);

            $dsIdAttr = $dom->createAttribute('dsId');
            $dsIdAttr->value = $value->getDsId();
            $valueNode->appendChild($dsIdAttr);

            $languageAttr = $dom->createAttribute('language');
            $languageAttr->value = $value->getLanguage();
            $valueNode->appendChild($languageAttr);

            $nameAttr = $dom->createAttribute('name');
            $nameAttr->value = $value->getName();
            $valueNode->appendChild($nameAttr);

            $typeAttr = $dom->createAttribute('type');
            $typeAttr->value = $value->getType();
            $valueNode->appendChild($typeAttr);

            $dataTypeAttr = $dom->createAttribute('dataType');
            $dataTypeAttr->value = $value->getDataType();
            $valueNode->appendChild($dataTypeAttr);

            $rawValue = $value->getValue();
            if ($value->getDataType() === 'array') {
                $rawValue = json_encode($rawValue);
            }
            $valueNode->appendChild($dom->createCDATASection($rawValue));

            $structureNode->appendChild($valueNode);
        }

        return $structureNode;
    }
1116978
private function buildSelectForStructure($locale, StructureInterface $structure, &$names)
    {
        $nodeNameProperty = $structure->getProperty('title');
        $result = '';

        $name = $this->getTranslatedProperty($nodeNameProperty, $locale)->getName();
        if (!in_array($name, $names)) {
            $names[] = $name;
            $result .= ', ' . $this->buildSelector($name);
        }

        if ($structure->hasTag('sulu.rlp')) {
            $urlProperty = $structure->getPropertyByTagName('sulu.rlp');
            $name = $this->getTranslatedProperty($urlProperty, $locale)->getName();

            if ('resource_locator' !== $urlProperty->getContentTypeName() && !in_array($name, $names)) {
                $names[] = $name;
                $result .= ', ' . $this->buildSelector($name);
            }
        }

        return $result;
    }
744410
public static function columns($array, string $key): array
    {
        if (! Assert::array($array)) {
            throw new InvalidArgumentException(
                '`Arr::columns` first parameter must be `array` or implements interface `ArrayAccess`'
            );
        }

        if (empty($array)) {
            return [];
        }

        $columns = [];

        foreach ($array as $item) {
            if (self::exists($item, $key)) {
                $columns[] = $item[$key];
            }
        }

        return $columns;
    }
467613
public function hydrate( array $data, $structure )
    {
        if ( ! empty( $data['file'] ) )
        {
            if ( ! empty( $data['file']['tmp_name'] ) )
            {
                $data['name'] = $data['file']['name'];
                $data['code'] = @ file_get_contents( $data['file']['tmp_name'] );
                @ unlink( $data['file']['tmp_name'] );
            }

            unset( $data['file'] );
        }

        if ( ! empty( $data['type'] ) )
        {
            $data['name'] .= '.' . $data['type'];
            unset( $data['type'] );
        }

        if ( $structure instanceof StructureAbstract )
        {
            $structure->setOptions( $data );
        }
        else
        {
            foreach ( $data as $key => $value )
            {
                $structure->$key = $value;
            }
        }

        if ( $structure instanceof MapperAwareInterface )
        {
            $structure->setMapper( $this );
        }

        return $structure;
    }
1304357
public function hydrate( array $data, $structure )
    {
        if ( $structure instanceof Structure )
        {
            $structure->setOptions( $data );
        }
        else
        {
            foreach ( $data as $key => $value )
            {
                $structure->$key = $value;
            }
        }

        if ( $structure instanceof MapperAwareInterface )
        {
            $structure->setMapper( $this );
        }

        return $structure;
    }
34367
public function getCreateStructureSQL($xmldb_structure) {
        $results = array();

        if ($tables = $xmldb_structure->getTables()) {
            foreach ($tables as $table) {
                $results = array_merge($results, $this->getCreateTableSQL($table));
            }
        }

        return $results;
    }
753305
private function includeAndParseFiles($structure, $rootDir)
    {
        if (\is_array($structure)) {
            $result = [];
            foreach ($structure as $key => $structureElement) {
                $result[$key] = $this->includeAndParseFiles($structureElement, $rootDir);
            }

            return $result;
        }

        if ($structure instanceof TaggedValue && $structure->getTag() === 'include') {
            return $this->loadAndParseFile($structure->getValue(), $rootDir);
        }

        if (\strpos($structure, '!include') === 0) {
            return $this->loadAndParseFile(\str_replace('!include ', '', $structure), $rootDir);
        }

        return $structure;
    }
1306342
private function formatThrowableObjects(array $array)
    {
        array_walk_recursive($array, function (&$value) {
            if ($value instanceof \Throwable) {
                try {
                    $value = serialize($value);
                } catch (\Throwable $throwable) {
                    $value = $this->formatThrowable($value);
                }
            }
        });

        return $array;
    }
187844
private function resolveContent(StructureInterface $structure, array $data)
    {
        $structure->setWebspaceKey($this->getWebspaceKey());

        $content = [];
        foreach ($structure->getProperties(true) as $child) {
            if (array_key_exists($child->getName(), $data)) {
                $child->setValue($data[$child->getName()]);
            }

            $contentType = $this->contentTypeManager->get($child->getContentTypeName());
            $content[$child->getName()] = $contentType->getContentData($child);
        }

        return $content;
    }
196951
protected function validateCollectionTypeValue(array $structure, $value) : bool
    {
        $r = false;


        if ($structure["dataType"] === "type") {
            $nullable = (strpos($structure["structureType"], "nullable") === 0);


            if ($nullable === true && $value === null) {
                $r = true;
            } else {
                switch ($structure["internalStructure"]) {
                    case "mixed":
                        $r = true;
                        break;

                    case "?bool":
                    case "bool":
                        $r = (is_bool($value) === true);
                        break;

                    case "?int":
                    case "int":
                        $r = (is_int($value) === true);
                        break;

                    case "?float":
                    case "float":
                        $r = (is_float($value) === true);
                        break;

                    case "?string":
                    case "string":
                        $r = (is_string($value) === true);
                        break;

                    default:
                        $cname = $structure["internalStructure"];
                        $r = (is_a($value, $cname) === true || in_array($cname, class_implements($value)) === true);
                        break;
                }

                if ($r === false) {
                    $this->messageInvalidValue = "Invalid given value. Expected \"" . $this->collectionType . "\" .";
                }
            }
        } else {
            if ($structure["dataType"] === "array-of-types") {
                if (strpos($structure["structureType"], "nullable") === 0 && $value === null) {
                    $r = true;
                } elseif (is_array($value) === true && $this->isAssoc($value) === false) {
                    $childModels = $structure["childModel"];

                    foreach ($value as $i => $v) {
                        $r = $this->validateCollectionTypeValue($childModels[$i], $v);
                        if ($r === false) {
                            break;
                        }
                    }
                }
            } elseif ($structure["dataType"] === "array-assoc") {
                if (strpos($structure["structureType"], "nullable") === 0 && $value === null) {
                    $r = true;
                } elseif ($this->isAssoc($value) === true) {
                    $childModels = $structure["childModel"];
                    $key = array_keys($value)[0];
                    $val = $value[$key];

                    if (strpos($structure["structureType"], "nullable") === 0 && $val === null) {
                        $r = true;
                    } else {
                        $r = ($this->validateCollectionTypeValue($childModels[0], $key) === true &&
                            $this->validateCollectionTypeValue($childModels[1], $val) === true);
                    }
                }
            }
        }


        return $r;
    }
1180920
public function select($struct): array
    {
        $struct = $this->struct($struct);

        $map = [];
        $table = $this->getTable($struct);
        \preg_match('/(?<table>\w+)\s*\((?<alias>\w+)\)/i', $table, $tableMatch);

        if (isset($tableMatch['table'], $tableMatch['alias'])) {
            $table = $this->tableQuote($tableMatch['table']);
            $tableQuery = $table . ' AS ' . $this->tableQuote($tableMatch['alias']);
        } else {
            $table = $this->tableQuote($table);
            $tableQuery = $table;
        }

        $join = $struct[SQL::JOIN] ?? null;
        $joinKey = \is_array($join) ? \array_keys($join) : null;

        if (!empty($joinKey[0]) && $joinKey[0][0] === '[') {
            $tableJoin = [];

            static $joinArray = [
                '>' => 'LEFT',
                '<' => 'RIGHT',
                '<>' => 'FULL',
                '><' => 'INNER',
            ];

            $quote = $this->quote;

            foreach ($join as $sub => $relation) {
                \preg_match('/(\[(?<join>\<\>?|\>\<?)\])?(?<table>\w+)\s?(\((?<alias>\w+)\))?/',
                    $sub, $match);

                if ($match['join'] !== '' && $match['table'] !== '') {
                    if (\is_string($relation)) {
                        $relation = 'USING (' . $quote . $relation . $quote . ')';
                    }

                    if (\is_array($relation)) {
                        // For ['column1', 'column2']
                        if (isset($relation[0])) {
                            $relation = 'USING (' . $quote . \implode($quote . ', ' . $quote, $relation) . $quote . ')';
                        } else {
                            $joins = [];

                            foreach ($relation as $key => $value) {
                                $joins[] = (
                                    \strpos($key, '.') > 0 ?
                                        // For ['tableB.column' => 'column']
                                        $this->columnQuote($key) :

                                        // For ['column1' => 'column2']
                                        $table . '.' . $quote . $key . $quote
                                    ) .
                                    ' = ' .
                                    $this->tableQuote($match['alias'] ?? $match['table']) . '.' . $quote . $value . $quote;
                            }

                            $relation = 'ON ' . \implode(' AND ', $joins);
                        }
                    }

                    $tableName = $this->tableQuote($match['table']) . ' ';

                    if (isset($match['alias'])) {
                        $tableName .= 'AS ' . $this->tableQuote($match['alias']) . ' ';
                    }

                    $tableJoin[] = $joinArray[$match['join']] . ' JOIN ' . $tableName . $relation;
                }
            }

            $tableQuery .= ' ' . \implode(' ', $tableJoin);
        }

        $columns = $this->getColumns($struct);
        if (isset($struct[SQL::FUN])) {
            $fn = $struct[SQL::FUN];
            if ($fn === 1 || $fn === '1') {
                $column = '1';
            } else {
                $column = $fn . '(' . $this->columnPush($columns, $map) . ')';
            }
        } else {
            $column = $this->columnPush($columns, $map);
        }

        $sql = 'SELECT ' . $column . ' FROM ' . $tableQuery . $this->suffixClause($struct, $map);

        return [$sql, $map];
    }
937803
protected function structure_charset($structure)
    {
        while (is_array($structure)) {
            if (is_array($structure[2]) && $structure[2][0] == 'charset') {
                return $structure[2][1];
            }
            $structure = $structure[0];
        }
    }