mtymek/blast-base-url

Unable to resolve service "Blast\BaseUrl\BaseUrlMiddleware" to a Factory

Closed this issue · 19 comments

Hi Mateusz,

Thank you for your pointers in my expressive issue. When updating my project from the cookbook, I ran into trouble. Aparantly I did something wrong in creating the pointer to the factory. I include the configuration file "middleware-pipeline.global.php". I am new to zend, so I could easily have misinterpreted the instructions. If you need more info, just let me know. Apart from the instructions in the cookbook, the project is the expressive-skeleton.

Could you have a look?

middleware-pipeline.global.php.zip

An afterthought. The cookbook mentions updating the file dependencies.config.php with a line for Blast\BaseUrl\BasePathHelper::class. So I wondered whether this file should also contain a pointer to the Factory (like in middleware-pipeline)?

edit: apparantly not.

Hi,

I'm not able to reproduce it - I just tried to follow the cookbook to double check and it worked like a charm. Then I used your config directly - it also worked.
Did you try it on empty Expressive skeleton, or is it a working application?

Hi Mateusz,

I did it on the expressive skeleton. However, I may have made a mistake somewhere. Just to be sure that I did not cause this myself, I will redo from start. This time I will register the changes in a VCS, so I know what I changed. Thanks for checking it out. Will get back to you hopefully tomorrow.

After recreating the expressive skeleton from scratch and re-doing the changes, I get the same error. The system cannot find the services connected to Blast. The exact message is:

Unable to resolve service "Blast\BaseUrl\BaseUrlMiddleware" to a factory; are you certain you provided it during configuration?

Could my setup be the problem?

  1. Document root = /data/home/guus/www
  2. Application root = /data/home/guus/www/expressive
  3. I set up expressive with all defaults except for templates (Plates) and the error handler (whoop).

P.S. For some reason I cannot update a zip or tar.gz file (both get an error: something went terribly wrong, try again). I include the patch for middleware-pipeline.global.php. Also I created .htaccess in the application root as described in the cookbook.

Index: config/autoload/middleware-pipeline.global.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- config/autoload/middleware-pipeline.global.php  (date 1472538488000)
+++ config/autoload/middleware-pipeline.global.php  (date 1472549755000)
@@ -5,6 +5,7 @@
 return [
     'dependencies' => [
         'factories' => [
+           Blast\BaseUrl\BaseUrlMiddleware::class => Blast\BaseUrl\BaseUrlMiddlewareFactory::class,
             Helper\ServerUrlMiddleware::class => Helper\ServerUrlMiddlewareFactory::class,
             Helper\UrlHelperMiddleware::class => Helper\UrlHelperMiddlewareFactory::class,
         ],
@@ -43,6 +44,8 @@
             ],
             'priority' => 10000,
         ],
