Giter VIP home page Giter VIP logo

laminas-mvc's Introduction

laminas-mvc

Continuous Integration

🇷🇺 Русским гражданам

Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм.

У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую.

Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!"

🇺🇸 To Citizens of Russia

We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism.

One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences.

You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!"

Laminas\Mvc is an MVC implementation focusing on performance and flexibility.

The MVC layer is built on top of the following components:

  • Laminas\ServiceManager - Laminas provides a set of default service definitions set up at Laminas\Mvc\Service. The ServiceManager creates and configures your application instance and workflow.

  • Laminas\EventManager - The MVC is event driven. This component is used everywhere from initial bootstrapping of the application, through returning response and request calls, to setting and retrieving routes and matched routes, as well as render views.

  • Laminas\Http - specifically the request and response objects, used within: Laminas\Stdlib\DispatchableInterface. All “controllers” are simply dispatchable objects.

  • File issues at https://github.com/laminas/laminas-mvc/issues

  • Documentation is at https://docs.laminas.dev/laminas-mvc/

laminas-mvc's People

Contributors

afilina avatar akrabat avatar asgrim avatar bakura10 avatar blanchonvincent avatar dasprid avatar evandotpro avatar ezimuel avatar freeaqingme avatar froschdesign avatar maks3w avatar marc-mabe avatar michalbundyra avatar micheh avatar mpinkston avatar mwillbanks avatar noopable avatar ocramius avatar prolic avatar radnan avatar ralphschindler avatar renovate[bot] avatar rodmcnew avatar samsonasik avatar sgehrig avatar snapshotpl avatar socalnick avatar thinkscape avatar weierophinney avatar xerkus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laminas-mvc's Issues

Impossible to test php errors in phtml with PHPUnit

Bug Report

Q A
Version(s) 3.1.1

Summary

Currently I'm developing with php 7.4, for CLI and Apache I have set error_reporting to E_ALL, php errors during rendering of phtml

Current behavior

The deprecation notice inside whateverAction is raising exception and fails test as expected.
The deprecation notice inside whatever.phtml file rendering an exception visible in browser but it passes the test. The visible error in browser is Deprecated: array_key_exists(): Using array_key_exists() on objects is deprecated. Use isset() or property_exists() instead in /path/to/whatever.phtml on line xy

How to reproduce

  1. Use php 7.4
  2. Set up error_reporting for CLI to E_ALL in php.ini
  3. Use current PHPUnit (version shouldn't matter, I'm using 9.4.1) and use default configuration with convertDeprecationsToExceptions set to true
  4. Use following piece of code in any action and the corresponding phtml file:
if (array_key_exists('test', new \ArrayObject())) {
    // This triggers deprecated error
}

Expected behavior

While testing with this configuration the rendering of a phtml file should obey the same rules as the normal php files.

Accept headers not satisfied in correct order by AcceptableViewModelSelector controller plugin

According to the WC3 Specifictations the Server should try to satisfy accept headers in order. Currently the order of the content-types in the Accept header is not respected.

So when I send a request with an Accept header like this: application/xml, application/json it should first try to return a xml and then a json model. When I do application/json, application/xml it should be the other way around.

The AcceptableViewModelSelector controller plugin does not seem to respect the order in which content types are requested.

I reported this issue here inside Apigility module but it turned out the behavior is caused by the Zend\Mvc\Controller\Plugin\AcceptableViewModelSelector controller plugin.


Originally posted by @Wilt at zendframework/zend-mvc#16

Unable to render template RuntimeException for AbstractRestfulController

I get an unable to render template error when i do not over-ride the AbstractRestfulController method.

By default, the response code is set and an array is returned which appears to be picked up and rendered using the default render strategy.

Would it be a good idea to set the response content and return the response or is there something I am missing in the configuration.

I would just like some feedback on this before I make a pull request.

Thanks,

James


Originally posted by @jerv13 at zendframework/zend-mvc#3

Psalm integration

Feature Request

Q A
QA yes

Summary

As decided during the Technical-Steering-Committee Meeting on August 3rd, 2020, Laminas wants to implement vimeo/psalm in all packages.

Implementing psalm is quite easy.

Required

  • Create a .psalm.xml.dist in the project root
  • Copy and paste the contents from this psalm.xml.dist
  • Run $ composer require vimeo/psalm
  • Run $ vendor/bin/psalm --set-baseline=psalm-baseline.xml
  • Add a composer script static-analysis with the command psalm --shepherd --stats
  • Add a new line to script: in .travis.yml: - if [[ $TEST_COVERAGE == 'true' ]]; then composer static-analysis ; fi
  • Remove phpstan from the project (phpstan.neon.dist, .travis.yml entry, composer.json require-dev and scripts)
Optional
  • Fix as many psalm errors as possible.

The mvc event listener invalid for namespace if it's multi segment namespaces

There is a question for me.
On a module, Like the path: module/Application, module/Admin, etc...
Most of time. the module namespace is use: Application\, Admin\, and now I want make a module is common module for other project. So I rename the namespace to: Brand\Admin\ replace the old Admin\ like this.
And then. the question is happened. I tracking all the script flow. The event manager just register the auto namespace first segment for the event identifier. Like the Brand\Admin\ registered in the identifiers is Brand
So I register listener on a module's onBootstrap() can not been called.

Code to reproduce the issue

namespace Brand\Admin
class Module {
//.... other code
public function onBootstrap(MvcEvent $event) {

        $sharedEventManager = $event->getApplication()->getEventManager()->getSharedManager();
        $sharedEventManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, function ($e) {
            echo '<h1>Hello, Baby!</h1>';
        }, 9999);
        // The will be ok. the eventmanager auto register identifier AbstractActionController
        //$sharedEventManager->attach(Zend\Mvc\Controller\AbstractActionController::class, MvcEvent::EVENT_DISPATCH, function ($e) {
            //echo '<h1>Hello, Baby!</h1>';
        //}, 9999);
        // Or not use shared event manager, use eventManger is OK.
    }
}

Expected results

the never output hello, baby.

Actual results

The listener never been called.


Originally posted by @leogitpro at zendframework/zend-mvc#274

Package http-interop/http-middleware is abandoned

The package http-interop/http-middleware is abandoned. You'll get this if you install zend-mvc version 3.1.1 with composer:

Package http-interop/http-middleware is abandoned, you should avoid using it. Use http-interop/http-server-middleware instead.

Code to reproduce the issue

Run in your favourite terminal:

$ composer require zendframework/zend-mvc

Expected results

No warnings are expected.

Actual results

A warning is displayed that the http-interop/http-middleware is abandoned.


Originally posted by @halfpastfouram at zendframework/zend-mvc#316

Fix controller namespace in event manager

This issue has been moved from the zendframework repository as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html


Original Issue: https://api.github.com/repos/zendframework/zendframework/issues/7457
User: @0xPaul
Created On: 2015-04-22T09:29:40Z
Updated At: 2015-05-04T14:59:12Z
Body
Controller was only registering the root namespace, e.g. Foo instead of Foo\Bar for a class named Foo\Bar\Baz.


Comment

User: @Martin-P
Created On: 2015-04-28T19:52:56Z
Updated At: 2015-04-28T19:52:56Z
Body
Perhaps you can add:

  • a unittest which shows the correct namespace is returned
  • a separate unittest which shows the wrong namespace is not returned

That way regressions can be avoided.


Comment

User: @0xPaul
Created On: 2015-04-29T08:48:33Z
Updated At: 2015-04-29T08:48:33Z
Body
If by you, you mean someone, then yes. I'm sure someone can do those things.


Comment

