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

feat: Bump minimum PHP version to 7.4 #82

Merged
merged 4 commits into from
Jun 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ ij_visual_guides = 80, 120

[*.php]
indent_size = 4
max_line_length = 120
ij_php_align_multiline_chained_methods = true
ij_php_align_phpdoc_comments = true
ij_php_align_phpdoc_param_names = true
ij_php_align_assignments = true
ij_php_align_multiline_array_initializer_expression = true
ij_php_align_key_value_pairs = true
ij_php_align_match_arm_bodies = true
ij_php_phpdoc_use_fqcn = true

[*.{yml, yaml, neon, xml, svg, json, js}]
indent_size = 2
Expand All @@ -18,3 +27,4 @@ indent_size = 2
trim_trailing_whitespace = false
indent_size = 2
max_line_length = 80
ij_markdown_wrap_text_if_long = true
4 changes: 2 additions & 2 deletions .github/workflows/qa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ jobs:
tests:
strategy:
matrix:
php: ['7.3','7.4','8.0','8.1']
runs-on: ubuntu-20.04
php: [ '7.4','8.0','8.1' ]
runs-on: ubuntu-22.04
steps:

- name: Setup PHP
Expand Down
25 changes: 12 additions & 13 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
The MIT License (MIT)
=====================

Copyright © 2015-2019 Jawira Portugal
Copyright © 2015-2022 Jawira Portugal

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 changes: 20 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@ Case converter

Use this library to convert string between:

| Name | Method | Output example |
| ------------- | --------------- | ----------------- |
| 🐪 Camel case | `toCamel()` | `myNameIsBond` |
| 👨‍🏫 Pascal case | `toPascal()` | `MyNameIsBond` |
| 🐍 Snake case | `toSnake()` | `my_name_is_bond` |
| 👩‍🏫 Ada case | `toAda()` | `My_Name_Is_Bond` |
| Ⓜ️ Macro case | `toMacro()` | `MY_NAME_IS_BOND` |
| 🥙 Kebab case | `toKebab()` | `my-name-is-bond` |
| 🚂 Train case | `toTrain()` | `My-Name-Is-Bond` |
| 🏦 Cobol case | `toCobol()` | `MY-NAME-IS-BOND` |
| 🔡 Lower case | `toLower()` | `my name is bond` |
| 🔠 Upper case | `toUpper()` | `MY NAME IS BOND` |
| 📰 Title case | `toTitle()` | `My Name Is Bond` |
| ✍️ Sentence case | `toSentence()` | `My name is bond` |
| ⚙️ Dot notation | `toDot()` | `my.name.is.bond` |
| Name | Method | Output example |
|-------------------|----------------|-------------------|
| 🐪 Camel case | `toCamel()` | `myNameIsBond` |
| 👨‍🏫 Pascal case | `toPascal()` | `MyNameIsBond` |
| 🐍 Snake case | `toSnake()` | `my_name_is_bond` |
| 👩‍🏫 Ada case | `toAda()` | `My_Name_Is_Bond` |
| Ⓜ️ Macro case | `toMacro()` | `MY_NAME_IS_BOND` |
| 🥙 Kebab case | `toKebab()` | `my-name-is-bond` |
| 🚂 Train case | `toTrain()` | `My-Name-Is-Bond` |
| 🏦 Cobol case | `toCobol()` | `MY-NAME-IS-BOND` |
| 🔡 Lower case | `toLower()` | `my name is bond` |
| 🔠 Upper case | `toUpper()` | `MY NAME IS BOND` |
| 📰 Title case | `toTitle()` | `My Name Is Bond` |
| ✍️ Sentence case | `toSentence()` | `My name is bond` |
| ⚙️ Dot notation | `toDot()` | `my.name.is.bond` |

Features:

Expand Down Expand Up @@ -52,8 +52,8 @@ Of course you can explicitly set the format of input string:
echo $hero->fromKebab()->toSnake(); // output: john_connor
```

You can also use the [provided factory][factory] to instantiate `Convert` class. A list of [all public methods] is also
available.
You can also use the [provided factory][factory] to instantiate `Convert` class.
A list of [all public methods] is also available.

i18n
----
Expand All @@ -74,7 +74,8 @@ $rus = new Convert('ОЧЕНЬ_ПРИЯТНО');
echo $rus->toCamel(); // output: оченьПриятно
```

`case-converter` is compatible with _Simple Case-Mapping_ and _Full Case-Mapping_.
`case-converter` is compatible with _Simple Case-Mapping_ and _Full
Case-Mapping_.
[Learn more about Case-Mapping][Case-Mapping].