+
+       [ 'middleware' => [ Blast\BaseUrl\BaseUrlMiddleware::class ], 'priority' => 1000 ],

         'routing' => [
             'middleware' => [

What you have looks good, which makes this issue even weirder for me...

Which version of PHP do you use? Which version of zend-servicemanager? What choices did you make during Skeleton setup?

Hi Mateusz,

I use FastRoute for routing, Zend-servicemanager for container and Plates for templating. Further I included Whoops for error handling.

Php version is 5.6.21-2. The zend-servicemanager shows version only in changelog: version 3.1.1 dated 2016-07-15.

The error points to expressive not being able to find the blast service, so I would expect my configuration to be wrong. Whatever the problem, Shouldn't it be outside blast?

For completeness I include composer.json:

{
    "name": "zendframework/zend-expressive-skeleton",
    "description": "Zend expressive skelton. Begin developing PSR-7 middleware applications in seconds",
    "type": "project",
    "homepage": "https://github.com/zendframework/zend-expressive-skeleton",
    "license": "BSD-3-Clause",
    "authors": [
        {
            "name": "Geert Eltink",
            "homepage": "https://xtreamwayz.com/"
        }
    ],
    "extra": {
        "branch-alias": {
            "dev-master": "1.0-dev",
            "dev-develop": "1.1-dev"
        }
    },
    "require": {
        "php": "^5.5 || ^7.0",
        "roave/security-advisories": "dev-master",
        "zendframework/zend-expressive": "^1.0",
        "zendframework/zend-expressive-helpers": "^2.0",
        "zendframework/zend-stdlib": "^2.7 || ^3.0",
        "zendframework/zend-expressive-fastroute": "^1.0",
        "zendframework/zend-servicemanager": "^2.7.3 || ^3.0",
        "ocramius/proxy-manager": "^1.0 || ^2.0",
        "zendframework/zend-expressive-platesrenderer": "^1.0",
        "mtymek/blast-base-url": "^0.2.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^4.8",
        "squizlabs/php_codesniffer": "^2.3",
        "filp/whoops": "^1.1 || ^2.0"
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/App/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "AppTest\\": "test/AppTest/"
        }
    },
    "scripts": {
        "check": [
            "@cs",
            "@test"
        ],
        "cs": "phpcs",
        "cs-fix": "phpcbf",
        "serve": "php -S 0.0.0.0:8080 -t public/ public/index.php",
        "test": "phpunit"
    }
}

Hi Mateusz,

I feel somewhat ashamed. I forgot to do a composer update on the server. After I did, the error reduced to the original 404 (the one I got without installing blast). Using the internal server (php -S 0.0.0.0:8080 -t public) shows the homepage, which is also what I got before installing Blast.

It seems, the base url is still the problem. What can I do to find out what is wrong?

No worries, glad you found it!

So, you have blast-base-url set up now, but you still get 404. Does it come directly from Apache, or from Expressive app?

It is encapsulated in the expressive header and footer, so I expect it to come from expressive.

expressive-blast-404

Alright - two more things you can to do help me tracking it down:

  • what is your .htaccess file?
  • what do you have in $_SERVER (you can simply var_dump it somewhere)?

The .htaccess in the application root contains:

RewriteEngine On
RewriteRule (.*) ./public/$1

$_SERVER var_dump below. On this public forum I had to change things that point to the test server.

array(34) { ["REDIRECT_STATUS"]=> string(3) "200" ["HTTP_HOST"]=> string(17) "<servername>.nl" ["HTTP_USER_AGENT"]=> string(72) "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0" ["HTTP_ACCEPT"]=> string(63) "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" ["HTTP_ACCEPT_LANGUAGE"]=> string(23) "en,nl;q=0.7,en-US;q=0.3" ["HTTP_ACCEPT_ENCODING"]=> string(13) "gzip, deflate" ["HTTP_DNT"]=> string(1) "1" ["HTTP_CONNECTION"]=> string(10) "keep-alive" ["HTTP_UPGRADE_INSECURE_REQUESTS"]=> string(1) "1" ["HTTP_CACHE_CONTROL"]=> string(9) "max-age=0" ["PATH"]=> string(60) "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ["SERVER_SIGNATURE"]=> string(79) "
Apache/2.4.18 (Debian) Server at <servername>.nl Port 443
" ["SERVER_SOFTWARE"]=> string(22) "Apache/2.4.18 (Debian)" ["SERVER_NAME"]=> string(17) "<servername>.nl" ["SERVER_ADDR"]=> string(11) "192.168.0.2" ["SERVER_PORT"]=> string(3) "443" ["REMOTE_ADDR"]=> string(13) "192.168.2.254" ["DOCUMENT_ROOT"]=> string(19) "/data/home/guus/www" ["REQUEST_SCHEME"]=> string(5) "https" ["CONTEXT_PREFIX"]=> string(0) "" ["CONTEXT_DOCUMENT_ROOT"]=> string(19) "/data/home/guus/www" ["SERVER_ADMIN"]=> string(26) "administrator@<someserver>.nl" ["SCRIPT_FILENAME"]=> string(47) "/data/home/guus/www/expressive/public/index.php" ["REMOTE_PORT"]=> string(5) "56286" ["REDIRECT_URL"]=> string(12) "/expressive/" ["GATEWAY_INTERFACE"]=> string(7) "CGI/1.1" ["SERVER_PROTOCOL"]=> string(8) "HTTP/1.1" ["REQUEST_METHOD"]=> string(3) "GET" ["QUERY_STRING"]=> string(0) "" ["REQUEST_URI"]=> string(12) "/expressive/" ["SCRIPT_NAME"]=> string(28) "/expressive/public/index.php" ["PHP_SELF"]=> string(28) "/expressive/public/index.php" ["REQUEST_TIME_FLOAT"]=> float(1472637668.631) ["REQUEST_TIME"]=> int(1472637668) } 

Edit: var_dump looks awful. If you want, I can add Zend-Debug and do a dump.

OK, I see what you're trying to do now. You have whole application in expressive directory under your web root, and you would like to serve it using http://domain.com/expressive URL. Unfortunately this is not supported by this library - it would work if you kept default .htaccess file, and accessed your app using following URL: http://domain.com/expressive/public - which I guess is not satisfying for you.

In order to make it work, I believe you'd need to do a bit more "magic" in your .htaccess file. Probably the second solution that was suggested in the cookbook (manually setting base path to /expressive) would work as well.

Hi,

Thanks for your efforts. Indeed, this is what I want, but, only on development. The reason is, we have only one virtual host per developer with multiple systems to test per developer. In production the document root can be anything I want it to be.

it would work if you kept default .htaccess file, and accessed your app using following URL: http://domain.com/expressive/public - which I guess is not satisfying for you.

I used the default .htaccess in the all of the sub directories (including public), beside the application root where I created the .htaccess with the 2 lines I pasted. Also, I did call the page using http://domain.com/expressive/public. However, just doing this returns the 404, whether I use blast or not. If this were the solution, I would certainly use it.

I was looking at the views / layouts (phtml) and it appears that expressive does not use anything to indicate the basepath. It refers to /zf-logo.png for instance, which assumes the document root is public/.

I would have expected something like $this->basePath() . zf-logo.png to make the field independent of subdirectories. Is anything like this available in expressive?

Afterthought, when reading the last part of your remark:

In order to make it work, I believe you'd need to do a bit more "magic" in your .htaccess file. Probably the second solution that was suggested in the cookbook (manually setting base path to /expressive) would work as well.

If I understand the second solution (last part of this cookbook), it presumes using zend-view and requires using $this->basePath('zf-logo.png') in stead of `/zf-logo.png' directly. I will certainly have a look at this, although I am not sure it will prevent the 404. Will get back to you though. Not sure what magic I would need in the .htaccess tho.

If you have any other idea's or remarks, plz comment :)

I added the last few lines of the cookbook, like you suggested and (using http://domain.com/expressive/public) and all is working.

Actually I am surprised. Apparantly, the last lines of configuration (after these lines in the cookbook):

To enable these features, we'll add some configuration to config/autoload/dependencies.global.php file:

are not optional. By adding them everything started working. It was my impression that to enable these features meant, the last lines were optional.

Happy to see that you managed to get it working!

Regarding your question, the last part of the cookbook is about URL generation, which indeed is used by view helpers like basePath or url. It is not required for routing though.
For example, imagine API endpoint served from subdirectory - it does not need view helpers, right? That's why this part is considered "optional".

Thanks for your comment. Being optional, it still is weird that it only started working after activation. I will get back to you after I try de-activating and see what happens. It should still work right? Will get back to you.

It seems that the last addition (basepath) really doesn't matter. Which means I must have changed something else and I really don't know what it is. That is slightly worriesome, however, not your problem: your module works as expected. Thanks for your efforts to support me, I really appreciate it!

P.S. I assume you will close the issue?

Alright, glad to see I could help!