* 5.0:
Make PhpDocExtractor compatible with phpDocumentor v5
Reset question validator attempts only for actual stdin
bumped Symfony version to 5.0.11
updated VERSION for 5.0.10
updated CHANGELOG for 5.0.10
bumped Symfony version to 4.4.11
updated VERSION for 4.4.10
updated CHANGELOG for 4.4.10
* 4.4:
Make PhpDocExtractor compatible with phpDocumentor v5
Reset question validator attempts only for actual stdin
bumped Symfony version to 4.4.11
updated VERSION for 4.4.10
updated CHANGELOG for 4.4.10
Version 5 of phpDocumentor introduced some changes to the
`getTagsByName()` method that break the `PhpDocExtractor`.
More specific, it now returns an instance of `InvalidTag` instead of
`null` when parsing an invalid tag.
* 4.4: (27 commits)
[Serializer] minor cleanup
fix merge
Run PHP 8 as 7.4.99
Remove calls to deprecated ReflectionParameter::getClass().
[VarDumper] fix PHP 8 support
Add php 8 to travis.
[Cache] Accessing undefined constants raises an Error in php8
[Cache] allow DBAL v3
Skip Doctrine DBAL on php 8 until we have a compatible version.
[DomCrawler] Catch expected ValueError.
Made method signatures compatible with their corresponding traits.
[ErrorHandler] Apply php8 fixes from Debug component.
[DomCrawler] Catch expected ValueError.
[Validator] Catch expected ValueError.
[VarDumper] ReflectionFunction::isDisabled() is deprecated.
[BrowserKit] Raw body with custom Content-Type header
[PropertyAccess] Parse php 8 TypeErrors correctly.
[Intl] Fix call to ReflectionProperty::getValue() for static properties.
[HttpKernel] Prevent calling method_exists() with non-string values.
Fix wrong roles comparison
...
* 5.0:
[PhpUnitBridge] fix bad test
[4.4] CS fixes
[3.4] CS fixes
Disable phpunit verbosity
Queue name is a required parameter
[FrameworkBundle] display actual target for error in AssetsInstallCommand
Remove patches for Doctrine bugs and deprecations
[Mime] fix bad method call on "EmailAddressContains"
[DI][EventDispatcher] added contract for implementation
* 4.4:
[PhpUnitBridge] fix bad test
[4.4] CS fixes
[3.4] CS fixes
Disable phpunit verbosity
Queue name is a required parameter
[FrameworkBundle] display actual target for error in AssetsInstallCommand
Remove patches for Doctrine bugs and deprecations
[Mime] fix bad method call on "EmailAddressContains"
[DI][EventDispatcher] added contract for implementation
* 3.4:
[FrameworkBundle] display actual target for error in AssetsInstallCommand
Remove patches for Doctrine bugs and deprecations
[DI][EventDispatcher] added contract for implementation
* 5.0:
[PhpUnitBridge] add PolyfillTestCaseTrait::expectExceptionMessageMatches to provide FC with recent phpunit versions
[Messenger] Make sure redis transports are initialized correctly
Remove return type for Twig function workflow_metadata()
[DI] fix typo
* 4.4:
[PhpUnitBridge] add PolyfillTestCaseTrait::expectExceptionMessageMatches to provide FC with recent phpunit versions
[Messenger] Make sure redis transports are initialized correctly
Remove return type for Twig function workflow_metadata()
[DI] fix typo
* 5.0: (31 commits)
[HttpClient] NativeHttpClient should not send >1.1 protocol version
[HttpClient] fix support for non-blocking resource streams
[Mailer] Make sure you can pass custom headers to Mailgun
[Mailer] Remove line breaks in email attachment content
Update links to documentation
[Validator] Add the missing translations for the Arabic (ar) locale
ensure to expect no validation for the right reasons
[Security-Guard] fixed 35203 missing name tag in param docblock
[HttpClient] fix casting responses to PHP streams
[PhpUnitBridge] Add test case for @expectedDeprecation annotation
[PhpUnitBridge][SymfonyTestsListenerTrait] Remove $testsWithWarnings stack
[FrameworkBundle] Fix getUser() phpdoc in AbstractController
[Mailer] Fix addresses management in Sendgrid API payload
[Mailer][MailchimpBridge] Fix missing attachments when sending via Mandrill API
[Mailer][MailchimpBridge] Fix incorrect sender address when sender has name
[HttpClient] fix capturing SSL certificates with NativeHttpClient
Update year in license files
Update year in license files
[TwigBridge][Form] Added missing help messages in form themes
Update year in license files
...
* 5.0:
[Routing] fix tests
[DI] minor cleanup
[Form] group constraints when calling the validator
Remove wrong @group legacy annotations
[DependencyInjection] Fix dumping multiple deprecated aliases
allow button names to start with uppercase letter
Allow PHP ^7.2.5
States that the HttpClient provides a Http Async implementation
[Routing] Fix ContainerLoader and ObjectLoaderTest
[HttpKernel] Make ErrorListener::onKernelException()'s dispatcher argument explicit
[HttpKernel] Drop deprecated ExceptionListener
Removed extra whitespace
[Security] Fix best encoder not wired using migrate_from
* 4.4:
[travis] Fix build-packages script
Add types to constructors and private/final/internal methods (Batch III)
[HttpClient] Async HTTPlug client
[Messenger] Allow to configure the db index on Redis transport
[HttpClient] bugfix exploding values of headers
[VarDumper] Made all casters final
[VarDumper] Added a support for casting Ramsey/Uuid
Remove useless testCanCheckIfTerminalIsInteractive test case
[Validator] Add the missing translations for the Thai (\"th\") locale
[Routing] gracefully handle docref_root ini setting
[Validator] Fix ValidValidator group cascading usage
This PR was merged into the 5.0-dev branch.
Discussion
----------
[String] a new component for object-oriented strings management with an abstract unit system
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
This is a reboot of #22184 (thanks @hhamon for working on it) and a generalization of my previous work on the topic ([patchwork/utf8](https://github.com/tchwork/utf8)). Unlike existing libraries (including `patchwork/utf8`), this component provides a unified API for the 3 unit systems of strings: bytes, code points and grapheme clusters.
The unified API is defined by the `AbstractString` class. It has 2 direct child classes: `BinaryString` and `AbstractUnicodeString`, itself extended by `Utf8String` and `GraphemeString`.
All objects are immutable and provide clear edge-case semantics, using exceptions and/or (nullable) types!
Two helper functions are provided to create such strings:
```php
new GraphemeString('foo') == u('foo'); // when dealing with Unicode, prefer grapheme units
new BinaryString('foo') == b('foo');
```
`GraphemeString` is the most linguistic-friendly variant of them, which means it's the one ppl should use most of the time *when dealing with written text*.
Future ideas:
- improve tests
- add more docblocks (only where they'd add value!)
- consider adding more methods in the string API (`is*()?`, `*Encode()`?, etc.)
- first class Emoji support
- merge the Inflector component into this one
- use `width()` to improve `truncate()` and `wordwrap()`
- move method `slug()` to a dedicated locale-aware service class
- propose your ideas (send PRs after merge)
Out of (current) scope:
- what [intl](https://php.net/intl) provides (collations, transliterations, confusables, segmentation, etc)
Here is the unified API I'm proposing in this PR, borrowed from looking at many existing libraries, but also Java, Python, JavaScript and Go.
```php
function __construct(string $string = '');
static function unwrap(array $values): array
static function wrap(array $values): array
function after($needle, bool $includeNeedle = false, int $offset = 0): self;
function afterLast($needle, bool $includeNeedle = false, int $offset = 0): self;
function append(string ...$suffix): self;
function before($needle, bool $includeNeedle = false, int $offset = 0): self;
function beforeLast($needle, bool $includeNeedle = false, int $offset = 0): self;
function camel(): self;
function chunk(int $length = 1): array;
function collapseWhitespace(): self
function endsWith($suffix): bool;
function ensureEnd(string $suffix): self;
function ensureStart(string $prefix): self;
function equalsTo($string): bool;
function folded(): self;
function ignoreCase(): self;
function indexOf($needle, int $offset = 0): ?int;
function indexOfLast($needle, int $offset = 0): ?int;
function isEmpty(): bool;
function join(array $strings): self;
function jsonSerialize(): string;
function length(): int;
function lower(): self;
function match(string $pattern, int $flags = 0, int $offset = 0): array;
function padBoth(int $length, string $padStr = ' '): self;
function padEnd(int $length, string $padStr = ' '): self;
function padStart(int $length, string $padStr = ' '): self;
function prepend(string ...$prefix): self;
function repeat(int $multiplier): self;
function replace(string $from, string $to): self;
function replaceMatches(string $fromPattern, $to): self;
function slice(int $start = 0, int $length = null): self;
function snake(): self;
function splice(string $replacement, int $start = 0, int $length = null): self;
function split(string $delimiter, int $limit = null, int $flags = null): array;
function startsWith($prefix): bool;
function title(bool $allWords = false): self;
function toBinary(string $toEncoding = null): BinaryString;
function toGrapheme(): GraphemeString;
function toUtf8(): Utf8String;
function trim(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): self;
function trimEnd(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): self;
function trimStart(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): self;
function truncate(int $length, string $ellipsis = ''): self;
function upper(): self;
function width(bool $ignoreAnsiDecoration = true): int;
function wordwrap(int $width = 75, string $break = "\n", bool $cut = false): self;
function __clone();
function __toString(): string;
```
`AbstractUnicodeString` adds these:
```php
static function fromCodePoints(int ...$codes): self;
function ascii(array $rules = []): self;
function codePoint(int $index = 0): ?int;
function folded(bool $compat = true): parent;
function normalize(int $form = self::NFC): self;
function slug(string $separator = '-'): self;
```
and `BinaryString`:
```php
static function fromRandom(int $length = 16): self;
function byteCode(int $index = 0): ?int;
function isUtf8(): bool;
function toUtf8(string $fromEncoding = null): Utf8String;
function toGrapheme(string $fromEncoding = null): GraphemeString;
```
Case insensitive operations are done with the `ignoreCase()` method.
e.g. `b('abc')->ignoreCase()->indexOf('B')` will return `1`.
For reference, CLDR transliterations (used in the `ascii()` method) are defined here:
https://github.com/unicode-org/cldr/tree/master/common/transforms
Commits
-------
dd8745aced [String] add more tests
82a00956bc [String] add tests
012e92a772 [String] a new component for object-oriented strings management with an abstract unit system
* 4.4:
[Security/Http] fix typo in deprecation message
[Security] Deprecate isGranted()/decide() on more than one attribute
Fixed a minor typo in the UPGRADE to 5.0 guide
Various tweaks 3.4
Various tweaks 4.3
[Security] Make stateful firewalls turn responses private only when needed
[PhpUnit] Fix usleep mock return value
Revert \"feature #33507 [WebProfiler] Deprecated intercept_redirects in 4.4 (dorumd)\"
[TwigBundle] typo
[TwigBundle] fix test case
[Lock] use Predis\ClientInterface instead of Predis\Client
Allow Twig 3
Minor tweaks
Fix version typo in deprecation notice
[Form][SubmitType] Add "validate" option
hint to the --parse-tags when parsing tags fails
Make legacy "wrong" RFC2047 encoding apply only to one header