Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[String] a new component for object-oriented strings management with an abstract unit system#33553

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
fabpot merged 3 commits intosymfony:masterfromnicolas-grekas:string-component
Sep 26, 2019

Conversation

@nicolas-grekas
Copy link
Member

@nicolas-grekasnicolas-grekas commentedSep 11, 2019
edited
Loading

QA
Branch?master
Bug fix?no
New feature?yes
Deprecations?no
Tickets-
LicenseMIT
Doc PRsymfony/symfony-docs#12376

[EDIT: classes have been renamed in#33816]

This is a reboot of#22184 (thanks@hhamon for working on it) and a generalization of my previous work on the topic (patchwork/utf8). Unlike existing libraries (includingpatchwork/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 theAbstractString class. It has 2 direct child classes:BinaryString andAbstractUnicodeString, itself extended byUtf8String andGraphemeString.

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:

newGraphemeString('foo') ==u('foo');// when dealing with Unicode, prefer grapheme unitsnewBinaryString('foo') ==b('foo');

GraphemeString is the most linguistic-friendly variant of them, which means it's the one ppl should use most of the timewhen 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
  • usewidth() to improvetruncate() andwordwrap()
  • move methodslug() to a dedicated locale-aware service class see[String] Introduce a locale-aware Slugger in the String component #33768
  • propose your ideas (send PRs after merge)

Out of (current) scope:

  • whatintl 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.

function __construct(string$string ='');staticfunction unwrap(array$values): arraystaticfunction wrap(array$values):arrayfunction 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():selffunction 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:

staticfunctionfromCodePoints(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;

andBinaryString:

staticfunction 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 theignoreCase() method.
e.g.b('abc')->ignoreCase()->indexOf('B') will return1.

For reference, CLDR transliterations (used in theascii() method) are defined here:
https://github.com/unicode-org/cldr/tree/master/common/transforms

julienbourdeau, ro0NL, you-ser, keichinger, kunicmarko20, mickaelandrieu, DavidFeller, romainnorberg, fbourigault, deleugpn, and 109 more reacted with thumbs up emojibrzuchal, funivan, babeuloula, gsdevme, amodliszewski, kaznovac, ayanozturk, NickvdMeij, mario-deluna, jmoz, and 6 more reacted with thumbs down emojilinaori, fbourigault, OskarStark, reyostallenberg, babeuloula, javiereguiluz, bobey, ayanozturk, decima, atailouloute, and 7 more reacted with hooray emojijulienbourdeau, Devristo, mnavarrocarter, romainnorberg, fbourigault, jeremyFreeAgent, ogizanagi, OskarStark, kubk, gocanto, and 16 more reacted with heart emojijulienbourdeau, romainnorberg, fbourigault, fancyweb, knmitov, jjanvier, jeremyFreeAgent, ogizanagi, OskarStark, javiereguiluz, and 6 more reacted with rocket emojiromainnorberg reacted with eyes emoji
@stof
Copy link
Member

no way to unignore case ? and no way to know whether the current object is ignoring case ? This makes the API unusable for code wanting to deal with the string in a case sensitive way while accepting an external string object.

Also should we merge this new component in 4.4, which would mean that its first release is already non-experimental ? We are not allowed to have experimental components in LTS versions, per our LTS policy.

cybernet, timfennis, and moxgeek reacted with thumbs up emoji

@nicolas-grekas
Copy link
MemberAuthor

nicolas-grekas commentedSep 11, 2019
edited
Loading

no way to unignore case ? and no way to know whether the current object is ignoring case ?

->ignoreCase() applies only to the very next call in the fluent API chain. This should answer both your questions. SeeAbstractString::__clone()

Also should we merge this new component in 4.4

That's something we need to decide indeed. On my side, I think we can make it non-experimental.

@stof
Copy link
Member

and what happens for all methods accepting a string as argument, when passing non-UTF-8 strings to the method on aUtf8String orGraphemeString ?

Regarding the naming, shouldUtf8String be renamed to highlight it is about code points ? AFAIK,GraphemeString also expects the string to be in UTF-8.

Note that these comments are based purely on your PR description. I haven't looked at the code yet.

@nicolas-grekas
Copy link
MemberAuthor

nicolas-grekas commentedSep 11, 2019
edited
Loading

what happens for all methods accepting a string as argument, when passing non-UTF-8 strings to the method on a Utf8String or GraphemeString ?

anInvalidArgumentException is thrown

should Utf8String be renamed to highlight it is about code points ?

I think UTF-8 is more common vocabulary. The previous PR usedCodePoint indeed, but this is cryptic to many, and doesn't convey the technical encoding scheme (it could use UTF-16BE/LE, etc., nothing would tell). That's why I thinkUtf8String is better.

@stof
Copy link
Member

@nicolas-grekas but the whole component is about UTF-8 strings. AFAICT, even BinaryString is not meant to operate on other encodings, as it does not validate that the string is valid UTF-8 before converting it to other implementations.
Btw, this means that naming the componentString might also be too generic.

@nicolas-grekas
Copy link
MemberAuthor

nicolas-grekas commentedSep 11, 2019
edited
Loading

BinaryString is not meant to operate on other encodings, as it does not validate that the string is valid UTF-8 before converting it to other implementations

It does, dunno why you think otherwise. If you try to convert a random binary string to UTF-8/Grapheme, you'll get anInvalidArgumentException too.

BinaryString is what it tells: it can handle any binary strings and doesn't care about the encoding, like the native PHP string functions, just using an OOP API.

Thus the name of the component.

@fabpot
Copy link
Member

To me, this should go as experimental in 5.0.

derrabus, Nyholm, onurkayaio, OskarStark, lyrixx, jvasseur, janmartenjongerius, Seldaek, curtchan, sstok, and 11 more reacted with thumbs up emojier1z reacted with confused emoji

@drupol
Copy link
Contributor

Definitely supporting this :-) Nice !

@javiereguiluz
Copy link
Member

javiereguiluz commentedSep 11, 2019
edited by nicolas-grekas
Loading

Sorry to sound naive, but I can't find in this pull request or the previous one, some brief explanation about when/where should developers use this.

Why/when should we use these classes/methods instead of the normal str_ PHP functions or the mb_str UTF8 functions? Thanks!

Note: I'm not questioning this ... I just want to know where this fits in Symfony developers and Symfony itself. Thanks a lot!

edit: see#33553 (comment)

DavidBadura, Toflar, mnapoli, magikid, stancl, sstok, rishipuri, dsentker, seyfer, funivan, and 3 more reacted with thumbs up emoji

@nicolas-grekasnicolas-grekasforce-pushed thestring-component branch 2 times, most recently from5ccd5a7 tof9b903bCompareSeptember 11, 2019 10:54
@javiereguiluz
Copy link
Member

For your consideration, we could turn these 4 methods:

function ensureLeft(string$prefix):selffunction ensureRight(string$suffix): selffunction padLeft(int$length, string$padStr = ' '): selffunction padRight(int$length, string$padStr = ' '): self

Into these 2 methods if we change the order of the arguments:

function padLeft(string$padStr ='',int$length =null):selffunction padRight(string$padStr = ' ', int $length = null): self

Example:

// BEFORE$s1 =u('lorem')->ensureLeft('abc');// $s1 = 'abclorem'$s2 =u('lorem')->ensureRight('abc');// $s2 = 'loremabc'$s3 =u('lorem')->padLeft(8,'abc');// $s3 = 'abcabcablorem'$s4 =u('lorem')->padRight(8,'abc');// $s4 = 'loremabcabcab'// AFTER$s1 =u('lorem')->padLeft('abc');// $s1 = 'abclorem'$s2 =u('lorem')->padRight('abc');// $s2 = 'loremabc'$s3 =u('lorem')->padLeft('abc',8);// $s3 = 'abcabcablorem'$s4 =u('lorem')->padRight('abc',8);// $s4 = 'loremabcabcab'
DavidBadura reacted with thumbs up emojisstok reacted with eyes emoji

@nicolas-grekas
Copy link
MemberAuthor

when/where should developers use this.

All the time would be fine. e.g.$matches = $string->match('/some-regexp/) is a much more friendly API thanpreg_match('/some-regexp/', $string, $matches) (even more if you consider error handling).

More specifically, I've observed ppl randomly add anmb_ prefix to string functions and magically expect this to fix their encoding issues. This is way too complex right now, doing it correctly is hard. e.g. the Console component deals with utf-8 strings everywhere, it's not pretty. This component would help a lot there. Twig is another place where strings are heavily manipulated and where graphemes are missing actually. It would benefit from the component too.

javiereguiluz, julienbourdeau, ro0NL, itaelle, yceruto, pscheit, kissifrot, ogizanagi, thib92, cryptiklemur, and 18 more reacted with thumbs up emojisstok reacted with laugh emoji

@nicolas-grekas
Copy link
MemberAuthor

For your consideration, we could turn these 4 methods:
Into these 2 methods if we change the order of the arguments:

This would be totally unexpected to me. I've seen no other libraries have this API and I'm not sure it works actually.

is in your plans that the methods returning self return a new mutated reference keeping the original one intact? If not/yes, why?

Absolutely! That's critical design concern, not just an implementation detail :) I added a note about it in the desription. Thanks for asking.

Copy link
Contributor

@azjezzazjezz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This is great, i believe this would make it easier for developers to deal with string encoding, just few notes about method naming :)

@javiereguiluz
Copy link
Member

@nicolas-grekas thanks for the explanation. It's perfectly clear now!

Another question: some methods are called "left", "right" instead of "prefix/suffix" or "start/end". What happens when the text is Arabic/Persian/Hebrew and uses right-to-text direction? For example,trimRight() removes things at the end of English text ... but at the beginning of Arabic text?

walva, Wirone, kissifrot, neyronius, cryptiklemur, shrink, RauchF, kalvisbuls, 7ochem, DavidBadura, and 5 more reacted with thumbs up emoji

@leofeyer
Copy link
Contributor

We have been usingtchwork/utf8 in Contao for years and it really is essential if you work with multiple languages beyond the ASCII character range. So +1 for adding this in Symfony and keep up the good work@nicolas-grekas. 👍

OskarStark, mstaack, er1z, plandolt, andreybolonin, and lrynek reacted with thumbs up emoji

@Devristo
Copy link
Contributor

It looks amazing. I am curious how it would work together with the rest of the ecosystem. Lets say compatibility with doctrine, intl, symfony/validator, etc? I am sure it will take time before it trickles down to other components, but the future seems bright ;)