Installation
Expand All @@ -94,7 +95,7 @@ Contributing

- If you liked this project, ⭐ star it on GitHub.
[![GitHub Repo stars](https://img.shields.io/github/stars/jawira/case-converter?style=social)](https://github.com/jawira/case-converter)
- Or follow me on Twitter.
- Or follow me on Twitter.
[![Twitter Follow](https://img.shields.io/twitter/follow/jawira?style=social)](https://twitter.com/jawira)

License
Expand Down
4 changes: 2 additions & 2 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
</target>

<target name="php:lint" description="Check syntax on PHP files">
<phplint>
<phplint haltonfailure="true">
<fileset dir="${project.basedir}">
<include name="**/*.php"/>
<exclude name="vendor/"/>
Expand All @@ -65,7 +65,6 @@
<env key="XDEBUG_MODE" value="coverage"/>
<arg line="--configuration=config/phpunit.xml"/>
<arg value="--testdox"/>
<arg value="--stop-on-defect"/>
</exec>
</target>

Expand Down Expand Up @@ -120,6 +119,7 @@
<arg value="jawira/plantuml"/>
</composer>
<exec executable="vendor/bin/plantuml" passthru="true" checkreturn="true">
<arg value="-checkmetadata"/>
<arg path="docs/**.puml"/>
</exec>
<composer command="remove">
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
}
],
"require": {
"php": "^7.1 || ^8.0",
"php": ">=7.4",
"ext-mbstring": "*"
},
"require-dev": {
Expand Down
17 changes: 14 additions & 3 deletions config/phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" bootstrap="../vendor/autoload.php"
forceCoversAnnotation="true" beStrictAboutCoversAnnotation="true" beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true" colors="true" stopOnFailure="true" stopOnError="true">
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
bootstrap="../vendor/autoload.php"
forceCoversAnnotation="true"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
colors="true"
stopOnFailure="true"
stopOnRisky="true"
stopOnDefect="true"
stopOnWarning="true"
stopOnIncomplete="true"
stopOnSkipped="true"
stopOnError="true">

<coverage processUncoveredFiles="true">
<include>
Expand Down
128 changes: 69 additions & 59 deletions docs/case-mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,90 +4,100 @@ Case-Mapping
Introduction
------------

> Case mapping or case conversion is a process whereby strings are converted
> to a particular form—uppercase, lowercase, or titlecase—possibly for display
> to the user.
_Case-mapping_ or _case conversion_ is performed everytime a character is
changed from _upper case_ to _lower case_, or from _lower case_ to _upper case_.
_Case converter_ performs _case-mapping_ everytime you use it.

PHP always performed _Simple Case-Mapping_, this is map one-to-one character
mapping. For example, one _lower case_ character is converter to one _upper
case_ character.
There are two kind of case-mapping:

PHP 7.3 introduced [Full Case-Mapping], you can have one-to-many character
mapping. In practice this means than you can have different results depending on
your PHP version.

```php
$german = new Convert('Straße');

echo $german->toUpper();
// Produces STRAßE on PHP 7.2
// Produces STRASSE on PHP 7.3
```
1. _Simple case-mapping_
2. _Full case-mapping_

Please note that _Full Case-Mapping_ is locale dependent:
_Simple case-mapping_ is one-to-one character mapping, for example a single
character "`A`" is replaced with another single character "`a`".

```php
// Turkish (requires appropriate locale)
$tur = new Convert('istambul');
echo $tur->toTrain(); // output: İstanbul
```
As you can image, _Full case-mapping_ performs one-to-many character
replacements (more precisely one-to-many code-points).
In real world use-cases, it's rare to perform _full case-mapping_, this is
because it only concerns a very small set of characters. For example in german
language, the letter "`ß`" is strictly lowercase and should be mapped to "`SS`"
in uppercase words.

Forcing _Simple Case-Mapping_
------------------------------
Case-Converter behaviour
------------------------

As told before, _Full Case-Mapping_ is only available on PHP 7.3 and newer.

The following code snippet is executed on PHP 7.3:
By default, Case-Converter will perform _full case-mapping_

```php
// German
// Full case-mapping
$ger = new Convert('Straße');
echo $ger->toUpper(); // output: STRASSE
echo $ger->toUpper(); // output: STRASSE
```

To force _Simple Case-Mapping_ you have to call `->forceSimpleCaseMapping()`:
If you want to perform _simple case-mapping_ then you have to
call `->forceSimpleCaseMapping()`:

```php
// German
// Simple case-mapping
$ger = new Convert('Straße');
$ger->forceSimpleCaseMapping();
echo $ger->toUpper(); // output: STRAßE
echo $ger->toUpper(); // output: STRAßE
```

Please note `->forceSimpleCaseMapping()` has no effect on _PHP 7.1_ and _PHP
7.2_ as these version can only perform _Simple Case-Mapping_.

Technical details
-----------------
As you can see, in _full case-mapping_ string length can change.

Internally `Case-Converter` uses [mb_convert_case()], this function uses the
following constants:
Case-Mapping in PHP
-------------------

- MB_CASE_LOWER
- MB_CASE_TITLE
- MB_CASE_UPPER

The problem is that, Before _PHP 7.3_, these constants perform simple
case-mapping and after _PHP 7.3_ perform full case-mapping.
PHP 7.3 introduced _full case-mapping_, you can have one-to-many character
mapping. In practice this means than you can have different results depending on
your PHP version.

If you want to maintain the old functionality after _PHP 7.3_ you have to call
`->forceSimpleCaseMapping()`:
Internally Case-Converter uses _mb_convert_case()_ . This function works in
conjunction with specific constants to tell what action to perform. For example:

```php
// German
$ger = new Convert('Straße');
$ger->forceSimpleCaseMapping();
echo $ger->toUpper(); // output: STRASSE
mb_convert_case('Foo', MB_CASE_UPPER); // FOO
```

***
Prior to PHP 7.3, these were the available constants and their use:

| Constant | Meaning |
|---------------|---------------------------------------------|
| MB_CASE_UPPER | Performs simple upper-case fold conversion. |
| MB_CASE_LOWER | Performs simple lower-case fold conversion. |
| MB_CASE_TITLE | Performs simple title-case fold conversion. |

But from PHP 7.3, new constants were added and their meaning changed:

| Constant | Meaning |
|----------------------|---------------------------------------------|
| MB_CASE_UPPER | Performs a full upper-case folding. |
| MB_CASE_LOWER | Performs a full lower-case folding. |
| MB_CASE_TITLE | Performs a full title-case conversion. |
| MB_CASE_UPPER_SIMPLE | Performs simple upper-case fold conversion. |
| MB_CASE_LOWER_SIMPLE | Performs simple lower-case fold conversion. |
| MB_CASE_TITLE_SIMPLE | Performs simple title-case fold conversion. |

Locale dependent mapping
------------------------

Some case-mapping are locale dependent. This is the case of Turkish where the
small letter "`i`" should be replaced by a capital letter with a dot "`İ`".
However, according to documentation:

IMHO this is a _breaking change_, PHP people should have keep untouched old
constants and create new ones for [Full Case-Mapping], for example:
`MB_CASE_LOWER_FULL`, `MB_CASE_TITLE_FULL`, and `MB_CASE_UPPER_FULL` (please
note these constants do not exist).
> Only unconditional, language agnostic full case-mapping is performed.

[Full Case-Mapping]: https://www.php.net/manual/en/migration73.new-features.php#migration73.new-features.mbstring.case-mapping-folding
This means that locale dependent mapping are ignored and not performed.

[mb_convert_case()]: https://www.php.net/manual/en/function.mb-convert-case.php
Resources
---------

<dl>
<dt>PHP 7.3 Full Case-Mapping and Case-Folding Support</dt>
<dd><a href="https://www.php.net/manual/en/migration73.new-features.php#migration73.new-features.mbstring.case-mapping-folding">https://www.php.net/manual/en/migration73.new-features.php#migration73.new-features.mbstring.case-mapping-folding</a></dd>
<dt>mb_convert_case()</dt>
<dd><a href="https://www.php.net/manual/en/function.mb-convert-case.php">https://www.php.net/manual/en/function.mb-convert-case.php</a></dd>
<dt>mbstring constant</dt>
<dd><a href="https://www.php.net/manual/en/mbstring.constants.php">https://www.php.net/manual/en/mbstring.constants.php</a></dd>
</dl>
1 change: 0 additions & 1 deletion src/CaseConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*
* Factory class which returns a Convert object.
*
* @package Jawira\CaseConverter
* @author Jawira Portugal <dev@tugal.be>
*/
class CaseConverter implements CaseConverterInterface
Expand Down
5 changes: 2 additions & 3 deletions src/CaseConverterException.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

namespace Jawira\CaseConverter;

use Exception;
use RuntimeException;

class CaseConverterException extends Exception
class CaseConverterException extends RuntimeException
{

}
1 change: 0 additions & 1 deletion src/CaseConverterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
/**
* Interface CaseConverterInterface
*
* @package Jawira\CaseConverter
* @author Jawira Portugal <dev@tugal.be>
*/
interface CaseConverterInterface
Expand Down
Loading