User: @Martin-P
Created On: 2015-04-29T09:09:15Z
Updated At: 2015-04-29T09:09:15Z
Body

If by you, you mean someone, then yes. I'm sure someone can do those things.

I'm sure someone can create unittests, but this is not _someone_s PR, it is your PR. So I meant you, @0xPaul 😉



Originally posted by @GeeH at zendframework/zend-mvc#171

AbstractRestfulController does not set the Allow headers.

This issue has been moved from the zendframework repository as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html


Original Issue: https://api.github.com/repos/zendframework/zendframework/issues/7674
User: @parkbot
Created On: 2016-02-19T00:12:44Z
Updated At: 2016-02-21T18:14:38Z
Body
https://tools.ietf.org/html/rfc7231#section-6.5.5

States a 405 response Must set the Allow header. The controller needs to have a method by which the allow headers are set when a 405 is returned.

Overriding each function just to get the controller to work properly seems like over kill.

Perhaps have an abstract function getAllowedMethods that returns an array of allowed methods that get populated when a 405 has been set?



Originally posted by @GeeH at zendframework/zend-mvc#167

Can't set a controller map template replacement to an empty string

The Inject template listener allows specifying a controller_map to map namespaces or specific controllers to directories. It is not currently possible to specify a mapping for a namespace to '' eg:

'controller_map' => [
    'my/long/namespace' => '',
]

This is due to a == comparison with false in the listener on line 142:
https://github.com/zendframework/zend-mvc/blob/f46acd021a0d571bc5df400bdd55243adc53580e/src/View/Http/InjectTemplateListener.php#L142 which should probably be ===

Fixing this may break BC...


Originally posted by @carnage at zendframework/zend-mvc#12

PHPStan fixes

In order to bump to PHP 7 minimum version in the future, I used phpstan to static analyse the code, correcting some phpdoc errors and adding guards throwing exceptions when needed. Code quality will be improved when other components will be improved.

It's just a first step, but I think it will be useful.

I don't know if this could be considered a BC break, probably it isn't.


Originally posted by @thomasvargiu at zendframework/zend-mvc#296

Ability to specify response code on controller plugin redirect

I have changed my routing setup on a production app, and I would like to provide search engines with the information that a new URL format is being used. For this I would like to use code 301 (Permanently Moved) instead of 302 (Found).

Code to reproduce the issue

In a controller action:

return $this->redirect()->toUrl('https://github.com'); //, ['statusCode' => 301]);

Expected results

I should be able to specify a statusCode of choosing

Actual results

The browser receives a 302 response code always.

Thanks for all your support!


Originally posted by @jroedel at zendframework/zend-mvc#313

Call to undefined method

Bug Report

In the MiddlewareListener the setResponsePrototype is called. This method was removed in the MiddlewarePipe.

Error: Call to undefined method Laminas\Stratigility\MiddlewarePipe::setResponsePrototype() in vendor/laminas/laminas-mvc/src/MiddlewareListener.php:135
Stack trace:
#0 vendor/laminas/laminas-mvc/src/MiddlewareListener.php(68): Laminas\Mvc\MiddlewareListener->createPipeFromSpec(Object(Laminas\ServiceManager\ServiceManager), Object(Laminas\Diactoros\Response), Array)
#1 vendor/laminas/laminas-eventmanager/src/EventManager.php(321): Laminas\Mvc\MiddlewareListener->onDispatch(Object(Laminas\Mvc\MvcEvent))
#2 vendor/laminas/laminas-eventmanager/src/EventManager.php(178): Laminas\EventManager\EventManager->triggerListeners(Object(Laminas\Mvc\MvcEvent), Object(Closure))
#3 vendor/laminas/laminas-mvc/src/Application.php(331): Laminas\EventManager\EventManager->triggerEventUntil(Object(Closure), Object(Laminas\Mvc\MvcEvent))
#4 public/index.php(43): Laminas\Mvc\Application->run()
#5 {main}
Q A
laminas/laminas-mvc 3.1.1
laminas/laminas-psr7bridge 1.2.1
laminas/laminas-stratigility 3.2.1
laminas/laminas-eventmanager 3.2.1
PHP 7.2.26

Summary

An error is raised when using the Middleware inside MVC.

Current behavior

How to reproduce

Expected behavior

No Error when using the Middleware Feature inside MVC.

Minor comment update

The statement in injectEventManager's comments that a shared event manager is injected into an existing event manager is incorrect - the code replaces the existing event manager with a new one. That's what I updated.

I may have added too much 'how it works' detail, but I puzzled over this a bit so I thought the explanation might help future readers.


Originally posted by @bitwombat at zendframework/zend-mvc#285

Using forward/dispatch results in different RouteMatch class object

This issue has been moved from the zendframework repository as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html


Original Issue: https://api.github.com/repos/zendframework/zendframework/issues/7389
User: @kuldeep-k
Created On: 2015-03-31T08:32:24Z
Updated At: 2015-11-06T21:05:11Z
Body
I am building a rest based auth forwarding. So I do code like below in listener class

public function __invoke(MvcEvent $event)
{
    print_r($event->getRouteMatch());
    $result = $this->adapter->authenticate();
    $routeMatch = $event->getRouteMatch();

    if (!$result->isValid()) {

        $response = $event->getResponse();

        $response->setStatusCode(401);

        /*$routeMatch = $event->getRouteMatch();
        $routeMatch->setParam('controller', 'Rest\Controller\Error');
        $routeMatch->setParam('action', 'auth');
        */

        $cpm = $this->getServiceLocator()->get('ControllerPluginManager');
        $fwd = $cpm->get('forward');
        return $fwd->dispatch('Rest\Controller\Error', array('action' => 'auth'));
    }
}

So first time request comes for controller Rest\Controller\Index action index (matched route "rest") but due to authentication failure forward happens to controller Rest\Controller\Error action auth (matched route "rest-error")

However what is printed is below

Zend\Mvc\Router\Http\RouteMatch Object
(
    [length:protected] => 5
    [params:protected] => Array
        (
            [controller] => Rest\Controller\Index
        )

    [matchedRouteName:protected] => rest
)
Zend\Mvc\Router\RouteMatch Object
(
    [params:protected] => Array
        (
            [action] => auth
        )

    [matchedRouteName:protected] => rest
)
Zend\Mvc\Router\RouteMatch Object
(
    [params:protected] => Array
        (
            [action] => auth
        )

    [matchedRouteName:protected] => rest
)

Which show that first request go to Zend\Mvc\Router\Http\RouteMatch while subsequent request goes to Zend\Mvc\Router\RouteMatch ( Due to not check of safe route request recursively goes end throw expected error "Circular forwarding detected")

Now from second request do not have controller information also, It matched to wrong matchedRouteName.

module.config.php have these routes

'routes' => array(
    'rest' => array(
        'type' => 'Zend\Mvc\Router\Http\Segment',
        'options' => array(
            'route'    => '/rest[/:id]',
            'constraints' => array(
                'id'     => '[0-9]+',
            ),
            'defaults' => array(
                'controller' => 'Rest\Controller\Index'
            ),
        ),
    ),
    'rest-error' => array(
        'type' => 'Zend\Mvc\Router\Http\Segment',
        'options' => array(
            'route'    => '/resterror',
            'constraints' => array(
                'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                'id'     => '[0-9]+',
            ),
            'defaults' => array(
                'controller' => 'Rest\Controller\Error',
                'action'     => 'auth',
            ),
        ),
    )
),

I tried on Zend Framework v2.3.4 & v2.2.4 .



Originally posted by @GeeH at zendframework/zend-mvc#174

Return type of AbstractActionController->getRequest can be improved

