Given an existing path, convert it to a path relative to a given starting path.

@param string $endPath   Absolute path of target
@param string $startPath Absolute path where traversal begins

@return string Path of target relative to starting path
547809
public function makePathRelative($endPath, $startPath)
    {
        // Normalize separators on Windows
        if ('\\' === DIRECTORY_SEPARATOR) {
            $endPath = str_replace('\\', '/', $endPath);
            $startPath = str_replace('\\', '/', $startPath);
        }

        // Split the paths into arrays
        $startPathArr = explode('/', trim($startPath, '/'));
        $endPathArr = explode('/', trim($endPath, '/'));

        if ('/' !== $startPath[0]) {
            array_shift($startPathArr);
        }

        if ('/' !== $endPath[0]) {
            array_shift($endPathArr);
        }

        $normalizePathArray = function ($pathSegments) {
            $result = array();

            foreach ($pathSegments as $segment) {
                if ('..' === $segment) {
                    array_pop($result);
                } else {
                    $result[] = $segment;
                }
            }

            return $result;
        };

        $startPathArr = $normalizePathArray($startPathArr);
        $endPathArr = $normalizePathArray($endPathArr);

        // Find for which directory the common path stops
        $index = 0;
        while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
            ++$index;
        }

        // Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
        if (count($startPathArr) === 1 && $startPathArr[0] === '') {
            $depth = 0;
        } else {
            $depth = count($startPathArr) - $index;
        }

        // When we need to traverse from the start, and we are starting from a root path, don't add '../'
        if ('/' === $startPath[0] && 0 === $index && 0 === $depth) {
            $traverser = '';
        } else {
            // Repeated "../" for each level need to reach the common path
            $traverser = str_repeat('../', $depth);
        }

        $endPathRemainder = implode('/', array_slice($endPathArr, $index));

        // Construct $endPath from traversing to the common path, then to the remaining $endPath
        $relativePath = $traverser.('' !== $endPathRemainder ? $endPathRemainder.'/' : '');

        return '' === $relativePath ? './' : $relativePath;
    }
974464
public function withBasePath($basePath)
    {
        if (!is_string($basePath)) {
            throw new InvalidArgumentException('Uri path must be a string');
        }
        if (!empty($basePath)) {
            $basePath = '/' . trim($basePath, '/');
        }
        $clone = clone $this;

        if ($basePath !== '/') {
            $clone->basePath = Validator::checkPath($basePath);
        }

        return $clone;
    }
830182
public function setBasePath(string $path)
    {
        if (Assert::stringNotEmpty($path)) {
            $this->basePath = rtrim($path, '\\/') . $this->separator;
        }
    }
225661
public function resourcesPath(?string $resourcesPath = null) {
        if ($resourcesPath != null) {
            $this->resourcesPath = $resourcesPath;
        }
        else if (!isset($this->resourcesPath)) {
            $this->resourcesPath = get_property("app.resources_path", $this->basePath . DIRECTORY_SEPARATOR . "resources");
        }
        return $this->resourcesPath;
    }
1081072
protected function findRelativePath($path)
    {
        if (null !== $this->basePath) {
            return strtr($path, array($this->basePath . DIRECTORY_SEPARATOR => ''));
        }

        return $path;
    }
329652
protected function realPath($additionalPath)
    {
        if (substr($additionalPath, 0, 1) === '/') {
            $path = $additionalPath;
        } else if ($additionalPath !== '') {
            $path = $this->path . $additionalPath;
        } else {
            $path = $this->path;
        }
    
        return $path;
    }
516763
protected function _abspath($path) {
		return $path == $this->separator ? $this->root : $this->root.$this->separator.$path;
	}
1199321
public function withBasePath($basePath)
    {
        if (!is_string($basePath)) {
            throw new InvalidArgumentException('Uri path must be a string');
        }
        if (!empty($basePath)) {
            $basePath = '/' . trim($basePath, '/'); // <-- Trim on both sides
        }
        $clone = clone $this;

        if ($basePath !== '/') {
            $clone->basePath = $this->filterPath($basePath);
        }

        return $clone;
    }
147980
public function findRelativePath($frompath, $topath)
    {
        Deprecated::method(3.3);

        $filesystem = new Filesystem();
        $relative = $filesystem->makePathRelative($topath, $frompath);

        return $relative;
    }
26951
public static function normalizePath($path, $endSlash = true)
    {
        $path = rtrim($path, '/') . DIRECTORY_SEPARATOR;
        $path = rtrim($path, DIRECTORY_SEPARATOR);

        $path = $endSlash ? $path . DIRECTORY_SEPARATOR : $path;

        return $path;
    }
772247
@Override
    public Path subpath(final int beginIndex, final int endIndex) {
        if (beginIndex < 0) {
            throw new IllegalArgumentException("Begin index must be greater than 0");
        }
        if (endIndex < 0) {
            throw new IllegalArgumentException("End index must be greater than 0");
        }
        if (endIndex <= beginIndex) {
            throw new IllegalArgumentException("End index must be greater than begin index");
        }
        final List<String> tokens = tokenize(this);
        final int tokenCount = tokens.size();
        if (beginIndex >= tokenCount) {
            throw new IllegalArgumentException("Invalid begin index " + endIndex + " for " + this.toString()
                + "; must be between 0 and " + tokenCount + " exclusive");
        }
        if (endIndex > tokenCount) {
            throw new IllegalArgumentException("Invalid end index " + endIndex + " for " + this.toString()
                + "; must be between 0 and " + tokenCount + " inclusive");
        }
        final StringBuilder newPathBuilder = new StringBuilder();
        for (int i = 0; i < endIndex; i++) {
            newPathBuilder.append(ArchivePath.SEPARATOR);
            newPathBuilder.append(tokens.get(i));
        }
        final Path newPath = this.fromString(newPathBuilder.toString());
        return newPath;
    }
841748
public function basePath($path = '')
    {
        return $this->getFilesystem()->dirname($this->path()) . ($path ? DIRECTORY_SEPARATOR . $path : $path);
    }
128924
protected function getFullPath($contextPath, $targetPath): string
    {
        if ($this->filesystem->isAbsolutePath($targetPath)) {
            return $targetPath;
        }

        return rtrim($contextPath, '/\\').DIRECTORY_SEPARATOR.$targetPath;
    }
646825
public static final function ppath ($path){
		while (!is_dir($path) && strlen($path) > 0){
			$path = preg_replace('/[^\/]+\/?$/', null, $path);
		}

		return !empty($path) ? $path : false;
	}
227271
protected function relativeTargetPath($path)
    {
        if (strpos($path, JPATH_ROOT) === 0) {
            $path = self::$resourceLocator->rewrite(
                $this->relativeJoomlaTargetPath($path),
                true
            );
        }

        return $path;
    }
562255
public function basePath($basePath = null)
    {
        if (!func_num_args()) {
            return $this->_basePath;
        }
        $this->_basePath = $basePath;
        return $this;
    }
681204
public function baseUrl($targetPath = null)
    {
        if (!isset($this->baseUrl)) {
            throw new RuntimeException(sprintf(
                'The base URI is not defined for [%s]',
                get_class($this)
            ));
        }

        if ($targetPath !== null) {
            return $this->createAbsoluteUrl($this->baseUrl, $targetPath);
        }

        return rtrim($this->baseUrl, '/').'/';
    }