src/PicoAuthPlugin.php
protected function resolveRealUrl($fileName)
    {
        $fileNameClean = str_replace("\0", '', $fileName);
        $realPath = realpath($fileNameClean);

        if ($realPath === false) {
            // the page doesn't exist or realpath failed
            return $this->requestUrl;
        }
        
        // Get Pico content path and file extension
        $contentPath = realpath($this->pico->getConfig('content_dir'));
        $contentExt = $this->pico->getConfig('content_ext');
        
        if (strpos($realPath, $contentPath) !== 0) {
            // The file is not inside the content path (symbolic link)
            throw new \RuntimeException("The plugin cannot be used with "
                . "symbolic links inside the content directory.");
        }

        // Get a relative path of $realPath from inside the $contentPath and remove an extension
        // len+1 to remove trailing path delimeter, which $contentPath doesn't have
        $name = substr($realPath, strlen($contentPath)+1, -strlen($contentExt));
        
        // Always use forward slashes
        if (DIRECTORY_SEPARATOR !== '/') {
            $name = str_replace(DIRECTORY_SEPARATOR, '/', $name);
        }
        
        // If the name ends with "/index", remove it, for the main page returns ""
        if (strlen($name) >= 5 && 0 === substr_compare($name, "index", -5)) {
            $name= rtrim(substr($name, 0, -5), '/');
        }
        
        return $name;
    }
protected function resolveRealUrl($fileName)
    {
        $fileNameClean = str_replace("\0", '', $fileName);
        $realPath = realpath($fileNameClean);

        if ($realPath === false) {
            // the page doesn't exist or realpath failed
            return $this->requestUrl;
        }
        
        // Get Pico content path and file extension
        $contentPath = realpath($this->pico->getConfig('content_dir'));
        $contentExt = $this->pico->getConfig('content_ext');
        
        if (strpos($realPath, $contentPath) !== 0) {
            // The file is not inside the content path (symbolic link)
            throw new \RuntimeException("The plugin cannot be used with "
                . "symbolic links inside the content directory.");
        }

        // Get a relative path of $realPath from inside the $contentPath and remove an extension
        // len+1 to remove trailing path delimeter, which $contentPath doesn't have
        $name = substr($realPath, strlen($contentPath)+1, -strlen($contentExt));
        
        // Always use forward slashes
        if (DIRECTORY_SEPARATOR !== '/') {
            $name = str_replace(DIRECTORY_SEPARATOR, '/', $name);
        }
        
        // If the name ends with "/index", remove it, for the main page returns ""
        if (strlen($name) >= 5 && 0 === substr_compare($name, "index", -5)) {
            $name= rtrim(substr($name, 0, -5), '/');
        }
        
        return $name;
    }
Resolves a given content file path to the pico url

Used for obtaining a unique url for a page file. This is required
for authorization as the $url pico provides in onRequest is not unique
and can have many equivalents (e.g. /pico/?page vs /pico/?./page).
Case sensitivity is the same as returned from realpath().

The naming rules follow Pico-defined standards:
/content/index.md => ""
/content/sub/page.md => "sub/page"
/content/sub/index.md => "sub"

Example: pico content_dir is /var/pico/content
then file name /var/pico/content/sub/page.md returns sub/page

@param string $fileName Pico page file path (from onRequestFile event)
@return string Resolved page url
@throws \RuntimeException If the filepath cannot be resolved to a url