Bug Report

Q A
Version(s) 3.2.0

Summary

PhpDoc of Laminas\Mvc\Controller\AbstractActionController (or its base class Laminas\Mvc\Controller\AbstractController actually) can be improved.
In reality when calling getRequest(), you may want to use methods like isPost, which is not implemented by the currently returned interface. A subclass like Laminas\Http\Request would be more desirable.
A similar issue applies to getResponse().
As far as I could tell from looking at the code, no other classes that implement this interface are ever returned. But I think that one of the contributors could better verify this.

Current behavior

Laminas\Mvc\Controller\AbstractActionController returns an Laminas\Stdlib\RequestInterface when calling getRequest()
Laminas\Mvc\Controller\AbstractActionController returns an Laminas\Stdlib\ResponseInterface when calling getResponse()

How to reproduce

Extend AbstractAction Controller and call getRequest() inside any action.
For a simple example, look at https://github.com/GEWIS/gewisweb/blob/1b16fa9a90043cd6d20e284e0bea0d8e18aededf/module/Frontpage/src/Controller/PollController.php#L77

Expected behavior

Laminas\Mvc\Controller\AbstractActionController returns an Laminas\Http\Request when calling getRequest()
Laminas\Mvc\Controller\AbstractActionController returns an Laminas\Http\Request when calling getResponse()

Flash Messenger Namespace Messages Return Nothing

This issue has been moved from the zendframework repository as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html


Original Issue: https://api.github.com/repos/zendframework/zendframework/issues/7632
User: @tomshaw
Created On: 2015-09-29T20:01:05Z
Updated At: 2015-11-06T22:24:52Z
Body
Login controller:

$this->flashMessenger()->addSuccessMessage('You have successfully logged in.');

Forwarded Index Controller.

no messages
$this->flashMessenger()->getSuccessMessages();

Below works without vital namespace information.

$this->flashMessenger()->addMessage('You have successfully logged in.');

Forwarded Index Controller.

$this->flashMessenger()->getMessages();

Comment

User: @mwillbanks
Created On: 2015-10-01T19:09:16Z
Updated At: 2015-10-01T19:09:16Z
Body
Hello @tomshaw I wanted to make sure I am understanding, you're stating that when you forward the controller (not redirect) that the flash messages are unavailable when using something like the addSuccessMessage vs. the addMessage. Is this a correct statement? The general case works properly but the specific case is not?


Comment

User: @tomshaw
Created On: 2015-10-01T19:14:56Z
Updated At: 2015-10-01T19:14:56Z
Body
Ignore forward. Redirect after a successful login.


Comment

User: @tomshaw
Created On: 2015-10-01T19:20:11Z
Updated At: 2015-10-01T19:20:11Z
Body
Using an ajax action I need not only the message but message type, error, success, info etc.



Originally posted by @GeeH at zendframework/zend-mvc#168

Provide documentation for the accumulated changes towards 4.0

Series of pull requests containing work towards next major MVC release will not provide documentation updates as part of those PRs due to overlapping nature of the changes and pending documentation rework (tracked in #55) in order to save effort that would otherwise be wasted.

This issue tracks PRs that must be documented before release could be made.

Updated AbstractActionController::indexAction return type to reflect real usage

  • Is this related to quality assurance?

When running static analysis against a simple userland controller like:

class MyController extends AbstractActionController
{
    public function indexAction()
    {
        return ['posts' => ['foo', 'bar']];
    }
}

That do NOT provide the return type, neither with PHP 7.1 return type nor via DocBlock, tools like PHPstan use inherited docs and report:

Method MyController::indexAction() should return Zend\View\Model\ViewModel but returns array.

Of course users should add return types, but it would result in requiring a massive code update without real benefits, since the default behavior of Zend\Mvc framework is to allow:

  1. null from \Zend\Mvc\View\Http\CreateViewModelListener::createViewModelFromNull listener
  2. array from \Zend\Mvc\View\Http\CreateViewModelListener::createViewModelFromArray listener
  3. ViewModel from \Zend\Mvc\View\Http\DefaultRenderingStrategy::render listener
  4. ResponseInterface from \Zend\Mvc\SendResponseListener::sendResponse listener

This change only applies to indexAction since I guess its usage is widespread: notFoundAction is untouched as users that override it are, IMHO, already advanced ones.

Ping @Ocramius you type lover ❤️

Reference: https://github.com/Slamdunk/phpstan-zend-framework/issues/5


Originally posted by @Slamdunk at zendframework/zend-mvc#312

Wrong primary key value assignment

Bug Report

namespace: Laminas\Db\RowGateway
class method: save()

There is a possible bug in following lines:
if (($primaryKeyValue = $result->getGeneratedValue()) && count($this->primaryKeyColumn) == 1) {
$this->primaryKeyData = [$this->primaryKeyColumn[0] => $primaryKeyValue];
}

Explanation:
$primaryKeyValue = $result->getGeneratedValue() assignment is wrong since the primary key value
holder could be a totally different column. PDO, for example, returns the first generated auto increment value, while the primary column value could come from data itself (it could happen that it was set before)

Summary

My suggestion: First of all is to fetch the primary key from data based on primary column definition ($this->primaryKeyColumn[0]) and if nothing was found then fetch from generated value.

$lastInsertedValue = $result->getGeneratedValue();
if ($lastInsertedValue && count($this->primaryKeyColumn) == 1) {
$primaryKeyValue = $this->data[$this->primaryKeyColumn[0]];
if (!$primaryKeyValue) $primaryKeyValue = $lastInsertedValue;
$this->primaryKeyData = [$this->primaryKeyColumn[0] => $primaryKeyValue];
}

PHP 8.0 support

Feature Request

Q A
New Feature yes

Summary

To be prepared for the december release of PHP 8.0, this repository has some additional TODOs to be tested against the new major version.

In order to make this repository compatible, one has to follow these steps:

  • Modify composer.json to provide support for PHP 8.0 by adding the constraint ~8.0.0
  • Modify composer.json to drop support for PHP less than 7.3
  • Modify composer.json to implement phpunit 9.3 which supports PHP 7.3+
  • Modify .travis.yml to ignore platform requirements when installing composer dependencies (simply add --ignore-platform-reqs to COMPOSER_ARGS env variable)
  • Modify .travis.yml to add PHP 8.0 to the matrix (NOTE: Do not allow failures as PHP 8.0 has a feature freeze since 2020-08-04!)
  • Modify source code in case there are incompatibilities with PHP 8.0

fixed SimpleStreamResponseSender ignored defined content length

Provide a narrative description of what you are trying to accomplish:

We are using the stream HTTP response to directly stream file content from S3 to clients.
As we are dealing with video files we are using the the Range/Content-Range headers to allow clients to download specific parts of files.

To be able to do so we use the Zend\Http\Response\Stream::setContentLength method together with fseek to define the parts of the file to send.

Where Stream::readStream is dealing with the content length it's not handled in SimpleStreamResponseSender and the stream gets send until EOF.

To fix that this PR uses stream_copy_to_stream to php://output instead of fpassthru if a content length has been defined.

  • Are you fixing a bug?

    • Detail how the bug is invoked currently.
    • Detail the original, incorrect behavior.
    • Detail the new, expected behavior.
    • Base your feature on the master branch, and submit against that branch.
    • Add a regression test that demonstrates the bug, and proves the fix.
    • Add a CHANGELOG.md entry for the fix.
  • Are you creating a new feature?

    • Why is the new feature needed? What purpose does it serve?
    • How will users use the new feature?
    • Base your feature on the develop branch, and submit against that branch.
    • Add only one feature per pull request; split multiple features over multiple pull requests
    • Add tests for the new feature.
    • Add documentation for the new feature.
    • Add a CHANGELOG.md entry for the new feature.
  • Is this related to quality assurance?

  • Is this related to documentation?


Originally posted by @marc-mabe at zendframework/zend-mvc#315

improvement: Adding examples for AbstractRestfulController actions

Provide a narrative description of what you are trying to accomplish:

  • Are you fixing a bug?

    • Detail how the bug is invoked currently.
    • Detail the original, incorrect behavior.
    • Detail the new, expected behavior.
    • Base your feature on the master branch, and submit against that branch.
    • Add a regression test that demonstrates the bug, and proves the fix.
    • Add a CHANGELOG.md entry for the fix.
  • Are you creating a new feature?

    • Why is the new feature needed? What purpose does it serve?
    • How will users use the new feature?
    • Base your feature on the develop branch, and submit against that branch.
    • Add only one feature per pull request; split multiple features over multiple pull requests
    • Add tests for the new feature.
    • Add documentation for the new feature.
    • Add a CHANGELOG.md entry for the new feature.
  • Is this related to quality assurance?

  • Is this related to documentation?


Originally posted by @alessandrofeitoza at zendframework/zend-mvc#286

Is it bug or feature? The problem with redirect plugin and session.

Hello

Let me first tell a story how I reached to this issue. I have spent more than 6 hours in sum with a face like this one 'O_O' trying to add a very simple feature, which every modern framework have, in my app based on zf3. It's a flash messenger.

I just wanted to display some fancy messages after actions connected with form submission, like auth or change password.

  1. I have started with official zend-mvc-flash messenger and was happy. After testing it in a scope of one action I decided to use it to display success message after a redirect. And was wondering why a message wasn't displayed. I started to debug $_SESSION and found that array key connected with FlashMessanger wasn't there. Only __ZF with validators and Zend_Auth were presented.
    Well, something wrong with auth, I decided. It was my guess because I have used Doctrine auth for auth routine and though that I have an error in config or a bug in DoctrineModule that overwrites session.

I was wrong. During my investigation, I became zend auth master and doctrine config master. But the problem wasn't there. I have tried all crazy config variants and different factories. No results.

  1. Then I decided that probably there is a bug in FlashMessanger. Maybe it conflicts with Doctrine or something. So I used some not popular modules from GitHub to wrap FlashMessenger or replace it.
    No results. Still nothing in session after form submit.

I decided to write my own plugin. And even did! It based on pure PHP solution wrapped with View Helper and Controller Plugin into Zend. I was happy, seems like it worked. I have even integrated it with some js lib to have temporary messages in the right corner.

  1. Next day I found, that my plugin faced the same problem. No value in session after form submit. In plugin logic I haven't used any Zend component, just worked with a $_SESSION. And the value was there until auth or password change form submits and redirect.

I decided to investigate zend-session docs, config variants, a code, and factories. I had a guess that session rewrites container somehow. I was wrong.

In the end, when I'm almost was defeated, I decided to use another redirect way with build in in my plugin simple redirect function. And it's worked!
Waaaait a minute. All the time problem was with a redirect plugin?
Then I saw this commented code.

$this->msg()->success("Password updated");
$this->redirect()->toRoute('profile', ['action' => 'index']);

}

