@param StructureInterface $structure
@param array $parts
@param string $separator default '-'

@return string
489479
private function implodeRlpParts(StructureInterface $structure, array $parts, $separator = '-')
    {
        $title = '';
        // concat rlp parts in sort of priority
        foreach ($structure->getPropertiesByTagName('sulu.rlp.part') as $property) {
            if (array_key_exists($property->getName(), $parts)) {
                $title = $parts[$property->getName()] . $separator . $title;
            }
        }
        $title = substr($title, 0, -1);

        return $title;
    }
477627
public function getJoinedMessage($separator = "\n")
    {
        $messages = $this->getDetailMessages();
        $array = array();
        foreach ($messages as $rules) {
            foreach ($rules as $options) {
                foreach ($options as $message) {
                    $array[] = $message;
                }
            }
        }
        return implode($separator, array_unique($array));
    }
1335470
public static function readableFor($value, string $separator = '; '): string
    {
        if (!static::accepts($value)) {
            throw new InvalidValueException($value, static::class);
        }
        if ($value === self::NONE) {
            return static::readableForNone();
        }

        $humanRepresentations = static::readables();

        if (isset($humanRepresentations[$value])) {
            return $humanRepresentations[$value];
        }

        $parts = [];

        foreach ($humanRepresentations as $flag => $readableValue) {
            if ($flag === ($flag & $value)) {
                $parts[] = $readableValue;
            }
        }

        return implode($separator, $parts);
    }
1180703
public function getOutlineNumber($separator='.', $includeRoot=true)
    {
        if($this->outlineNumbers === null)
        {
            $numbers = array(1);

            if(!$this->isRoot())
            {
                $ancestors = $this->getAncestors();
                $root = $ancestors[0];

                $rootDescendants = $root->getDescendants(count($ancestors));

                $siblingNumber = 1;
                $level = 1;
                $pathLevel = 1;
                $stack = array();
                foreach($rootDescendants as $wrapper)
                {
                    $parent = end($stack);
                    while($parent && $wrapper->getLeftValue() > $parent->getRightValue())
                    {
                        array_pop($stack);
                        $parent = end($stack);
                        $level--;
                    }

                    if($wrapper->getLeftValue() <= $this->getLeftValue() && $wrapper->getRightValue() >= $this->getRightValue())
                    {
                        // On path

                        if($wrapper->isEqualTo($this))
                        {
                            $numbers[] = $siblingNumber;
                            break;
                        }
                        else if($wrapper->isEqualTo($ancestors[$pathLevel]))
                        {
                            $numbers[] = $siblingNumber;
                            $siblingNumber = 1;
                            $pathLevel++;
                        }
                    }
                    else if($pathLevel == $level)
                    {
                        $siblingNumber++;
                    }

                    if($wrapper->hasChildren())
                    {
                        array_push($stack, $wrapper);
                        $level++;
                    }
                }
            }

            $this->outlineNumbers = $numbers;
        }

        if($includeRoot === false)
        {
            return implode(array_slice($this->outlineNumbers, 1), $separator);
        }

        return implode($this->outlineNumbers, $separator);
    }
79274
protected function selectmultiple_button(structure $structure) {
        $buttonoptions = array(
            'type'  => 'button',
            'name'  => 'selectmultiple',
            'id'    => 'selectmultiplecommand',
            'value' => get_string('selectmultipleitems', 'quiz'),
            'class' => 'btn btn-secondary mb-1'
        );
        if (!$structure->can_be_edited()) {
            $buttonoptions['disabled'] = 'disabled';
        }

        return html_writer::tag('button', get_string('selectmultipleitems', 'quiz'), $buttonoptions);
    }
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];
        }
    }
523322
protected function makeParametersDDL($separator = " ")
    {
        $params = [];

        foreach ($this->parameters as $parameter) {
            $params[] = $parameter->getDDL();
        }

        return implode(',' . $separator, $params);
    }