Copy link
Contributor

@azjezzazjezz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

i suggest addingAbstractString::contains(string ...$needles): bool, where it returns true in case the string contains one of the needles.

if ($text->contains(...$blacklisted)) {echo'nope!';}

@nicolas-grekasnicolas-grekasforce-pushed thestring-component branch 2 times, most recently from892f621 to921b92fCompareSeptember 23, 2019 18:02
Copy link
Member

@xabbuhxabbuh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I am not finished reviewing this PR, but here are some ideas I got so far.

@nicolas-grekasnicolas-grekasforce-pushed thestring-component branch 2 times, most recently from8900c38 to3b6f46aCompareSeptember 23, 2019 21:25
return \strlen($this->string) - \strlen($suffix) === ($this->ignoreCase ? strripos($this->string, $suffix) : strrpos($this->string, $suffix));
}

public function equalsTo($string): bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
publicfunction equalsTo($string):bool
/**
* @param AbstractString|string|string[]$string
*/
publicfunction equalsTo($string):bool

Can be useful for autocompletion, static analysis and so on. Other methods could benefit from this doc.

Copy link
MemberAuthor

@nicolas-grekasnicolas-grekasSep 25, 2019
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Any object that implements__toString() is allowed actually. That's whatstring means already to me. What's the relation with autocompletion?