Hmmm... I read controller plugin redirect docs.
https://docs.zendframework.com/zend-mvc/plugins/#redirect-plugin
And I returned redirection back with $this->redirect() and changed it in this way

$this->msg()->success("Password updated");
return $this->redirect()->toRoute('profile', ['action' => 'index']);

}

And it's worked like a charm. After a redirect, all session keys like flash_messenger and FlashMessneger were presented.


So, I have spent more than 6 hours with a debug, trying different stuff, writing my own flash messenger plugin, and reading docs only because of

return

This is what I think about this situation encoded in rude64();

^&amp;^%$$%#$#^) ()* (*&amp;*^%$%$@ ##$^&amp;^*&amp;&amp;( ()* (* !!!!

And now we reached the question.
In a documentation written, that usage of return with redirect plugin is optional.

If you return this immediately, you can effectively short-circuit execution of the request.

And from this phrase, we could conclude that there shouldn't be a difference if you return a response immediately or not.

In each case, the Response object is returned.

Somebody, please, explain me, why $this->redirect() with a return and without return works differently?

Why without return after redirect all my custom keys in $_SESSION were deleted and it's looked like the session was created from scratch?

I'm using latest skeleton app with all latest vendor zend libs. All configs and code are correct (I have checked 100 times).

If there is no adequate answer to my questions, then, please, consider this issue as a bug report.
Because on my opinion redirect plugin SHOULD work the same in both cases, if a response was returned immediately or not (we just reached an end of action method).

Some senior PHP developer with 6 years of experience shouldn't be so confused with a framework which he loves...


Originally posted by @seyfer at zendframework/zend-mvc#227

Unable to resolve service "MvcTranslator" to a factory

Bug Report

Q A
Version(s) 3.1.1

Summary

Laminas\Mvc\Service\TranslatorServiceFactory is not exist

Current behavior

Fatal error: Uncaught Laminas\ServiceManager\Exception\ServiceNotFoundException: Unable to resolve service "MvcTranslator" to a factory; are you certain you provided it during configuration?

Fatal error no catch in views

When I have an exception in a "view" from a ViewHelper I recive a generic message :
"An error occurred during execution; please try again later.
No Exception available" without give me more info about the error.

But when I try same error in "layout" I recive this message "Fatal error: Uncaught Error:" with additional information about the error (trace-files).

How you know, when not have information about error take a lot of time to debug.

Thanks for help

Environment: zf3 + php7 + ZendServer (Migration process of zf2 to zf3)


Originally posted by @wilariz at zendframework/zend-mvc#199

Documentation rework for 4.0

Current documentation is severely outdated and does not meet our quality standards.

This is a tracking issue for all documentation improvements that must be done for the next major release.

@settermjd your input on the improved documentation structure would be greatly appreciated.

AbstractActionController:indexAction states it can only return `ViewModel`

Bug Report (non-critical)

Q A
Version(s) 3.2.0

Summary

The pre-defined method AbstractActionController::indexAction states that it can only return ViewModel.
In Projects which implement their own FooController::indexAction, static analysis complains about an invalid return type if e.g. a Laminas\Http\Response is returned.

Current behavior

Static code analysis complains about invalid return type.

How to reproduce

<?php
declare(strict_types=1);

use Laminas\Http\Response;
use Laminas\Mvc\Controller\AbstractActionController;

final class FooController extends AbstractActionController
{
    public function indexAction(): Response
    {
        return new Response();
    }
}
Return type                                                            
         (Laminas\Http\Response) of method                                           
         FooController::indexAction() should be       
         compatible with return type (Laminas\View\Model\ViewModel) of method   
         Laminas\Mvc\Controller\AbstractActionController::indexAction()   

Expected behavior

No errors.

[ZF3] Simplifying MvcEvent

This issue has been moved from the zendframework repository as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html


Original Issue: https://api.github.com/repos/zendframework/zendframework/issues/7185
User: @bakura10
Created On: 2015-02-05T15:11:06Z
Updated At: 2015-11-06T21:25:43Z
Body
Hi everyone,

I think I may already talked about that, but I'd like to know if someone has started thinking about how can we simplify the dispatching process (is this the middleware solution?).

I have a lot of pain points with current MvcEvent, especially because it aggregates so many things and plug into so many different events that it makes it hard to work with.