44913
private function fetchStructure($structure, $partNumber = null) {
        $this->client->openFolder($this->folder_path);

        if ($structure->type == IMAP::MESSAGE_TYPE_TEXT &&
            ($structure->ifdisposition == 0 ||
                ($structure->ifdisposition == 1 && !isset($structure->parts) && $partNumber == null)
            )
        ) {
            if ($structure->subtype == "PLAIN") {
                if (!$partNumber) {
                    $partNumber = 1;
                }

                $encoding = $this->getEncoding($structure);

                $content = imap_fetchbody($this->client->getConnection(), $this->uid, $partNumber, $this->fetch_options | IMAP::FT_UID);
                $content = $this->decodeString($content, $structure->encoding);

                // We don't need to do convertEncoding() if charset is ASCII (us-ascii):
                //     ASCII is a subset of UTF-8, so all ASCII files are already UTF-8 encoded
                //     https://stackoverflow.com/a/11303410
                //
                // us-ascii is the same as ASCII:
                //     ASCII is the traditional name for the encoding system; the Internet Assigned Numbers Authority (IANA)
                //     prefers the updated name US-ASCII, which clarifies that this system was developed in the US and
                //     based on the typographical symbols predominantly in use there.
                //     https://en.wikipedia.org/wiki/ASCII
                //
                // convertEncoding() function basically means convertToUtf8(), so when we convert ASCII string into UTF-8 it gets broken.
                if ($encoding != 'us-ascii') {
                    $content = $this->convertEncoding($content, $encoding);
                }

                $body = new \stdClass;
                $body->type = "text";
                $body->content = $content;

                $this->bodies['text'] = $body;

                $this->fetchAttachment($structure, $partNumber);

            } elseif ($structure->subtype == "HTML") {
                if (!$partNumber) {
                    $partNumber = 1;
                }

                $encoding = $this->getEncoding($structure);

                $content = imap_fetchbody($this->client->getConnection(), $this->uid, $partNumber, $this->fetch_options | IMAP::FT_UID);
                $content = $this->decodeString($content, $structure->encoding);
                if ($encoding != 'us-ascii') {
                    $content = $this->convertEncoding($content, $encoding);
                }

                $body = new \stdClass;
                $body->type = "html";
                $body->content = $content;

                $this->bodies['html'] = $body;
            }
        } elseif ($structure->type == IMAP::MESSAGE_TYPE_MULTIPART) {
            foreach ($structure->parts as $index => $subStruct) {
                $prefix = "";
                if ($partNumber) {
                    $prefix = $partNumber.".";
                }
                $this->fetchStructure($subStruct, $prefix.($index + 1));
            }
        } else {
            if ($this->getFetchAttachmentOption() === true) {
                $this->fetchAttachment($structure, $partNumber);
            }
        }
    }
885032
public function buildClassMethods(StructureInterface $structure, TypeInterface $source_type, TypeInterface $target_type, array &$result)
    {
        $namespace = $structure->getNamespace();

        if ($namespace) {
            $namespace = '\\' . ltrim($namespace, '\\');
        }

        $target_instance_class = $namespace . '\\' . Inflector::classify(Inflector::singularize($target_type->getName()));

        $classified_association_name = Inflector::classify($this->getName());

        $getter_name = "get{$classified_association_name}";
        $setter_name = "set{$classified_association_name}";
        $fk_getter_name = "get{$classified_association_name}Id";
        $fk_setter_name = "set{$classified_association_name}Id";

        $result[] = '';
        $result[] = '    /**';
        $result[] = '     * Return ' . Inflector::singularize($source_type->getName()) . ' ' . $this->getName() . '.';
        $result[] = '     *';
        $result[] = '     * @return ' . $target_instance_class;
        $result[] = '     */';
        $result[] = '    public function ' . $getter_name . '()';
        $result[] = '    {';
        $result[] = '        return $this->pool->getById(' . var_export($target_instance_class, true) . ', $this->' . $fk_getter_name . '());';
        $result[] = '    }';

        $setter_access_level = $this->getProtectSetter() ? 'protected' : 'public';

        $result[] = '';
        $result[] = '    /**';
        $result[] = '     * Set ' . Inflector::singularize($source_type->getName()) . ' ' . $this->getName() . '.';
        $result[] = '     *';
        $result[] = '     * @param  ' . $target_instance_class  . ' $value';
        $result[] = '     * @return $this';
        $result[] = '     */';
        $result[] = '    ' . $setter_access_level . ' function &' . $setter_name . '(' . $target_instance_class . ' $value' . ($this->isRequired() ? '' : ' = null') . ')';
        $result[] = '    {';

        if ($this->isRequired()) {
            $result[] = '        if (empty($value) || !$value->isLoaded()) {';
            $result[] = '            throw new \\InvalidArgumentException(\'Valid related instance is required\');';
            $result[] = '        }';
            $result[] = '';
            $result[] = '        $this->' . $fk_setter_name . '($value->getId());';
            $result[] = '';
            $result[] = '        return $this;';
        } else {
            $result[] = '        if (empty($value)) {';
            $result[] = '            $this->' . $fk_setter_name . '(0);';
            $result[] = '        } else {';
            $result[] = '            $this->' . $fk_setter_name . '($value->getId());';
            $result[] = '        }';
            $result[] = '';
            $result[] = '        return $this;';
        }

        $result[] = '    }';
    }