Copy link
Contributor

@tigitztigitzSep 26, 2019
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I mean that when working with PhpStorm it seems that it can help you autocomplete the variable to pass in a function given what's available in the scope if the function is properly documented:
image

As you can see above$id is not suggested here as it doesn't respect the documented type hint

@fabpot
Copy link
Member

Thank you@nicolas-grekas.

nicolas-grekas, fancyweb, romainnorberg, terjebraten-certua, and hbolshakov reacted with hooray emoji

fabpot added a commit that referenced this pull requestSep 26, 2019
…anagement with an abstract unit system (nicolas-grekas, hhamon, gharlan)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:```phpnew GraphemeString('foo') == u('foo'); // when dealing with Unicode, prefer grapheme unitsnew 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.```phpfunction __construct(string $string = '');static function unwrap(array $values): arraystatic function wrap(array $values): arrayfunction 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(): selffunction 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:```phpstatic 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`:```phpstatic 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/transformsCommits-------dd8745a [String] add more tests82a0095 [String] add tests012e92a [String] a new component for object-oriented strings management with an abstract unit system
@fabpotfabpot merged commitdd8745a intosymfony:masterSep 26, 2019
@nicolas-grekasnicolas-grekas deleted the string-component branchSeptember 26, 2019 08:32
@nicolas-grekas
Copy link
MemberAuthor

Thank you everyone for the reviews, it's been invaluable!
Please send PRs for any follow-ups now!

fancyweb, blackmorth, azjezz, lyrixx, hhamon, and someniatko reacted with thumbs up emojitigitz, blackmorth, azjezz, lyrixx, hhamon, timfennis, and pultho reacted with rocket emoji

@tigitztigitz mentioned this pull requestSep 26, 2019
nicolas-grekas added a commit that referenced this pull requestOct 7, 2019
…tring (nicolas-grekas)This PR was merged into the 5.0-dev branch.Discussion----------[String] renamed core classes to Byte/CodePoint/UnicodeString| Q             | A| ------------- | ---| Branch?       | master| Bug fix?      | no| New feature?  | no| Deprecations? | no| Tickets       | -| License       | MIT| Doc PR        | -In#33553 there have been discussions about the naming of the classes - eg. "what's a grapheme", "why `Utf8String`", "lowercase on binary is weird", etc.What about these names? Would they get your votes *vs* the current ones?- `BinaryString` -> `ByteString`- `Utf8String` -> `CodePointString`- `GraphemeString` -> `UnicodeString`Commits-------63c105d [String] renamed core classes to Byte/CodePoint/UnicodeString
@fabpotfabpot mentioned this pull requestNov 12, 2019
@MaPePeR
Copy link
Contributor

no way to unignore case ? and no way to know whether the current object is ignoring case ?

->ignoreCase() applies only to the very next call in the fluent API chain. This should answer both your questions. SeeAbstractString::__clone()

I think this answer is incomplete, because there is nothing that stops someone from calling a function likefoo(u("abc")->ignoreCase()), which will then result in every operation in that function being case insensitive unless the function creates a clone of the argument.

This might also happen unintentionally when someone intends to do a lot of case insensitive operations, so they do$a = u("abc")->ignoreCase(); and later afoo($a) is added and strange things might happen.

You might say "Use the code in a wrong way and you will get wrong results", but i still think that this behavior is kind of odd.
I like the style of writing/reading it - that part is ok - but because we cannot overwrite the assignment operator, like in C++, to clear theignoreCase-Flag this can cause some weird side effects.

Maybe have theignoreCase() function return an object of a different class, that is not part of theAbstractString hierarchy and implements a subset of the string functions, so we can at least protect against this with type hints?

ausi, DrMurx, and jvasseur reacted with thumbs up emoji

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@derrabusderrabusderrabus left review comments

@lyrixxlyrixxlyrixx left review comments

@stofstofstof left review comments

@javiereguiluzjaviereguiluzjaviereguiluz left review comments

@xabbuhxabbuhxabbuh requested changes

@fabpotfabpotfabpot approved these changes

+34 more reviewers

@noniagriconomienoniagriconomienoniagriconomie left review comments

@jakzaljakzaljakzal left review comments

@kaznovackaznovackaznovac left review comments

@drupoldrupoldrupol left review comments

@gharlangharlangharlan left review comments

@apfelboxapfelboxapfelbox left review comments

@nicholasruununicholasruununicholasruunu left review comments

@rybakitrybakitrybakit left review comments

@WironeWironeWirone left review comments

@TobionTobionTobion left review comments

@tomasfejfartomasfejfartomasfejfar left review comments

@greg0iregreg0iregreg0ire left review comments

@aboksaboksaboks left review comments

@sstoksstoksstok left review comments

@source-consultingsource-consultingsource-consulting left review comments

@ausiausiausi left review comments

@TomasVotrubaTomasVotrubaTomasVotruba left review comments

@tigitztigitztigitz requested changes

@linaorilinaorilinaori left review comments

@GrahamCampbellGrahamCampbellGrahamCampbell requested changes

@fancywebfancywebfancyweb left review comments

@CthulhuDenCthulhuDenCthulhuDen left review comments

@babeuloulababeuloulababeuloula left review comments

@gocantogocantogocanto left review comments

@gmponosgmponosgmponos left review comments

@rob006rob006rob006 left review comments

@CDROCDROCDRO left review comments

@JMLamodiereJMLamodiereJMLamodiere left review comments

@gitomatogitomatogitomato left review comments

@ro0NLro0NLro0NL left review comments

@BackEndTeaBackEndTeaBackEndTea left review comments

@azjezzazjezzazjezz left review comments

@tuqqutuqqutuqqu left review comments

@terjebraten-certuaterjebraten-certuaterjebraten-certua left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

5.0

Development

Successfully merging this pull request may close these issues.

49 participants

@nicolas-grekas@stof@fabpot@drupol@javiereguiluz@leofeyer@Devristo@apfelbox@kuraobi@tomasfejfar@Sarke@TinoDidriksen@derrabus@GrahamCampbell@ausi@er1z@MaPePeR@jakzal@kaznovac@gharlan@lyrixx@nicholasruunu@rybakit@Wirone@Tobion@greg0ire@aboks@sstok@TomasVotruba@ro0NL@tigitz@linaori@xabbuh@fancyweb@CthulhuDen@babeuloula@gocanto@gmponos@rob006@CDRO@JMLamodiere@gitomato@noniagriconomie@BackEndTea@azjezz@tuqqu@terjebraten-certua@source-consulting@hhamon

[8]ページ先頭

©2009-2025 Movatter.jp