For instance, the getViewModel is confusing. It seems that a lot of listeners inside the framework (or third-party module) set the view model inside result (using setResult), but at some point of the process, it gets magically injected using setViewResult (but why only at some point of the process, and not as soon as we create a view model?).

The same for exception. Currently, the framework set the exception into a param. This is a bit fragile, because a param is just a param. A listener could possible remove the param, and subsequent listeners could have unexpected results.

I don't have any idea of how it could work, but the fact that the MvcEvent is nearly transferred from start to bottom, always make me ask questions like: "ok, so at this point... do I have a view model? if so, where it is stored exaclty?" or "what kind of data "getResult" will return me here?".

If anyone has worked extensively with listeners and hook into the dispatch process, please share your experience and pain points, I'm sure it would help us and other contributors.

ping @weierophinney @Ocramius


Comment

User: @stefanotorresi
Created On: 2015-02-05T17:53:24Z
Updated At: 2015-02-05T17:53:24Z
Body
I feel your pain, but the whole point of the event is that it's a message passed along between the various components, so I guess the fact that it holds different data in different phases of the cycle is completely intentional.

if I had to strip it down to the bare minimum, I would say that the event should only aggregate request and response (immediatly injected since the start of the cycle), a reference to the last exception (with a setter that injects previous exceptions each time is invoked), and finally a KVS of user parameters (which should not be things crucial to the execution tho, just optional things to pass around listeners).

also, I would rather have the rendering process using a completely different event cycle, because the main cycle should always be failsafe and be at least capable to provide a sane response, instead of as it is now, where errors occurred during rendering may also affect the rendering of the error themselves.


Comment

User: @bakura10
Created On: 2015-02-05T17:58:46Z
Updated At: 2015-02-05T17:58:46Z
Body
The rendering process is already handled by another event (ViewEvent), but it shares the same complexity as MvcEvent. But the point is: do we need the request in ViewEvent? Do we need the view model (rendering purpose) in the MvcEvent?

Maybe I'm missing some use cases, but couldn't we have something like that:

  1. Application triggers RoutingEvent.RESOLVE_ROUTE (RoutingEvent being a new event that is not aware of ViewModel, but only what it needs to do its work).
  2. Then Application triggers MvcEvent.CONTROLLER.
    ... and so-on...

If we are able to split the event in smaller events, then we could have less side-effects and more focused events.


Comment

User: @Ocramius
Created On: 2015-02-05T18:00:58Z
Updated At: 2015-02-05T18:00:58Z
Body

The rendering process is already handled by another event

That is a different concern: that's just because the view layer as it stands is a terrible mess.


Comment

User: @stefanotorresi
Created On: 2015-02-05T18:12:58Z
Updated At: 2015-02-05T18:12:58Z
Body
Yes there is another event, but the two cycles are tied together, Zend\Mvc\View\Http\DefaultRenderingStrategy listens to \Zend\Mvc\MvcEvent::EVENT_RENDER, and this is what I'd like to get rid of :p

If we consider the middleware approach suggested by @weierophinney, I imagine rendering would happen during a middleware dispatch, being just a body being created and injected into a response.

I guess the mvc cycle could just turn into a much simpler control cycle that just invokes middlewares, which in turn trigger other event cycles (routing, rendering, whatever).
That would allow the base application control event (say a MiddlewareEvent) to only have those things I mentioned: request, response, errors, and a kvs.


Comment

User: @bakura10
Created On: 2015-02-05T18:16:57Z
Updated At: 2015-02-05T18:16:57Z
Body
Ha yes I forgot the EVENT_RENDER. Definitely bad that MvcEvent coordinates this too. Definitely.


Comment

User: @RalfEggert
Created On: 2015-04-22T08:56:31Z
Updated At: 2015-04-22T08:56:31Z
Body
Should be marked for ZF3 milestone, shouldn't it?


Comment

User: @danizord
Created On: 2015-04-22T16:00:57Z
Updated At: 2015-04-22T16:00:57Z
Body
The mess and complexity is caused by the fact that events are mutable and we take advantage of it.
Not sure if this is possible, but it would be great to have ZF3 lifecycle working with immutable events.



Originally posted by @GeeH at zendframework/zend-mvc#177

PHP Fatal error: Declaration of Laminas\Mvc\Service\ModuleManagerFactory::__invoke not compatible with the interface signature

Bug Report

This issue noticed with an existing running project with a recent composer install as part of the build process. The old build is working fine but any new build throwing fatal error during ModuleManager invoke

Q A
Version(s) x.y.z

Summary

When the service manager tries to load modules ModuleManagerFactory invoke fails due to incompatible function parameter

error:
PHP Fatal error: Declaration of Laminas\Mvc\Service\ModuleManagerFactory::__invoke(Interop\Container\ContainerInterface $container, $name, ?array $options = NULL) must be compatible with Laminas\ServiceManager\Factory\FactoryInterface::__invoke(Psr\Container\ContainerInterface $container, $requestedName, ?array $options = NULL) in vendor\laminas\laminas-mvc\src\Service\ModuleManagerFactory.php on line 36

Current behavior

The code is failing during the bootstrap where the Module Manager tries to load modules. This was working until last week. and from today with new composer install application started breaking

How to reproduce

Try to load a module during bootstrap
$serviceManagerConfig = new ServiceManagerConfig();
$serviceManager = new ServiceManager();
$serviceManagerConfig->configureServiceManager($serviceManager);
$serviceManager->setService('ApplicationConfig', $config);
$serviceManager->get('ModuleManager')->loadModules();
static::$serviceManager = $serviceManager;

Then run any code which triggers this ModuleManager factory and it will provide the below fatal error
PHP Fatal error: Declaration of Laminas\Mvc\Service\ModuleManagerFactory::__invoke(Interop\Container\ContainerInterface $container, $name, ?array $options = NULL) must be compatible with Laminas\ServiceManager\Factory\FactoryInterface::__invoke(Psr\Container\ContainerInterface $container, $requestedName, ?array $options = NULL) in vendor\laminas\laminas-mvc\src\Service\ModuleManagerFactory.php on line 36

Expected behavior

The code should load the Module Manager without error.

Suggestion: AbstractRestfulController:$identifierName should default to null

This issue has been moved from the zendframework repository as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html


Original Issue: https://api.github.com/repos/zendframework/zendframework/issues/7395
User: @tylkomat
Created On: 2015-04-01T07:27:21Z
Updated At: 2015-11-06T21:05:28Z
Body
As pointed out on the mailing list strange things can happen when relying on the default value.

I propose to let it default to null and throw an exception if not set. That makes the usage for the developer much easier, as he will have to override it in his class.

Unfortunately this change is a BC-Break for the people that rely on the default value.



Originally posted by @GeeH at zendframework/zend-mvc#173

Do we really need notFoundAction?

The question is simple: do we really need notFoundAction?

https://github.com/zendframework/zend-mvc/blob/master/src/Controller/AbstractActionController.php#L43

I don't think so...

My problems:

  1. It's not triggering a dispatch error, while all other and similar (!) errors do. If we can't locate the controller, we trigger a dispatch error, if we can't locate the action inside that controller, we do not trigger any error. What is the reason for handling similar errors in different ways? If we don't have notFoundController, then why have we notFoundAction?
  2. Because it doesn't trigger any error, it's hard to bypass it. If a custom error and exception handling is needed, we can do it easily by attaching custom listeners to the dispatch.error event, but this doesn't work for notFoundAction becasue the missing event. We cannot use the dispatch event neither: with priority 1 or lower it's too late, notFoundAction already returned a ViewModel with 404 status code, with priority 2 or higher it's too early, we don't have the controller yet.