804204
protected function getSectionStructureFromIncomingStructure($section)
    {
        $pos = strpos($section, '.');
        if ($pos === false) {
            $section = (int) $section;
            if ($section === 0) {
                return $this->structure;
            }

            return $this->structure->parts[($section - 1)];
        }
        $sections = explode('.', $section);
        $count = count($sections);
        $outObject = null;
        foreach ($sections as $section) {
            $section = (int) $section;
            if (!isset($outObject)) {
                $outObject = $this->getObjectStructureFromParts($this->structure, ($section - 1));
            } else {
                $outObject = $this->getObjectStructureFromParts($outObject, ($section - 1));
            }
        }

        return $outObject;
    }
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;
    }
1252470
private function doDiff(Diff $diff, ElementtypeStructure $fromStructure = null, ElementtypeStructure $toStructure = null)
    {
        $rii = new \RecursiveIteratorIterator($fromStructure->getIterator(), \RecursiveIteratorIterator::SELF_FIRST);
        foreach ($rii as $fromNode) {
            /* @var $fromNode ElementtypeStructureNode */

            if ($toNode = $toStructure->getNode($fromNode->getDsId())) {
                if (implode('_', $toNode->getRepeatableDsIdPath()) !== implode('_', $fromNode->getRepeatableDsIdPath())) {
                    $diff->addMoved($fromNode, $toNode);
                }
            } else {
                $diff->addRemoved($fromNode);
            }
        }

        $rii = new \RecursiveIteratorIterator($toStructure->getIterator(), \RecursiveIteratorIterator::SELF_FIRST);
        foreach ($rii as $toNode) {
            /* @var $toNode \Phlexible\Bundle\ElementtypeBundle\Model\ElementtypeStructureNode */

            if (!$fromStructure->getNode($toNode->getDsId())) {
                $diff->addAdded($toNode);
            }
        }

        return $diff;
    }
7929
protected function fetchAttachment($structure, $partNumber) {

        $oAttachment = new Attachment($this, $structure, $partNumber);

        if ($oAttachment->getName() !== null) {
            if ($oAttachment->getId() !== null) {
                $this->attachments->put($oAttachment->getId(), $oAttachment);
            } else {
                $this->attachments->push($oAttachment);
            }
        }
    }
591293
public function extract( $structure )
    {
        if ( $structure instanceof StructureAbstract )
        {
            return $structure->toArray();
        }

        if ( $structure instanceof Traversable )
        {
            return ArrayUtils::iteratorToArray( $structure );
        }

        return (array) $structure;
    }
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;
    }
987706
private function applyStructure(ElementStructure $rootElementStructure, ElementtypeStructure $elementtypeStructure, array $values)
    {
        $this->structures[null] = $rootElementStructure;
        $map = [null => $rootElementStructure->getDataId()];

        foreach ($values as $key => $value) {
            $parts = explode('__', $key);
            $identifier = $parts[0];
            $repeatableIdentifier = null;
            if (isset($parts[1])) {
                $repeatableIdentifier = $parts[1];
            }

            if (preg_match('/^group-([-a-f0-9]{36})-id-([a-fA-F0-9-]+)$/', $identifier, $match)) {
                // existing repeatable group
                $parent = $this->structures[$repeatableIdentifier];
                $dsId = $match[1];
                $dataId = $match[2];
                $node = $elementtypeStructure->getNode($dsId);
                $map[$identifier] = $dataId;
                $this->structures[$identifier] = $elementStructure = new ElementStructure();
                $elementStructure
                    ->setDataId($dataId)
                    ->setDsId($dsId)
                    ->setParentName($parent->getName())
                    ->setName($node->getName());
                $parent->addStructure($elementStructure);
            } elseif (preg_match('/^group-([-a-f0-9]{36})-new-.+$/', $identifier, $match)) {
                // new repeatable group
                $parent = $this->structures[$repeatableIdentifier];
                $dsId = $match[1];
                $dataId = UuidUtil::generate();
                $node = $elementtypeStructure->getNode($dsId);
                $map[$identifier] = $dataId;
                $this->structures[$identifier] = $elementStructure = new ElementStructure();
                $elementStructure
                    ->setDataId($dataId)
                    ->setDsId($dsId)
                    ->setParentName($parent->getName())
                    ->setName($node->getName());
                $parent->addStructure($elementStructure);
            }
        }

        return $map;
    }
1080542
public static function getDelimitersKeys(array $data, $delimitersNumbers)
    {
        $delimiterKeys = [];

        $elementsNumbers = count($data);

        if ($elementsNumbers <= $delimitersNumbers) {
            throw new RestructureException("Elements number not bigger than delimiter.");
        }

        $portion = ($elementsNumbers - 1) / $delimitersNumbers;
        $portion = (int)$portion;
        $stablePortion = $portion;

        foreach ($data as $key => $value) {
            if (!is_int($key)) {
                throw new RestructureException("Associative array. Expect indexed.");
            }

            if ($key === $portion) {
                $delimiterKeys[] = $key;
                $portion += $stablePortion;
            }
        }

        return $delimiterKeys;
    }