Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

is_current_url() doesn't take basepath into consideration #199

Open
MrBrax opened this issue Nov 12, 2020 · 21 comments
Open

is_current_url() doesn't take basepath into consideration #199

MrBrax opened this issue Nov 12, 2020 · 21 comments
Labels

Comments

@MrBrax
Copy link

MrBrax commented Nov 12, 2020

When using is_current_url() and a slimphp basepath is set, it won't return true when visiting that route. Removing the basepath fixes it.

@l0gicgate
Copy link
Member

Are you instantiating the TwigMiddleware with the same basePath as you have set in Slim?

@MrBrax
Copy link
Author

MrBrax commented Nov 12, 2020

I'm not sure actually, i remember implementing it being a real pain.

Current setup

@l0gicgate
Copy link
Member

Are you sure this gets called:
https://github.com/MrBrax/TwitchAutomator/blob/947956114a9002ebcbb909d1efc8b191b249ac9b/public/index.php#L57

Because if you look in the TwigMiddleware it gets the basePath from the app:
https://github.com/slimphp/Twig-View/blob/3.x/src/TwigMiddleware.php#L71

@MrBrax
Copy link
Author

MrBrax commented Nov 12, 2020

I didn't know that was possible, nor what that thing does. Gonna have to research more.

@MrBrax
Copy link
Author

MrBrax commented Nov 12, 2020

Are you sure this gets called:
https://github.com/MrBrax/TwitchAutomator/blob/947956114a9002ebcbb909d1efc8b191b249ac9b/public/index.php#L57

Yes, the basepath works everywhere else, in the base_path() function too

@l0gicgate
Copy link
Member

You should try and do some debugging by putting a var_dump($currentUrl) at this line:
https://github.com/slimphp/Twig-View/blob/3.x/src/TwigRuntimeExtension.php#L80

As you can see, the base path is taken into consideration there.

@MrBrax
Copy link
Author

MrBrax commented Nov 12, 2020

That tells me that the basepath is appended twice.

<a href="{{ url_for('about') }}" becomes /path/path/about

@l0gicgate
Copy link
Member

That doesn't give me any insight on what's going on. You will need to debug what's happening in TwigRuntimeExtension and var_dump($this->uri) and var_dump($this->basePath).

Add those statements in the vendor source files where those files are located.

@MrBrax
Copy link
Author

MrBrax commented Nov 12, 2020

$currentUrl = "/path/path/dashboard"

$this->uri = object(Slim\Psr7\Uri)#160 (8) { ["scheme":protected]=> string(4) "http" ["user":protected]=> string(0) "" ["password":protected]=> string(0) "" ["host":protected]=> string(17) "example.com" ["port":protected]=> int(14184) ["path":protected]=> string(15) "/path/dashboard" ["query":protected]=> string(10) "/dashboard" ["fragment":protected]=> string(0) "" }

$this->basePath = "/path"

@l0gicgate
Copy link
Member

It seems that something is modifying the request URI and adding the basepath to it and it shouldn’t.

@MrBrax
Copy link
Author

MrBrax commented Nov 12, 2020

nginx maybe? setting nginx up with subfolders took me days of trial and error, almost nothing worked. maybe there's something in there

@MrBrax
Copy link
Author

MrBrax commented Nov 13, 2020

I'll keep it broken though, too much weird stuff to debug. Thanks though.

@kloor
Copy link

kloor commented Nov 25, 2020

Hello @l0gicgate,

I think I've run into the same issue, and made a simple test case. Within my Apache DocumentRoot, I created a folder named testcase and added the following index.php file:

<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;

require __DIR__ . '/vendor/autoload.php';

$app = AppFactory::create();
$app->setBasePath('/testcase');

$twig = Twig::create('.');
$app->add(TwigMiddleware::create($app, $twig));

$app->get('/', function (Request $request, Response $response, $args) {
    $view = Twig::fromRequest($request);
    $response->getBody()->write($view->fetchFromString('{{ current_url() }}'));

    return $response;
});

$app->run();

The following .htaccess file:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]

And the following composer.json file:

{
    "require": {
        "slim/slim": "^4.6",
        "slim/twig-view": "^3.1",
        "slim/psr7": "^1.2"
    }
}

After composer install if I access the directory in the web browser, the output from the current_url() is /testcase/testcase/. I haven't investigated further, but it does seem like base path should not be prepended to the path from the URI.

@bYemma
Copy link