What should be done?

  1. We should remove the notFoundAction and modify onDispatch (https://github.com/zendframework/zend-mvc/blob/master/src/Controller/AbstractActionController.php#L60).
  2. We should check the existance of the method in the DispatchListener (https://github.com/zendframework/zend-mvc/blob/master/src/DispatchListener.php#L77). If the method doesn't exists, we should trigger a dispatch error and set the name of the error to the following:

const ERROR_CONTROLLER_METHOD_NOT_FOUND = 'error-controller-method-not-found';

(I think it would be better than the old ERROR_CONTROLLER_CANNOT_DISPATCH, which means nothing for me, it's too general.)

After that we could do small simplifications in RouteNotFoundReason, and remove weird lines (!!!) similar to this one: https://github.com/zendframework/zend-mvc/blob/master/src/View/Http/RouteNotFoundStrategy.php#L231

By the way, that line and this switch case (https://github.com/zendframework/zend-mvc/blob/master/src/View/Http/RouteNotFoundStrategy.php#L135) perfectly shows how illogical the error handling in it's current form is. There are errors (retrieved via getError from MvcEvent) and there is ERROR_CONTROLLER_CANNOT_DISPATCH.

(The impossibility of retrieving the error type ERROR_CONTROLLER_CANNOT_DISPATCH from the MvcEvent via the getError method can cause further problems too. Let's say we would like to log them...)

Opinions?


Originally posted by @wesperinteractive at zendframework/zend-mvc#204

While attempting to create httproutenotfoundstrategy

Hello

We have custom system based on zf2, when I update zend-mvc to version 2.7.15 , I have this error :

[err] #1096 in vendor/zendframework/zend-servicemanager/src/ServiceManager.php
While attempting to create httproutenotfoundstrategy(alias: HttpRouteNotFoundStrategy) an invalid factory was registered for this instance type.

we have custom config fro load all (( Default mvc-related service configuration )), I do some changes on my config file and all new options like MiddlewareListener and ..

But we have problem and error on loading HttpRouteNotFoundStrategy and HttpExceptionStrategy and HttpDefaultRenderingStrategy

My custom config is :

return [
    // ServiceMananger configuration
    'service_manager'    => [
        'aliases'            => [
            'configuration'                              => 'config',
            'Configuration'                              => 'config',
            'console'                                    => 'ConsoleAdapter',
            'Console'                                    => 'ConsoleAdapter',
            'ConsoleDefaultRenderingStrategy'            => View\Console\DefaultRenderingStrategy::class,
            'ControllerLoader'                           => 'ControllerManager',
            'Di'                                         => 'DependencyInjector',
            'HttpDefaultRenderingStrategy'               => View\Http\DefaultRenderingStrategy::class,
            //'MiddlewareListener'                       => 'Zend\Mvc\MiddlewareListener',
            //'RouteListener'                            => 'Zend\Mvc\RouteListener',
            //'SendResponseListener'                     => 'Zend\Mvc\SendResponseListener',
            'View'                                       => 'Zend\View\View',
            'ViewFeedRenderer'                           => 'Zend\View\Renderer\FeedRenderer',
            'ViewJsonRenderer'                           => 'Zend\View\Renderer\JsonRenderer',
            'ViewPhpRendererStrategy'                    => 'Zend\View\Strategy\PhpRendererStrategy',
            'ViewPhpRenderer'                            => 'Zend\View\Renderer\PhpRenderer',
            'ViewRenderer'                               => 'Zend\View\Renderer\PhpRenderer',
            'Zend\Di\LocatorInterface'                   => 'DependencyInjector',
            'Zend\Form\Annotation\FormAnnotationBuilder' => 'FormAnnotationBuilder',
            'Zend\Mvc\Controller\PluginManager'          => 'ControllerPluginManager',
            'Zend\Mvc\View\Http\InjectTemplateListener'  => 'InjectTemplateListener',
            'Zend\View\Renderer\RendererInterface'       => 'Zend\View\Renderer\PhpRenderer',
            'Zend\View\Resolver\TemplateMapResolver'     => 'ViewTemplateMapResolver',
            'Zend\View\Resolver\TemplatePathStack'       => 'ViewTemplatePathStack',
            'Zend\View\Resolver\AggregateResolver'       => 'ViewResolver',
            'Zend\View\Resolver\ResolverInterface'       => 'ViewResolver',
        ],
        'invokables'         => [
            'SharedEventManager'   => 'Zend\EventManager\SharedEventManager',

            // From ServiceListenerFactory
            //'DispatchListener'   => 'Zend\Mvc\DispatchListener',
            'RouteListener'        => 'Zend\Mvc\RouteListener',
            'MiddlewareListener'   => 'Zend\Mvc\MiddlewareListener',
            'ViewJsonRenderer'     => 'Zend\View\Renderer\JsonRenderer',
            'ViewFeedRenderer'     => 'Zend\View\Renderer\FeedRenderer',

            // Pi custom service
            'SendResponseListener' => 'Pi\Mvc\SendResponseListener',
            'ViewHelperManager'    => 'Pi\Mvc\Service\ViewHelperManager',
            'Config'               => 'Pi\Mvc\Service\Config',
            'ErrorStrategy'        => 'Pi\Mvc\View\Http\ErrorStrategy',
            'ViewStrategyListener' => 'Pi\Mvc\View\Http\ViewStrategyListener',
            'FeedStrategyListener' => 'Pi\Mvc\View\Http\FeedStrategyListener',
            'ApiStrategyListener'  => 'Pi\Mvc\View\Http\ApiStrategyListener',
        ],
        'factories'          => [
            'Application'                                => ApplicationFactory::class,
            //'config'                                   => 'Zend\Mvc\Service\ConfigFactory',
            'ControllerManager'                          => 'Zend\Mvc\Service\ControllerManagerFactory',
            //'ControllerPluginManager'                  => 'Zend\Mvc\Service\ControllerPluginManagerFactory',
            'ConsoleAdapter'                             => 'Zend\Mvc\Service\ConsoleAdapterFactory',
            'ConsoleExceptionStrategy'                   => ConsoleExceptionStrategyFactory::class,
            'ConsoleRouter'                              => ConsoleRouterFactory::class,
            'ConsoleRouteNotFoundStrategy'               => ConsoleRouteNotFoundStrategyFactory::class,
            'ConsoleViewManager'                         => 'Zend\Mvc\Service\ConsoleViewManagerFactory',
            'DependencyInjector'                         => DiFactory::class,
            'DiAbstractServiceFactory'                   => DiAbstractServiceFactoryFactory::class,
            'DiServiceInitializer'                       => DiServiceInitializerFactory::class,
            'DiStrictAbstractServiceFactory'             => DiStrictAbstractServiceFactoryFactory::class,
            'DispatchListener'                           => 'Zend\Mvc\Service\DispatchListenerFactory',
            'FilterManager'                              => 'Zend\Mvc\Service\FilterManagerFactory',
            'FormAnnotationBuilder'                      => 'Zend\Mvc\Service\FormAnnotationBuilderFactory',
            'FormElementManager'                         => 'Zend\Mvc\Service\FormElementManagerFactory',
            'HttpExceptionStrategy'                      => HttpExceptionStrategyFactory::class,
            'HttpMethodListener'                         => 'Zend\Mvc\Service\HttpMethodListenerFactory',
            'HttpRouteNotFoundStrategy'                  => HttpRouteNotFoundStrategyFactory::class,
            'HttpRouter'                                 => HttpRouterFactory::class,
            'HttpViewManager'                            => 'Zend\Mvc\Service\HttpViewManagerFactory',
            'HydratorManager'                            => 'Zend\Mvc\Service\HydratorManagerFactory',
            'InjectTemplateListener'                     => 'Zend\Mvc\Service\InjectTemplateListenerFactory',
            'InputFilterManager'                         => 'Zend\Mvc\Service\InputFilterManagerFactory',
            'LogProcessorManager'                        => 'Zend\Mvc\Service\LogProcessorManagerFactory',
            'LogWriterManager'                           => 'Zend\Mvc\Service\LogWriterManagerFactory',
            //'MvcTranslator'                            => 'Zend\Mvc\Service\TranslatorServiceFactory',
            'PaginatorPluginManager'                     => 'Zend\Mvc\Service\PaginatorPluginManagerFactory',
            'Request'                                    => 'Zend\Mvc\Service\RequestFactory',
            'Response'                                   => 'Zend\Mvc\Service\ResponseFactory',
            //'Router'                                   => 'Zend\Mvc\Service\RouterFactory',
            'RoutePluginManager'                         => 'Zend\Mvc\Service\RoutePluginManagerFactory',
            'SerializerAdapterManager'                   => 'Zend\Mvc\Service\SerializerAdapterPluginManagerFactory',
            'TranslatorPluginManager'                    => 'Zend\Mvc\Service\TranslatorPluginManagerFactory',
            'ValidatorManager'                           => 'Zend\Mvc\Service\ValidatorManagerFactory',
            View\Console\DefaultRenderingStrategy::class => InvokableFactory::class,
            //'ViewHelperManager'                        => 'Zend\Mvc\Service\ViewHelperManagerFactory',
            View\Http\DefaultRenderingStrategy::class    => HttpDefaultRenderingStrategyFactory::class,
            'ViewFeedStrategy'                           => 'Zend\Mvc\Service\ViewFeedStrategyFactory',
            'ViewJsonStrategy'                           => 'Zend\Mvc\Service\ViewJsonStrategyFactory',
            'ViewManager'                                => 'Zend\Mvc\Service\ViewManagerFactory',
            //'ViewResolver'                             => 'Zend\Mvc\Service\ViewResolverFactory',
            'ViewTemplateMapResolver'                    => 'Zend\Mvc\Service\ViewTemplateMapResolverFactory',
            'ViewTemplatePathStack'                      => 'Zend\Mvc\Service\ViewTemplatePathStackFactory',
            'ViewPrefixPathStackResolver'                => 'Zend\Mvc\Service\ViewPrefixPathStackResolverFactory',
            'Zend\Mvc\MiddlewareListener'                => InvokableFactory::class,
            'Zend\Mvc\RouteListener'                     => InvokableFactory::class,
            'Zend\Mvc\SendResponseListener'              => InvokableFactory::class,
            'Zend\View\Renderer\FeedRenderer'            => InvokableFactory::class,
            'Zend\View\Renderer\JsonRenderer'            => InvokableFactory::class,
            'Zend\View\Renderer\PhpRenderer'             => ViewPhpRendererFactory::class,
            'Zend\View\Strategy\PhpRendererStrategy'     => ViewPhpRendererStrategyFactory::class,
            'Zend\View\View'                             => ViewFactory::class,

            // Pi custom service
            'Application'                                => 'Pi\Mvc\Service\ApplicationFactory',
            'ControllerLoader'                           => 'Pi\Mvc\Service\ControllerLoaderFactory',
            'ControllerPluginManager'                    => 'Pi\Mvc\Service\ControllerPluginManagerFactory',
            'MvcTranslator'                              => 'Pi\Mvc\Service\TranslatorServiceFactory',
            'ViewResolver'                               => 'Pi\Mvc\Service\ViewResolverFactory',
        ],
        'abstract_factories' => [
            'Zend\Form\FormAbstractServiceFactory',
        ],
    ],

    // Listeners to be registered on Application::bootstrap
    'listeners'          => [
        'ViewStrategyListener',
    ],

    // ViewManager configuration
    'view_manager'       => [
        'display_not_found_reason' => true,
        'display_exceptions'       => true,
        'not_found_template'       => 'error-404',
        'exception_template'       => 'error',
        'error_template'           => 'error',
        'denied_template'          => 'error-denied',
        'layout'                   => 'layout-front',
        'layout_error'             => 'layout-simple',
        'layout_ajax'              => 'layout-content',

        'mvc_strategies' => [
            'ErrorStrategy',
        ],

        'strategies' => [
            'ViewJsonStrategy',
        ],
    ],

    // ViewHelper config placeholder
    'view_helper_config' => [],

    // Response sender config
    'send_response'      => [
        // Compression for response
        // By enabling response compression, bandwidth and response time can be decreased but CPU utilization will be increased
        // If compress is needed, it is highly recommended to enable it through web server
        // Or enable `zlib.output_compression` in php.ini
        // @see https://gist.github.com/taiwen/c077ba2c8a33356d8815 for instruction

        // Just in case compression is not enabled by web server or by PHP, specify following specs
        // @note PHP `zlib` extension is required
        'compress' => false,
    ],
];

Do you have any idea ?


Originally posted by @voltan at zendframework/zend-mvc#311

RESTful: Handle single field request with empty value

Controller/AbstractRestfulController

There is no way to PUT/PATCH object with single field to empty value.

PUT /item/1
Content-Type: application/x-www-form-urlencoded

name=

Request payload is interpreted as string ($data = 'name=';) regardless Content-Type.
Proper value is $data = ['name' => ''];

I think ideally is split behaviour by Content-Type but that follows to huge BC. (see testCanReceiveStringAsRequestContent)

My pull request handle just one situation (example above) by header.


Originally posted by @autowp at zendframework/zend-mvc#251

[WIP]Drop module manager

This PR removes ModuleManager from MVC, removes dependency on its ServiceListener and changes factories for various managers that depended on it to pull config from container instead. Container is now expected to be configured before application is created.

Main container is no longer required to be ServiceManager. To accommodate that change, EventManager initializer is removed. Should users need it, they should implement it in userland code but preferable approach, however, is to inject dependencies explicitly.

Update: Bootstrapper introduced by this PR was dropped as it provided little value, considering conceptual order of early Application lifecycle stages.

Introduced new ApplicationListenerProvider service which is a listener aggregate that provides default listeners and pulls list of listeners from main config: $config[Zend\Mvc\Application::class]['listeners'] = []. Entries are either a container id string or instance of listener aggregate interface. This is one of the parts to be replaced as part of eventual migration to PSR event manager.

Application::init() helper method is dropped. zend-mvc application setup is expected to resemble that of zend-expressive:

// config/config.php
$aggregator = new ConfigAggregator([
    // ...
    Zend\Mvc\ConfigProvider::class,
    Zend\Router\ConfigProvider::class,

    // Default Application module config
    Application\ConfigProvider::class,

    new PhpFileProvider(realpath(__DIR__) . '/autoload/{{,*.}global,{,*.}local}.php'),
    // ...
], $cacheConfig['config_cache_path']);

return $aggregator->getMergedConfig();
// public/index.php
use Zend\Mvc\Application;

// ...
chdir(dirname(__DIR__));
require 'vendor/autoload.php';
 
(function () {
    $container = require 'config/container.php';
    $app = $container->get(Application::class);
    $app->run();
})();

Back in the time, module manager was introduced to provide basic packaging support, module loading, autoloading, config loading and merging. Number of important things happened since then.
Composer emerged and became a standard package manager in php world. It solved packaging and autoloading needs. Module is no longer need to be registered with zend-service manager, located and loaded in order to register autoloading rules it provides.
No longer constrained by autoloading, dedicated ConfigAggregator was able to handle config loading and merging in a simple and clean way.
Since service configuration is available before container is created, Zend\ModuleManager\Listener\ServiceListener for various plugin managers is obsoleted and could be replaced by regular factories. ( This PR did exactly that, look at eg Zend\Mvc\Container\ControllerManagerFactory)

Second most used module feature is Module::onBootstrap(). Just a convenience method for providing listener for zend-mvc bootstrap event. Zend-modulemanager registered those during module loading. Now, with config available early, factories for Zend\Mvc\Application could pull from config and register a list of extra listener aggregates ($config[Zend\Mvc\Application::class]['listeners'] = []). Listener aggregates themselves could be managed by container with all the power and flexibility that gives.

Module can be closely replicated with just a config provider:

namespace MyPackage;

use Zend\EventManager\ListenerAggregateInterface;
use Zend\Mvc\MvcEvent;
use Zend\ServiceManager\Factory\InvokableFactory;
 
class ConfigProvider implements ListenerAggregateInterface
{
   /**
    * Configuration
    */
   public function __invoke() : array
   {
       return [
           Application::class => [
               'listeners' => [
                   static::class,
               ]
           ],
           'dependencies' => [
               'factories' => [
                   static::class => InvokableFactory::class,
               ]
           ]
       ];
   }
   
   public function onBootstrap(MvcEvent $event)
   {
       $event->getApplication();
       // ...
   }

   public function attach(EventManagerInterface $events, $priority = 1)
   {
       $events->attach(MvcEvent::EVENT_BOOTSTRAP, [$this, 'onBootstrap']);
   }
}

Note that this PR provides no convenience wrapper for that use case at this time since upcoming PSR-14 for Event Manager is expected to be accepted before 4.0 is ready.


Overall, dropping module manager from zend-mvc greatly simplifies whole zend-mvc application setup and brings zend-mvc more in line with newer zend-expressive and ConfigProviders usage in Zend Framework components.

TODO

  • Replace ServiceListener as a configurator for plugin managers with factories pulling config from config service
  • Drop module manager
  • Provide alternative way to configure and bootstrap application from config
  • Add ConfigProvider
  • Move all container configuration to ConfigProvider
  • Replace main ServiceManager container with PSR-11 ContainerInterface
    • Drop EventManager initializer
    • Update all factories to PSR-11
  • Document changes

Originally posted by @Xerkus at zendframework/zend-mvc#273

support zend-stratigility 3?

originally i submitted issue at ZendSkeletonApplication repo zendframework/ZendSkeletonApplication#433 , which seems should be here

When I tried to use middleware in zend-mvc 3, it require to install zend-stratigility as it seems it no longer required, so I add the zend-stratigility to require with command:

composer require zendframework/zend-stratigility

and it installed the zend-stratigility 3. After it installed, I got the following error:

( ! ) Fatal error: Uncaught Error: Call to undefined method Zend\Stratigility\MiddlewarePipe::setResponsePrototype() in /Users/samsonasik/www/zf-mvc3/vendor/zendframework/zend-mvc/src/MiddlewareListener.php on line 134
( ! ) Error: Call to undefined method Zend\Stratigility\MiddlewarePipe::setResponsePrototype() in /Users/samsonasik/www/zf-mvc3/vendor/zendframework/zend-mvc/src/MiddlewareListener.php on line 134

So, I downgraded the version to v2 with command:

composer require zendframework/zend-stratigility:^2.0

And it works.

How about support zend-stratigility v3 as well?


Originally posted by @samsonasik at zendframework/zend-mvc#283

AbstractRestfulController's onDispatch - set action/method parameter prior dispatch

AbstractRestfulController: Set action/method parameter prior dispatch

I've wrote an authentication module to authenticate users and setup authentication chains..
It registers a listener to the MvcEvent::EVENT_DISPATCH@ AbstractActionController
The authenticator can either allow or kill the request depending on the configuration. We can dictate, in the configuration, the list of controllers that requires authentication as well as indicating which controller's action to require authentication.

The above would fail if we register the listener @ AbstractController as the action parameter is not yet set when the callback is fired. It is set only after processing the request (see AbstractRestfulController.php) or if the action is already registered by the router.

Our target is to distinguish between various "actions" the restful controller is mapping to, to filter unauthenticated users on a per-action or per-restful-method basis.
While it is possible to achieve the above by embedding additional checkers in the header of each method, we are hoping to achieve it by registering a listener for convenience.

It boils down to setting an additional parameter (e.g. method) to indicate which method will fire, and to authenticate, that parameter must be readable before the request is dispatched by the restful controller.

I have not yet dived into the internals, but what about an early dispatch listener that will set the method parameter according to the mappings of AbstractRestfulController?


Originally posted by @alichry at zendframework/zend-mvc#314

ViewHelperManager Service cannot be created outside Application context

This issue has been moved from the zendframework repository as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html


Original Issue: https://api.github.com/repos/zendframework/zendframework/issues/7191
User: @boukeversteegh
Created On: 2015-02-06T13:54:40Z
Updated At: 2015-02-06T14:20:45Z
Body
To Bootstrap my unit tests, I had to use the ViewHelperManager to hydrate some entities (with zf-hal) and insert them in my ElasticSearch database, however since there is no Route and MvcEvent at this point, the following error occurred:

PHP Fatal error:  Call to a member function getRouteMatch() on null in
/var/www/app/vendor/zendframework/zendframework/library/Zend/Mvc/Service/ViewHelperManagerFactory.php on line 70

Comment

User: @stefanotorresi
Created On: 2015-02-06T14:20:45Z
Updated At: 2015-02-06T14:20:45Z
Body
The factory is meant to be used within an initialized Zend\Mvc\Application. In your test, either set up a test application running init() explicitly with a mock config, or override the url plugin factory.



Originally posted by @GeeH at zendframework/zend-mvc#176

Class names for ServiceListenerFactory

I noticed that most services defined in the Zend\Mvc\Service\ServiceListenerFactory still use strings for the services names instead of class names.

https://github.com/zendframework/zend-mvc/blob/develop/src/Service/ServiceListenerFactory.php

It looks a little inconsequent in a factory when all services are requested by class names except the very important ViewHelperManager for example. Is there a chance to get this sorted?

Example:

namespace UserFrontend\Authorization;

use Interop\Container\ContainerInterface;
use UserModel\Permissions\UserAcl;
use Zend\Authentication\AuthenticationService;
use Zend\ServiceManager\Factory\FactoryInterface;
use Zend\View\Helper\Navigation;

class AuthorizationListenerFactory implements FactoryInterface
{
    public function __invoke(
        ContainerInterface $container,
        $requestedName,
        array $options = null
    ) {
        $viewHelperManager = $container->get('ViewHelperManager');

        $authService      = $container->get(AuthenticationService::class);
        $userAcl          = $container->get(UserAcl::class);
        $navigationHelper = $viewHelperManager->get(Navigation::class);

        $authorizationListener = new AuthorizationListener(
            $authService, $userAcl, $navigationHelper
        );

        return $authorizationListener;
    }
}

Originally posted by @RalfEggert at zendframework/zend-mvc#186

Inject parameters into controller actions

Feature Request

Q A
New Feature yes
RFC no
BC Break no

Summary

The summary of the problem I encountered can be found on the Laminas forum.

In short, I would like to be able to inject parameters into controller action functions so that I don't have to fetch/cast them via the Request object, either on top of the action, producing a large clutter of repetitive code lines, neither throughout in the code to avoid the clutter which only makes it more difficult to understand the request the action is supposed to handle.

The mechanism I'm referring too is achieved in the Symfony world with Param Converters or with the @RequestBody annotation in Spring Framework

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.