Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/4.0.x' into 3.19.x-merge-up-in…
Browse files Browse the repository at this point in the history
…to-4.0.x_BwqaMWP9

# Conflicts:
#	psalm-baseline.xml
#	src/SplPriorityQueue.php
  • Loading branch information
gsteel committed Jan 19, 2024
2 parents 6a192dd + 6256dda commit 45b9dca
Show file tree
Hide file tree
Showing 18 changed files with 528 additions and 515 deletions.
125 changes: 125 additions & 0 deletions docs/book/v4/console-helper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Console Helper

Writing one-off scripts or vendor binaries for a package is often problematic:

- You need to parse arguments manually.
- You need to send output to the console in a meaningful fashion:
- Using `STDOUT` for meaningful, expected output
- Using `STDERR` for error messages
- Ensuring any line breaks are converted to `PHP_EOL`
- Optionally, using console colors to provide context, which means:
- Detecting whether or not the console supports colors in the first place
- Providing appropriate escape sequences to produce color

`Laminas\Stdlib\ConsoleHelper` helps to address the second major bullet point and
all beneath it in a minimal fashion.

## Usage

Typical usage is to instantiate a `ConsoleHelper`, and call one of its methods:

```php
use Laminas\Stdlib\ConsoleHelper;

$helper = new ConsoleHelper();
$helper->writeLine('This is output');
```

You can optionally pass a PHP stream resource to the constructor, which will be
used to determine whether or not color support is available:

```php
$helper = new ConsoleHelper($stream);
```

By default, it assumes `STDOUT`, and tests against that.

## Available methods

`ConsoleHelper` provides the following methods.

### colorize

- `colorize(string $string) : string`

`colorize()` accepts a formatted string, and will then apply ANSI color
sequences to them, if color support is detected.

The following sequences are currently supported:

- `<info>...</info>` will apply a green color sequence around the provided text.
- `<error>...</error>` will apply a red color sequence around the provided text.

You may mix multiple sequences within the same stream.

### write

- `write(string $string, bool $colorize = true, resource $stream = STDOUT) : void`

Emits the provided `$string` to the provided `$stream` (which defaults to
`STDOUT` if not provided). Any EOL sequences are convered to `PHP_EOL`. If
`$colorize` is `true`, the string is first passed to `colorize()` as well.

### writeline

- `writeLine(string $string, bool $colorize = true, resource $stream = STDOUT) : void`

Same as `write()`, except it also appends a `PHP_EOL` sequence to the `$string`.

### writeErrorMessage

- `writeErrorMessage(string $message)`

Wraps `$message` in an `<error></error>` sequence, and passes it to
`writeLine()`, using `STDERR` as the `$stream`.

## Example

Below is an example class that accepts an argument list, and determines how and
what to emit.

```php
namespace Foo;

use Laminas\Stdlib\ConsoleHelper;

class HelloWorld
{
private $helper;

public function __construct(ConsoleHelper $helper = null)
{
$this->helper = $helper ?: new ConsoleHelper();
}

public function __invoke(array $args)
{
if (! count($args)) {
$this->helper->writeErrorMessage('Missing arguments!');
return;
}

if (count($args) > 1) {
$this->helper->writeErrorMessage('Too many arguments!');
return;
}

$target = array_shift($args);

$this->helper->writeLine(sprintf(
'<info>Hello</info> %s',
$target
));
}
}
```

## When to upgrade

`ConsoleHelper` is deliberately simple, and assumes that your primary need for
console tooling is for output considerations.