bYemma commented Apr 3, 2021

I have the same issue. The base path is applied twice.

@iRaziul
Copy link

iRaziul commented May 4, 2021

Why?

The problem occurs while using slim in the sub-directory.

While running slim in a sub-directory the $request->getUri()->getPath() will returns the absolute path.

// create app
$app = AppFactory::create();
$app->setBasePath('/project/slim4');

// twig
$twig = Twig::create('.');

// middleware
$app->add(TwigMiddleware::create($app, $twig))

Let's check the path (in middleware or controller/action)

public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args = []) : ResponseInterface
{
    exit($request->getUri()->getPath());  # /project/slim4
}

The constructor of TwigRuntimeExtension accepts 3 parameters routeParser, uri and basePath.

In isCurrentUrl and getCurrenturl methods:

$currentUrl = $this->basePath.$this->uri->getPath();

$this->basePath returns /project/slim4

$this->uri->getPath() returns /projects/slim4/

so $currentUrl returns /project/slim4/project/slim4/ 😒

Solution!

This method can be applied to make it work without making any changes to Twig-View

// create app
$app = AppFactory::create();
$app->setBasePath('/project/slim4');

// twig
$twig = Twig::create('.');

// middleware
$app->add(new TwigMiddleware($twig, $app->getRouteCollector()->getRouteParser()));

@l0gicgate
Copy link
Member

I think there is an issue with double invocation when resolving the middleware perhaps.. It'd be great to get a failing test case so we can fix this.

@MrBrax
Copy link
Author

MrBrax commented May 5, 2021

Funny how I've moved on to a SPA since then, but i hope this gets resolved.

@paulocanedo
Copy link

I have the same issue, configured a nginx as a reverse proxy to my application:

https://domain.com/myapp -> http://internal_ip/

In TwigRuntimeExtension::isCurrentUrl:

  • $this->basePath: /myapp
  • $this->uri->getPath(): /myapp/request (already have the basepath)

The solution proposed by @iRaziul worked for me.

@diodo
Copy link

diodo commented Jun 12, 2023

Any news on this issue ? Because the solution proposed by iRaziul not work for me. I use TwigWebpackExtension and it break all links to js and css. I need to set the basePath.

blast007 added a commit to blast007/Twig-View that referenced this issue Jul 30, 2023
@dfranco
Copy link

dfranco commented Mar 8, 2024

Any news on this issue ? Because the solution proposed by iRaziul not work for me. I use TwigWebpackExtension and it break all links to js and css. I need to set the basePath.

I have the exact same issue, is there any will to fix it ?

blast007 added a commit to blast007/Twig-View that referenced this issue Jul 8, 2024
@odan
Copy link
Contributor

odan commented Jul 14, 2024

I can confirm this behavior (bug).

Minimal example application:

<?php

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;

require __DIR__ . '/../vendor/autoload.php';

$app = AppFactory::create();
$app->setBasePath('/slim4-demo');

$twig = Twig::create('.');
$app->add(TwigMiddleware::create($app, $twig));

$app->get('/', function (Request $request, Response $response) {
    $view = Twig::fromRequest($request);
    $response->getBody()->write($view->fetchFromString('Twig-View current_url: {{ current_url() }}<br>'));
    $response->getBody()->write('Request URI Path: ' . $request->getUri()->getPath());

    return $response;
});

$app->run();

Running this application on Apache in a sub-directory of the webroot directory /slim4-demo the result looks as follows:

URL: http://localhost:8080/slim4-demo/

Actual result

Twig-View current_url: /slim4-demo/slim4-demo/
Request URI Path: /slim4-demo/

Expected result:

Twig-View current_url: /slim4-demo/
Request URI Path: /slim4-demo/

The suggested workaround might work in some situation, but it might cause errors in combination with Twig::fromRequest.
Example:

$app->add(new TwigMiddleware($twig, $app->getRouteCollector()->getRouteParser()));

// ...
$app->get('/', function (Request $request, Response $response) {
    $view = Twig::fromRequest($request); // RuntimeException!
    // ...
    return $response;
});

This would throw an Exception like: Uncaught RuntimeException: Twig could not be found in the server request attributes using the key "view".

So it might not be the best solution for all.

The basePath is already part of the request URI. Tested with slim/psr7 and nyholm/psr7.
So adding the basePath twice should be fixed as shown in the commit: blast007@65c1a9f

@odan odan added the bug label Jul 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants