Prepare REST requests

@param array $parts router parts
559569
protected function prepareRestRequest(array &$parts)
    {
        if (!empty($parts) && in_array($parts[0], $this->restPrefixes)) {
            /*
             * if the request is something like /_/posts/1/comments/2
             * it will convert it to something like /posts/comments/1/2
             */

            // first remove the REST prefix
            array_shift($parts);

            $restRoute = $restParams = [];
            $i = 1;

            foreach ($parts as $part) {
                if ($i % 2) {
                    $restRoute[] = $part;
                } else {
                    $restParams[] = $part;
                }

                $i++;
            }

            $parts = array_merge($restRoute, $restParams);
        }
    }
1257908
private function prepareRoutes($module, array $routes)
    {
        $result = array();

        foreach ($routes as $uriTemplate => $options) {
            // Controller is the special case
            if (isset($options['controller'])) {
                // Override with module-compliant
                $options['controller'] = sprintf('%s:%s', $this->grabModuleName($module), $options['controller']);
            }

            $result[$uriTemplate] = $options;
        }

        return $result;
    }
982979
private function parseHostAndPath(array $locationParts): void
    {
        $path = $locationParts['path'] ?? '';
        $host = $locationParts['host'] ?? '';

        if ($this->getScheme() === 'file') {
            $this->path = $host . $path;
        } else {
            $this->host = $host;
            $this->path = $path;
        }
    }
326889
protected function buildUri(array $parts)
    {
        $uri = 
            ($parts['scheme'] ? "{$parts['scheme']}:" : '') . 
            ($parts['user'] || $parts['host'] ? '//' : '') . 
            ($parts['user'] ? "{$parts['user']}" : '') . 
            ($parts['user'] && $parts['pass'] ? ":{$parts['pass']}" : '') . 
            ($parts['user'] ? '@' : '') . 
            ($parts['host'] ? "{$parts['host']}" : '') . 
            ($parts['port'] ? ":{$parts['port']}" : '');
            
        $uri .=
            ($uri && $parts['path'] && $parts['path'][0] !== '/' ? '/' : '') .
            ($parts['path'] ? "{$parts['path']}" : '') . 
            ($parts['query'] ? "?{$parts['query']}" : '') . 
            ($parts['fragment'] ? "#{$parts['fragment']}" : '');
            
        return $uri;
    }
1054697
protected function setUriParts(array $parts)
    {
        foreach ($parts as $key => $value) {
            if (!method_exists($this, "set$key")) {
                continue;
            }
            $this->{"set$key"}($value);
        }
    }
1174785
public static function generateQueryString(array $parts)
    {
        $return = "";

        foreach ($parts as $part) {
            if ($part instanceof Column) {
                if ($part->getColumnName() === '*') {
                    $return .= "*";
                } else {
                    $return .= "`{$part->getColumnName()}`"; // @codeCoverageIgnore
                }

                if ($part->getColumnAs() !== null) {
                    $return .= " " . $part->getColumnAs(); // @codeCoverageIgnore
                }

                $return .= ",";
            }
        }

        return ($return !== "" ? substr($return, 0, -1) : "*");
    }
1208675
private function parseQuery(array $locationParts): void
    {
        if (isset($locationParts['query'])) {
            $queryParts = explode('&', $locationParts['query']);
            foreach ($queryParts as $part) {
                $option = $this->splitKeyValuePair($part);

                $this->query[$option[0]] = $option[1];
            }
        }
    }
342497
public static function buildFromParseUrlParts(array $parts) {
        $url = '';

        $url .= isset($parts['scheme']) ? $parts['scheme'] : 'http';
        $url .= '://';

        if (isset($parts['user'])) {
            $url .= $parts['user'];

            if (isset($parts['pass'])) {
                $url .= ':' . $parts['pass'];
            }

            $url .= '@';
        }

        $url .= isset($parts['host']) ? $parts['host'] : '';
        $url .= isset($parts['port']) ? ':' . $parts['port'] : '';
        $url .= isset($parts['path']) ? $parts['path'] : '';
        $url .= isset($parts['query']) ? '?' . $parts['query'] : '';
        $url .= isset($parts['fragment']) ? '#' . $parts['fragment'] : '';

        return $url;
    }