If you need to parse complex argument strings, we recommend using
[symfony/console](http://symfony.com/doc/current/components/console.html),
as this package provides those capabilities, as well as far more colorization
and console feature detection facilities.
46 changes: 46 additions & 0 deletions docs/book/v4/migration/v3-to-v4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Migration from Version 3 to 4

Version 4 of `laminas-stdlib` contains a number of backwards incompatible changes. This guide is intended to help you upgrade from the version 3 series to version 4.

## New Features

### Parameter, Property and Return Type Hints Have Been Added Throughout

All classes have been updated to make use of parameter and return types. In general usage, this should not pose too many problems, providing you have been passing the previously documented types to the methods that have changed, however, it is advisable to audit your existing usage of the library for potential type errors. A static analysis tool like Psalm or PHPStan will help you with this.

The addition of property, parameter and return types will cause fatal errors for extending classes that re-define those properties or override changed methods. If you have extended from any classes in laminas-stdlib, you should check that property types and method signatures are compatible and update them if they are not aligned.

### `PriorityQueue::toArray()` Now Returns Data in Order of Priority

In previous versions, `PriorityQueue::toArray()` returned data in insertion order. This method now returns data in priority order making it effectively the same as `iterator_to_array($queue)`, with the exception that you can pass extraction flags to `PriorityQueue::toArray()`.

## Removed Features

- The `JsonSerializable` interface, deprecated in the 3.x series has been removed
- `ArrayUtils::filter()`, deprecated in the 3.x series and its related constants `ArrayUtils::ARRAY_FILTER_USE_BOTH` and `ArrayUtils::ARRAY_FILTER_USE_KEY` have been removed

## Signature Changes

### Breaking Changes to Return Types in Iterable Classes

A number of Queue, Stack and Heap implementations have different return types in order to align with the built-in PHP interfaces that they implement such as `Iterator` or `IteratorAggregate` etc.

#### `insert()` Signature Change for Iterable Types

PHP's built-in `\SplPriorityQueue`, `\SplHeap`, `\SplMinHeap` and other similar classes return `true` from the `insert()` method. Classes that either extend from or have similar semantics to these built-in types previously had varying return types such as `void`, `self`. From version 4, the method signature for `insert()` where implemented has been changed to `bool` _(true)_.

- `Laminas\Stdlib\SplPriorityQueue::insert()` previously returned `void`. This has been changed to `bool` to align with `\SplPriorityQueue`
- `Laminas\Stdlib\PriorityQueue::insert()` previously returned `self`. This has been changed to `bool` for consistency
- `Laminas\Stdlib\PriorityList::insert()` previously returned `void`. This has been changed to `bool` for consistency
- `Laminas\Stdlib\FastPriorityQueue::insert()` previously returned `void`. This has been changed to `bool` for consistency

#### Other Method Signature Changes

##### `Laminas\Stdlib\PriorityList`

- `next()` previously returned `false` or the node value at the next index and now returns `void` to align with the `Iterator` interface.
- `setPriority()` previously returned `self` and now returns `void` for consistency.

## Deprecations

None.
11 changes: 8 additions & 3 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ nav:
- v3:
- "Console Helper": v3/console-helper.md
- Migration: v3/migration.md
- v4:
- "Console Helper": v4/console-helper.md
- Migration:
- "Migration from Version 3 to 4": v4/migration/v3-to-v4.md
site_name: laminas-stdlib
site_description: Laminas\Stdlib
repo_url: 'https://github.com/laminas/laminas-stdlib'
extra:
project: Components
current_version: v3
current_version: v4
versions:
- v3
- v4
plugins:
- redirects:
redirect_maps:
migration.md: v3/migration.md
console-helper.md: v3/console-helper.md
migration.md: v4/migration.md
console-helper.md: v4/console-helper.md
90 changes: 24 additions & 66 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.20.0@3f284e96c9d9be6fe6b15c79416e1d1903dcfef4">
<files psalm-version="5.15.0@5c774aca4746caf3d239d9c8cadb9f882ca29352">
<file src="src/AbstractOptions.php">
<DocblockTypeContradiction>
<code><![CDATA[! is_array($options) && ! $options instanceof Traversable]]></code>
Expand All @@ -25,9 +25,6 @@
<DocblockTypeContradiction>
<code><![CDATA[! is_array($data) && ! is_object($data)]]></code>
</DocblockTypeContradiction>
<InvalidCast>
<code>$key</code>
</InvalidCast>
<InvalidPropertyAssignmentValue>
<code><![CDATA[$this->storage]]></code>
</InvalidPropertyAssignmentValue>
Expand Down Expand Up @@ -102,20 +99,21 @@
</file>
<file src="src/FastPriorityQueue.php">
<DocblockTypeContradiction>
<code>is_int($priority)</code>
<code><![CDATA[throw new Exception\InvalidArgumentException("The extract flag specified is not valid")]]></code>
</DocblockTypeContradiction>
<ImplementedReturnTypeMismatch>
<code>TValue|int|array{data: TValue|false, priority: int|null}|false</code>
<code>TValue|int|array{data: TValue, priority: int}|null</code>
</ImplementedReturnTypeMismatch>
<LessSpecificReturnStatement>
<code>$array</code>
<code>$value</code>
<code><![CDATA[match ($this->extractFlag) {
self::EXTR_DATA => current($this->values[$this->maxPriority]),
self::EXTR_PRIORITY => $this->maxPriority,
self::EXTR_BOTH => [
'data' => current($this->values[$this->maxPriority]),
'priority' => $this->maxPriority,
],
}]]></code>
</LessSpecificReturnStatement>
<MethodSignatureMustProvideReturnType>
<code>serialize</code>
<code>unserialize</code>
</MethodSignatureMustProvideReturnType>
<MixedArgument>
<code><![CDATA[$item['data']]]></code>
<code><![CDATA[$item['priority']]]></code>
Expand All @@ -129,8 +127,7 @@
<code><![CDATA[$this->maxPriority]]></code>
</MixedAssignment>
<MoreSpecificReturnType>
<code>TValue|int|array{data: TValue, priority: int}|false</code>
<code><![CDATA[list<TValue|int|array{data: TValue, priority: int}>]]></code>
<code>TValue|int|array{data: TValue, priority: int}|null</code>
</MoreSpecificReturnType>
<PossiblyNullArrayOffset>
<code><![CDATA[$this->priorities]]></code>
Expand All @@ -139,8 +136,6 @@
<code><![CDATA[$this->values]]></code>
<code><![CDATA[$this->values]]></code>
<code><![CDATA[$this->values]]></code>
<code><![CDATA[$this->values]]></code>
<code><![CDATA[$this->values]]></code>
</PossiblyNullArrayOffset>
</file>
<file src="src/Glob.php">
Expand Down Expand Up @@ -181,48 +176,17 @@
<code>setMetadata</code>
</MissingReturnType>
</file>
<file src="src/PriorityList.php">
<FalsableReturnStatement>
<code><![CDATA[$node ? $node['data'] : false]]></code>
</FalsableReturnStatement>
<InvalidFalsableReturnType>
<code>current</code>
</InvalidFalsableReturnType>
<InvalidReturnStatement>
<code><![CDATA[$node ? $node['data'] : false]]></code>
</InvalidReturnStatement>
<MixedReturnTypeCoercion>
<code>next</code>
</MixedReturnTypeCoercion>
<RedundantCastGivenDocblockType>
<code>(int) $priority</code>
<code>(int) $priority</code>
</RedundantCastGivenDocblockType>
</file>
<file src="src/PriorityQueue.php">
<MethodSignatureMustProvideReturnType>
<code>serialize</code>
<code>unserialize</code>
</MethodSignatureMustProvideReturnType>
</file>
<file src="src/SplPriorityQueue.php">
<DocblockTypeContradiction>
<code><![CDATA[! array_key_exists('priority', $item)
|| ! is_array($item['priority'])]]></code>
<code><![CDATA[! is_array($item['priority'])]]></code>
<code>is_array($item)</code>
<code>is_array($priority)</code>
</DocblockTypeContradiction>
<ImplementedReturnTypeMismatch>
<code>void</code>
</ImplementedReturnTypeMismatch>
<InvalidArgument>
<code>$priority</code>
<code>$priority</code>
</InvalidArgument>
<MethodSignatureMustProvideReturnType>
<code>serialize</code>
<code>unserialize</code>
</MethodSignatureMustProvideReturnType>
<MixedArgument>
<code><![CDATA[$item['data']]]></code>
</MixedArgument>
<MixedArgumentTypeCoercion>
<code>$toUnserialize</code>
</MixedArgumentTypeCoercion>
</file>
<file src="src/StringUtils.php">
<DocblockTypeContradiction>
Expand Down Expand Up @@ -326,23 +290,12 @@
</UndefinedInterfaceMethod>
</file>
<file src="test/ArrayUtilsTest.php">
<DeprecatedConstant>
<code>ArrayUtils::ARRAY_FILTER_USE_BOTH</code>
<code>ArrayUtils::ARRAY_FILTER_USE_KEY</code>
</DeprecatedConstant>
<DeprecatedMethod>
<code>ArrayUtils::filter($data, $callback, $flag)</code>
<code><![CDATA[ArrayUtils::filter([], "INVALID")]]></code>
</DeprecatedMethod>
<DuplicateArrayKey>
<code><![CDATA['-10000' => null]]></code>
</DuplicateArrayKey>
<MixedArgument>
<code>$test</code>
</MixedArgument>
<UndefinedFunction>
<code><![CDATA["INVALID"]]></code>
</UndefinedFunction>
</file>
<file src="test/CustomArrayObject.php">
<PropertyNotSetInConstructor>
Expand All @@ -365,7 +318,7 @@
</file>
<file src="test/FastPriorityQueueTest.php">
<MixedAssignment>
<code>$datum</code>
<code>$item</code>
<code>$test[]</code>
<code>$test[]</code>
<code>$test[]</code>
Expand Down Expand Up @@ -395,4 +348,9 @@
<code><![CDATA[$parameters->foof]]></code>
</UndefinedPropertyFetch>
</file>
<file src="test/SplPriorityQueueTest.php">
<MixedPropertyTypeCoercion>
<code>new SplPriorityQueue()</code>
</MixedPropertyTypeCoercion>
</file>
</files>
Loading

0 comments on commit 45b9dca

Please sign in to comment.