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

Merge release 3.8.0 into 4.0.x #176

Open
wants to merge 28 commits into
base: 4.0.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
121f5a0
Lock file maintenance
renovate[bot] Aug 5, 2024
ac1f308
Lock file maintenance
renovate[bot] Aug 26, 2024
b8526fd
PhpUnit Deprecations fix for PHPUnit8.4 support
Atul-glo35265 Oct 17, 2024
8ce8a5e
PhpUnit Deprecations fix for PHPUnit8.4 support
Atul-glo35265 Oct 17, 2024
8aaaee9
Merge pull request #172 from Atul-glo35265/php8.4_deprecation_fix
Xerkus Oct 18, 2024
d53c8f8
Lock file maintenance
renovate[bot] Oct 18, 2024
7a38c11
Fix docs formatting
Xerkus Oct 18, 2024
d569d62
Merge pull request #170 from laminas/renovate/lock-file-maintenance
Xerkus Oct 18, 2024
bfc2565
Lock file maintenance
renovate[bot] Oct 28, 2024
20d922a
Update to latest PHP 8.1 syntax
samsonasik Nov 3, 2024
61a9a8d
Lock file maintenance
renovate[bot] Nov 4, 2024
3d69a69
Lock file maintenance
renovate[bot] Nov 11, 2024
c4913a1
Add php 8.4 support
fezfez Nov 14, 2024
f3912e5
Remove Prophecy from unit tests
fezfez Nov 14, 2024
db3b635
Migrate to phpunit 10
fezfez Nov 14, 2024
49bb932
Migrate to phpunit 10
fezfez Nov 14, 2024
449fc49
Fix syntax deprecation in php 8.4
fezfez Nov 14, 2024
82d27e0
Fix syntax deprecation in php 8.4
fezfez Nov 14, 2024
183057f
Clean PHPunit config
fezfez Nov 14, 2024
0d268e4
Clean PHPunit config
fezfez Nov 14, 2024
a399c07
Check if the var is array or iterable before foreach
fezfez Nov 14, 2024
8a1860c
Clean PHPunit config
fezfez Nov 14, 2024
516b2cd
Clean PHPunit config
fezfez Nov 14, 2024
08dbead
Update lowest version for some package to ensure they work on php 8.4
fezfez Nov 14, 2024
331bb5c
Remove redundant check
fezfez Nov 14, 2024
7899bb5
Merge pull request #174 from fezfez/php8.4
gsteel Nov 14, 2024
a9410d4
Merge pull request #173 from samsonasik/update-to-latest-php81-syntax
gsteel Nov 14, 2024
53ba28b
Lock file maintenance
renovate[bot] Nov 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .laminas-ci.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"ignore_php_platform_requirements": {
"8.3": true
"8.4": true
}
}
12 changes: 5 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,20 @@
"extra": {
},
"require": {
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
"php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0",
"container-interop/container-interop": "^1.2",
"laminas/laminas-eventmanager": "^3.4",
"laminas/laminas-http": "^2.15",
"laminas/laminas-modulemanager": "^2.8",
"laminas/laminas-modulemanager": "^2.16",
"laminas/laminas-router": "^3.11.1",
"laminas/laminas-servicemanager": "^3.20.0",
"laminas/laminas-stdlib": "^3.6",
"laminas/laminas-view": "^2.14"
"laminas/laminas-stdlib": "^3.19",
"laminas/laminas-view": "^2.18.0"
},
"require-dev": {
"laminas/laminas-coding-standard": "^2.5.0",
"laminas/laminas-json": "^3.6",
"phpspec/prophecy": "^1.17.0",
"phpspec/prophecy-phpunit": "^2.0.2",
"phpunit/phpunit": "^9.6.13",
"phpunit/phpunit": "^10.5.38",
"webmozart/assert": "^1.11"
},
"suggest": {
Expand Down
1,136 changes: 367 additions & 769 deletions composer.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/book/mvc-event.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ The following listeners are only attached in a console context:

Class | Priority | Method Called | Description
------------------------------------------------|---------:|-----------------------------|------------
`Laminas\Mvc\View\Console\RouteNotFoundStrategy` | 1 | `handleRouteNotFoundError ` | Detect if an error is a "route not found" condition. If a “controller not found” or “invalid controller” error type is encountered, sets the response status code to 404.
`Laminas\Mvc\View\Console\RouteNotFoundStrategy` | 1 | `handleRouteNotFoundError` | Detect if an error is a "route not found" condition. If a “controller not found” or “invalid controller” error type is encountered, sets the response status code to 404.
`Laminas\Mvc\View\Console\ExceptionStrategy` | 1 | `prepareExceptionViewModel` | Create an exception view model, and sets the status code to 404.
`Laminas\Mvc\View\Console\InjectViewModelListener` | -100 | `injectViewModel` | Inserts the `ViewModel` (in this case, a `ConsoleModel`) and adds it to the `MvcEvent` object. It either (a) adds it as a child to the default, composed view model, or (b) replaces it if the result is marked as terminable.

Expand Down
14 changes: 7 additions & 7 deletions docs/book/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,13 +234,13 @@ generate a URL string from the provided parameters. It has the following
signature:

- `fromRoute(string $route = null, array $params = [], array $options = [], bool $reuseMatchedParams = false): string`, where:
- `$name`: the name of the route to use for URL generation.
- `$params`: Any parameter substitutions to use with the named route.
- `$options`: Options used by the router when generating the URL (e.g., `force_canonical`, `query`, etc.).
- `$reuseMatchedParams`: Whether or not to use route match parameters from the
current URL when generating the new URL. This will only affect cases where
the specified `$name` matches the currently matched route; the default is
`true`.
- `$name`: the name of the route to use for URL generation.
- `$params`: Any parameter substitutions to use with the named route.
- `$options`: Options used by the router when generating the URL (e.g., `force_canonical`, `query`, etc.).
- `$reuseMatchedParams`: Whether or not to use route match parameters from the
current URL when generating the new URL. This will only affect cases where
the specified `$name` matches the currently matched route; the default is
`true`.

> ### Requires MvcEvent
>
Expand Down
2 changes: 1 addition & 1 deletion docs/book/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ The associated class will then be instantiated and invoked.

Learn more about routing [in the laminas-router documentation](https://docs.laminas.dev/laminas-router/routing).

## Test it Out!
## Test it Out

Create a new vhost pointing its document root to the `public` directory of your application, and fire it up in a browser.
You should see the default homepage template of [laminas-mvc-skeleton](https://github.com/laminas/laminas-mvc-skeleton).
Expand Down
2 changes: 1 addition & 1 deletion docs/book/send-response-event.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Class | Priority | Method
------------------------------------------------------------ | -------: | ------------- | -----------
`Laminas\Mvc\SendResponseListener\PhpEnvironmentResponseSender` | -1000 | `__invoke` | This is used in HTTP contexts (this is the most often used).
`Laminas\Mvc\SendResponseListener\ConsoleResponseSender` | -2000 | `__invoke` | This is used in console contexts.
`Laminas\Mvc\SendResponseListener\SimpleStreamResponseSender` | -3000 | `__invoke` |
`Laminas\Mvc\SendResponseListener\SimpleStreamResponseSender` | -3000 | `__invoke` | This is used in HTTP context to pass through stream directly to output.

Because each listener has negative priority, adding your own logic to modify the
`Response` involves adding a new listener without priority (as priority defaults
Expand Down
62 changes: 33 additions & 29 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="./vendor/autoload.php"
convertDeprecationsToExceptions="true"
colors="true">
<coverage includeUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
</coverage>

<testsuites>
<testsuite name="laminas-mvc Test Suite">
<directory>./test/</directory>
</testsuite>
</testsuites>

<groups>
<exclude>
<group>disable</group>
</exclude>
</groups>

<php>
<ini name="date.timezone" value="UTC"/>
<!-- OB_ENABLED should be enabled for some tests to check if all
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="./vendor/autoload.php"
colors="true"
cacheDirectory=".phpunit.cache"
failOnDeprecation="true"
failOnNotice="true"
failOnWarning="true"
failOnPhpunitDeprecation="true"
displayDetailsOnPhpunitDeprecations="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true">
<testsuites>
<testsuite name="laminas-mvc Test Suite">
<directory>./test/</directory>
</testsuite>
</testsuites>
<groups>
<exclude>
<group>disable</group>
</exclude>
</groups>
<php>
<ini name="date.timezone" value="UTC"/>
<!-- OB_ENABLED should be enabled for some tests to check if all
functionality works as expected. Such tests include those for
Laminas\Soap and Laminas\Session, which require that headers not be
sent in order to work. -->
<env name="TESTS_LAMINAS_OB_ENABLED" value="false"/>
</php>
<env name="TESTS_LAMINAS_OB_ENABLED" value="false"/>
</php>
<source>
<include>
<directory suffix=".php">./src</directory>
</include>
</source>
</phpunit>
8 changes: 4 additions & 4 deletions src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ class Application implements
*/
public function __construct(
protected ServiceManager $serviceManager,
EventManagerInterface $events = null,
RequestInterface $request = null,
ResponseInterface $response = null
?EventManagerInterface $events = null,
?RequestInterface $request = null,
?ResponseInterface $response = null
) {
$this->setEventManager($events ?: $serviceManager->get('EventManager'));
$this->request = $request ?: $serviceManager->get('Request');
Expand Down Expand Up @@ -200,7 +200,7 @@ public function setEventManager(EventManagerInterface $eventManager)
{
$eventManager->setIdentifiers([
self::class,
$this::class,
static::class,
]);
$this->events = $eventManager;
return $this;
Expand Down
6 changes: 3 additions & 3 deletions src/Controller/AbstractController.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ abstract public function onDispatch(MvcEvent $e);
* @param null|Response $response
* @return Response|mixed
*/
public function dispatch(Request $request, Response $response = null)
public function dispatch(Request $request, ?Response $response = null)
{
$this->request = $request;
if (! $response) {
Expand Down Expand Up @@ -147,7 +147,7 @@ public function getResponse()
*/
public function setEventManager(EventManagerInterface $events)
{
$className = $this::class;
$className = static::class;

$identifiers = [
self::class,
Expand Down Expand Up @@ -258,7 +258,7 @@ public function setPluginManager(PluginManager $plugins)
* @param null|array $options Options to pass to plugin constructor (if not already instantiated)
* @return mixed
*/
public function plugin($name, array $options = null)
public function plugin($name, ?array $options = null)
{
return $this->getPluginManager()->get($name, $options);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/AbstractRestfulController.php
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ public function notFoundAction()
* @return mixed|Response
* @throws Exception\InvalidArgumentException
*/
public function dispatch(Request $request, Response $response = null)
public function dispatch(Request $request, ?Response $response = null)
{
if (! $request instanceof HttpRequest) {
throw new InvalidArgumentException('Expected an HTTP request');
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/LazyControllerAbstractFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class LazyControllerAbstractFactory implements AbstractFactoryInterface
*
* @return DispatchableInterface
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null)
{
$reflectionClass = new ReflectionClass($requestedName);

Expand Down
4 changes: 2 additions & 2 deletions src/Controller/MiddlewareController.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
final class MiddlewareController extends AbstractController
{
public function __construct(
private MiddlewarePipe $pipe,
private ResponseInterface $responsePrototype,
private readonly MiddlewarePipe $pipe,
private readonly ResponseInterface $responsePrototype,
EventManagerInterface $eventManager,
MvcEvent $event
) {
Expand Down
12 changes: 6 additions & 6 deletions src/Controller/Plugin/AcceptableViewModelSelector.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class AcceptableViewModelSelector extends AbstractPlugin
*
* @var string Default ViewModel
*/
protected $defaultViewModelName = 'Laminas\View\Model\ViewModel';
protected $defaultViewModelName = \Laminas\View\Model\ViewModel::class;

/**
* Detects an appropriate viewmodel for request.
Expand All @@ -57,7 +57,7 @@ class AcceptableViewModelSelector extends AbstractPlugin
* @return ModelInterface|null
*/
public function __invoke(
array $matchAgainst = null,
?array $matchAgainst = null,
$returnDefault = true,
&$resultReference = null
) {
Expand All @@ -74,7 +74,7 @@ public function __invoke(
* @return ModelInterface|null
*/
public function getViewModel(
array $matchAgainst = null,
?array $matchAgainst = null,
$returnDefault = true,
&$resultReference = null
) {
Expand All @@ -100,7 +100,7 @@ public function getViewModel(
* @return ModelInterface|null Returns null if $returnDefault = false and no match could be made
*/
public function getViewModelName(
array $matchAgainst = null,
?array $matchAgainst = null,
$returnDefault = true,
&$resultReference = null
) {
Expand All @@ -121,7 +121,7 @@ public function getViewModelName(
* @param array $matchAgainst (optional) The Array to match against
* @return AbstractFieldValuePart|null The object that was matched
*/
public function match(array $matchAgainst = null)
public function match(?array $matchAgainst = null)
{
$request = $this->getRequest();
$headers = $request->getHeaders();
Expand Down Expand Up @@ -176,7 +176,7 @@ public function getDefaultViewModelName()
* @param array $matchAgainst (optional) The Array to match against
* @return AcceptableViewModelSelector provides fluent interface
*/
public function setDefaultMatchAgainst(array $matchAgainst = null)
public function setDefaultMatchAgainst(?array $matchAgainst = null)
{
$this->defaultMatchAgainst = $matchAgainst;
return $this;
Expand Down
8 changes: 4 additions & 4 deletions src/Controller/Plugin/Forward.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ public function getListenersToDetach()
// from getting attached to the ViewModel twice when a calling action
// returns the output generated by a forwarded action.
$this->listenersToDetach = [[
'id' => 'Laminas\Stdlib\DispatchableInterface',
'id' => \Laminas\Stdlib\DispatchableInterface::class,
'event' => MvcEvent::EVENT_DISPATCH,
'class' => 'Laminas\Mvc\View\Http\InjectViewModelListener',
'class' => \Laminas\Mvc\View\Http\InjectViewModelListener::class,
]];
}
return $this->listenersToDetach;
Expand Down Expand Up @@ -101,7 +101,7 @@ public function setListenersToDetach($listeners)
* @throws Exception\DomainException if composed controller does not define InjectApplicationEventInterface
* or Locator aware; or if the discovered controller is not dispatchable
*/
public function dispatch($name, array $params = null)
public function dispatch($name, ?array $params = null)
{
$event = clone($this->getEvent());

Expand Down Expand Up @@ -231,7 +231,7 @@ protected function getEvent()
if (! $controller instanceof InjectApplicationEventInterface) {
throw new DomainException(sprintf(
'Forward plugin requires a controller that implements InjectApplicationEventInterface; received %s',
(is_object($controller) ? $controller::class : var_export($controller, 1))
(get_debug_type($controller))
));
}

Expand Down
2 changes: 1 addition & 1 deletion src/Controller/Plugin/Service/ForwardFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ForwardFactory implements FactoryInterface
* @return Forward
* @throws ServiceNotCreatedException if Controllermanager service is not found in application service locator
*/
public function __invoke(ContainerInterface $container, $name, array $options = null)
public function __invoke(ContainerInterface $container, $name, ?array $options = null)
{
if (! $container->has('ControllerManager')) {
throw new ServiceNotCreatedException(sprintf(
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/PluginManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class PluginManager extends AbstractPluginManager
* @param null|array $options Options to use when creating the instance.
* @return DispatchableInterface
*/
public function get($name, array $options = null)
public function get($name, ?array $options = null)
{
$plugin = parent::get($name, $options);
$this->injectController($plugin);
Expand Down
2 changes: 1 addition & 1 deletion src/DispatchListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
*/
class DispatchListener extends AbstractListenerAggregate
{
public function __construct(private ControllerManager $controllerManager)
public function __construct(private readonly ControllerManager $controllerManager)
{
}

Expand Down
2 changes: 1 addition & 1 deletion src/MiddlewareListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ protected function marshalInvalidMiddleware(
$middlewareName,
MvcEvent $event,
Application $application,
Exception $exception = null
?Exception $exception = null
) {
$event->setName(MvcEvent::EVENT_DISPATCH_ERROR);
$event->setError($type);
Expand Down
16 changes: 10 additions & 6 deletions src/ResponseSender/AbstractResponseSender.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@ public function sendHeaders(SendResponseEvent $event)

$response = $event->getResponse();

foreach ($response->getHeaders() as $header) {
if ($header instanceof MultipleHeaderInterface) {
header($header->toString(), false);
continue;
$headers = $response->getHeaders();

if (is_iterable($headers)) {
foreach ($response->getHeaders() as $header) {
if ($header instanceof MultipleHeaderInterface) {
header($header->toString(), false);
continue;
}
header($header->toString());
}
header($header->toString());
}

$status = $response->renderStatusLine();
header($status);
header((string) $status);

$event->setHeadersSent();
return $this;
Expand Down
2 changes: 1 addition & 1 deletion src/SendResponseListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function setEventManager(EventManagerInterface $eventManager)
{
$eventManager->setIdentifiers([
self::class,
$this::class,
static::class,
]);
$this->eventManager = $eventManager;
$this->attachDefaultListeners();
Expand Down
2 changes: 1 addition & 1 deletion src/Service/AbstractPluginManagerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ abstract class AbstractPluginManagerFactory implements FactoryInterface
* @param null|array $options
* @return AbstractPluginManager
*/
public function __invoke(ContainerInterface $container, $name, array $options = null)
public function __invoke(ContainerInterface $container, $name, ?array $options = null)
{
$options = $options ?: [];
$pluginManagerClass = static::PLUGIN_MANAGER_CLASS;
Expand Down
Loading