943927
public static function prepare($params = [])
    {
        $positions = array_combine(array_keys($params), array_fill(0, count($params), 0));
        $data = [];

        do {
            $data[] = self::getByIndexes($params, $positions);
        } while (self::updateIndexesToNextIteration($params, $positions));

        return $data;
    }
1214343
public function setParts(array $parts)
    {
        if (count($parts) > 1) {
            throw new \InvalidArgumentException('Only one value allowed');
        }
        if (isset($parts[0]) && $parts[0] instanceof DateTimeInterface) {
            $this->setDateTime($parts[0]);
        } else {
            parent::setParts($parts);
        }
    }
7812
protected static function buildPath(string ...$parts)
    {
        $parts = array_map(function (string $part) {
            if (!$part) {
                throw new InvalidArgumentException('Missing required parameter.');
            }

            return self::urlEncode($part);
        }, $parts);

        return implode('/', $parts);
    }
454760
public static function buildUrl($parts)
    {
        $url = '';

        if (isset($parts['scheme'])) {
            $url .= $parts['scheme'].'://';
        }

        if (isset($parts['user'])) {
            if (isset($parts['pass'])) {
                $url .= $parts['user'].':'.$parts['pass'].'@';
            } else {
                $url .= $parts['user'].'@';
            }
        }

        if (isset($parts['host'])) {
            $url .= $parts['host'];
        }

        if (isset($parts['port'])) {
            $url .= ':'.$parts['port'];
        }

        if (isset($parts['path'])) {
            $url .= $parts['path'];
        }

        if (isset($parts['query'])) {
            $url .= '?'.$parts['query'];
        }

        if (isset($parts['fragment'])) {
            $url .= '#'.$parts['fragment'];
        }

        return $url;
    }
938178
protected static function buildUrlMergeUrlParts($parts)
    {
        $partsDefault = array(
            'scheme'    => null,
            'host'      => null,
            'port'      => null,
            'path'      => '/',
            'query'     => '',
            'fragment'  => null,
        );
        if (!empty($parts['url'])) {
            $urlParts = self::parseUrl(htmlspecialchars_decode($parts['url']));
            if (!$urlParts['scheme']) {
                $urlParts['scheme'] = 'omit';
            }
            if (!empty($parts['path'])) {
                // discard url's query and fragment
                $urlParts['query']      = null;
                $urlParts['params']     = array();
                $urlParts['fragment']   = null;
            }
            if ($urlParts['query'] && !empty($parts['query'])) {
                // merge the queries
                $paramsParts = Str::parse($parts['query']);
                $params = ArrayUtil::mergeDeep($urlParts['params'], $paramsParts);
                $parts['query'] = self::buildQueryString($params);
            }
            $partsDefault = array_merge($partsDefault, $urlParts);
        }
        $parts = array_merge($partsDefault, $parts);
        return $parts;
    }
1037886
public function setParts(array $parts)
    {
        if (isset($parts[0]) && $parts[0] instanceof DateTimeInterface) {
            $this->setDateTimes($parts);
        } else {
            parent::setParts($parts);
        }
    }
1192534
public function prepend(string ...$parts): self
    {
        array_push($parts, $this->path);

        return self::make(...$parts);
    }
231983
public function setParts(array $parts): self
    {
        $this->parts = [];
        foreach ($parts as $part) {
            $this->addPart($part);
        }

        return $this;
    }
263759
protected function processParts(array $parts)
    {
        return array_values(array_filter($parts, function ($part) {
            if (empty($part) || $part instanceof CommentPart) {
                return false;
            }
            return true;
        }));
    }