365 Commits

Author SHA1 Message Date
Tomasz Kuter
8e6055a48e [UW-2934] chore(composer): added PHP 8.x to composer.json 2023-03-09 12:54:19 +01:00
xevolic
d392b20570 Merge pull request #1 from meritoo/master
[UW-2934] Merge official version 1.1.x
2023-03-09 12:52:26 +01:00
Meritoo
cddafc3604 Update Changelog 2022-09-10 18:10:51 +02:00
Meritoo
08a2d0878f Interfaces of different types of collections. May be used to build specific collections. 2022-09-10 18:06:25 +02:00
Meritoo
d4cb732096 Migrate PHPUnit configuration file to current format 2022-09-10 13:44:22 +02:00
Meritoo
5ebf624b7b Replace deprecated assertRegExp() function with assertMatchesRegularExpression() in PHPUnit tests (after upgrade of PHPUnit 8.x -> 9.x) 2022-09-10 13:44:22 +02:00
Meritoo
bbc5f6a43d Bump PHP version to 7.4 (from 7.2) 2022-09-10 13:02:02 +02:00
Meritoo
41ef088ffe Upgrade all dev packages (to the latest, stable versions for PHP 7.4) 2022-09-10 13:01:10 +02:00
Meritoo
a3adae50b8 Reformat code automatically 2022-02-12 14:46:47 +01:00
Meritoo
a3af138f0c Update documentation for Infection (Mutation Testing) and use the "nproc" command that returns the number of processors available 2022-02-12 13:33:30 +01:00
Meritoo
31a7ca6d1a [Arrays] Improve tests of function that returns elements from given level 2022-02-06 18:08:22 +01:00
Meritoo
ba24e2de23 [Arrays] Allow to define a key of next level elements in a function that returns elements from given level 2022-02-06 15:29:20 +01:00
Meritoo
ae72d582e6 Reformat code 2022-02-05 21:24:19 +01:00
Meritoo
067be1ab1d [Arrays] Function that returns elements from given level 2022-02-05 19:50:36 +01:00
Meritoo
151ce39226 Fix "str_replace(): Argument #2 ($replace) must be of type array|string, int given" TypeError while running test of Meritoo\Common\ValueObject\Template::fill() 2022-02-05 16:57:12 +01:00
Meritoo
feb8fc293b Fix "floor(): Argument #1 ($num) must be of type int|float, string given" TypeError while running test of Meritoo\Common\Utilities\Miscellaneous::isDecimal() 2022-02-05 16:54:36 +01:00
Meritoo
fcaae95810 [BaseCollection] Prepare elements while adding them by addMultiple() method in the same way as passing them in constructor 2021-04-27 22:13:11 +02:00
Meritoo
a459bfe1ce Use larger collection while testing the BaseCollection class 2021-04-11 22:22:36 +02:00
Meritoo
1eb86cf102 [BaseCollection] Fix incorrectly working limit() method 2021-04-11 22:16:34 +02:00
Meritoo
0d3265d7b6 Increase code coverage of the BaseTestCaseTrait 2021-04-04 23:26:35 +02:00
Meritoo
598f1731be Add missing "declare(strict_types=1)" 2021-04-04 23:09:50 +02:00
Meritoo
95b0cf6cab Create clear() & limit() methods in BaseCollection class 2021-04-04 23:09:13 +02:00
Meritoo
118fa64772 Increase code coverage of the BaseCollection class 2021-04-04 23:06:36 +02:00
Meritoo
d5542b60e3 Implement methods of CollectionInterface directly in BaseCollection class (instead of traits) 2021-04-04 23:05:42 +02:00
Meritoo
a4d24a788b Reformat code 2021-03-29 21:41:54 +02:00
Meritoo
4f8c355d1b Create and implement CollectionInterface as contract of all collections (e.g. based on the BaseCollection class) 2021-03-29 21:41:54 +02:00
Meritoo
e47eaae8b2 Move Renderable class: Meritoo\Common -> Meritoo\Common\Contract 2021-03-28 22:34:45 +02:00
Meritoo
1116034fe6 Mark PHPUnit test as risky when it does not have a @covers annotation 2021-03-28 22:19:11 +02:00
Meritoo
64f474fcf1 Change mode of Xdebug to "coverage" in Docker's configuration to make it possible to generate code coverage by PHPUnit 2021-03-28 22:16:04 +02:00
Meritoo
47d07150d3 Minor refactoring 2021-02-26 15:13:33 +01:00
Meritoo
c6efc30872 Fix "Array and string offset access syntax with curly braces is deprecated" error while running tests (using PHP 7.4) 2021-02-26 15:09:02 +01:00
Meritoo
ab0c0e6e89 Update Changelog 2021-02-20 17:09:11 +01:00
Meritoo
351224f1f9 Use PHP 7.4 while running build in Travis CI 2021-02-20 16:37:06 +01:00
Meritoo
416f0cd8af Do not install hirak/prestissimo package while running build in Travis CI 2021-02-20 16:26:07 +01:00
Meritoo
e38dda200a Use meritoo/php Docker image (instead of deprecated meritoo/php7) 2021-02-20 16:20:57 +01:00
Meritoo
8fec0db05f Increase Mutation Score Indicator (MSI) by creating stronger tests of BaseCollection class 2020-10-24 17:31:25 +02:00
Meritoo
5cd58aec25 [Miscellaneous] [Regex] Implement data providers in tests 2020-08-25 15:36:49 +02:00
Meritoo
ddb3f0a544 [Miscellaneous] [Regex] Use simpler & stronger pattern to match name of file 2019-12-18 20:31:33 +01:00
Meritoo
872259e63d [BaseCollection] Treat the null index as "no index" only while adding new element, iow. do not treat empty string as "no index" behaviour 2019-09-19 12:33:03 +02:00
Meritoo
d8e3d5e7cb Update documentation of BaseCollection class 2019-09-18 15:13:03 +02:00
Meritoo
2fdb18312d Remove project configuration (project files related to IDE) 2019-09-18 14:54:02 +02:00
Meritoo
a7c39b26ba Rename Collection class to BaseCollection. Add BaseCollection::isValidType() method to validate type of element before add it to collection. Add BaseCollection ::prepareElements() method to allow preparation of elements in custom way. 2019-09-18 14:51:09 +02:00
Meritoo
b91606ada9 Increase Mutation Score Indicator (MSI) by creating stronger tests of Arrays class 2019-09-15 20:14:23 +02:00
Meritoo
1f45d38ab8 Add @internal @coversNothing annotations in PHPUnit tests 2019-09-15 13:33:03 +02:00
Meritoo
b0e404aeb9 Minor refactoring 2019-09-09 16:06:20 +02:00
Meritoo
9903c82496 Add Miscellaneous::calculateGreatestCommonDivisor() method 2019-09-09 09:41:07 +02:00
Meritoo
678cdfdf01 Minor refactoring 2019-09-06 11:58:55 +02:00
Meritoo
ded1a04900 Add test for the BaseTestCaseTrait trait 2019-09-06 11:58:40 +02:00
Meritoo
16cdd1cd60 Extract BaseTestCaseTrait::assertMethodVisibility() & BaseTestCaseTrait::assertMethodArgumentsCount() methods (from BaseTestCaseTrait::assertMethodVisibilityAndArguments() method) 2019-09-05 21:57:59 +02:00
Meritoo
f7a8da0550 Add Uri::buildUrl() method
Builds url with given root url and parts of url
2019-08-28 16:01:27 +02:00
Meritoo
891411e231 Add Arrays::containsEmptyStringsOnly() method
Returns information if given array contains an empty strings only
2019-08-28 15:51:03 +02:00
Meritoo
10992570ad Make more readable documentation of Arrays class 2019-08-28 15:44:37 +02:00
Meritoo
e704dacabd Add Regex::clearBeginningSlash() and Regex::clearEndingSlash() methods (that remove slash from the beginning and the end of given string) 2019-08-27 20:26:31 +02:00
Meritoo
0afcf9843e Make more readable documentation of Regex class 2019-08-27 20:23:28 +02:00
Meritoo
cc06cdde6f Minor refactoring 2019-08-25 20:22:42 +02:00
Meritoo
030e33064d Increase Mutation Score Indicator (MSI) by making Meritoo\Common\Traits\Test\Base\BaseTestCaseTrait::getFilePathForTesting() method protected (instead of public) 2019-08-24 17:22:07 +02:00
Meritoo
bc20645cba Increase Mutation Score Indicator (MSI) by removing "src/Type/DatePeriod.php:131 [M] LogicalOr" mutant 2019-08-11 13:25:28 +02:00
Meritoo
ec1e95a086 Minor refactoring 2019-08-11 13:06:19 +02:00
Meritoo
21bfadf5d6 Increase Mutation Score Indicator (MSI) by removing "src/Type/DatePeriod.php:120 [M] TrueValue" mutant 2019-08-11 12:56:08 +02:00
Meritoo
ce7ec254b1 Increase Mutation Score Indicator (MSI) by removing "src/Type/Base/BaseType.php:37 [M] TrueValue" mutant 2019-08-11 12:55:12 +02:00
Meritoo
fe6ec278e3 Minor refactoring 2019-08-11 12:30:50 +02:00
Meritoo
462625caff Missing test of Reflection::getConstants() method 2019-08-11 12:24:55 +02:00
Meritoo
a86a10c51e Increase Mutation Score Indicator (MSI) by removing "src/Exception/Reflection/CannotResolveClassNameException.php:29 [M] TrueValue" mutant 2019-08-10 21:32:40 +02:00
Meritoo
a5148de31c Make task with Infection dependent of PHPUnit tests 2019-08-10 21:32:29 +02:00
Meritoo
dabb1e90c3 Update .gitignore, docker-compose.yml, phpunit.xml.dist 2019-08-02 12:35:07 +02:00
Meritoo
79708f4e61 PHP CS Fixer > configuration > make more readable & remove unnecessary code 2019-08-02 12:21:03 +02:00
Meritoo
b251bcec0e Update project configuration (project files related to IDE) 2019-06-20 21:36:31 +02:00
Meritoo
a2c875556e Move validation of year, month and day to separate methods 2019-06-20 21:32:03 +02:00
Meritoo
c5a68b54af Fix "Argument 1 of Meritoo\\Common\\Utilities\\Date::getdayofweek expects int, string|false provided" bug pointed by Psalm 2019-06-20 21:31:35 +02:00
Meritoo
4ddc299e5b Fix "Cannot call method add on possibly null value" bug pointed by Psalm 2019-06-20 21:04:44 +02:00
Meritoo
c0998ac5b9 Fix "Argument 1 of DateTime::setdate expects int, string|false provided" bug pointed by Psalm 2019-06-20 20:29:17 +02:00
Meritoo
a1c3ba8543 Fix "Cannot call method sub on possibly null value" bug pointed by Psalm 2019-06-20 20:21:14 +02:00
Meritoo
6efbf940a3 Fix "Found a redundant condition when evaluating docblock-defined type $composerJsonPath and trying to reconcile type 'string' to string" bug pointed by Psalm 2019-06-20 20:05:56 +02:00
Meritoo
1ac1a221ec Minor refactoring 2019-06-20 19:25:34 +02:00
Meritoo
5678b5b22a Fix "Found a contradiction when evaluating $fullBundleName and trying to reconcile type 'string' to !string" bug pointed by Psalm 2019-06-20 18:58:20 +02:00
Meritoo
3b81d0d932 Do not require name of class by BaseTestCaseTrait::assertMethodVisibilityAndArguments() method 2019-06-17 08:43:40 +02:00
Meritoo
c4e09f77a3 Update Changelog 2019-06-02 19:17:39 +02:00
Meritoo
11e5ce3d56 Store .env in repository (do not ignore) 2019-06-02 19:04:23 +02:00
Meritoo
a9b985385e Add project configuration (project files related to IDE) 2019-06-02 19:03:55 +02:00
Meritoo
15824d3f77 composer > squizlabs/php_codesniffer package > use ^3.4 (instead of ^2.9) 2019-06-02 18:23:12 +02:00
Meritoo
e002adc162 PHP Coding Standards Fixer > fix coding standard 2019-05-30 21:55:09 +02:00
Meritoo
538aa1fa79 Docker > use images (instead of Dockerfiles) 2019-05-30 21:50:27 +02:00
Meritoo
b482d814e4 Use .env instead of .env.dist 2019-05-30 21:32:00 +02:00
Meritoo
2091adc8d0 Collection > trait > return "void" where "self" causes type hinting problem and is not required 2019-05-11 00:19:38 +02:00
Meritoo
e75854feee Collection > trait > split into smaller traits (to make it more flexible) 2019-05-10 23:48:19 +02:00
Meritoo
9a1f49d373 Trait for the Collection > type hinting 2019-05-10 22:17:40 +02:00
Meritoo
98d0fed61d Refactoring 2019-05-05 23:06:18 +02:00
Meritoo
a6b2704c66 BaseType::isCorrectType() method > make static 2019-05-05 23:05:42 +02:00
Meritoo
dd5ac0f7e6 Fix code pointed by Psalm 2019-05-05 09:49:03 +02:00
Meritoo
421d19ff10 Readme > review and fix "unknown" badges 2019-05-02 22:51:26 +02:00
Meritoo
8b5cbd6f2e Composer.json > update PHP version constraints 2019-04-19 22:07:25 +02:00
Meritoo
0f2c6bb099 Phing > tests > add task for Psalm (https://psalm.dev) 2019-04-18 14:31:31 +02:00
Meritoo
f5e8c8c740 Readme > badge with required PHP version > update & get from Packagist 2019-04-16 11:44:36 +02:00
Meritoo
c7c96daaaf PHP Coding Standards Fixer > fix coding standard 2019-04-15 21:23:49 +02:00
Meritoo
4c6fb569bc PHP Coding Standards Fixer > update configuration 2019-04-15 21:23:05 +02:00
Meritoo
b166b8b805 PHP Coding Standards Fixer > fix coding standard 2019-04-13 21:47:49 +02:00
Meritoo
414ce0fd06 Reflection > getPropertyValue() method > refactoring 2019-04-13 21:38:06 +02:00
Meritoo
fa370be08a Tests > Reflection > getPropertyValues() method > make stronger verification of the dot-separated properties (get values of the chain) 2019-04-13 19:03:23 +02:00
Meritoo
a56b325307 Minor refactoring 2019-04-13 18:33:38 +02:00
Meritoo
eb8fa110ad Reflection > getPropertyValue() method > look for the property in parent classes 2019-04-13 18:29:27 +02:00
Meritoo
6f90f5a249 Reflection > fix deprecations 2019-04-13 17:27:06 +02:00
Meritoo
2bbd0a4ef3 PHPUnit > increase code coverage 2019-04-10 09:09:44 +02:00
Meritoo
e66cbd54e2 Template with placeholders > verification of placeholders without values > make stronger and point out which are missing 2019-04-10 08:57:33 +02:00
Meritoo
39b0172a85 Travis CI > run many tasks using Phing > update configuration 2019-04-07 16:19:31 +02:00
Meritoo
e05bc2302d PHPUnit > increase code coverage 2019-04-06 08:47:26 +02:00
Meritoo
a13a629408 PHP Coding Standards Fixer > fix coding standard 2019-04-06 08:00:01 +02:00
Meritoo
0f64705132 PHP Coding Standards Fixer > update configuration 2019-04-06 07:59:31 +02:00
Meritoo
4f55f33385 Phing > php-coveralls > add task 2019-04-05 20:47:46 +02:00
Meritoo
134a5a0108 Phing > configuration > minor update 2019-04-05 20:43:29 +02:00
Meritoo
d1c1d48473 Infection (Mutation Testing Framework) > fix bugs while running (generate proper code coverage, bugs while running tests randomly) 2019-04-05 20:42:42 +02:00
Meritoo
685addc7c4 PHPUnit > directory with code coverage > rename 2019-04-05 20:36:21 +02:00
Meritoo
602855d2a7 PHPUnit > execute tests in random order > fix XSD namespace (required to use the "executionOrder" attribute) 2019-04-03 20:26:06 +02:00
Meritoo
da9ae20a33 Implement Psalm (https://github.com/vimeo/psalm) 2019-04-03 19:47:08 +02:00
Meritoo
92e607a3f0 PHPUnit > execute tests in random order 2019-04-03 15:06:05 +02:00
Meritoo
9f2a5294a8 Phing > configuration > remove unnecessary tests/Resources/var/ directory (and subdirectories) 2019-04-03 12:53:59 +02:00
Meritoo
87422af5c7 Implement PHPStan (https://github.com/phpstan/phpstan) 2019-04-03 12:49:48 +02:00
Meritoo
1db4a55e31 Fix integration with Coveralls (available as the badge in README.md) 2019-04-03 12:41:15 +02:00
Meritoo
ca4bf05b38 Travis CI > run many tasks using Phing (instead of PHPUnit only) 2019-04-03 12:39:04 +02:00
Meritoo
cecaa65ef6 Implement Mutation Testing Framework (infection/infection package) 2019-04-03 12:30:37 +02:00
Meritoo
a90eeed583 Phing > configuration > minor updates 2019-04-03 11:22:12 +02:00
Meritoo
312e721dc3 Phing > remove old and unused tools 2019-04-03 11:18:11 +02:00
Meritoo
a93355f2c8 RenderableInterface > something that may be rendered 2019-04-02 21:40:50 +02:00
Meritoo
a4d6a1c785 Bump version 2019-04-02 21:16:40 +02:00
Meritoo
ed1c9358aa Changelog > update > enter latest modifications 2019-04-02 21:16:25 +02:00
Meritoo
faf1da6134 Collection/storage of templates 2019-04-02 21:08:11 +02:00
Meritoo
0b74f8da6f Template with placeholders that may be filled by real data 2019-04-02 21:03:03 +02:00
Meritoo
8a94241eb8 Regex > make compatible with PHP 7.3
Tests > Regex > fix "preg_match(): Compilation failed: invalid range in character class at offset 4" bug
2019-04-02 15:46:02 +02:00
Meritoo
87249aa30b TravisCI > run using PHP 7.2 & 7.3 > make compatible with PHP 7.2+ 2019-04-02 13:12:04 +02:00
Meritoo
1b4577cc8a Fix coding standards (using PHP Coding Standards Fixer) 2019-04-02 12:03:53 +02:00
Meritoo
7ddfcf6946 .gitignore > ignore PHPUnit's results cache (related to PHPUnit 8.0) 2019-04-02 12:02:08 +02:00
Meritoo
10bf198df5 Phing > fix "This task requires the PHP_CodeSniffer package installed and available on the include path" bug > make compatible with PHPUnit 8.0 (and PHP 7.2+) 2019-04-02 11:54:36 +02:00
Meritoo
95a81ab322 Tests > fix "This test did not perform any assertions" bug > make compatible with PHPUnit 8.0 (and PHP 7.2+) 2019-04-02 10:40:51 +02:00
Meritoo
8a27cd94ef Tests > fix "assertArraySubset() is deprecated and will be removed in PHPUnit 9" bug > make compatible with PHPUnit 8.0 (and PHP 7.2+) 2019-04-02 10:15:57 +02:00
Meritoo
ce37db5f33 Tests > fix "Call to undefined method getMock()" bug > make compatible with PHPUnit 8.0 (and PHP 7.2+) 2019-04-02 09:03:11 +02:00
Meritoo
b68dd78b06 Tests > fix "Using assertContains() with string haystacks is deprecated and will not be supported in PHPUnit 9. Refactor your test to use assertStringContainsString() or assertStringContainsStringIgnoringCase() instead." bug > make compatible with PHPUnit 8.0 (and PHP 7.2+) 2019-04-02 08:39:50 +02:00
Meritoo
c89b6da0db Tests > fix "Call to undefined method setExpectedException()" bug > make compatible with PHPUnit 8.0 (and PHP 7.2+) 2019-04-02 08:31:24 +02:00
Meritoo
8b5a530bbc Tests > setUp() and tearDown() methods > make compatible with PHPUnit 8.0 (and PHP 7.2+) 2019-04-02 08:27:20 +02:00
Meritoo
e623c87268 Composer > bump versions of packages (available for PHP 7.2+) 2019-04-02 08:24:40 +02:00
Meritoo
90bc438cae Composer > support/require PHP 7.2+ (instead of 5.6+) 2019-04-01 22:59:04 +02:00
Krzysztof Nizioł
28a11d611c Merge branch 'master' of github.com:meritoo/common-library 2019-03-25 09:23:57 +01:00
Meritoo
5022efb9a3 Minor refactoring 2019-03-24 22:19:45 +01:00
Meritoo
56b058ca1d Size, e.g. of image 2019-03-24 22:15:54 +01:00
Meritoo
eade6a25ad Collection > the getByIndex() method > returns element with given index 2019-03-16 19:58:02 +01:00
Meritoo
9f6af6b6a4 Collection > create trait (to make it more flexible) 2019-03-16 12:37:35 +01:00
Krzysztof Nizioł
df36e050e7 Merge branch 'master' of github.com:meritoo/common-library 2019-03-05 10:21:44 +01:00
Meritoo
a021870ebd Minor refactoring 2019-03-05 10:18:45 +01:00
Meritoo
d88ead92fe Tests > use @dataProvider 2019-03-05 10:18:35 +01:00
Meritoo
5ebde80646 Tests > use "Meritoo\Test\Common" namespace (instead of "Meritoo\Common\Test") 2019-03-04 19:35:42 +01:00
Meritoo
fe40d9caee ValueObject > Human > represents a human 2019-03-04 19:25:38 +01:00
Meritoo
ba6c185ed9 Tests > missing tests 2019-03-04 19:24:23 +01:00
Meritoo
c175fcd126 Minor refactoring 2019-03-04 19:22:07 +01:00
Meritoo
2247000a8a Documentation > Value Objects > add missing information 2019-03-04 18:52:07 +01:00
Meritoo
924e492e11 Arrays > refactoring & more tests 2019-02-24 23:21:55 +01:00
Krzysztof Nizioł
ddd558a7d4 Merge remote-tracking branch 'meritoo/master' 2019-02-23 13:29:37 +01:00
Meritoo
ede9a182b4 Changelog > update > enter latest modifications 2019-02-23 12:47:10 +01:00
Meritoo
fad0aa607a Changelog > update > enter latest modifications 2019-02-23 11:58:13 +01:00
Meritoo
3a38c09ce2 ValueObject > Company > represents a company 2019-02-22 20:38:13 +01:00
Meritoo
07a04d86f0 ValueObject > BankAccount > represents bank account 2019-02-22 20:37:16 +01:00
Meritoo
0c7e27b884 ValueObject > Address > represents address of company, institution, user etc. 2019-02-22 20:35:43 +01:00
Meritoo
421d336498 Tests > ValueObject > Version > fix namespace 2019-02-22 14:19:32 +01:00
Meritoo
292c5e6d4f Arrays > getNonEmptyValues() method > returns non-empty values, e.g. without "" (empty string), null or []
Arrays > getNonEmptyValuesAsString() method > returns non-empty values concatenated by given separator
2019-02-22 14:19:17 +01:00
Meritoo
79c09a26a6 Regex > createSlug() method > returns slug for given value 2019-02-21 23:26:36 +01:00
Meritoo
d46548d102 Miscellaneous > variableDump() method > remove, because unnecessary 2019-02-21 23:10:15 +01:00
Meritoo
651c4f2259 Minor refactoring 2019-02-21 23:09:42 +01:00
Meritoo
8c3c85608a Tests > Regex > minor update 2019-02-21 16:54:06 +01:00
Meritoo
22c96f0a18 Tests > Regex > fix "The mode is not binary-safe ('b' is missing)" bug 2019-02-21 16:51:18 +01:00
Meritoo
aa93cd8e25 Tests > Regex > remove unnecessary @throws tags 2019-02-21 16:50:20 +01:00
Meritoo
4391baed3d Fix "Argument 3 of Meritoo\Common\Utilities\Date::getDateDifference expects int|null, string(days) provided" bug 2019-02-04 22:43:07 +01:00
Meritoo
b879dbd803 .gitignore > minor update 2019-01-27 14:54:20 +01:00
Meritoo
7233fdac52 Phing > update configuration 2019-01-27 14:54:02 +01:00
Meritoo
ec5129ad6b Tests > Date > more test cases 2018-11-09 23:39:01 +01:00
Meritoo
39ede292d6 Merge branch 'develop' 2018-11-03 09:09:09 +01:00
Meritoo
8e9dcb3206 Reflection > setPropertiesValues() method > sets values of properties in given object 2018-11-03 08:53:01 +01:00
Meritoo
06fbf63e09 Tests > refactoring 2018-11-03 08:50:12 +01:00
Meritoo
4e600ec599 Utilities > Reflection > setPropertyValue() method > fix description and test 2018-11-03 08:16:49 +01:00
Meritoo
b4ccbbac11 Utilities > Date > update descriptions of methods 2018-11-03 08:10:03 +01:00
Meritoo
c82f53219e Phing > PHPUnit > run with code coverage (to get all reports) 2018-10-29 08:31:38 +01:00
Meritoo
c8fc0b14ff Exceptions > UnknownTypeException > remove duplicated and unnecessary sprintf() call > sprintf(sprintf()) 2018-10-28 00:12:18 +02:00
Meritoo
3c3d1b997e Docker > docker-compose.yml > add "phpunit" service > used to run PHPUnit's tests 2018-10-28 00:10:42 +02:00
Meritoo
61209e3f67 Documentation > Development > add commands based on Phing & update whole document 2018-10-28 00:09:29 +02:00
Meritoo
822dbf6830 Phing > tests > remove mutation tests (because Infection requires PHP 7.1+) 2018-10-28 00:06:52 +02:00
Meritoo
870bfe48a2 Docker > Dockerfile > fix installation of Composer 2018-10-28 00:03:35 +02:00
Meritoo
ff416fda69 Phing > update configuration 2018-10-25 11:05:32 +02:00
Meritoo
61676a445e Docker > update docker-compose.yml > composer > fix "allowed memory size of 1610612736 bytes exhausted" bug 2018-10-25 10:31:44 +02:00
Meritoo
1f5106bcf0 Docker > improve performance > fix indentations 2018-10-25 10:31:21 +02:00
Meritoo
971224b2e6 PHPUnit > update configuration 2018-10-25 10:28:00 +02:00
Meritoo
7e4b14a92f Phing > update configuration 2018-10-25 10:27:48 +02:00
Meritoo
38c68b0952 Readme > add badge with required PHP version 2018-10-19 22:54:26 +02:00
Meritoo
ca9c3bd8f1 Utilities > Date > update descriptions of methods 2018-10-19 22:54:11 +02:00
Meritoo
97c6112919 TravisCI > fix indentation 2018-09-20 20:41:48 +02:00
Meritoo
26b136d676 Tests > increase code coverage 2018-09-20 17:30:07 +02:00
Meritoo
4db631223f Phing > tests > PHPUnit > do not use dox format (for output results) 2018-09-08 08:21:50 +02:00
Meritoo
5d6b559108 Phing > tests > missing path of directory with code coverage report 2018-09-07 13:48:44 +02:00
Krzysztof Nizioł
e31af27c01 Merge branch 'master' of github.com:meritoo/common-library
# Conflicts:
#	README.md
2018-09-06 22:01:00 +02:00
Meritoo
575bb344cd BaseTestCaseTrait > minor refactoring 2018-08-27 22:04:35 +02:00
Meritoo
35b70f53e7 BaseType > minor refactoring 2018-08-26 16:39:45 +02:00
Meritoo
51ff110101 Phing > update configuration 2018-08-26 15:43:34 +02:00
Meritoo
2f9138d093 Merge branch 'develop' 2018-08-08 18:37:09 +02:00
Meritoo
75707a3f76 Utilities > Bootstrap4CssSelector > useful methods related to CSS selectors and the Bootstrap4 (front-end component library) 2018-08-07 23:31:50 +02:00
Meritoo
8ecbefbba6 Utilities > CssSelector > useful methods related to CSS selectors 2018-08-07 23:31:30 +02:00
Meritoo
e850375c19 Tests > refactoring & minor improvements 2018-08-06 21:43:57 +02:00
Meritoo
0bd1e1e158 Merge branch 'develop' 2018-07-29 16:01:31 +02:00
Meritoo
535ae65e5e Utilities > Reflection > setPropertyValue() method > sets value of given property 2018-07-29 16:00:13 +02:00
Meritoo
60d7b03cd7 Utilities > Reflection > refactoring 2018-07-29 15:34:33 +02:00
Meritoo
c20fa5941f Docker > improve performance 2018-07-28 21:01:07 +02:00
Meritoo
a448d592d2 Documentation > Value Objects 2018-07-02 21:24:20 +02:00
Meritoo
e53273fb32 Merge branch 'develop' 2018-07-02 20:20:52 +02:00
Meritoo
cc30ad8d9e Move version of this package to "VERSION" file (from "composer.json" file) 2018-07-02 20:19:29 +02:00
Meritoo
9f08a2aaaf ValueObject > class Version > represents version of software 2018-07-02 20:07:33 +02:00
Meritoo
b49605a26c TravisCI - fix "No output has been received in the last 10m0s" bug (build times out because no output was received) 2018-07-02 10:40:33 +02:00
Meritoo
8441c82356 TravisCI > run using PHP 7.2 too 2018-07-02 09:53:16 +02:00
Meritoo
55dde2e898 Merge branch 'develop' 2018-07-02 09:34:53 +02:00
Meritoo
a32e0c4cca Documentation > Exceptions 2018-07-02 09:31:07 +02:00
Meritoo
834b24f348 Exceptions > create instance of exception using static "create()" method (instead of constructor) 2018-07-02 08:54:24 +02:00
Meritoo
9342f0e87e Docker > rename "php-cli" service to "php" 2018-07-02 08:47:56 +02:00
Meritoo
72fd87e165 Composer > support/require PHP 5.6+ (instead of 5.5.9+) 2018-07-02 08:12:26 +02:00
Meritoo
64499b49d3 Update @author and @copyright in classes' descriptions 2018-07-01 21:07:47 +02:00
Meritoo
848adef015 Arrays > minor refactoring 2018-07-01 17:45:03 +02:00
Meritoo
1431fd9935 Composer > require ext-pcre 2018-07-01 17:37:51 +02:00
Meritoo
3bb7a182c2 Merge branch 'develop' 2018-06-22 08:26:10 +02:00
Meritoo
5c9436e4e2 Collection > add() method > treat empty string as not provided index (same as null) 2018-06-22 08:10:06 +02:00
Meritoo
1a649d35e1 Merge branch 'develop' 2018-06-18 09:37:27 +02:00
Meritoo
107480d01b StyleCI > disable & remove 2018-06-16 14:43:16 +02:00
Meritoo
f4c12661b4 StyleCI configuration > fix bug "The provided fixer 'concat_with_spaces' cannot be enabled at the same time as 'concat_without_spaces'" 2018-06-16 14:36:33 +02:00
Meritoo
fc7df571e2 StyleCI configuration > fix bug "The provided fixer 'binary_operator_spaces' cannot be enabled again because it was already enabled" 2018-06-16 14:34:00 +02:00
Meritoo
0f37edfc9b Coding standard > fix automatically 2018-06-16 14:31:04 +02:00
Meritoo
ae3e82e233 Documentation > Docker > add paragraph for PHP Coding Standards Fixer 2018-06-16 14:21:01 +02:00
Meritoo
c99a099c31 StyleCI & PHP Coding Standards Fixer > update configuration 2018-06-16 14:15:35 +02:00
Meritoo
c443ef22d7 .gitignore > PHP Coding Standards Fixer > ignore custom settings 2018-06-16 14:12:07 +02:00
Meritoo
be8b4a3498 Arrays > remove unnecessary code 2018-06-16 14:10:57 +02:00
Meritoo
b1ddc6d561 .env.dist > enter default values (for easier .env creation) 2018-06-16 10:04:14 +02:00
Meritoo
ffe34eb9cf StyleCI > update configuration 2018-06-15 23:06:47 +02:00
Meritoo
155c091a3e StyleCI > update configuration 2018-06-15 23:04:06 +02:00
Meritoo
0a3955026b Revert "StyleCI > update configuration"
This reverts commit f9fa5f5
2018-06-15 23:00:53 +02:00
Meritoo
f9fa5f5915 StyleCI > update configuration 2018-06-15 23:00:29 +02:00
Meritoo
43945a8721 Composer > do not require symfony/http-foundation package
Miscellaneous > remove getCurlResponseWithHeaders() method
2018-06-15 22:54:00 +02:00
Meritoo
e9da0cf351 Reorganize documentation & update Readme 2018-06-14 22:28:53 +02:00
Meritoo
4c534394d9 Docker > Dockerfile > add "WORKDIR" (instead of "working_dir" in docker-compose.yml) 2018-06-14 21:35:50 +02:00
Meritoo
3726a26e47 Reorganize documentation & update Readme 2018-06-14 21:35:14 +02:00
Meritoo
fb24bc2ff1 Docker > use project-related binaries globally 2018-06-14 11:50:45 +02:00
Meritoo
57a78d1299 Reorganize documentation & update Readme 2018-06-14 11:32:54 +02:00
Meritoo
696cff023c Add changelog 2018-06-14 11:32:25 +02:00
Meritoo
9197682cd2 Readme > update paragraphs with Composer, Docker & use 1st level headers 2018-06-14 09:55:44 +02:00
Meritoo
49638ff1c3 .gitignore > update sections' separators 2018-06-13 22:21:28 +02:00
Meritoo
abf0ebf7ec Tests > increase code coverage 2018-06-09 14:25:20 +02:00
Meritoo
2e60176d95 Docker > Dockerfile > make bash terminal wider (increase columns count) 2018-06-07 20:56:48 +02:00
Meritoo
c351ce887a Tests > implement PHPUnit (instead of Codeception) 2018-06-07 20:51:55 +02:00
Meritoo
8a6262a8c3 Phing > tests > update name of property with path (tests_framework.path > tests.framework.path) & ignore /build directory 2018-05-28 21:22:00 +02:00
Meritoo
3c83a8800e Start names of special directories without dot 2018-05-28 21:10:20 +02:00
Meritoo
233473d915 Tests > implement Codeception (instead of PHPUnit) 2018-05-28 17:53:25 +02:00
Meritoo
7382bce842 Phing > tests > do not verify if the "tests" directory exists 2018-05-28 17:05:12 +02:00
Meritoo
c5b42017d2 Phing > tests > do not create database (for code coverage) 2018-05-28 17:03:19 +02:00
Meritoo
bc54f734e2 Phing > update properties.dist > remove unnecessary properties and disabled code 2018-05-28 16:56:59 +02:00
Meritoo
0eb5343df0 Docker > name of containers > use custom suffix
Docker > the "composer" service
2018-05-28 15:03:52 +02:00
Meritoo
52e74c8b48 Tests > increase code coverage 2018-05-28 15:03:11 +02:00
Meritoo
96bdb6eb60 Improve coding standard 2018-05-06 17:21:55 +02:00
Meritoo
5be449a83d Docker > Dockerfile > fix bug when error messages are displayed in french instead of english language (example: "chmod(): Aucun fichier ou dossier de ce type") 2018-05-06 14:40:17 +02:00
Meritoo
132a0a00e7 Docker > Dockerfile > fix bug "pecl/xdebug requires PHP (version >= 7.0.0), installed version is 5.5.38" 2018-05-04 12:53:45 +02:00
Meritoo
6fd18111b4 TravisCI - fix "No output has been received in the last 10m0s" bug (build times out because no output was received) 2018-04-04 21:54:45 +02:00
Meritoo
26c63ecb5c TravisCI > composer > install hirak/prestissimo package globally 2018-04-04 21:40:44 +02:00
Meritoo
bedb6333b9 TravisCI > "composer install" command > increase verbosity to maximum 2018-04-04 21:21:51 +02:00
Meritoo
ec2b5742ec Revert "TravisCI - fix "No output has been received in the last 10m0s" bug (build times out because no output was received)"
This reverts commit ec2f3c6
2018-04-04 21:16:36 +02:00
Meritoo
ec2f3c6ead TravisCI - fix "No output has been received in the last 10m0s" bug (build times out because no output was received) 2018-04-04 08:57:08 +02:00
Meritoo
834c12f280 TravisCI - install locales before running tests - remove unnecessary command 2018-04-03 22:57:41 +02:00
Meritoo
122ff41dad TravisCI - install locales before running tests 2018-04-03 19:13:38 +02:00
Meritoo
180a8b8b5d TravisCI - install locales before running tests 2018-04-03 17:10:40 +02:00
Meritoo
499c603d54 TravisCI - install locales before running tests 2018-04-03 17:04:43 +02:00
Meritoo
1cbc87222f TravisCI - install locales before running tests 2018-04-03 16:58:54 +02:00
Meritoo
129b75ea93 Revert "TravisCI - install locales before running tests"
This reverts commit aae7609
2018-04-03 16:58:32 +02:00
Meritoo
aae7609c8c TravisCI - install locales before running tests 2018-04-03 16:55:12 +02:00
Meritoo
5578b051a7 Update PHPDoc and comments 2018-04-03 08:26:51 +02:00
Meritoo
f111174ed2 Tests - increase code coverage 2018-04-03 08:22:10 +02:00
Meritoo
ddbff1b557 Update PHPDoc and comments 2018-04-02 22:46:52 +02:00
Meritoo
8d1df9ced8 Tests - increase code coverage 2018-04-02 22:44:30 +02:00
Meritoo
b7d0b61094 tests > PHPUnit configuration > update 2018-03-30 21:15:42 +02:00
Meritoo
ad64d2e02a Docker - Dockerfile - minor update 2018-01-27 13:10:14 +01:00
Meritoo
470b8244ec Utilities - Locale - getLocale() method - returns locale for given category 2018-01-27 13:05:20 +01:00
Meritoo
af38c35a1b Utilities - Locale - setLocale() method - return result of setting new locale (instead of "true")
Tests - Locale - fix incorrectly prepared tests
2018-01-27 13:04:04 +01:00
Meritoo
1e3e1d454e Docker - Dockerfile - install "locales" package & generate popular locales
Required to run tests related to setlocale() function (and Meritoo\Common\Utilities\Locale class) properly
2018-01-27 12:59:55 +01:00
Meritoo
57b411b59f Tests - increase code coverage 2018-01-17 21:37:07 +01:00
Meritoo
8a4860088f Phing - Composer-related task - validate Composer 2018-01-14 21:19:06 +01:00
Meritoo
e9b8fb8852 Regex - isBinaryValue() method - returns information if given value is a binary value 2018-01-10 17:35:42 +01:00
Meritoo
780d4df17e Tests - increase code coverage 2017-12-26 14:37:17 +01:00
Meritoo
d801e675fc Exception - InvalidHtmlAttributesException - an exception used while html attributes are invalid 2017-12-24 00:03:23 +01:00
Meritoo
6753076937 Regex - isValidHtmlAttribute() & areValidHtmlAttributes() methods - returns information if given html attribute is valid & if given html attributes are valid 2017-12-23 23:08:49 +01:00
Meritoo
7f713e0c6e Docker - name of containers - use custom prefix 2017-12-22 10:44:07 +01:00
Meritoo
ebbed4825c Bundle - getBundleViewPath() method - return path using namespaced syntax 2017-12-21 23:45:01 +01:00
Meritoo
7d23ff59d1 Bundle - getBundleViewPath() method - verify name of bundle 2017-12-21 22:45:23 +01:00
Meritoo
0e4c33241e Tests - BundleTest - minor refactoring 2017-12-21 22:05:07 +01:00
Meritoo
66aefa2446 Regex - isValidBundleName() method - returns information if given name of bundle is valid 2017-12-21 21:47:45 +01:00
Meritoo
5aaf7cde72 Minor refactoring 2017-12-21 20:41:12 +01:00
Meritoo
8bb529b88d Docker - Dockerfile - minor refactoring 2017-12-02 13:23:26 +01:00
Meritoo
3588c00009 Docker - do not install "zip" package 2017-12-02 13:12:34 +01:00
Meritoo
78480ac853 .gitignore - ignore .env 2017-12-02 12:53:32 +01:00
Krzysztof Niziol
3bcda8e906 composer.json - update name of this package (name of vendor, actually) 2017-11-08 14:52:19 +01:00
Krzysztof Niziol
1641c50d1d composer.json - update name of this package 2017-11-07 16:34:49 +01:00
Krzysztof Niziol
afbbdfe437 composer.json - update name of this package 2017-11-07 15:24:51 +01:00
Meritoo
8bcf006e02 Tests - increase code coverage 2017-11-05 19:35:13 +01:00
Meritoo
edc51aeee1 DatePeriod - change namespace (Meritoo\Common\Utilities -> Meritoo\Common\Type) & extend BaseType 2017-11-03 20:21:08 +01:00
Meritoo
6d4e422165 BaseTestCase & BaseTypeTestCase - add traits to use in other test cases (e.g. in Symfony's kernel-related test case) 2017-11-02 22:00:38 +01:00
Meritoo
6f441bb9ea Tests - BaseTestCaseTest - fix bug while there is a difference (split second) 2017-11-02 13:58:24 +01:00
Meritoo
73030d703b composer.json - bump version 2017-11-02 12:25:39 +01:00
Meritoo
36ddb326b9 Tests - increase code coverage 2017-10-31 21:27:42 +01:00
Meritoo
452a4ec458 Tests - BaseTestCase - rename method getFilePathToTests() -> getFilePathForTesting() 2017-10-31 21:26:39 +01:00
Meritoo
325fe6b141 Support PHP 5.5.9+ 2017-10-31 20:28:55 +01:00
Meritoo
a1c26b3812 Phing - tests - phpcodesniffer task - fix "This task requires the PHP_CodeSniffer package installed and available on the include path" bug
Details: https://github.com/phingofficial/phing/issues/716
2017-10-26 20:04:05 +02:00
Meritoo
67d93036cf Phing - update properties.dist file 2017-10-22 21:40:23 +02:00
Meritoo
9368616dfe composer.json - update versions of the "dev" packages 2017-10-22 20:09:02 +02:00
Meritoo
5ab68d3667 Tests - Docker - update Xdebug configuration
Required to fix problem "Connection with XDebug 2.5.1 was not established. Validate installation."
2017-10-22 17:55:49 +02:00
Meritoo
4613a63f02 Tests - Docker - install vim, add custom php.ini, add "vendor/bin" to the $PATH global variable 2017-10-20 00:03:38 +02:00
Meritoo
9dac5bd11c Tests - Docker - update name of image and container 2017-10-18 21:50:02 +02:00
Meritoo
12100db058 Tests - Docker - update port 2017-10-18 20:02:09 +02:00
Meritoo
f9ab0a6194 Tests - Docker - add required libraries, PHP extensions & optimize size of Docker's image 2017-10-18 17:01:13 +02:00
Meritoo
b824808cd4 Tests - use Docker (as environment guard) 2017-10-18 00:31:18 +02:00
Meritoo
71e1eeb81b Start names of special directories with dot
BaseTestCase - add setter for path of directory with data used by test cases
2017-10-17 20:49:13 +02:00
Meritoo
70c273750d .gitignore update 2017-10-10 20:09:40 +02:00
Meritoo
e5e39651f3 Tests - fix names of constructors' tests 2017-10-02 15:56:53 +02:00
Meritoo
4683970c87 composer.json - update versions of the "dev" packages & sort them 2017-10-02 14:06:57 +02:00
Meritoo
559466c0ce composer.json - move tests-related classes to "autoload-dev" section (used for development purposes only and avoid polluting the autoloader in production) 2017-09-29 09:19:03 +02:00
Meritoo
bfd69c1098 Minor fix of coding standard 2017-09-27 21:52:10 +02:00
Meritoo
45493b37b0 Remove composer.lock 2017-09-27 21:51:48 +02:00
Meritoo
37e7b14ae2 Minor fix of coding standard 2017-09-27 20:09:51 +02:00
Meritoo
a12aaf4bc0 Tests - increase code coverage 2017-09-27 17:08:39 +02:00
Meritoo
f9c480aa19 Reflection - getPropertyValue() method - verify if getter is accessible publicly 2017-09-27 17:00:25 +02:00
Meritoo
ffa3fbffe7 Exception - DisabledMethodException - an exception used while method cannot be called, because is disabled 2017-09-22 23:27:21 +02:00
Meritoo
48aa27fb86 Tests - test cases of exceptions 2017-09-22 23:26:30 +02:00
Meritoo
86cc5ff79b Refactor & fix coding standard 2017-09-22 23:25:16 +02:00
Meritoo
633696ebc0 Reflection - getProperties() method - allow to include properties of parent classes 2017-09-21 22:38:50 +02:00
Meritoo
a0d28b326e BaseTestCase - make static and rename methods (start names of methods with "assert" instead of "verify") 2017-09-21 16:52:15 +02:00
Meritoo
318a635ffd BaseTestCase - assertHasNoConstructor() method - asserts that class with given namespace has no constructor 2017-09-21 16:47:41 +02:00
Meritoo
6c70fdd673 Revert "Composer - update packages"
This reverts commit 204e879
2017-09-20 22:00:09 +02:00
Meritoo
204e8793ac Composer - update packages 2017-09-20 21:55:05 +02:00
Meritoo
3dd37ae202 BaseTestCase - fix getting path of file used by tests (by implementing the Miscellaneous::getProjectRootPath() method) 2017-09-20 21:54:07 +02:00
Meritoo
ef017c9d6a Miscellaneous - getProjectRootPath() method - returns project's root path 2017-09-20 21:52:34 +02:00
Meritoo
5030dc2062 Refactor & fix coding standard 2017-09-20 21:47:39 +02:00
Meritoo
2c76158093 Readme - fix displaying 1st block of code 2017-09-20 16:19:36 +02:00
Meritoo
0b560fdf18 Exception - 3 exceptions related to file path & content 2017-09-20 13:50:18 +02:00
Meritoo
284d403061 Fix coding standard (minor fix) 2017-09-20 12:55:25 +02:00
Meritoo
7dbb3f9b2e Tests - update namespace of PHPUnit's TestCase
Related to update versions of the "dev" packages
2017-09-20 11:58:21 +02:00
Meritoo
fba821b798 Readme - StyleCI badge - update configuration file (required to fix failed StyleCI analysis) 2017-09-20 10:56:49 +02:00
Meritoo
3985c70076 Readme - minor update 2017-09-20 09:30:06 +02:00
Meritoo
921d4e6106 composer.json - update versions of the "dev" packages 2017-09-20 09:29:19 +02:00
Meritoo
7aa2239dbd Fix coding standard (no_blank_lines_after_phpdoc, single_blank_line_before_namespace, yoda_style) 2017-09-20 09:27:56 +02:00
Meritoo
e1fefcdeae Readme - move badges below description & update description 2017-09-19 20:10:27 +02:00
Meritoo
94a464cb4d Readme - TravisCI badge - do not support PHP 7.2, because friendsofphp/php-cs-fixer package can be run using PHP lower than 7.2 only
Details:
$ composer install
Your requirements could not be resolved to an installable set of packages
friendsofphp/php-cs-fixer v2.3.2 requires php ^5.6 || >=7.0 <7.2 -> your PHP version (7.3.0-dev) does not satisfy that requirement
2017-09-19 18:09:13 +02:00
Meritoo
463ee751b2 Readme - TravisCI badge - do not support nightly build of PHP, because friendsofphp/php-cs-fixer pacakge cane be run using maximum PHP 7.2
Details:
$ composer install
Your requirements could not be resolved to an installable set of packages
friendsofphp/php-cs-fixer v2.3.2 requires php ^5.6 || >=7.0 <7.2 -> your PHP version (7.3.0-dev) does not satisfy that requirement
2017-09-19 17:55:41 +02:00
Meritoo
89af7145f6 Readme - TravisCI badge - fix bug related to PHP 5.6 while running PHPUnit
Bug:
PHP Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR) in tests/Meritoo/Common/Test/Utilities/DateTest.php
2017-09-19 17:53:07 +02:00
Meritoo
09c8569938 Readme - TravisCI badge - update configuration file 2017-09-19 17:37:58 +02:00
Meritoo
5ab2cd9de8 Readme - add badges - TravisCI, Packagist, StyleCI, GitHub commits, GitHub license, Coverage 2017-09-19 17:10:03 +02:00
Meritoo
60eff29e82 Readme - update usage information and add examples 2017-09-19 17:06:29 +02:00
Meritoo
5aa5ff4380 BaseTestCase - fix typo 2017-09-16 14:06:19 +02:00
Meritoo
6483a8f5b7 BaseTypeTestCase - base test case for the type of something 2017-09-16 14:02:10 +02:00
Meritoo
5c0ef79b15 TestCase - make abstract & move from namespace Meritoo\Common\Utilities to Meritoo\Common\Test\Base 2017-09-16 14:01:20 +02:00
Meritoo
324f64f912 Tests - modify namespace "Meritoo\Common\Tests" -> "Meritoo\Common\Test" 2017-09-11 19:57:36 +02:00
Meritoo
5940ebba9a PHPUnit - use "Meritoo Package" as project name 2017-09-11 13:33:52 +02:00
Meritoo
787b8c697c Phing - use "Meritoo Package" as project name 2017-09-10 14:16:21 +02:00
Meritoo
96c02cdc3d Tests - verifyMethodVisibilityAndArguments() method - implementation 2017-09-10 10:22:07 +02:00
Meritoo
87d7bff5f5 TestCase - verifyMethodVisibilityAndArguments() method - verify visibility and arguments of method or class constructor 2017-09-10 10:21:28 +02:00
Meritoo
bd7c874e88 Refactor & fix coding standard 2017-09-09 21:33:49 +02:00
Meritoo
e1ffb78214 Collection of elements (class & tests) 2017-09-07 22:17:44 +02:00
Meritoo
d4dc274763 Add missing information about license 2017-09-07 15:17:52 +02:00
Meritoo
aeea1df04b Exception - InvalidUrlException - an exception used while url is invalid 2017-08-30 21:27:36 +02:00
Meritoo
b5e63ff619 Regex - move exceptions related to regular expressions to namespace with "Regex" 2017-08-30 21:25:26 +02:00
Meritoo
ecaebcca0e Remove & ignore the ".idea" folder 2017-08-30 21:07:53 +02:00
Meritoo
17ac1dc72c Readme - update installation instructions 2017-08-29 23:17:55 +02:00
206 changed files with 30349 additions and 15476 deletions

2
.coveralls.yml Normal file
View File

@@ -0,0 +1,2 @@
coverage_clover: build/reports/coveralls/clover.xml
json_path: build/reports/coveralls/upload.json

15
.env Normal file
View File

@@ -0,0 +1,15 @@
# ------------------------------------------------------------------------------
### Docker
# ------------------------------------------------------------------------------
#
# All containers
#
DOCKER_CONTAINER_OWNER=meritoo
DOCKER_CONTAINER_PROJECT=common-library
#
# PHP configuration:
# - timezone
#
PHP_DATE_TIMEZONE=Europe/London

279
.gitignore vendored
View File

@@ -1,95 +1,129 @@
# ----------------------------------------------------------------------------------------------------------------------
### Vendors
# ----------------------------------------------------------------------------------------------------------------------
/vendor/
# ------------------------------------------------------------------------------
### Linux template
# ------------------------------------------------------------------------------
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# ----------------------------------------------------------------------------------------------------------------------
### Composer
# ----------------------------------------------------------------------------------------------------------------------
/composer.phar
# ------------------------------------------------------------------------------
### macOS template
# ------------------------------------------------------------------------------
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# ----------------------------------------------------------------------------------------------------------------------
### Phing
# ----------------------------------------------------------------------------------------------------------------------
/phing/properties
# ------------------------------------------------------------------------------
### Windows template
# ------------------------------------------------------------------------------
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# ----------------------------------------------------------------------------------------------------------------------
### PHPUnit
# ----------------------------------------------------------------------------------------------------------------------
/phpunit.xml
# ----------------------------------------------------------------------------------------------------------------------
### PHP Coding Standards Fixer generated files
# ----------------------------------------------------------------------------------------------------------------------
/.php_cs.cache
# ----------------------------------------------------------------------------------------------------------------------
### Generated databases
# ----------------------------------------------------------------------------------------------------------------------
/data/tmp
*.sql
*.sqlite
# ----------------------------------------------------------------------------------------------------------------------
### Compiled source
# ----------------------------------------------------------------------------------------------------------------------
*.com
*.class
*.dll
*.exe
*.o
*.so
# ----------------------------------------------------------------------------------------------------------------------
### Shell scripts
# ----------------------------------------------------------------------------------------------------------------------
/*.sh
# ----------------------------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
### JetBrains template
# ----------------------------------------------------------------------------------------------------------------------
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# ------------------------------------------------------------------------------
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Sensitive or high-churn files:
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle:
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# CMake
cmake-build-debug/
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# Mongo Explorer plugin:
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
## File-based project format:
# File-based project format
*.iws
## Plugin-specific files:
# IntelliJ
out/
@@ -108,82 +142,63 @@ crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# ----------------------------------------------------------------------------------------------------------------------
### NetBeans template
# ----------------------------------------------------------------------------------------------------------------------
nbproject/private/
build/
nbbuild/
dist/
nbdist/
nbactions.xml
.nb-gradle/
# ------------------------------------------------------------------------------
### Build files
# ------------------------------------------------------------------------------
/build/
# ----------------------------------------------------------------------------------------------------------------------
### OSX template
# ----------------------------------------------------------------------------------------------------------------------
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# ------------------------------------------------------------------------------
### Phing
# ------------------------------------------------------------------------------
/phing/properties
# ----------------------------------------------------------------------------------------------------------------------
### Linux template
# ----------------------------------------------------------------------------------------------------------------------
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# ------------------------------------------------------------------------------
### Infection
# ------------------------------------------------------------------------------
/infection.json
# ----------------------------------------------------------------------------------------------------------------------
### Windows template
# ----------------------------------------------------------------------------------------------------------------------
# Windows image file caches
Thumbs.db
ehthumbs.db
# ------------------------------------------------------------------------------
### Temporary data & databases
# ------------------------------------------------------------------------------
/data/tmp
*.sqlite
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# ------------------------------------------------------------------------------
### Composer & vendors
# ------------------------------------------------------------------------------
/composer.lock
/composer.phar
/vendor/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
# ------------------------------------------------------------------------------
### PHPUnit
# ------------------------------------------------------------------------------
/phpunit.xml
/.phpunit.result.cache
/tests/Resources/var
# ------------------------------------------------------------------------------
### PHP Coding Standards Fixer
# ------------------------------------------------------------------------------
/.php_cs
/.php_cs.cache
# ------------------------------------------------------------------------------
### PHP_CodeSniffer
# ------------------------------------------------------------------------------
/.phpcs-cache
/phpcs.xml

1
.idea/.name generated
View File

@@ -1 +0,0 @@
Common Library (GitHub)

View File

@@ -1,210 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/tests/Meritoo/Common/Tests" isTestSource="false" packagePrefix="Meritoo\Common\Tests\" />
<sourceFolder url="file://$MODULE_DIR$/src/Meritoo/Common" isTestSource="false" packagePrefix="Meritoo\Common\" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/vendor/behat/transliterator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/annotations" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/collections" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/common" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/dbal" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/inflector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/instantiator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/lexer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/orm" />
<excludeFolder url="file://$MODULE_DIR$/vendor/friendsofphp/php-cs-fixer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/gecko-packages/gecko-php-unit" />
<excludeFolder url="file://$MODULE_DIR$/vendor/gedmo/doctrine-extensions" />
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
<excludeFolder url="file://$MODULE_DIR$/vendor/paragonie/random_compat" />
<excludeFolder url="file://$MODULE_DIR$/vendor/pdepend/pdepend" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-common" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phploc/phploc" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpmd/phpmd" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/prophecy" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-token-stream" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit-mock-objects" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/log" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/environment" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/finder-facade" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/git" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-enumerator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/phpcpd" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/resource-operations" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/version" />
<excludeFolder url="file://$MODULE_DIR$/vendor/squizlabs/php_codesniffer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/config" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/console" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/debug" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/dependency-injection" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/filesystem" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/finder" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-foundation" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/options-resolver" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php70" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/stopwatch" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/yaml" />
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/fdomdocument" />
<excludeFolder url="file://$MODULE_DIR$/vendor/webmozart/assert" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library name="PHP" type="php">
<CLASSES>
<root url="file://$MODULE_DIR$/vendor/behat/transliterator" />
<root url="file://$MODULE_DIR$/vendor/composer" />
<root url="file://$MODULE_DIR$/vendor/doctrine/annotations" />
<root url="file://$MODULE_DIR$/vendor/doctrine/cache" />
<root url="file://$MODULE_DIR$/vendor/doctrine/collections" />
<root url="file://$MODULE_DIR$/vendor/doctrine/common" />
<root url="file://$MODULE_DIR$/vendor/doctrine/dbal" />
<root url="file://$MODULE_DIR$/vendor/doctrine/inflector" />
<root url="file://$MODULE_DIR$/vendor/doctrine/instantiator" />
<root url="file://$MODULE_DIR$/vendor/doctrine/lexer" />
<root url="file://$MODULE_DIR$/vendor/doctrine/orm" />
<root url="file://$MODULE_DIR$/vendor/friendsofphp/php-cs-fixer" />
<root url="file://$MODULE_DIR$/vendor/gecko-packages/gecko-php-unit" />
<root url="file://$MODULE_DIR$/vendor/gedmo/doctrine-extensions" />
<root url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
<root url="file://$MODULE_DIR$/vendor/paragonie/random_compat" />
<root url="file://$MODULE_DIR$/vendor/pdepend/pdepend" />
<root url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-common" />
<root url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
<root url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
<root url="file://$MODULE_DIR$/vendor/phploc/phploc" />
<root url="file://$MODULE_DIR$/vendor/phpmd/phpmd" />
<root url="file://$MODULE_DIR$/vendor/phpspec/prophecy" />
<root url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
<root url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
<root url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
<root url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
<root url="file://$MODULE_DIR$/vendor/phpunit/php-token-stream" />
<root url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
<root url="file://$MODULE_DIR$/vendor/phpunit/phpunit-mock-objects" />
<root url="file://$MODULE_DIR$/vendor/psr/container" />
<root url="file://$MODULE_DIR$/vendor/psr/log" />
<root url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<root url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
<root url="file://$MODULE_DIR$/vendor/sebastian/diff" />
<root url="file://$MODULE_DIR$/vendor/sebastian/environment" />
<root url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
<root url="file://$MODULE_DIR$/vendor/sebastian/finder-facade" />
<root url="file://$MODULE_DIR$/vendor/sebastian/git" />
<root url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
<root url="file://$MODULE_DIR$/vendor/sebastian/object-enumerator" />
<root url="file://$MODULE_DIR$/vendor/sebastian/phpcpd" />
<root url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
<root url="file://$MODULE_DIR$/vendor/sebastian/resource-operations" />
<root url="file://$MODULE_DIR$/vendor/sebastian/version" />
<root url="file://$MODULE_DIR$/vendor/squizlabs/php_codesniffer" />
<root url="file://$MODULE_DIR$/vendor/symfony/config" />
<root url="file://$MODULE_DIR$/vendor/symfony/console" />
<root url="file://$MODULE_DIR$/vendor/symfony/debug" />
<root url="file://$MODULE_DIR$/vendor/symfony/dependency-injection" />
<root url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
<root url="file://$MODULE_DIR$/vendor/symfony/filesystem" />
<root url="file://$MODULE_DIR$/vendor/symfony/finder" />
<root url="file://$MODULE_DIR$/vendor/symfony/http-foundation" />
<root url="file://$MODULE_DIR$/vendor/symfony/options-resolver" />
<root url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
<root url="file://$MODULE_DIR$/vendor/symfony/polyfill-php70" />
<root url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
<root url="file://$MODULE_DIR$/vendor/symfony/process" />
<root url="file://$MODULE_DIR$/vendor/symfony/stopwatch" />
<root url="file://$MODULE_DIR$/vendor/symfony/yaml" />
<root url="file://$MODULE_DIR$/vendor/theseer/fdomdocument" />
<root url="file://$MODULE_DIR$/vendor/webmozart/assert" />
</CLASSES>
<SOURCES>
<root url="file://$MODULE_DIR$/vendor/behat/transliterator" />
<root url="file://$MODULE_DIR$/vendor/composer" />
<root url="file://$MODULE_DIR$/vendor/doctrine/annotations" />
<root url="file://$MODULE_DIR$/vendor/doctrine/cache" />
<root url="file://$MODULE_DIR$/vendor/doctrine/collections" />
<root url="file://$MODULE_DIR$/vendor/doctrine/common" />
<root url="file://$MODULE_DIR$/vendor/doctrine/dbal" />
<root url="file://$MODULE_DIR$/vendor/doctrine/inflector" />
<root url="file://$MODULE_DIR$/vendor/doctrine/instantiator" />
<root url="file://$MODULE_DIR$/vendor/doctrine/lexer" />
<root url="file://$MODULE_DIR$/vendor/doctrine/orm" />
<root url="file://$MODULE_DIR$/vendor/friendsofphp/php-cs-fixer" />
<root url="file://$MODULE_DIR$/vendor/gecko-packages/gecko-php-unit" />
<root url="file://$MODULE_DIR$/vendor/gedmo/doctrine-extensions" />
<root url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
<root url="file://$MODULE_DIR$/vendor/paragonie/random_compat" />
<root url="file://$MODULE_DIR$/vendor/pdepend/pdepend" />
<root url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-common" />
<root url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
<root url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
<root url="file://$MODULE_DIR$/vendor/phploc/phploc" />
<root url="file://$MODULE_DIR$/vendor/phpmd/phpmd" />
<root url="file://$MODULE_DIR$/vendor/phpspec/prophecy" />
<root url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
<root url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
<root url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
<root url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
<root url="file://$MODULE_DIR$/vendor/phpunit/php-token-stream" />
<root url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
<root url="file://$MODULE_DIR$/vendor/phpunit/phpunit-mock-objects" />
<root url="file://$MODULE_DIR$/vendor/psr/container" />
<root url="file://$MODULE_DIR$/vendor/psr/log" />
<root url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<root url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
<root url="file://$MODULE_DIR$/vendor/sebastian/diff" />
<root url="file://$MODULE_DIR$/vendor/sebastian/environment" />
<root url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
<root url="file://$MODULE_DIR$/vendor/sebastian/finder-facade" />
<root url="file://$MODULE_DIR$/vendor/sebastian/git" />
<root url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
<root url="file://$MODULE_DIR$/vendor/sebastian/object-enumerator" />
<root url="file://$MODULE_DIR$/vendor/sebastian/phpcpd" />
<root url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
<root url="file://$MODULE_DIR$/vendor/sebastian/resource-operations" />
<root url="file://$MODULE_DIR$/vendor/sebastian/version" />
<root url="file://$MODULE_DIR$/vendor/squizlabs/php_codesniffer" />
<root url="file://$MODULE_DIR$/vendor/symfony/config" />
<root url="file://$MODULE_DIR$/vendor/symfony/console" />
<root url="file://$MODULE_DIR$/vendor/symfony/debug" />
<root url="file://$MODULE_DIR$/vendor/symfony/dependency-injection" />
<root url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
<root url="file://$MODULE_DIR$/vendor/symfony/filesystem" />
<root url="file://$MODULE_DIR$/vendor/symfony/finder" />
<root url="file://$MODULE_DIR$/vendor/symfony/http-foundation" />
<root url="file://$MODULE_DIR$/vendor/symfony/options-resolver" />
<root url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
<root url="file://$MODULE_DIR$/vendor/symfony/polyfill-php70" />
<root url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
<root url="file://$MODULE_DIR$/vendor/symfony/process" />
<root url="file://$MODULE_DIR$/vendor/symfony/stopwatch" />
<root url="file://$MODULE_DIR$/vendor/symfony/yaml" />
<root url="file://$MODULE_DIR$/vendor/theseer/fdomdocument" />
<root url="file://$MODULE_DIR$/vendor/webmozart/assert" />
</SOURCES>
</library>
</orderEntry>
</component>
</module>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ComposerJsonPluginSettings">
<unboundedVersionInspectionSettings>
<excludedPackages />
</unboundedVersionInspectionSettings>
<customRepositories />
</component>
</project>

6
.idea/encodings.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Common Library (GitHub).iml" filepath="$PROJECT_DIR$/.idea/Common Library (GitHub).iml" />
</modules>
</component>
</project>

75
.idea/php.xml generated
View File

@@ -1,75 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpIncludePathManager">
<include_path>
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
<path value="$PROJECT_DIR$/vendor/doctrine/annotations" />
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
<path value="$PROJECT_DIR$/vendor/doctrine/common" />
<path value="$PROJECT_DIR$/vendor/doctrine/cache" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/doctrine/collections" />
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/phpspec/prophecy" />
<path value="$PROJECT_DIR$/vendor/symfony/yaml" />
<path value="$PROJECT_DIR$/vendor/symfony/config" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
<path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
<path value="$PROJECT_DIR$/vendor/behat/transliterator" />
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
<path value="$PROJECT_DIR$/vendor/symfony/filesystem" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php70" />
<path value="$PROJECT_DIR$/vendor/theseer/fdomdocument" />
<path value="$PROJECT_DIR$/vendor/symfony/dependency-injection" />
<path value="$PROJECT_DIR$/vendor/symfony/debug" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
<path value="$PROJECT_DIR$/vendor/symfony/options-resolver" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
<path value="$PROJECT_DIR$/vendor/symfony/process" />
<path value="$PROJECT_DIR$/vendor/symfony/console" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit-mock-objects" />
<path value="$PROJECT_DIR$/vendor/gecko-packages/gecko-php-unit" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-token-stream" />
<path value="$PROJECT_DIR$/vendor/sebastian/finder-facade" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
<path value="$PROJECT_DIR$/vendor/sebastian/git" />
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
<path value="$PROJECT_DIR$/vendor/sebastian/resource-operations" />
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
<path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
<path value="$PROJECT_DIR$/vendor/friendsofphp/php-cs-fixer" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/doctrine/orm" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
<path value="$PROJECT_DIR$/vendor/pdepend/pdepend" />
<path value="$PROJECT_DIR$/vendor/sebastian/phpcpd" />
<path value="$PROJECT_DIR$/vendor/phploc/phploc" />
<path value="$PROJECT_DIR$/vendor/squizlabs/php_codesniffer" />
<path value="$PROJECT_DIR$/vendor/phpmd/phpmd" />
<path value="$PROJECT_DIR$/vendor/paragonie/random_compat" />
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
<path value="$PROJECT_DIR$/vendor/gedmo/doctrine-extensions" />
</include_path>
</component>
<component name="PhpUnit">
<phpunit_settings>
<PhpUnitSettings load_method="CUSTOM_LOADER" custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" phpunit_phar_path="" />
</phpunit_settings>
</component>
</project>

14
.idea/webResources.xml generated
View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WebResourcesPaths">
<contentEntries>
<entry url="file://$PROJECT_DIR$">
<entryData>
<resourceRoots>
<path value="file://$PROJECT_DIR$/data" />
</resourceRoots>
</entryData>
</entry>
</contentEntries>
</component>
</project>

View File

@@ -1,30 +1,52 @@
<?php
$finder = PhpCsFixer\Finder::create()
/*
* Do not verify:
* - all DependencyInjection/Configuration classes: the Configuration.php files
* - autoloader from /app directory: autoload.php
*/
->notPath('/DependencyInjection\/Configuration\.php/')
->notPath('/autoload\.php/')
->in([
__DIR__ . '/src',
__DIR__ . '/tests',
->in(__DIR__)
->exclude([
'build',
'vendor',
])
->notPath([
'tests/Resources/var/',
]);
return PhpCsFixer\Config::create()
->setRules([
'@Symfony' => true,
'phpdoc_summary' => false,
'phpdoc_separation' => false,
'phpdoc_align' => false,
'cast_spaces' => false,
'@Symfony' => true,
'@PhpCsFixer' => true,
'@PHP71Migration' => true,
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => [
'align_double_arrow' => true,
],
'concat_space' => [
'blank_line_before_return' => false,
'cast_spaces' => false,
'concat_space' => [
'spacing' => 'one',
],
'ordered_class_elements' => [
'order' => [
'use_trait',
'constant_public',
'constant_protected',
'constant_private',
'property_public',
'property_protected',
'property_private',
'construct',
'destruct',
'magic',
'method_public',
'method_protected',
'method_private',
],
],
'phpdoc_add_missing_param_annotation' => true,
'phpdoc_align' => false,
'phpdoc_order' => true,
'phpdoc_separation' => false,
'phpdoc_summary' => false,
'trim_array_spaces' => false,
])
->setFinder($finder);
->setFinder($finder)
;

2
.travis-php-config.ini Normal file
View File

@@ -0,0 +1,2 @@
date.timezone = Europe/London
memory_limit = 2G

23
.travis.yml Normal file
View File

@@ -0,0 +1,23 @@
language: php
php:
- 7.2
- 7.3
- 7.4
before_install:
- sudo locale-gen de_DE.UTF-8 es_ES.UTF-8 en_GB.UTF-8 en_US.UTF-8 fr_FR.UTF-8 it_IT.UTF-8 pl_PL.UTF-8 ru_RU.UTF-8
- pear channel-discover pear.phing.info
install:
- pear install phing/phing
- phpenv rehash
before_script:
- phpenv config-add .travis-php-config.ini
script:
- phing
after_success:
- travis_retry php vendor/bin/php-coveralls -v

185
CHANGELOG.md Normal file
View File

@@ -0,0 +1,185 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# 1.1.8
1. [Composer] Upgrade all dev packages (to the latest, stable versions for PHP `7.4`)
2. [BaseCollection] Interfaces of different types of collections. May be used to build specific collections.
# 1.1.7
1. [Arrays] Allow to define a key of next level elements in a function that returns elements from given level
# 1.1.6
1. [Arrays] Function that returns elements from given level
# 1.1.5
1. [BaseCollection] Prepare elements while adding them by `addMultiple()` method in the same way as passing them in
constructor.
# 1.1.4
1. [BaseCollection] Fix incorrectly working limit() method
# 1.1.3
1. Move `Renderable` class: `Meritoo\Common` -> `Meritoo\Common\Contract`
2. Create and implement `CollectionInterface` as contract of all collections (e.g. based on the `BaseCollection` class)
# 1.1.2
1. Change mode of `Xdebug` to `coverage` in Docker's configuration to make it possible to generate code coverage by
`PHPUnit`
2. Mark PHPUnit test as risky when it does not have a `@covers` annotation
# 1.1.1
1. [BaseCollection] Treat the `null` index as "no index" only while adding new element, iow. do not treat empty string
as "no index" behaviour.
2. [Miscellaneous] [Regex] Use simpler & stronger pattern to match name of file
3. Do not install `hirak/prestissimo` package while running Travis CI (incompatible with your PHP version, PHP
extensions and Composer version)
4. Use PHP `7.4` while running build in Travis CI
# 1.1.0
1. Rename Meritoo\Common\Collection\Collection class to Meritoo\Common\Collection\BaseCollection. Add BaseCollection::
isValidType() method to validate type of element before add it to collection. Add BaseCollection ::prepareElements()
method to allow preparation of elements in custom way.
# 1.0.6
1. Use `.env` instead of `.env.dist`
2. Docker > use images (instead of Dockerfiles)
3. composer > squizlabs/php_codesniffer package > use ^3.4 (instead of ^2.9)
4. Do not require name of class by BaseTestCaseTrait::assertMethodVisibilityAndArguments() method
5. PHP CS Fixer > configuration > make more readable & remove unnecessary code
6. Update .gitignore, docker-compose.yml, phpunit.xml.dist
# 1.0.5
1. Collection > trait > return "void" where "self" causes type hinting problem and is not required
# 1.0.4
1. PHP Coding Standards Fixer > update configuration
2. Phing > tests > add task for Psalm (https://psalm.dev)
3. Collection > trait > split into smaller traits (to make it more flexible)
# 1.0.3
1. Travis CI > run many tasks using Phing > update configuration
2. Template with placeholders > verification of placeholders without values > make stronger and point out which are
missing
3. Reflection > getPropertyValue() method > look for the property in parent classes
# 1.0.2
1. Phing > remove old and unused tools
2. Phing > configuration > minor updates
3. Implement Mutation Testing Framework (infection/infection package)
4. Travis CI > run many tasks using Phing (instead of PHPUnit only)
5. Fix integration with [Coveralls](https://www.coveralls.io) (available as the badge in [README.md](README.md))
6. Implement [PHPStan](https://github.com/phpstan/phpstan)
7. PHPUnit > execute tests in random order
8. Implement [Psalm](https://github.com/vimeo/psalm)
9. Infection (Mutation Testing Framework) > fix bugs while running (generate proper code coverage, bugs while running
tests randomly)
10. Phing > php-coveralls > add task
# 1.0.1
1. Regex > make compatible with PHP 7.3 Tests > Regex > fix "preg_match(): Compilation failed: invalid range in
character class at offset 4" bug
2. Collection/storage of templates
3. Template with placeholders that may be filled by real data
4. RenderableInterface > something that may be rendered
# 1.0.0
1. Composer > support/require PHP 7.2+ (instead of 5.6+)
# 0.1.8
1. Size, e.g. of image
# 0.1.7
1. Collection > create trait (to make it more flexible)
# 0.1.6
1. Arrays > refactoring & more tests
2. ValueObject > Human > represents a human
3. Tests > use `Meritoo\Test\Common` namespace (instead of `Meritoo\Common\Test`)
4. Tests > use @dataProvider
# 0.1.5
1. Tests > Date > one more test case
2. Phing > update configuration
3. Miscellaneous > variableDump() method > remove, because unnecessary
4. Regex > createSlug() method > returns slug for given value
5. Arrays > getNonEmptyValues() method > returns non-empty values, e.g. without "" (empty string), null or []
6. Arrays > getNonEmptyValuesAsString() method > returns non-empty values concatenated by given separator
7. ValueObject > Company > represents a company
8. ValueObject > BankAccount > represents bank account
9. ValueObject > Address > represents address of company, institution, user etc.
# 0.1.4
1. Phing > update configuration
2. Utilities > Date > update descriptions of methods
3. Docker > docker-compose.yml > add "phpunit" service > used to run PHPUnit's tests
4. Reflection > setPropertiesValues() method > sets values of properties in given object
# 0.1.3
1. Tests > refactoring & minor improvements
2. Utilities > CssSelector > useful methods related to CSS selectors
3. Utilities > Bootstrap4CssSelector > useful methods related to CSS selectors and the Bootstrap4 (front-end component
library)
# 0.1.2
1. Documentation > Value Objects
2. Docker > improve performance
3. Utilities > Reflection > setPropertyValue() method > sets value of given property
# 0.1.1
1. TravisCI > run using PHP 7.2 too
2. ValueObject > class Version > represents version of software
3. Move version of this package to `VERSION` file (from `composer.json` file)
# 0.1.0
1. Composer > support/require PHP 5.6+ (instead of 5.5.9+)
2. Docker > rename `php-cli` service to `php`
3. Exceptions > create instance of exception using static `create()` method (instead of constructor)
4. Documentation > Exceptions
# 0.0.21
1. Composer > require ext-pcre
2. Arrays > minor refactoring
3. Update @author and @copyright in classes' descriptions
# 0.0.20
1. Collection > add() method > treat empty string as not provided index (same as null)
# 0.0.19
1. Add this changelog
2. Reorganize documentation & update [Readme](README.md)
3. Docker: use project-related binaries globally
4. StyleCI & PHP Coding Standards Fixer: update configuration
5. Documentation > Docker > add paragraph for PHP Coding Standards Fixer
6. Coding standard > fix automatically
7. StyleCI configuration > fix bug "The provided fixer 'binary_operator_spaces' cannot be enabled again because it was
already enabled"
8. StyleCI > disable & remove

View File

@@ -1,38 +1,49 @@
# Meritoo Common Library
Useful classes, methods, extensions etc.
## Installation
Common and useful classes, methods, exceptions etc.
#### Composer
![PHP from Packagist](https://img.shields.io/packagist/php-v/meritoo/common-library.svg?style=flat-square)
[![Build Status](https://travis-ci.com/meritoo/common-library.svg?branch=master&style=flat-square)](https://travis-ci.com/meritoo/common-library)
[![Packagist](https://img.shields.io/packagist/v/meritoo/common-library.svg?style=flat-square)](https://packagist.org/packages/meritoo/common-library)
[![license](https://img.shields.io/github/license/meritoo/common-library.svg?style=flat-square)](https://github.com/meritoo/common-library)
[![GitHub commits](https://img.shields.io/github/commits-since/meritoo/common-library/0.0.1.svg?style=flat-square)](https://github.com/meritoo/common-library)
[![Coverage Status](https://coveralls.io/repos/github/meritoo/common-library/badge.svg?branch=master&style=flat-square)](https://coveralls.io/github/meritoo/common-library)
1. Open ```composer.json``` and add address of repository in ```repositories``` section:
# Installation
```json
"repositories": [
{
"type": "vcs",
"url": "git@github.com:meritoo/common-library.git"
}
]
```
In your `composer.json` add address of repository into `repositories` section:
2. Run [Composer](https://getcomposer.org) to install new package:
```bash
$ composer require meritoo/common-library
```
> How to install Composer: https://getcomposer.org/download
## Usage
This package contains a lot of static methods, so usage is not so complicated. Just run the static method who would you like to use. Example:
```php
use Meritoo\Common\Utilities\Arrays;
$firstElement = Arrays::getFirstElement(['lorem' 'ipsum']);
// result: "lorem"
```json
"repositories": [
(...)
{
"type": "vcs",
"url": "https://github.com/wiosna-dev/common-library"
}
]
```
Run [Composer](https://getcomposer.org) to install this package in your project:
```bash
composer require wiosna-dev/common-library
```
> [How to install Composer?](https://getcomposer.org/download)
# Usage
1. [Base test case (with common methods and data providers)](docs/Base-test-case.md)
2. [Collection of elements](docs/Collection/BaseCollection.md)
3. [Exceptions](docs/Static-methods.md)
4. [Static methods](docs/Static-methods.md)
1. [Arrays](docs/Static-methods/Arrays.md)
2. [Regex](docs/Static-methods/Regex.md)
3. [Uri](docs/Static-methods/Uri.md)
5. [Value Objects](docs/Value-Objects.md)
# Development
More information [you can find here](docs/Development.md)
Enjoy!

1
VERSION Normal file
View File

@@ -0,0 +1 @@
1.1.8

View File

@@ -1,46 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="Meritoo Common Library" basedir="." default="build:main" phingVersion="2.14.0">
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.14.0">
<!-- Properties -->
<if>
<available file="phing/properties" property="custom.properties.available"/>
<available file="${project.basedir}/phing/properties" property="custom.properties.available" />
<then>
<property file="phing/properties" />
<property file="${project.basedir}/phing/properties" />
</then>
<else>
<property file="phing/properties.dist" />
<property file="${project.basedir}/phing/properties.dist" />
</else>
</if>
<!-- Default / main target -->
<target name="build:main"
depends="build:app, build:tests"
description="Builds everything and runs all tests" />
depends="build:app,
build:tests"
/>
<!-- Build app -->
<target name="build:app" description="Prepares app to build and tests">
<phing phingfile="phing/app.xml" haltonfailure="true" />
<target name="build:app">
<phing phingfile="${project.basedir}/phing/app.xml" haltonfailure="true" />
</target>
<!-- Build tests -->
<target name="build:tests" description="Runs all tests, checks and creates docs">
<phing phingfile="phing/tests.xml" haltonfailure="true" />
<!--
Conditional running of tests.
Disabled, because not required.
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
2017-02-22
<if>
<equals arg1="${env}" arg2="test" />
<then>
<phing phingfile="phing/tests.xml" haltonfailure="true" />
</then>
<else>
<echo message="[Skipped] Running tests, checks and creating docs, because it's a not 'test' environment..." />
</else>
</if>
-->
<target name="build:tests">
<phing phingfile="${project.basedir}/phing/tests.xml" haltonfailure="true" />
</target>
</project>

View File

@@ -1,8 +1,7 @@
{
"name": "meritoo/common-library",
"name": "wiosna-dev/common-library",
"description": "Useful classes, methods, extensions etc.",
"license": "MIT",
"version": "0.0.1",
"authors": [
{
"name": "Meritoo.pl",
@@ -11,24 +10,37 @@
}
],
"require": {
"php": ">=5.6.0",
"doctrine/orm": "^2.5",
"gedmo/doctrine-extensions": "^2.4",
"symfony/http-foundation": "^3.3"
"php": "^7.4 || ^8.0",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-intl": "*",
"ext-json": "*",
"ext-pcre": "*",
"ext-simplexml": "*",
"doctrine/orm": "^2.6",
"gedmo/doctrine-extensions": "^3.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8 || ^5.0",
"squizlabs/php_codesniffer": "^2.8",
"phpmd/phpmd": "^2.6",
"sebastian/phpcpd": "^3.0",
"pdepend/pdepend": "^2.5",
"phploc/phploc": "^3.0",
"friendsofphp/php-cs-fixer": "^2.1"
"friendsofphp/php-cs-fixer": "^3.11",
"infection/infection": "^0.26",
"php-coveralls/php-coveralls": "^2.5",
"phpstan/phpstan": "^1.8",
"phpunit/phpunit": "^9",
"sebastian/phpcpd": "^6.0",
"squizlabs/php_codesniffer": "^3.7",
"vimeo/psalm": "^4.0"
},
"autoload": {
"psr-4": {
"Meritoo\\Common\\": "src/Meritoo/Common/",
"Meritoo\\Common\\Tests\\": "tests/Meritoo/Common/Tests/"
"Meritoo\\Common\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Meritoo\\Test\\Common\\": "tests/"
}
},
"config": {
"sort-packages": true
}
}

3518
composer.lock generated

File diff suppressed because it is too large Load Diff

33
docker-compose.yml Normal file
View File

@@ -0,0 +1,33 @@
version: '3'
services:
#
# Required to run project
#
php:
image: meritoo/php:7.4
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-php
entrypoint: php
command: -S 0.0.0.0:9999
environment:
PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE}
volumes:
- .:/var/www/application:cached
composer:
image: meritoo/php:7.4
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-composer
entrypoint: php -d memory_limit=-1 /usr/local/bin/composer
volumes:
- .:/var/www/application:cached
#
# Required to run PHPUnit's tests
#
phpunit:
image: meritoo/php:7.4
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-phpunit
entrypoint: ./vendor/bin/phpunit
command: --version
volumes:
- .:/var/www/application:cached
environment:
XDEBUG_MODE: coverage

63
docs/Base-test-case.md Normal file
View File

@@ -0,0 +1,63 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# Base test case (with common methods and data providers)
Located here: `Meritoo\Common\Test\Base\BaseTestCase`.
##### Usage
1. Just extend the `BaseTestCase` class or implement `Meritoo\Common\Traits\Test\Base\BaseTestCaseTrait` trait.
2. Use one of available data providers, e.g. `@dataProvider provideEmptyValue`, or asserts,
e.g. `static::assertMethodVisibility($method, $visibilityType);`
##### Examples
```php
class DateTest extends BaseTestCase
{
/**
* @param mixed $value Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetDateTimeEmptyValue($value)
{
self::assertFalse(Date::getDateTime($value));
}
(...)
}
```
```php
class MimeTypesTest extends BaseTestCase
{
(...)
/**
* @param bool $mimeType The mime type, e.g. "video/mpeg"
* @dataProvider provideBooleanValue
*/
public function testGetExtensionBooleanMimeType($mimeType)
{
self::assertEquals('', MimeTypes::getExtension($mimeType));
}
(...)
}
```
# More
1. [**Base test case (with common methods and data providers)**](Base-test-case.md)
2. [Collection of elements](Collection/BaseCollection.md)
3. [Templates](Collection/Templates.md)
4. [Exceptions](Exceptions.md)
5. [Static methods](Static-methods.md)
1. [Arrays](Static-methods/Arrays.md)
2. [Regex](Static-methods/Regex.md)
3. [Uri](Static-methods/Uri.md)
6. [Value Objects](Value-Objects.md)
[&lsaquo; Back to `Readme`](../README.md)

View File

@@ -0,0 +1,90 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# BaseCollection
### Namespace
`Meritoo\Common\Collection\BaseCollection`
### Info
It's a set of some elements with the same type, e.g. objects. It's iterable and countable. Provides very useful methods.
Some of them:
- `getFirst()` - returns the first element in the collection
- `getLast()` - returns the last element in the collection
- `isEmpty()` - returns information if collection is empty
- `add($element, $index = null)` - adds given element (at the end of collection)
- `addMultiple($elements, $useIndexes = false)` - adds given elements (at the end of collection)
- `prepend($element)` - prepends given element (adds given element at the beginning of collection)
- `remove($element)` - removes given element
### Implementation
You have to implement:
```php
abstract protected function isValidType($element): bool;
```
This method verifies 1 element before it will be added to collection. Returns information if the element has valid,
expected type.
Example (from `Meritoo\Common\Collection\Templates` class):
```php
protected function isValidType($element): bool
{
return $element instanceof Template;
}
```
### Methods to overwrite
You can, if you wish, overwrite these methods:
1. To prepare elements used to initialize the collection in your own way:
```php
protected function prepareElements(array $elements): array
```
2. To validate type of elements in your own way:
```php
protected function getElementsWithValidType(array $elements): array
```
### Examples of usage
```php
use Meritoo\Common\Collection\StringCollection;
$emptyCollection = new StringCollection();
var_dump($emptyCollection->isEmpty()); // bool(true)
$elements = [
'lorem',
'ipsum',
123 => 'dolor',
345 => 'sit',
];
$simpleCollection = new StringCollection($elements);
var_dump($simpleCollection->has('dolor')); // bool(true)
```
# More
1. [Base test case (with common methods and data providers)](../Base-test-case.md)
2. [**Collection of elements**](BaseCollection.md)
3. [Templates](Templates.md)
4. [Exceptions](../Exceptions.md)
5. [Static methods](../Static-methods.md)
1. [Arrays](../Static-methods/Arrays.md)
2. [Regex](../Static-methods/Regex.md)
6. [Value Objects](../Value-Objects.md)
[&lsaquo; Back to `Readme`](../../README.md)

View File

@@ -0,0 +1,67 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# Templates
### Namespace
`Meritoo\Common\Collection\Templates`
### Info
Collection/storage of templates, instance of `Meritoo\Common\ValueObject\Template` class.
##### New instance
New instance can be created using:
1. Constructor:
```php
new Templates([
'first' => new Template('First name: %first_name%'),
'last' => new Template('Last name: %last_name%'),
]);
```
2. Static method `fromArray(array $templates)` - creates and returns the collection from given array
```php
Templates::fromArray([
'first' => 'First name: %first_name%',
'last' => 'Last name: %last_name%',
]);
```
##### Methods
Has all methods of parent class `Meritoo\Common\Collection\Collection` + `findTemplate(string $index)` method that finds
and returns template with given index.
Example of usage:
```php
$templates = new Templates([
'first' => new Template('First name: %first_name%'),
'last' => new Template('Last name: %last_name%'),
]);
$template = $templates->findTemplate('first'); // new Template('First name: %first_name%')
```
Throws an `Meritoo\Common\Exception\ValueObject\Template\TemplateNotFoundException` exception if template with given
index was not found.
# More
1. [Base test case (with common methods and data providers)](../Base-test-case.md)
2. [Collection of elements](BaseCollection.md)
3. [**Templates**](Templates.md)
4. [Exceptions](../Exceptions.md)
5. [Static methods](../Static-methods.md)
1. [Arrays](../Static-methods/Arrays.md)
2. [Regex](../Static-methods/Regex.md)
6. [Value Objects](../Value-Objects.md)
[&lsaquo; Back to `Readme`](../../README.md)

159
docs/Development.md Normal file
View File

@@ -0,0 +1,159 @@
# Meritoo Common Library
Development-related information
# Requirements
* [Docker](https://www.docker.com)
* Your favourite IDE :)
# Getting started
1. Build, create and start Docker's containers by running command:
```bash
docker-compose up -d
```
2. Rebuild project by running command (installs packages, prepares required directories and runs tests):
```bash
docker-compose exec php phing
```
> [What is Docker?](https://www.docker.com/what-docker)
# Composer
Available as `composer` service. You can run any Composer's command using the `composer` service:
```bash
docker-compose run --rm composer [command]
```
Examples below.
##### Install packages
```bash
docker-compose run --rm composer install
```
##### Update packages
```bash
docker-compose run --rm composer update
```
##### Add package
```bash
docker-compose run --rm composer require [vendor]/[package]
```
##### Remove package
```bash
docker-compose run --rm composer remove [vendor]/[package]
```
# Coding Standards Fixer
Fix coding standard by running command:
```bash
docker-compose exec php php-cs-fixer fix
```
or
```bash
docker-compose exec php phing -f phing/tests.xml build:fix-coding-standards
```
Omit cache and run the Fixer from scratch by running command:
```bash
docker-compose exec php rm .php_cs.cache && docker-compose exec php php-cs-fixer fix
```
> [Want more?](https://cs.sensiolabs.org)
# Tests
### Prerequisites
Install required packages by running command: `docker-compose run --rm composer install`.
### Running [PHPUnit](https://phpunit.de) tests
##### Easy (with code coverage)
```bash
docker-compose run --rm phpunit --verbose
```
or
```bash
docker-compose exec php phing -f phing/tests.xml test:phpunit
```
##### Quick (without code coverage)
```bash
docker-compose run --rm phpunit --verbose --no-coverage
```
# Infection - Mutation Testing
Served by [InfectionMutation Testing Framework](https://infection.github.io).
### Running tests
```bash
$ docker-compose exec php bash
root@18f2f0cfaa5d:/var/www/application# XDEBUG_MODE=coverage ./vendor/bin/infection --threads=$(nproc)
```
or
```bash
$ docker-compose exec php bash
root@18f2f0cfaa5d:/var/www/application# XDEBUG_MODE=coverage phing -f phing/tests.xml test:infection
```
### Result of testing
##### Terminal
Example of output:
```bash
125 mutations were generated:
105 mutants were killed
3 mutants were not covered by tests
5 covered mutants were not detected
0 errors were encountered
12 time outs were encountered
Metrics:
Mutation Score Indicator (MSI): 93%
Mutation Code Coverage: 97%
Covered Code MSI: 95%
```
##### Stored in `build/reports/infection` directory
* `build/reports/infection/infection-log.txt`
* `build/reports/infection/summary-log.txt`
# Other
Rebuild project and run tests by running command:
```bash
docker-compose exec php phing
```
[&lsaquo; Back to `Readme`](../README.md)

70
docs/Exceptions.md Normal file
View File

@@ -0,0 +1,70 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# Exceptions
### Create instance of exception
This package contains a lot of exceptions. Each of them contains static method `create()` with proper arguments that is
used to create instance of the exception. Example:
```php
use Meritoo\Common\Exception\Bundle\IncorrectBundleNameException;
throw IncorrectBundleNameException::create('RisusIpsum');
```
### Base exception for unknown type of something
##### Short description
It's a `Meritoo\Common\Exception\Base\UnknownTypeException` class. Related to `Meritoo\Common\Type\Base\BaseType` class
that represents type of something, e.g. type of button, order.
##### Usage
You can extend `Meritoo\Common\Exception\Base\UnknownTypeException` class and create your own static method,
e.g. `createException()`, which will be used create instance of the exception. Inside the `createException()` method you
can call `parent::create()` method.
##### Example
```php
<?php
namespace Your\Package\Exception\Type;
use Meritoo\Common\Exception\Base\UnknownTypeException;
use Your\Package\Type\SimpleType;
class UnknownSimpleTypeException extends UnknownTypeException
{
/**
* Creates exception
*
* @param string $unknownType Unknown and simple type
* @return UnknownSimpleTypeException
*/
public static function createException($unknownType)
{
/* @var UnknownSimpleTypeException $exception */
$exception = parent::create($unknownType, new SimpleType(), 'my simple type of something');
return $exception;
}
}
```
# More
1. [Base test case (with common methods and data providers)](Base-test-case.md)
2. [Collection of elements](Collection/BaseCollection.md)
3. [Templates](Collection/Templates.md)
4. [**Exceptions**](Exceptions.md)
5. [Static methods](Static-methods.md)
1. [Arrays](Static-methods/Arrays.md)
2. [Regex](Static-methods/Regex.md)
3. [Uri](Static-methods/Uri.md)
6. [Value Objects](Value-Objects.md)
[&lsaquo; Back to `Readme`](../README.md)

29
docs/Static-methods.md Normal file
View File

@@ -0,0 +1,29 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# Static methods
This package contains a lot of class with static methods, so usage is not so complicated. Just run the static method who
would you like to use. Example:
```php
use Meritoo\Common\Utilities\Arrays;
$firstElement = Arrays::getFirstElement(['lorem', 'ipsum']);
var_dump($firstElement); // string(5) "lorem"
```
# More
1. [Base test case (with common methods and data providers)](Base-test-case.md)
2. [Collection of elements](Collection/BaseCollection.md)
3. [Templates](Collection/Templates.md)
4. [Exceptions](Exceptions.md)
5. [**Static methods**](Static-methods.md)
1. [Arrays](Static-methods/Arrays.md)
2. [Regex](Static-methods/Regex.md)
3. [Uri](Static-methods/Uri.md)
6. [Value Objects](Value-Objects.md)
[&lsaquo; Back to `Readme`](../README.md)

View File

@@ -0,0 +1,109 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# Arrays
> Useful methods related to arrays
Class: `Meritoo\Common\Utilities\Arrays`
File: `src/Utilities/Arrays.php`
### containsEmptyStringsOnly(array): bool
> Returns information if given array contains an empty strings only
##### Arguments
- `array $array` - The array to verify
##### Examples
1)
- array: `[]` (an empty array)
- result: `false`
2)
- array: `["", -1]`
- result: `false`
3)
- array: `["", null, ""]`
- result: `true`
### getNonEmptyValues(array $values)
> Returns non-empty values, e.g. without "" (empty string), null or []
##### Arguments
- `array $values` - The values to filter
##### Examples
1)
- values: `[]` (no values)
- result: `[]` (an empty array)
2)
- values: `[null, ""]` (all empty values)
- result: `[]` (an empty array)
3)
- values: `["test 1", "", 123, null, 0]`
- result: `["test 1", 123, 0]`
### getNonEmptyValuesAsString(array $values, $separator = ', ')
> Returns non-empty values concatenated by given separator
##### Arguments
- `array $values` - The values to filter
- `[string $separator]` - (optional) Separator used to implode the values. Default: ", ".
##### Examples
1)
- values: `[]` (no values)
- separator: default or any other string
- result: `""` (an empty string)
2)
- values: `[null, ""]` (all empty values)
- separator: default or any other string
- result: `""` (an empty string)
3)
- values: `["test 1", "", 123, null, 0]`
- separator: `", "` (default)
- result: `"test 1, 123, 0"`
4)
- values: `["test 1", "", 123, null, 0]`
- separator: `" | "`
- result: `"test 1 | 123 | 0"`
# More
1. [Base test case (with common methods and data providers)](../Base-test-case.md)
2. [Collection of elements](../Collection/BaseCollection.md)
3. [Templates](../Collection/Templates.md)
4. [Exceptions](../Exceptions.md)
5. [Static methods](../Static-methods.md)
1. [**Arrays**](Arrays.md)
2. [Regex](Regex.md)
3. [Uri](Uri.md)
6. [Value Objects](../Value-Objects.md)
[&lsaquo; Back to `Readme`](../../README.md)

View File

@@ -0,0 +1,99 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# Regex
> Useful methods related to regular expressions
Class: `Meritoo\Common\Utilities\Regex`
File: `src/Utilities/Regex.php`
### createSlug($value)
> Returns slug for given value
##### Arguments
- `string $value` - Value that should be transformed to slug
##### Examples
1)
- value: non-scalar or `null`
- result: `false`
2)
- value: `""` (an empty string)
- result: `""` (an empty string)
3)
- value: `"Lorem ipsum. Dolor sit 12.34 amet."`
- result: `"lorem-ipsum-dolor-sit-1234-amet"`
### clearBeginningSlash(string): string
> Clears, removes slash from the beginning of given string
##### Arguments
- `string $string` - String that may contains slash as the 1st character
##### Examples
1)
- string: `"lorem ipsum"`
- result: `"lorem ipsum"`
2)
- string: `"/lorem ipsum"`
- result: `"lorem ipsum"`
3)
- string: `"/ lorem 123 ipsum"`
- result: `" lorem 123 ipsum"`
### clearEndingSlash(string): string
> Clears, removes slash from the end of given string
##### Arguments
- `string $string` - String that may contains slash as the last character
##### Examples
1)
- string: `"lorem ipsum"`
- result: `"lorem ipsum"`
2)
- string: `"lorem ipsum/"`
- result: `"lorem ipsum"`
3)
- string: `"lorem 123 ipsum /"`
- result: `"lorem 123 ipsum "`
# More
1. [Base test case (with common methods and data providers)](../Base-test-case.md)
2. [Collection of elements](../Collection/BaseCollection.md)
3. [Templates](../Collection/Templates.md)
4. [Exceptions](../Exceptions.md)
5. [Static methods](../Static-methods.md)
1. [Arrays](../Static-methods/Arrays.md)
2. [**Regex**](Regex.md)
3. [Uri](Uri.md)
6. [Value Objects](../Value-Objects.md)
[&lsaquo; Back to `Readme`](../../README.md)

View File

@@ -0,0 +1,47 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# Uri
> Useful methods related to uri
Class: `Meritoo\Common\Utilities\Uri`
File: `src/Utilities/Uri.php`
### buildUrl(string, string ...): string
> Builds url with given root url and parts of url (concatenates them using "/")
##### Arguments
- `string $rootUrl` - Protocol and domain (or domain only)
- `string ...$urlParts` - Parts of url that will be concatenated with the rool url by "/"
##### Examples
1)
- rootUrl: `"http://my.example"`
- urlParts: `""` (an empty string)
- result: `"http://my.example"`
2)
- rootUrl: `"http://my.example"`
- urlParts: `"/test", "/123"`
- result: `"http://my.example/test/123"`
# More
1. [Base test case (with common methods and data providers)](../Base-test-case.md)
2. [Collection of elements](../Collection/BaseCollection.md)
3. [Templates](../Collection/Templates.md)
4. [Exceptions](../Exceptions.md)
5. [Static methods](../Static-methods.md)
1. [Arrays](Arrays.md)
2. [Regex](Regex.md)
3. [**Uri**](Uri.md)
6. [Value Objects](../Value-Objects.md)
[&lsaquo; Back to `Readme`](../../README.md)

365
docs/Value-Objects.md Normal file
View File

@@ -0,0 +1,365 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# Value Objects
Located in `Meritoo\Common\ValueObject` namespace and in `src/ValueObject/` directory.
### Address
##### Namespace
`Meritoo\Common\ValueObject\Address`
##### Info
Represents address of company, institution, user etc. Contains properties:
1. `$street` - the street
2. `$buildingNumber` - the number of building
3. `$flatNumber` - the number of flat
4. `$zipCode` - the zip code
5. `$city` - the city, location
##### New instance
New instance can be created using constructor
```php
new Address('New York', '00123', '4th Avenue', '10', '200');
```
##### Methods
Has getters for each property, e.g. `getFlatNumber()` or `getZipCode()`, and 1 extra method:
```php
getFullStreet()
```
that returns name of street with related numbers (building & flat number).
Example:
```php
$address = new Address('New York', '00123', '4th Avenue', '10', '200');
$fullStreet = $address->getFullStreet(); // "4th Avenue 10/200"
```
##### Conversion to string (the `__toString()` method)
Instance of `Address` may be represented as string that contains all non-empty properties separated by `, `.
Example:
```php
$address = new Address('New York', '00123', '4th Avenue', '10', '200');
$asString = (string)$address; // "4th Avenue 10/200, 00123, New York"
```
### BankAccount
##### Namespace
`Meritoo\Common\ValueObject\BankAccount`
##### Info
Represents bank account. Contains properties:
1. `$bankName` - name of bank
2. `$accountNumber` - number of bank's account
##### New instance
New instance can be created using constructor
```php
new BankAccount('Bank of America', '1234567890')
```
##### Methods
Has getters for each property `getBankName()` and `getAccountNumber()`.
##### Conversion to string (the `__toString()` method)
Instance of `BankAccount` may be represented as string that contains all non-empty properties separated by `, `.
Example:
```php
$bank = new BankAccount('Bank of America', '1234567890');
$asString = (string)$bank; // "Bank of America, 1234567890"
```
### Company
##### Namespace
`Meritoo\Common\ValueObject\Company`
##### Info
Represents a company. Contains properties:
1. `$name` - name of company
2. `$address` - address of company
3. `$bankAccount` - bank account of company
##### New instance
New instance can be created using constructor:
```php
new Company(
'Test 1',
new Address('New York', '00123', '4th Avenue', '10', '200'),
new BankAccount('Bank 1', '12345')
);
```
##### Methods
Has getters for each property `getName()`, `getAddress()` and `getBankAccount()`.
##### Conversion to string (the `__toString()` method)
Instance of `Company` may be represented as string that contains all non-empty properties separated by `, `.
Example:
```php
$company = new Company(
'Test 1',
new Address('New York', '00123', '4th Avenue', '10', '200'),
new BankAccount('Bank 1', '12345')
);
$asString = (string)$company; // "Test 1, 4th Avenue 10/200, 00123, New York, Bank 1, 12345"
```
### Human
##### Namespace
`Meritoo\Common\ValueObject\Human`
##### Info
Represents human. Based on `\Meritoo\Common\Traits\ValueObject\HumanTrait` trait. Contains properties same
as `HumanTrait` trait:
1. `$firstName` - first name
2. `$lastName` - last name
3. `$email` - email address
4. `$birthDate` - birth date
##### New instance
New instance can be created using constructor:
```php
new Human('John', 'Scott', 'john@scott.com', new \DateTime('2001-01-01'));
```
##### Methods
Has getters for each property, e.g. `getFirstName()`, `getEmail()` etc.
##### Conversion to string (the `__toString()` method)
Instance of `Human` may be represented as string that contains first name, last name and email address (if provided).
Example:
```php
$human1 = new Human('John', 'Scott');
$asString1 = (string)$human1; // "John Scott"
$human2 = new Human('John', 'Scott', 'john@scott.com', new \DateTime('2001-01-01'));
$asString2 = (string)$human2; // "John Scott <john@scott.com>"
```
### Size
##### Namespace
`Meritoo\Common\ValueObject\Size`
##### Info
Size, e.g. of image. Contains properties:
1. `width` - the width
2. `height` - the height
3. `unit` - unit used when width or height should be returned with unit, default: `"px"`
4. `separator` - separator used when converting to string, default: `" x "`
##### New instance
New instance can be created using static methods:
1. `fromArray()` - creates new instance from given array
```php
// Using default "px" unit
Size::fromArray([200, 100]);
// With custom "mm" unit
Size::fromArray([200, 100], 'mm');
```
2. `fromString()` - creates new instance from given string
```php
// Using default "px" unit and default " x " separator
Size::fromString('200 x 100');
// With custom "mm" unit and " X " separator
Size::fromString('200 X 100', 'mm', ' X ');
```
##### Methods
Has:
- getters and setters for `width` and `height` properties.
- setter for `separator` property
- `toString()` and `toArray()` methods that returns size represented as string and array
##### Conversion to string (using `__toString()` method)
Instance of `Size` may be represented as string that contains width and height separated by separator (default: `" x "`)
.
Example:
```php
$size = Size::fromArray([200, 100]);
// With default separator
$asString1 = (string)$size; // "200 x 100"
// With custom separator
$size->setSeparator('X');
$asString2 = (string)$size; // "200X100"
```
### Template
##### Namespace
`Meritoo\Common\ValueObject\Template`
##### Info
Template with placeholders that may be filled by real data. Contains properties:
1. `$content` - raw string with placeholders (content of the template)
##### New instance
New instance can be created using constructor:
```php
new Template('First name: %first_name%');
```
Each placeholder should be wrapped by `%` character, e.g. `%first_name%`. If content of template is an empty string or
does not contain 1 placeholder at least, an `Meritoo\Common\Exception\ValueObject\Template\InvalidContentException`
exception will be thrown.
Examples of invalid content of template:
```php
new Template(''); // An empty string
new Template('test'); // Without placeholders
new Template('This is %test'); // With starting tag only (invalid placeholder)
```
##### Methods
Has 1 public method: `fill(array $values)`. Returns content of the template filled with given values (by replacing
placeholders with their proper values).
Example of usage:
```php
$template = new Template('My name is %name% and I am %profession%');
$result = $template->fill([
'name' => 'Jane',
'profession' => 'photographer',
]); // "My name is Jane and I am photographer"
```
Throws an `Meritoo\Common\Exception\ValueObject\Template\NotEnoughValuesException` exception if there is not enough
values (iow. more placeholders than values).
### Version
##### Namespace
`Meritoo\Common\ValueObject\Version`
##### Info
Represents version of software. Contains properties:
1. `$majorPart` - the "major" part of version
2. `$minorPart` - the "minor" part of version
3. `$patchPart` - the "patch" part of version
##### New instance
New instance can be created using:
1. Constructor:
```php
new Version(1, 0, 2);
```
2. Static methods:
1. `fromArray(array $version)` - creates new instance using given version as array
```php
Version::fromArray([1, 0, 2]);
```
2. `fromString(string $version)` - creates new instance using given version as string:
```php
Version::fromString('1.0.2');
```
##### Methods
Has getters for each property: `getMajorPart()`, `getMinorPart()`, `getPatchPart()`.
##### Conversion to string (using `__toString()` method)
Instance of `Version` may be represented as string that contains all properties separated by `.` (`$majorPart`
.`$minorPart`.`$patchPart`).
Example:
```php
$version = new Version(1, 0, 2);
$asString = (string)$version; // "1.0.2"
```
# More
1. [Base test case (with common methods and data providers)](Base-test-case.md)
2. [Collection of elements](Collection/BaseCollection.md)
3. [Templates](Collection/Templates.md)
4. [Exceptions](Exceptions.md)
5. [Static methods](Static-methods.md)
1. [Arrays](Static-methods/Arrays.md)
2. [Regex](Static-methods/Regex.md)
3. [Uri](Static-methods/Uri.md)
6. [**Value Objects**](Value-Objects.md)
[&lsaquo; Back to `Readme`](../README.md)

13
infection.json.dist Normal file
View File

@@ -0,0 +1,13 @@
{
"timeout": 10,
"source": {
"directories": [
"src"
]
},
"logs": {
"text": "build/reports/infection/infection-log.txt",
"summary": "build/reports/infection/summary-log.txt",
"debug": "build/reports/infection/debug-log.txt"
}
}

View File

@@ -1,79 +1,169 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="Meritoo Common Library" basedir="." default="build:main" phingVersion="2.14.0">
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
<!-- Properties -->
<if>
<available file="phing/properties" property="custom.properties.available"/>
<available file="${project.basedir}/phing/properties" property="custom.properties.available" />
<then>
<property file="phing/properties" />
<property file="${project.basedir}/phing/properties" />
</then>
<else>
<property file="phing/properties.dist" />
<property file="${project.basedir}/phing/properties.dist" />
</else>
</if>
<!-- Filesets -->
<import file="${project.basedir}/phing/filesets.xml" />
<!-- Default / main target -->
<target name="build:main"
depends="build:app"
description="Builds the application" />
/>
<!-- App target -->
<target name="build:app"
depends="app:composer, app:vendors, app:checkout"
description="Prepares app to build." />
<!-- Check / update composer -->
<target name="app:composer" description="Checks / updates composer">
<echo msg="Checking / updating composer..." />
depends="app:clean,
app:composer:self-update,
app:composer:install,
app:composer:validate,
app:checkout"
/>
<!-- Updates Composer -->
<target name="app:composer:self-update">
<if>
<available file="composer.phar" />
<not>
<available file="${composer.path}" property="composer.local.unavailable" />
</not>
<then>
<echo msg="[Skipped] Downloading of Composer skipped, because exist in the project..." />
</then>
<else>
<if>
<os family="windows" />
<then>
<fail message="Composer not found! Go to http://getcomposer.org/download and download the Composer." />
</then>
<else>
<exec command="${composer.download_command}" checkreturn="true" />
<exec command="${composer.download_command}" checkreturn="true" passthru="true" />
</else>
</if>
</else>
</then>
</if>
<composer command="selfupdate" />
<!-- Update Composer -->
<composer php="${composer.php}" composer="${composer.path}" command="selfupdate">
<arg value="--ansi" />
</composer>
</target>
<!-- Project Install/update vendors -->
<target name="app:vendors" description="Installs / updates vendors">
<echo msg="Installing / updating vendors..." />
<if>
<istrue value="${composer.self-update}"/>
<then>
<composer php="${composer.php}" composer="${composer.path}" command="self-update"/>
</then>
</if>
<if>
<istrue value="${composer.validate}"/>
<then>
<composer php="${composer.php}" composer="${composer.path}" command="validate"/>
</then>
</if>
<!-- Validates composer.* files -->
<target name="app:composer:validate" depends="app:composer:install">
<composer php="${composer.php}" composer="${composer.path}" command="validate">
<arg value="--no-check-all" />
<arg value="--strict" />
<arg value="--ansi" />
</composer>
</target>
<!-- Project clean -->
<target name="app:clean">
<if>
<equals arg1="${env}" arg2="prod" />
<then>
<composer php="${composer.php}" composer="${composer.path}" command="install">
<arg value="--optimize-autoloader" />
</composer>
<echo message="[Skipped] Cleaning project (and directories cleanup) -> 'prod' environment" />
</then>
<else>
<composer php="${composer.php}" composer="${composer.path}" command="install" />
<foreach list="${directoriesToEmpty}" param="directory" target="app:clean:empty" />
</else>
</if>
<foreach list="${directoriesToCheck}" param="directory" target="app:clean:check" />
<foreach list="${directoriesToEmpty}" param="directory" target="app:permissions" />
</target>
<!-- Cleaning directory (making empty) directory -->
<target name="app:clean:empty">
<if>
<available file="${directory}" type="dir" property="dir_is_available" />
<then>
<delete includeemptydirs="true" dir="${directory}" />
</then>
</if>
</target>
<!-- Checking if directory exists -->
<target name="app:clean:check">
<if>
<not>
<available file="${directory}" type="dir" property="dir_is_available" />
</not>
<then>
<if>
<or>
<contains string="${directory}" substring="cache" />
<contains string="${directory}" substring="logs" />
<contains string="${directory}" substring="sessions" />
</or>
<then>
<mkdir dir="${directory}" mode="0777" />
</then>
<else>
<mkdir dir="${directory}" mode="0775" />
</else>
</if>
</then>
</if>
</target>
<!-- Installs vendors -->
<target name="app:composer:install" depends="app:composer:self-update">
<composer php="${composer.php}" composer="${composer.path}" command="install">
<arg value="--optimize-autoloader" />
<arg value="--ansi" />
</composer>
</target>
<!-- Clearing cache -->
<target name="app:cache">
<if>
<istrue value="${cache.clearWithWarmup}" />
<then>
<SymfonyConsole console="bin/console" command="cache:clear">
<arg name="env" value="${env}" />
</SymfonyConsole>
</then>
<else>
<SymfonyConsole console="bin/console" command="cache:clear">
<arg name="env" value="${env}" />
<arg name="no-warmup" />
</SymfonyConsole>
</else>
</if>
</target>
<!-- Clearing cache (faster) -->
<target name="app:cache:faster">
<SymfonyConsole console="bin/console" command="cache:clear">
<arg name="env" value="${env}" />
<arg name="no-optional-warmers" />
</SymfonyConsole>
</target>
<!-- Warming up cache -->
<target name="app:cache:warmup">
<SymfonyConsole console="bin/console" command="cache:warmup">
<arg name="env" value="${env}" />
</SymfonyConsole>
</target>
<!-- Setting permissions of given directory -->
<target name="app:permissions">
<if>
<not>
<os family="windows" />
</not>
<then>
<exec command="chmod -R 777 ${directory}/*" />
</then>
</if>
</target>
<!-- Checkout and finalization -->

20
phing/composer-install.sh Normal file
View File

@@ -0,0 +1,20 @@
#!/bin/sh
EXPECTED_SIGNATURE="$(curl -L https://composer.github.io/installer.sig)"
# Original line (with wget):
# EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_SIGNATURE="$(php -r "echo hash_file('SHA384', 'composer-setup.php');")"
if [[ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]]
then
>&2 echo 'ERROR: Invalid installer signature'
rm composer-setup.php
exit 1
fi
php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php
exit ${RESULT}

14
phing/filesets.xml Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
<!-- Directories to check -->
<property name="directoriesToCheck" value="
${dir.data.tests},
${dir.data.temporary}"
/>
<!-- Directories to empty -->
<property name="directoriesToEmpty" value="
${dir.data.temporary}"
/>
</project>

View File

@@ -1,19 +1,3 @@
# --------------------------------------------------------------------------------
# Information
# --------------------------------------------------------------------------------
# Property files contain key/value pairs
# key = value
#
# Property keys may contain alphanumeric chars and colons, but
# not special chars. This way you can create pseudo-namespaces
#
# You can refer to values of other properties by enclosing their keys in "${}".
# Example: dir.js = ${dir.web}/js
#
# Everything behind the equal sign is the value, you do
# not have to enclose strings: text=This is some text, Your OS is ${php.os}
# --------------------------------------------------------------------------------
# Common, e.g. default environment
# --------------------------------------------------------------------------------
@@ -22,104 +6,84 @@
#
env = dev
# Install assets using symlinks
#
assets.installWithSymlink = true
# Clear cache with the "warmup" option
#
cache.clearWithWarmup = true
# The cache:clear command should always be called with the --no-warmup option. Warmup should be done via the cache:warmup command.
# https://github.com/symfony/symfony/blob/master/UPGRADE-3.3.md#frameworkbundle
#
# Meritoo <github@meritoo.pl>
# 2017-06-06
#
cache.clearWithWarmup = false
# --------------------------------------------------------------------------------
# Composer
# --------------------------------------------------------------------------------
composer.download_command = php -r "eval('?>'.file_get_contents('https://getcomposer.org/installer'));"
# Path to composer executable or composer.phar file
# Command used to download Composer
#
composer.path = composer.phar
#composer.path = /usr/local/bin/composer
composer.download_command = bash ${project.basedir}/phing/composer-install.sh
# Path to php executable used by composer
# Path to Composer executable or downloaded composer.phar file
#
composer.path = ${project.basedir}/composer.phar
# Path to PHP executable used by Composer
#
composer.php = php
# Self update of the composer
#
composer.self-update = false
# Validate the composer.json file
#
composer.validate = false
# --------------------------------------------------------------------------------
# Directories
# --------------------------------------------------------------------------------
# System directories
#
dir.data = ${project.basedir}/data
dir.src = ${project.basedir}/src
dir.data = ${project.basedir}/data
dir.tests = ${project.basedir}/tests
# --------------------------------------------------------------------------------
# Build directories
# --------------------------------------------------------------------------------
#
dir.build = ${project.basedir}/build
dir.reports = ${dir.build}/logs
dir.reports.pdepend = ${dir.reports}/pdepend
dir.reports.coverage = ${dir.reports}/phpunit_coverage
#
# Disabled, because unnecessary right now
# phpdocumentor/phpdocumentor cannot be installed via Composer
#
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
# 2017-02-22
#
#dir.docs = ${dir.build}/docs
#dir.docs.phpdoc2 = ${dir.docs}/phpdoc2
dir.reports = ${dir.build}/reports
dir.reports.coverage = ${dir.reports}/phpunit-coverage
dir.reports.code_sniffer = ${dir.reports}/code_sniffer
# --------------------------------------------------------------------------------
# Data directories
# --------------------------------------------------------------------------------
#
dir.data.tests = ${dir.data}/tests
dir.data.temporary = ${dir.data}/tmp
# --------------------------------------------------------------------------------
# Static Analysis
# --------------------------------------------------------------------------------
# Paths of frameworks used to run analysis:
# - PHPStan
#
check.phpstan.command = ./vendor/bin/phpstan analyse
check.psalm.command = ./vendor/bin/psalm --report=build/reports/psalm.json
check.php_coveralls.command = ./vendor/bin/php-coveralls --ansi -v
# --------------------------------------------------------------------------------
# Testing
# --------------------------------------------------------------------------------
# Path of the PHP Coding Standards Fixer (http://cs.sensiolabs.org)
#
tests.cs_fixer.command = ./vendor/bin/php-cs-fixer fix --verbose
# Path of the PHP_CodeSniffer (https://github.com/squizlabs/PHP_CodeSniffer)
#
tests.code_sniffer.command = ./vendor/bin/phpcs --report-full=${dir.reports.code_sniffer}/full.txt --report-summary=${dir.reports.code_sniffer}/summary.txt --report-checkstyle=${dir.reports.code_sniffer}/checkstyle.xml
# Test database path
#
tests.database = ${dir.data.temporary}/database.sqlite
# Paths of frameworks used to run tests:
# - PHPUnit (unit tests)
# - Infection (mutation tests)
#
# Disabled, because unnecessary right now
# PHPUnit is installed and loaded by Composer
#
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
# 2017-02-22
#
# Run PHPUnit using exec task instead of phpunitTask
#phpunit.useExec = false
#
# Disabled, because unnecessary right now
# We want generate code coverage always
#
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
# 2017-02-22
#
# Collect coverage data during tests
#phpunit.withCoverage = true
# Path of the PHPUnit (https://phpunit.de)
#
phpUnit.path = ./vendor/bin/phpunit
# Path of the PHP Coding Standards Fixer (http://cs.sensiolabs.org)
#
phpCsFixer.path = ./vendor/bin/php-cs-fixer
tests.phpunit.command = ./vendor/bin/phpunit --verbose
tests.mutation.command = ./vendor/bin/infection --ansi --threads=$(nproc) --coverage=build/reports/infection

View File

@@ -1,22 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="Meritoo Common Library" basedir="." default="build:main" phingVersion="2.14.0">
<!--
The AutoloaderTask is required to load binaries installed by Composer.
The "autoloaderpath" attribute of this task is not required, because it's default value is: vendor/autoload.php.
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
2017-02-23
-->
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
<autoloader />
<!-- Properties -->
<if>
<available file="phing/properties" property="custom.properties.available"/>
<available file="${project.basedir}/phing/properties" property="custom.properties.available" />
<then>
<property file="phing/properties" />
<property file="${project.basedir}/phing/properties" />
</then>
<else>
<property file="phing/properties.dist" />
<property file="${project.basedir}/phing/properties.dist" />
</else>
</if>
@@ -35,271 +29,85 @@
<!-- Default / main target -->
<target name="build:main"
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, app:checkout"
description="Runs all tests and builds everything" />
<!--
Before:
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, build:doc, app:checkout"
After:
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, app:checkout"
The "build:doc" task is disabled, because it cannot be installed via Composer:
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
2017-02-22
-->
depends="build:fix-coding-standards,
build:check,
build:test,
app:checkout"
/>
<!-- Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org) -->
<target name="build:fix-coding-standards" description="Fixes coding standards using the PHP Coding Standards Fixer">
<echo msg="Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org)..." />
<!--
Attention.
Rules for formatting are defined in /.php_cs.dist file.
-->
<exec
passthru="true"
command="${phpCsFixer.path} fix --verbose"
/>
<target name="build:fix-coding-standards">
<exec command="${tests.cs_fixer.command}" passthru="true" />
</target>
<!-- Doc target -->
<!--
Disabled, because it cannot be installed via Composer:
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
2017-02-22
-->
<!--<target name="build:doc"-->
<!--depends="build:prepare, doc:phpdoc2"-->
<!--description="Generates API documentation" />-->
<!-- Check target -->
<target name="build:check"
depends="check:cs, check:md, check:cpd, check:depend, check:loc"
description="Analyzes code" />
depends="check:cs,
check:cpd,
check:phpstan,
check:psalm,
check:coveralls"
/>
<!-- Test target -->
<target name="build:test"
depends="test:phpunit"
description="Executes all tests" />
depends="test:phpunit,
test:infection"
/>
<!-- Project build clean -->
<target name="build:clean" description="Cleans up build directories">
<echo msg="Cleaning docs and reports directories..." />
<!--<delete dir="${dir.docs}" />-->
<delete dir="${dir.reports}" />
</target>
<!-- Project build prepare -->
<target name="build:prepare" description="Create build directories">
<echo msg="Creating build directories..." />
<!--<mkdir dir="${dir.docs}" />-->
<!--<mkdir dir="${dir.docs.phpdoc2}" />-->
<mkdir dir="${dir.reports}" />
<mkdir dir="${dir.reports.coverage}" />
<mkdir dir="${dir.reports.pdepend}" />
</target>
<!-- PHPDocumentor2 API documentation target -->
<!--
Disabled, because it cannot be installed via Composer:
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
2017-02-22
<target name="doc:phpdoc2" description="Generates API documentations">
<echo msg="Generating API Documentation with phpDocumentor 2..." />
<phpdoc2 title="${phing.project.name}"
destdir="${dir.docs.phpdoc2}"
template="responsive">
<fileset refid="sourcecode" />
</phpdoc2>
</target>
-->
<!-- Symfony2 code sniffer -->
<!--
Attention 1.
To use Symfony2 standards to check coding you have to:
copy, symlink or check out repo to a folder called Symfony2 inside the phpcs Standards directory.
Example:
$ pear config-show | grep php_dir
$ cd /path/to/pear/PHP/CodeSniffer/Standards
$ git clone git://github.com/opensky/Symfony2-coding-standard.git Symfony2
Attention 2.
PSR2 standard is used instead of Symfony2 standard, because after installation squizlabs/php_codesniffer package
via Composer the Symfony2 standard is not included / available in this package. In this case the PHP Coding
Standards Fixer (http://cs.sensiolabs.org) is used.
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
2017-02-22
-->
<target name="check:cs" description="Checks coding standard">
<echo msg="Checking coding standard..." />
<phpcodesniffer standard="PSR2" showWarnings="true">
<fileset refid="sourcecode" />
<formatter type="checkstyle" outfile="${dir.reports}/checkstyle.xml" />
<formatter type="csv" outfile="${dir.reports}/checkstyle.csv" />
<formatter type="summary" outfile="${dir.reports}/checkstyle_summary.txt" />
</phpcodesniffer>
<!-- PHP_CodeSniffer -->
<target name="check:cs" depends="build:prepare">
<exec command="${tests.code_sniffer.command}" passthru="true" />
</target>
<!-- copy/paste detector -->
<target name="check:cpd" description="Checks similar code blocks.">
<echo msg="Checking similar code blocks..." />
<target name="check:cpd" depends="build:prepare">
<phpcpd>
<fileset refid="sourcecode" />
<formatter type="pmd" outfile="${dir.reports}/pmd-cpd.xml" />
<formatter type="pmd" outfile="${dir.reports}/copy-paste-detector.xml" />
</phpcpd>
<!--
Previous / old version
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
2017-02-22
<exec command="phpcpd \-\-log-pmd=${dir.reports}/pmd-cpd.xml ${dir.src}" />
-->
</target>
<!-- Mess detector -->
<target name="check:md" description="Generate code metrics">
<echo msg="Generating code metrics..." />
<phpmd rulesets="codesize,controversial,design,naming,unusedcode">
<fileset refid="sourcecode" />
<formatter type="html" outfile="${dir.reports}/phpmd.html" />
<formatter type="text" outfile="${dir.reports}/phpmd.txt" />
</phpmd>
<!-- Run static analysis -->
<target name="check:phpstan" depends="build:prepare">
<exec command="${check.phpstan.command}" passthru="true" />
</target>
<!-- Code dependency -->
<target name="check:depend" description="Checks coupling and dependency">
<echo msg="Checking coupling and dependency..." />
<phpdepend>
<fileset refid="sourcecode" />
<logger type="jdepend-xml" outfile="${dir.reports.pdepend}/jdepend.xml" />
<logger type="jdepend-chart" outfile="${dir.reports.pdepend}/dependencies.svg" />
<logger type="overview-pyramid" outfile="${dir.reports.pdepend}/overview-pyramid.svg" />
</phpdepend>
<!-- Run static analysis -->
<target name="check:psalm" depends="build:prepare">
<exec command="${check.psalm.command}" passthru="true" />
</target>
<!-- Measure the size and analyzing the structure of a project -->
<target name="check:loc" description="Measures the size and analyzes the structure of a project">
<echo msg="Measuring the size and analyzing the structure of a project..." />
<phploc reportType="txt" reportName="phploc" reportDirectory="${dir.reports}">
<fileset refid="sourcecode" />
</phploc>
<!--
Previous / old version
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
2017-02-22
<exec command="phploc \-\-log-csv=${dir.reports}/phploc.csv ${dir.src}" />
-->
<!-- Run analysis of code coverage -->
<target name="check:coveralls" depends="test:phpunit">
<exec command="${check.php_coveralls.command}" passthru="true" />
</target>
<!-- Unit tests -->
<target name="test:phpunit" description="Executes PHPUnit tests">
<!-- Check test database -->
<!-- PHPUnit tests -->
<target name="test:phpunit" depends="build:prepare">
<exec command="${tests.phpunit.command}" passthru="true" />
</target>
<!-- Run mutation testing -->
<target name="test:infection" depends="test:phpunit">
<exec command="${tests.mutation.command}" passthru="true" />
</target>
<!-- Project build clean -->
<target name="build:clean">
<if>
<not>
<available file="${dir.data.tests}" type="dir" property="dir.data.tests.available" />
</not>
<available file="${dir.reports}" type="dir" property="dir_is_available" />
<then>
<mkdir dir="${dir.data.tests}" />
<delete dir="${dir.reports}" />
</then>
</if>
<if>
<not>
<available file="${tests.database}" property="tests.database.available" />
</not>
<then>
<touch file="${tests.database}" />
</then>
</if>
<echo msg="Running unit tests..." />
<coverage-setup database="${dir.reports.coverage}/coverage.db">
<fileset refid="sourcecode" />
</coverage-setup>
<exec command="${phpUnit.path} --verbose --configuration ${project.basedir}/phpunit.xml.dist" passthru="true" />
<!--
I have to use ExecTask to run PHPUnit instead of PHPUnitTask, because tests are not running if PHPUnitTask is
used (don't know why):
Total tests run: 0, Failures: 0, Errors: 0, Incomplete: 0, Skipped: 0
</target>
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
2017-02-23
<phpunit configuration="${project.basedir}/phpunit.xml.dist" printsummary="true">
<formatter type="xml" todir="${dir.reports}" outfile="phpunit.xml" />
<formatter type="plain" todir="${dir.reports}" outfile="phpunit.txt" />
<formatter type="clover" todir="${dir.reports.coverage}" />
<formatter type="summary" todir="${dir.reports}" outfile="phpunit_summary.txt" />
</phpunit>
-->
<!--
Previous / old version
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
2017-02-22
<if>
<istrue value="${phpunit.useExec}" />
<then>
<if>
<istrue value="${phpunit.withCoverage}" />
<then>
<echo message="Running tests with code coverage..." />
<exec command="phpunit \-\-log-junit ${dir.reports}/phpunit.xml \-\-coverage-clover ${dir.reports.coverage}/clover-coverage.xml \-\-coverage-crap4j ${dir.reports.coverage}/crap4j-coverage.xml \-\-coverage-html ${dir.reports.coverage}/ -c ${project.basedir} \-\-colors" passthru="true" checkreturn="true" />
</then>
<else>
<echo message="Running tests without code coverage..." />
<exec command="phpunit \-\-log-junit ${dir.reports}/phpunit.xml -c ${project.basedir} \-\-colors" passthru="true" checkreturn="true" />
</else>
</if>
</then>
<else>
<if>
<istrue value="${phpunit.withCoverage}" />
<then>
<echo message="Running tests with code coverage..." />
<coverage-setup database="${dir.reports.coverage}/coverage.db">
<fileset refid="sourcecode" />
</coverage-setup>
<phpunit printsummary="true" codecoverage="true">
<formatter type="xml" todir="${dir.reports}" outfile="phpunit.xml" />
<formatter type="plain" todir="${dir.reports}" outfile="phpunit.txt" />
<formatter type="clover" todir="${dir.reports.coverage}" />
<formatter type="summary" todir="${dir.reports}" outfile="phpunit_summary.txt" />
</phpunit>
</then>
<else>
<echo message="Running tests without code coverage..." />
<phpunit printsummary="true">
<formatter todir="${dir.reports}" type="xml" outfile="phpunit.xml" />
<batchtest>
<fileset refid="tests" />
</batchtest>
</phpunit>
</else>
</if>
</else>
</if>
-->
<!-- Project build prepare -->
<target name="build:prepare" depends="build:clean">
<mkdir dir="${dir.reports}" />
<mkdir dir="${dir.reports.coverage}" />
<mkdir dir="${dir.reports.code_sniffer}" />
</target>
<!-- Checkout and finalization -->

16
phpcs.xml.dist Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
<arg name="basepath" value="."/>
<arg name="cache" value=".phpcs-cache"/>
<arg name="colors"/>
<arg name="extensions" value="php"/>
<rule ref="PSR2"/>
<file>src/</file>
<file>tests/</file>
</ruleset>

5
phpstan.neon.dist Normal file
View File

@@ -0,0 +1,5 @@
parameters:
level: 1
paths:
- src
- tests

View File

@@ -1,35 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
<!-- https://phpunit.readthedocs.io/en/8.2/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
backupGlobals="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="true"
bootstrap="./vendor/autoload.php"
executionOrder="random"
forceCoversAnnotation="true"
verbose="true"
>
<coverage>
<include>
<directory>src</directory>
</include>
<report>
<clover outputFile="build/reports/coveralls/clover.xml" />
<html outputDirectory="build/reports/phpunit-coverage/html" />
<xml outputDirectory="build/reports/infection/coverage-xml" />
</report>
</coverage>
<php>
<ini name="error_reporting" value="-1" />
</php>
<testsuites>
<testsuite name="Meritoo's Common Library Test Suite">
<directory>./tests/</directory>
<testsuite name="Meritoo Package - Main Test Suite">
<directory>tests</directory>
</testsuite>
<testsuite name="Collection">
<directory>tests/Collection</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./src/</directory>
</whitelist>
</filter>
<groups>
<exclude>
<group>performance</group>
</exclude>
</groups>
<logging>
<log type="coverage-html" target="./build/logs/phpunit_coverage/html" />
<junit outputFile="build/reports/infection/phpunit.junit.xml" />
</logging>
</phpunit>

53
psalm.xml Normal file
View File

@@ -0,0 +1,53 @@
<?xml version="1.0"?>
<psalm
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
totallyTyped="false"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config file:///project/vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
<issueHandlers>
<LessSpecificReturnType errorLevel="info" />
<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
<DeprecatedMethod errorLevel="info" />
<DeprecatedProperty errorLevel="info" />
<DeprecatedClass errorLevel="info" />
<DeprecatedConstant errorLevel="info" />
<DeprecatedInterface errorLevel="info" />
<DeprecatedTrait errorLevel="info" />
<InternalMethod errorLevel="info" />
<InternalProperty errorLevel="info" />
<InternalClass errorLevel="info" />
<MissingClosureReturnType errorLevel="info" />
<MissingReturnType errorLevel="info" />
<MissingPropertyType errorLevel="info" />
<InvalidDocblock errorLevel="info" />
<MisplacedRequiredParam errorLevel="info" />
<PropertyNotSetInConstructor errorLevel="info" />
<MissingConstructor errorLevel="info" />
<MissingClosureParamType errorLevel="info" />
<MissingParamType errorLevel="info" />
<RedundantCondition errorLevel="info" />
<DocblockTypeContradiction errorLevel="info" />
<RedundantConditionGivenDocblockType errorLevel="info" />
<UnresolvableInclude errorLevel="info" />
<RawObjectIteration errorLevel="info" />
<InvalidStringClass errorLevel="info" />
</issueHandlers>
</psalm>

View File

@@ -0,0 +1,349 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Collection;
use ArrayIterator;
use Meritoo\Common\Contract\Collection\CollectionInterface;
use Meritoo\Common\Utilities\Arrays;
/**
* Collection of elements with the same type
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
abstract class BaseCollection implements CollectionInterface
{
/**
* The elements of collection
*
* @var array
*/
private array $elements;
/**
* Class constructor
*
* @param array $elements (optional) Elements of collection
*/
public function __construct(array $elements = [])
{
$validated = $this->getElementsWithValidType($elements);
$this->elements = $this->prepareElements($validated);
}
/**
* {@inheritdoc}
*/
public function add($element, $index = null): void
{
if (!$this->isValidType($element)) {
return;
}
if (null === $index) {
$this->elements[] = $element;
return;
}
$this->elements[$index] = $element;
}
/**
* {@inheritdoc}
*/
public function addMultiple($elements, bool $useIndexes = false): void
{
if (empty($elements)) {
return;
}
$prepared = $this->prepareElements($elements);
foreach ($prepared as $index => $element) {
if ($useIndexes) {
$this->add($element, $index);
continue;
}
$this->add($element);
}
}
/**
* {@inheritdoc}
*/
public function append($element): void
{
$this->elements[] = $element;
}
/**
* {@inheritdoc}
*/
public function clear(): void
{
$this->elements = [];
}
/**
* {@inheritdoc}
*/
public function count(): int
{
return count($this->elements);
}
/**
* {@inheritdoc}
*/
public function getByIndex($index)
{
return $this->elements[$index] ?? null;
}
/**
* {@inheritdoc}
*/
public function getFirst()
{
return Arrays::getFirstElement($this->elements);
}
/**
* {@inheritdoc}
*/
public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->elements);
}
/**
* {@inheritdoc}
*/
public function getLast()
{
return Arrays::getLastElement($this->elements);
}
/**
* {@inheritdoc}
*/
public function getNext($element)
{
return Arrays::getNextElement($this->elements, $element);
}
/**
* {@inheritdoc}
*/
public function getPrevious($element)
{
return Arrays::getPreviousElement($this->elements, $element);
}
/**
* {@inheritdoc}
*/
public function has($element): bool
{
$index = Arrays::getIndexOf($this->elements, $element);
return null !== $index && false !== $index;
}
/**
* {@inheritdoc}
*/
public function isEmpty(): bool
{
return empty($this->elements);
}
/**
* {@inheritdoc}
*/
public function isFirst($element): bool
{
return reset($this->elements) === $element;
}
/**
* {@inheritdoc}
*/
public function isLast($element): bool
{
return end($this->elements) === $element;
}
/**
* {@inheritdoc}
*/
public function limit(int $max, int $offset = 0): self
{
$result = clone $this;
$negativeMax = $max <= 0;
$exceededMax = $max >= $this->count();
if ($negativeMax || $exceededMax) {
if ($negativeMax) {
$result->clear();
}
return $result;
}
$iteration = -1;
foreach ($result as $index => $element) {
$iteration++;
if ($iteration >= $offset && $iteration < $offset + $max) {
continue;
}
unset($result[$index]);
}
return $result;
}
/**
* {@inheritdoc}
*/
public function offsetExists($offset): bool
{
return $this->exists($offset);
}
/**
* {@inheritdoc}
*/
public function offsetGet($offset)
{
if ($this->exists($offset)) {
return $this->elements[$offset];
}
return null;
}
/**
* {@inheritdoc}
*/
public function offsetSet($offset, $value): void
{
$this->elements[$offset] = $value;
}
/**
* {@inheritdoc}
*/
public function offsetUnset($offset): void
{
if ($this->exists($offset)) {
unset($this->elements[$offset]);
}
}
/**
* {@inheritdoc}
*/
public function prepend($element): void
{
array_unshift($this->elements, $element);
}
/**
* {@inheritdoc}
*/
public function remove($element): void
{
if (0 === $this->count()) {
return;
}
foreach ($this->elements as $index => $existing) {
if ($element === $existing) {
unset($this->elements[$index]);
break;
}
}
}
/**
* {@inheritdoc}
*/
public function toArray(): array
{
return $this->elements;
}
/**
* Returns information if given element has valid type
*
* @param mixed $element Element of collection
* @return bool
*/
abstract protected function isValidType($element): bool;
/**
* Prepares elements to initialize the collection.
* Feel free to override and prepare elements in your way.
*
* @param array $elements The elements of collection to prepare
* @return array
*/
protected function prepareElements(array $elements): array
{
return $elements;
}
/**
* Returns information if element with given index/key exists
*
* @param int|string $index The index/key of element
* @return bool
*/
private function exists($index): bool
{
return isset($this->elements[$index]) || array_key_exists($index, $this->elements);
}
/**
* Returns elements of collection with valid types
*
* @param array $elements The elements of collection to verify
* @return array
*/
private function getElementsWithValidType(array $elements): array
{
if (empty($elements)) {
return [];
}
$result = [];
foreach ($elements as $index => $element) {
if (!$this->isValidType($element)) {
continue;
}
$result[$index] = $element;
}
return $result;
}
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Collection;
use DateTime;
/**
* Collection of DateTime instances
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class DateTimeCollection extends BaseCollection
{
protected function isValidType($element): bool
{
return $element instanceof DateTime;
}
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Collection;
/**
* Collection of integers
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class IntegerCollection extends BaseCollection
{
protected function isValidType($element): bool
{
return is_int($element);
}
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Collection;
/**
* Collection of strings
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class StringCollection extends BaseCollection
{
protected function isValidType($element): bool
{
return is_string($element);
}
}

View File

@@ -0,0 +1,72 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Collection;
use Meritoo\Common\Exception\ValueObject\Template\TemplateNotFoundException;
use Meritoo\Common\ValueObject\Template;
/**
* Collection/storage of templates
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class Templates extends BaseCollection
{
/**
* Finds and returns template with given index
*
* @param string $index Index that contains required template
* @return Template
* @throws TemplateNotFoundException
*/
public function findTemplate(string $index): Template
{
$template = $this->getByIndex($index);
if ($template instanceof Template) {
return $template;
}
// Oops, template not found
throw TemplateNotFoundException::create($index);
}
/**
* Creates and returns the collection from given array
*
* @param array $templates Pairs of key-value where: key - template's index, value - template's content
* @return Templates
*/
public static function fromArray(array $templates): Templates
{
// No templates. Nothing to do.
if (empty($templates)) {
return new static();
}
$result = new static();
foreach ($templates as $index => $template) {
$result->add(new Template($template), $index);
}
return $result;
}
/**
* {@inheritdoc}
*/
protected function isValidType($element): bool
{
return $element instanceof Template;
}
}

View File

@@ -0,0 +1,55 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Contract\Collection;
/**
* Contract for collection that may add elements
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
interface AddableCollectionInterface
{
/**
* Adds given element (at the end of collection)
*
* @param mixed $element The element to add
* @param mixed $index (optional) Index / key of the element
* @return void
*/
public function add($element, $index = null): void;
/**
* Adds given elements (at the end of collection)
*
* @param array|CollectionInterface $elements The elements to add
* @param bool $useIndexes (optional) If is set to true, indexes of given elements will be
* used in this collection. Otherwise - not.
* @return void
*/
public function addMultiple(array $elements, bool $useIndexes = false): void;
/**
* Appends given element (adds given element at the end of collection)
*
* @param mixed $element The element to add at the end
* @return void
*/
public function append($element): void;
/**
* Prepends given element (adds given element at the beginning of collection)
*
* @param mixed $element The element to add at the beginning
* @return void
*/
public function prepend($element): void;
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Contract\Collection;
/**
* Contract for collection that may be cleared (all its elements may be removed)
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
interface ClearableCollectionInterface
{
/**
* Removes all elements of the collection
*
* @return void
*/
public function clear(): void;
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Contract\Collection;
use ArrayAccess;
use IteratorAggregate;
/**
* Contract for collection of elements with the same type
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
interface CollectionInterface extends ArrayAccess, IteratorAggregate, AddableCollectionInterface,
RemovableCollectionInterface, CountableCollectionInterface, ClearableCollectionInterface,
GettableCollectionInterface, VerifiableCollectionInterface, ReducibleCollectionInterface
{
/**
* Returns representation of object as array
*
* @return array
*/
public function toArray(): array;
}

View File

@@ -0,0 +1,23 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Contract\Collection;
use Countable;
/**
* Contract for collection that may count its elements
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
interface CountableCollectionInterface extends Countable
{
}

View File

@@ -0,0 +1,58 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Contract\Collection;
/**
* Contract for collection that returns first, last element etc.
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
interface GettableCollectionInterface
{
/**
* Returns element with given index
*
* @param mixed $index Index / key of element to return
* @return mixed
*/
public function getByIndex($index);
/**
* Returns first element
*
* @return mixed
*/
public function getFirst();
/**
* Returns last element
*
* @return mixed
*/
public function getLast();
/**
* Returns element next after given element
*
* @param mixed $element The element whose next element should be returned
* @return mixed
*/
public function getNext($element);
/**
* Returns element preceding given element
*
* @param mixed $element The element whose previous element should be returned
* @return mixed
*/
public function getPrevious($element);
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Contract\Collection;
/**
* Contract for collection that may reduce its elements
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
interface ReducibleCollectionInterface
{
/**
* Returns new instance of this collection with limited elements
*
* @param int $max Maximum elements to return
* @param int $offset (optional) Position of element from which limitation should start
* @return $this
*/
public function limit(int $max, int $offset = 0): self;
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Contract\Collection;
/**
* Contract for collection that may remove elements
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
interface RemovableCollectionInterface
{
/**
* Removes given element
*
* @param mixed $element The element to remove
* @return void
*/
public function remove($element): void;
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Contract\Collection;
/**
* Contract for collection that may verify its elements
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
interface VerifiableCollectionInterface
{
/**
* Returns information if given element exists in collection
*
* @param mixed $element The element to verify
* @return bool
*/
public function has($element): bool;
/**
* Returns information if collection is empty (has not any element)
*
* @return bool
*/
public function isEmpty(): bool;
/**
* Returns information if given element is the first element in collection
*
* @param mixed $element The element to verify
* @return bool
*/
public function isFirst($element): bool;
/**
* Returns information if given element is the last element in collection
*
* @param mixed $element The element to verify
* @return bool
*/
public function isLast($element): bool;
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Contract\Renderable;
use Meritoo\Common\Collection\Templates;
/**
* Interface/Contract of something that may be rendered
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
interface RenderableInterface
{
/**
* Renders this object using given templates
*
* @param Templates $templates Collection/storage of templates that will be required while rendering this and
* related objects, e.g. children of this object
* @return string
*/
public function render(Templates $templates): string;
}

View File

@@ -0,0 +1,42 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Base;
use Exception;
use Meritoo\Common\Type\Base\BaseType;
use Meritoo\Common\Utilities\Arrays;
/**
* An exception used while type of something is unknown
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
abstract class UnknownTypeException extends Exception
{
/**
* Creates exception
*
* @param mixed $unknownType The unknown type of something (value of constant)
* @param BaseType $typeInstance An instance of class that contains type of the something
* @param string $typeName Name of the something
* @return UnknownTypeException
*/
public static function create($unknownType, BaseType $typeInstance, string $typeName): UnknownTypeException
{
$template = 'The \'%s\' type of %s is unknown. Probably doesn\'t exist or there is a typo. You should use one'
.' of these types: %s.';
$allTypes = $typeInstance->getAll();
$types = Arrays::values2string($allTypes, '', ', ') ?? '[types not found]';
$message = sprintf($template, $unknownType, $typeName, $types);
return new static($message);
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Bundle;
use Exception;
/**
* An exception used while name of bundle is incorrect
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class IncorrectBundleNameException extends Exception
{
/**
* Creates exception
*
* @param string $bundleName Incorrect name of bundle
* @return IncorrectBundleNameException
*/
public static function create($bundleName)
{
$template = 'Name of bundle \'%s\' is incorrect. It should start with big letter and end with "Bundle". Is'
.' there everything ok?';
$message = sprintf($template, $bundleName);
return new static($message);
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\File;
use Exception;
/**
* An exception used while file with given path is empty (has no content)
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class EmptyFileException extends Exception
{
/**
* Creates exception
*
* @param string $emptyFilePath Path of the empty file
* @return EmptyFileException
*/
public static function create($emptyFilePath)
{
$template = 'File with path \'%s\' is empty (has no content). Did you provide path of proper file?';
$message = sprintf($template, $emptyFilePath);
return new static($message);
}
}

View File

@@ -0,0 +1,30 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\File;
use Exception;
/**
* An exception used while path of given file is empty
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class EmptyFilePathException extends Exception
{
/**
* Creates exception
*
* @return EmptyFilePathException
*/
public static function create(): EmptyFilePathException
{
return new static('Path of the file is empty. Did you provide path of proper file?');
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\File;
use Exception;
/**
* An exception used while file with given path does not exist
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class NotExistingFileException extends Exception
{
/**
* Creates exception
*
* @param string $notExistingFilePath Path of not existing (or not readable) file
* @return NotExistingFileException
*/
public static function create($notExistingFilePath)
{
$template = 'File with path \'%s\' does not exist (or is not readable). Did you provide path of proper file?';
$message = sprintf($template, $notExistingFilePath);
return new static($message);
}
}

View File

@@ -0,0 +1,40 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Method;
use Exception;
/**
* An exception used while method cannot be called, because is disabled
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class DisabledMethodException extends Exception
{
/**
* Creates exception
*
* @param string $disabledMethod Name of the disabled method
* @param string $alternativeMethod (optional) Name of the alternative method
* @return DisabledMethodException
*/
public static function create($disabledMethod, $alternativeMethod = '')
{
$template = 'Method %s() cannot be called, because is disabled.';
$message = sprintf($template, $disabledMethod);
if (!empty($alternativeMethod)) {
$template = '%s Use %s() instead.';
$message = sprintf($template, $message, $alternativeMethod);
}
return new static($message);
}
}

View File

@@ -13,20 +13,20 @@ use Exception;
/**
* An exception used while name of class or trait cannot be resolved
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class CannotResolveClassNameException extends Exception
{
/**
* Class constructor
* Creates exception
*
* @param array|object|string $source Source of the class's / trait's name. It cane be an array of objects,
* namespaces, object or namespace.
* @param bool $forClass (optional) If is set to true, message of this exception for class is
* prepared. Otherwise - for trait.
* @param string $source Source of name of the class or trait
* @param bool $forClass (optional) If is set to true, message of this exception for class is prepared. Otherwise
* - for trait.
* @return CannotResolveClassNameException
*/
public function __construct($source, $forClass = true)
public static function create(string $source, bool $forClass = true): CannotResolveClassNameException
{
$forWho = 'trait';
$value = '';
@@ -36,12 +36,12 @@ class CannotResolveClassNameException extends Exception
}
if (is_scalar($source)) {
$value = sprintf(' %s', (string)$source);
$value = sprintf(' %s', $source);
}
$template = 'Name of %s from given \'%s\'%s cannot be resolved. Is there everything ok?';
$message = sprintf($template, $forWho, gettype($source), $value);
parent::__construct($message);
return new static($message);
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Reflection;
use Exception;
/**
* An exception used while given class hasn't constructor
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class ClassWithoutConstructorException extends Exception
{
/**
* Creates exception
*
* @param string $className Fully-qualified name of class that hasn't constructor
* @return ClassWithoutConstructorException
*/
public static function create(string $className): ClassWithoutConstructorException
{
$template = 'Oops, class \'%s\' hasn\'t constructor. Did you use proper class?';
$message = sprintf($template, $className);
return new static($message);
}
}

View File

@@ -14,25 +14,26 @@ use Meritoo\Common\Utilities\Reflection;
/**
* An exception used while given class has no child classes
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class MissingChildClassesException extends Exception
{
/**
* Class constructor
* Creates exception
*
* @param array|object|string $parentClass Class that hasn't child classes, but it should. An array of objects,
* strings, object or string.
* @return MissingChildClassesException
*/
public function __construct($parentClass)
public static function create($parentClass): MissingChildClassesException
{
$template = 'The \'%s\' class requires one child class at least who will extend her (maybe is an abstract'
. ' class), but the child classes are missing. Did you forget to extend this class?';
.' class), but the child classes are missing. Did you forget to extend this class?';
$parentClassName = Reflection::getClassName($parentClass);
$parentClassName = Reflection::getClassName($parentClass) ?? '[unknown class]';
$message = sprintf($template, $parentClassName);
parent::__construct($message);
return new static($message);
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Reflection;
use Exception;
/**
* An exception used while property does not exist in instance of class
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class NotExistingPropertyException extends Exception
{
/**
* Creates exception
*
* @param mixed $object Object that should contains given property
* @param null|string $property Name of the property
* @return NotExistingPropertyException
*/
public static function create($object, ?string $property): NotExistingPropertyException
{
$template = 'Property \'%s\' does not exist in instance of class \'%s\'. Did you use proper name of property?';
$message = sprintf($template, $property, get_class($object));
return new static($message);
}
}

View File

@@ -14,26 +14,27 @@ use Meritoo\Common\Utilities\Reflection;
/**
* An exception used while given class has more than one child class
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class TooManyChildClassesException extends Exception
{
/**
* Class constructor
* Creates exception
*
* @param array|object|string $parentClass Class that has more than one child class, but it shouldn't. An array
* of objects, strings, object or string.
* @param array $childClasses Child classes
* @return TooManyChildClassesException
*/
public function __construct($parentClass, array $childClasses)
public static function create($parentClass, array $childClasses): TooManyChildClassesException
{
$template = "The '%s' class requires one child class at most who will extend her, but more than one child"
. " class was found:\n- %s\n\nWhy did you create more than one classes that extend '%s' class?";
." class was found:\n- %s\n\nWhy did you create more than one classes that extend '%s' class?";
$parentClassName = Reflection::getClassName($parentClass);
$parentClassName = Reflection::getClassName($parentClass) ?? '[unknown class]';
$message = sprintf($template, $parentClassName, implode("\n- ", $childClasses), $parentClassName);
parent::__construct($message);
return new static($message);
}
}

View File

@@ -6,27 +6,31 @@
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception;
namespace Meritoo\Common\Exception\Regex;
use Exception;
/**
* An exception used while length of given hexadecimal value of color is incorrect
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class IncorrectColorHexLengthException extends \Exception
class IncorrectColorHexLengthException extends Exception
{
/**
* Class constructor
* Creates exception
*
* @param string $color Incorrect hexadecimal value of color
* @return IncorrectColorHexLengthException
*/
public function __construct($color)
public static function create($color)
{
$template = 'Length of hexadecimal value of color \'%s\' is incorrect. It\'s %d, but it should be 3 or 6.'
. ' Is there everything ok?';
.' Is there everything ok?';
$message = sprintf($template, $color, strlen($color));
parent::__construct($message);
return new static($message);
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Regex;
use Exception;
/**
* An exception used while given hexadecimal value of color is invalid
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class InvalidColorHexValueException extends Exception
{
/**
* Creates exception
*
* @param string $color Invalid hexadecimal value of color
* @return InvalidColorHexValueException
*/
public static function create($color)
{
$message = sprintf('Hexadecimal value of color \'%s\' is invalid. Is there everything ok?', $color);
return new static($message);
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Regex;
use Exception;
/**
* An exception used while html attributes are invalid
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class InvalidHtmlAttributesException extends Exception
{
/**
* Creates exception
*
* @param string $htmlAttributes Invalid html attributes
* @return InvalidHtmlAttributesException
*/
public static function create($htmlAttributes)
{
$message = sprintf('HTML attributes \'%s\' are invalid. Is there everything ok?', $htmlAttributes);
return new static($message);
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Regex;
use Exception;
/**
* An exception used while url is invalid
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class InvalidUrlException extends Exception
{
/**
* Creates exception
*
* @param string $url Invalid url
* @return InvalidUrlException
*/
public static function create($url)
{
$message = sprintf('Url \'%s\' is invalid. Is there everything ok?', $url);
return new static($message);
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Type;
use Meritoo\Common\Exception\Base\UnknownTypeException;
use Meritoo\Common\Type\DatePartType;
/**
* An exception used while type of date part, e.g. "year", is unknown
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class UnknownDatePartTypeException extends UnknownTypeException
{
/**
* Creates exception
*
* @param string $unknownDatePart Unknown type of date part
* @param string $value Incorrect value
* @return UnknownDatePartTypeException
*/
public static function createException(string $unknownDatePart, string $value): UnknownDatePartTypeException
{
return parent::create($unknownDatePart, new DatePartType(), sprintf('date part (with value %s)', $value));
}
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Type;
use Meritoo\Common\Exception\Base\UnknownTypeException;
use Meritoo\Common\Type\OopVisibilityType;
/**
* An exception used while the visibility of a property, a method or (as of PHP 7.1.0) a constant is unknown
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class UnknownOopVisibilityTypeException extends UnknownTypeException
{
/**
* Creates exception
*
* @param string $unknownType Unknown visibility of a property, a method or (as of PHP 7.1.0) a constant
* @return UnknownOopVisibilityTypeException
*/
public static function createException(string $unknownType): UnknownOopVisibilityTypeException
{
return parent::create($unknownType, new OopVisibilityType(), 'OOP-related visibility');
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\ValueObject;
use Exception;
/**
* An exception used while dimensions of size, passed to the instance of Size class, are invalid
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class InvalidSizeDimensionsException extends Exception
{
/**
* Creates exception
*
* @param int $width The width
* @param int $height The height
* @return InvalidSizeDimensionsException
*/
public static function create($width, $height)
{
$template = 'Dimensions of size should be positive, but they are not: %d, %d. Is there everything ok?';
$message = sprintf($template, $width, $height);
return new static($message);
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Exception\ValueObject\Template;
use Exception;
/**
* An exception used while content of template is invalid
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class InvalidContentException extends Exception
{
/**
* Creates an exception
*
* @param string $content Invalid content of template
* @return InvalidContentException
*/
public static function create(string $content): InvalidContentException
{
$template = 'Content of template \'%s\' is invalid. Did you use string with 1 placeholder at least?';
$message = sprintf($template, $content);
return new static($message);
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\ValueObject\Template;
use Exception;
/**
* An exception used while there are missing values required to fill all placeholders in template
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class MissingPlaceholdersInValuesException extends Exception
{
/**
* Creates an exception
*
* @param string $content Content of template
* @param array $missingPlaceholders Missing placeholders in provided values, iow. placeholders without values
* @return MissingPlaceholdersInValuesException
*/
public static function create(string $content, array $missingPlaceholders): MissingPlaceholdersInValuesException
{
$template = 'Cannot fill template \'%s\', because of missing values for placeholder(s): %s. Did you provide all'
.' required values?';
$message = sprintf($template, $content, implode(', ', $missingPlaceholders));
return new static($message);
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Exception\ValueObject\Template;
use Exception;
/**
* An exception used while template with given index was not found
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class TemplateNotFoundException extends Exception
{
/**
* Creates the exception
*
* @param string $index Index that should contain template, but it was not found
* @return TemplateNotFoundException
*/
public static function create(string $index): TemplateNotFoundException
{
$template = 'Template with \'%s\' index was not found. Did you provide all required templates?';
$message = sprintf($template, $index);
return new static($message);
}
}

View File

@@ -1,41 +0,0 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Base;
use Exception;
use Meritoo\Common\Type\Base\BaseType;
use Meritoo\Common\Utilities\Arrays;
/**
* An exception used while type of something is unknown
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
abstract class UnknownTypeException extends Exception
{
/**
* Class constructor
*
* @param string|int $unknownType The unknown type of something (value of constant)
* @param BaseType $typeInstance An instance of class that contains type of the something
* @param string $typeName Name of the something
*/
public function __construct($unknownType, BaseType $typeInstance, $typeName)
{
$allTypes = $typeInstance->getAll();
$types = Arrays::values2string($allTypes, '', ', ');
$template = 'The \'%s\' type of %s is unknown. Probably doesn\'t exist or there is a typo. You should use one'
. ' of these types: %s.';
$message = sprintf(sprintf($template, $unknownType, $typeName, $types));
parent::__construct($message);
}
}

View File

@@ -1,32 +0,0 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception\Date;
use Exception;
/**
* An exception used while given part of date is incorrect, e.g. value of year is incorrect
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class IncorrectDatePartException extends Exception
{
/**
* Class constructor
*
* @param string $value Incorrect value
* @param string $datePart Type of date part, e.g. "year". One of \Meritoo\Common\Type\DatePartType class constants.
*/
public function __construct($value, $datePart)
{
$message = sprintf('Value of %s \'%s\' is incorrect. Is there everything ok?', $datePart, $value);
parent::__construct($message);
}
}

View File

@@ -1,29 +0,0 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Exception;
/**
* An exception used while given hexadecimal value of color is incorrect
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class InvalidColorHexValueException extends \Exception
{
/**
* Class constructor
*
* @param string $color Incorrect hexadecimal value of color
*/
public function __construct($color)
{
$message = sprintf('Hexadecimal value of color \'%s\' is incorrect. Is there everything ok?', $color);
parent::__construct($message);
}
}

View File

@@ -1,46 +0,0 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Utilities;
/**
* Useful methods for bundle
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Bundle
{
/**
* Returns path to view / template of given bundle
*
* @param string $viewPath Path of the view / template, e.g. "MyDirectory/my-template"
* @param string $bundleName Name of the bundle, e.g. "MyExtraBundle"
* @param string $extension (optional) Extension of the view / template
* @return string|null
*/
public static function getBundleViewPath($viewPath, $bundleName, $extension = 'html.twig')
{
/*
* Unknown path, extension of the view / template or name of the bundle?
* Nothing to do
*/
if (empty($viewPath) || empty($bundleName) || empty($extension)) {
return null;
}
/*
* Path of the view / template doesn't end with given extension?
*/
if (!Regex::endsWith($viewPath, $extension)) {
$viewPath = sprintf('%s.%s', $viewPath, $extension);
}
return sprintf('%s:%s', $bundleName, $viewPath);
}
}

View File

@@ -1,816 +0,0 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Utilities;
/**
* Useful methods for mime types of files
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class MimeTypes
{
/**
* Mime types data
*
* @var array
*/
private static $mimeTypes = [
'7z' => 'application/x-7z-compressed',
'ez' => 'application/andrew-inset',
'atom' => 'application/atom+xml',
'atomcat' => 'application/atomcat+xml',
'atomsvc' => 'application/atomsvc+xml',
'ccxml' => 'application/ccxml+xml',
'davmount' => 'application/davmount+xml',
'ecma' => 'application/ecmascript',
'pfr' => 'application/font-tdpfr',
'stk' => 'application/hyperstudio',
'js' => 'application/javascript',
'json' => 'application/json',
'hqx' => 'application/mac-binhex40',
'cpt' => 'application/mac-compactpro',
'mrc' => 'application/marc',
'ma' => 'application/mathematica',
'nb' => 'application/mathematica',
'mb' => 'application/mathematica',
'mathml' => 'application/mathml+xml',
'mbox' => 'application/mbox',
'mscml' => 'application/mediaservercontrol+xml',
'mp4s' => 'application/mp4',
'dot' => 'application/msword',
'doc' => 'application/msword',
/*
* MS Office system file format MIME types
* http://technet.microsoft.com/en-us/library/ee309278%28office.12%29.aspx
*/
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'mxf' => 'application/mxf',
'bin' => 'application/octet-stream',
'dms' => 'application/octet-stream',
'lha' => 'application/octet-stream',
'lzh' => 'application/octet-stream',
'class' => 'application/octet-stream',
'so' => 'application/octet-stream',
'iso' => 'application/octet-stream',
'dmg' => 'application/octet-stream',
'dist' => 'application/octet-stream',
'distz' => 'application/octet-stream',
'pkg' => 'application/octet-stream',
'bpk' => 'application/octet-stream',
'dump' => 'application/octet-stream',
'elc' => 'application/octet-stream',
'scpt' => 'application/octet-stream',
'oda' => 'application/oda',
'ogg' => 'application/ogg',
'pdf' => 'application/pdf',
'pgp' => 'application/pgp-encrypted',
'asc' => 'application/pgp-signature',
'sig' => 'application/pgp-signature',
'prf' => 'application/pics-rules',
'p10' => 'application/pkcs10',
'p7m' => 'application/pkcs7-mime',
'p7c' => 'application/pkcs7-mime',
'p7s' => 'application/pkcs7-signature',
'cer' => 'application/pkix-cert',
'crl' => 'application/pkix-crl',
'pkipath' => 'application/pkix-pkipath',
'pki' => 'application/pkixcmp',
'pls' => 'application/pls+xml',
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
'cww' => 'application/prs.cww',
'rdf' => 'application/rdf+xml',
'rif' => 'application/reginfo+xml',
'rnc' => 'application/relax-ng-compact-syntax',
'rl' => 'application/resource-lists+xml',
'rs' => 'application/rls-services+xml',
'rsd' => 'application/rsd+xml',
'rss' => 'application/rss+xml',
'rtf' => 'application/rtf',
'sbml' => 'application/sbml+xml',
'sdp' => 'application/sdp',
'setpay' => 'application/set-payment-initiation',
'setreg' => 'application/set-registration-initiation',
'shf' => 'application/shf+xml',
'smi' => 'application/smil+xml',
'smil' => 'application/smil+xml',
'gram' => 'application/srgs',
'grxml' => 'application/srgs+xml',
'ssml' => 'application/ssml+xml',
'plb' => 'application/vnd.3gpp.pic-bw-large',
'psb' => 'application/vnd.3gpp.pic-bw-small',
'pvb' => 'application/vnd.3gpp.pic-bw-var',
'pwn' => 'application/vnd.3m.post-it-notes',
'aso' => 'application/vnd.accpac.simply.aso',
'imp' => 'application/vnd.accpac.simply.imp',
'acu' => 'application/vnd.acucobol',
'atc' => 'application/vnd.acucorp',
'acutc' => 'application/vnd.acucorp',
'xdp' => 'application/vnd.adobe.xdp+xml',
'xfdf' => 'application/vnd.adobe.xfdf',
'ami' => 'application/vnd.amiga.ami',
'cii' => 'application/vnd.anser-web-certificate-issue-initiation',
'fti' => 'application/vnd.anser-web-funds-transfer-initiation',
'atx' => 'application/vnd.antix.game-component',
'mpkg' => 'application/vnd.apple.installer+xml',
'aep' => 'application/vnd.audiograph',
'mpm' => 'application/vnd.blueice.multipass',
'bmi' => 'application/vnd.bmi',
'rep' => 'application/vnd.businessobjects',
'cdxml' => 'application/vnd.chemdraw+xml',
'mmd' => 'application/vnd.chipnuts.karaoke-mmd',
'cdy' => 'application/vnd.cinderella',
'cla' => 'application/vnd.claymore',
'c4g' => 'application/vnd.clonk.c4group',
'c4d' => 'application/vnd.clonk.c4group',
'c4f' => 'application/vnd.clonk.c4group',
'c4p' => 'application/vnd.clonk.c4group',
'c4u' => 'application/vnd.clonk.c4group',
'csp' => 'application/vnd.commonspace',
'cst' => 'application/vnd.commonspace',
'cdbcmsg' => 'application/vnd.contact.cmsg',
'cmc' => 'application/vnd.cosmocaller',
'clkx' => 'application/vnd.crick.clicker',
'clkk' => 'application/vnd.crick.clicker.keyboard',
'clkp' => 'application/vnd.crick.clicker.palette',
'clkt' => 'application/vnd.crick.clicker.template',
'clkw' => 'application/vnd.crick.clicker.wordbank',
'wbs' => 'application/vnd.criticaltools.wbs+xml',
'pml' => 'application/vnd.ctc-posml',
'ppd' => 'application/vnd.cups-ppd',
'curl' => 'application/vnd.curl',
'rdz' => 'application/vnd.data-vision.rdz',
'dna' => 'application/vnd.dna',
'mlp' => 'application/vnd.dolby.mlp',
'dpg' => 'application/vnd.dpgraph',
'dfac' => 'application/vnd.dreamfactory',
'mag' => 'application/vnd.ecowin.chart',
'nml' => 'application/vnd.enliven',
'esf' => 'application/vnd.epson.esf',
'msf' => 'application/vnd.epson.msf',
'qam' => 'application/vnd.epson.quickanime',
'slt' => 'application/vnd.epson.salt',
'ssf' => 'application/vnd.epson.ssf',
'es3' => 'application/vnd.eszigno3+xml',
'et3' => 'application/vnd.eszigno3+xml',
'ez2' => 'application/vnd.ezpix-album',
'ez3' => 'application/vnd.ezpix-package',
'fdf' => 'application/vnd.fdf',
'gph' => 'application/vnd.flographit',
'ftc' => 'application/vnd.fluxtime.clip',
'fm' => 'application/vnd.framemaker',
'frame' => 'application/vnd.framemaker',
'maker' => 'application/vnd.framemaker',
'fnc' => 'application/vnd.frogans.fnc',
'ltf' => 'application/vnd.frogans.ltf',
'fsc' => 'application/vnd.fsc.weblaunch',
'oas' => 'application/vnd.fujitsu.oasys',
'oa2' => 'application/vnd.fujitsu.oasys2',
'oa3' => 'application/vnd.fujitsu.oasys3',
'fg5' => 'application/vnd.fujitsu.oasysgp',
'bh2' => 'application/vnd.fujitsu.oasysprs',
'ddd' => 'application/vnd.fujixerox.ddd',
'xdw' => 'application/vnd.fujixerox.docuworks',
'xbd' => 'application/vnd.fujixerox.docuworks.binder',
'fzs' => 'application/vnd.fuzzysheet',
'txd' => 'application/vnd.genomatix.tuxedo',
'kml' => 'application/vnd.google-earth.kml+xml',
'kmz' => 'application/vnd.google-earth.kmz',
'gqf' => 'application/vnd.grafeq',
'gqs' => 'application/vnd.grafeq',
'gac' => 'application/vnd.groove-account',
'ghf' => 'application/vnd.groove-help',
'gim' => 'application/vnd.groove-identity-message',
'grv' => 'application/vnd.groove-injector',
'gtm' => 'application/vnd.groove-tool-message',
'tpl' => 'application/vnd.groove-tool-template',
'vcg' => 'application/vnd.groove-vcard',
'zmm' => 'application/vnd.handheld-entertainment+xml',
'hbci' => 'application/vnd.hbci',
'les' => 'application/vnd.hhe.lesson-player',
'hpgl' => 'application/vnd.hp-hpgl',
'hpid' => 'application/vnd.hp-hpid',
'hps' => 'application/vnd.hp-hps',
'jlt' => 'application/vnd.hp-jlyt',
'pcl' => 'application/vnd.hp-pcl',
'pclxl' => 'application/vnd.hp-pclxl',
'x3d' => 'application/vnd.hzn-3d-crossword',
'mpy' => 'application/vnd.ibm.minipay',
'afp' => 'application/vnd.ibm.modcap',
'listafp' => 'application/vnd.ibm.modcap',
'list3820' => 'application/vnd.ibm.modcap',
'irm' => 'application/vnd.ibm.rights-management',
'sc' => 'application/vnd.ibm.secure-container',
'igl' => 'application/vnd.igloader',
'ivp' => 'application/vnd.immervision-ivp',
'ivu' => 'application/vnd.immervision-ivu',
'xpw' => 'application/vnd.intercon.formnet',
'xpx' => 'application/vnd.intercon.formnet',
'qbo' => 'application/vnd.intu.qbo',
'qfx' => 'application/vnd.intu.qfx',
'rcprofile' => 'application/vnd.ipunplugged.rcprofile',
'irp' => 'application/vnd.irepository.package+xml',
'xpr' => 'application/vnd.is-xpr',
'jam' => 'application/vnd.jam',
'rms' => 'application/vnd.jcp.javame.midlet-rms',
'jisp' => 'application/vnd.jisp',
'ktz' => 'application/vnd.kahootz',
'ktr' => 'application/vnd.kahootz',
'karbon' => 'application/vnd.kde.karbon',
'chrt' => 'application/vnd.kde.kchart',
'kfo' => 'application/vnd.kde.kformula',
'flw' => 'application/vnd.kde.kivio',
'kon' => 'application/vnd.kde.kontour',
'kpr' => 'application/vnd.kde.kpresenter',
'kpt' => 'application/vnd.kde.kpresenter',
'ksp' => 'application/vnd.kde.kspread',
'kwd' => 'application/vnd.kde.kword',
'kwt' => 'application/vnd.kde.kword',
'htke' => 'application/vnd.kenameaapp',
'kia' => 'application/vnd.kidspiration',
'kne' => 'application/vnd.kinar',
'knp' => 'application/vnd.kinar',
'skp' => 'application/vnd.koan',
'skd' => 'application/vnd.koan',
'skt' => 'application/vnd.koan',
'skm' => 'application/vnd.koan',
'lbd' => 'application/vnd.llamagraphics.life-balance.desktop',
'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml',
'123' => 'application/vnd.lotus-1-2-3',
'apr' => 'application/vnd.lotus-approach',
'pre' => 'application/vnd.lotus-freelance',
'nsf' => 'application/vnd.lotus-notes',
'org' => 'application/vnd.lotus-organizer',
'scm' => 'application/vnd.lotus-screencam',
'lwp' => 'application/vnd.lotus-wordpro',
'portpkg' => 'application/vnd.macports.portpkg',
'mcd' => 'application/vnd.mcd',
'mc1' => 'application/vnd.medcalcdata',
'cdkey' => 'application/vnd.mediastation.cdkey',
'mwf' => 'application/vnd.mfer',
'mfm' => 'application/vnd.mfmp',
'flo' => 'application/vnd.micrografx.flo',
'igx' => 'application/vnd.micrografx.igx',
'mif' => 'application/vnd.mif',
'daf' => 'application/vnd.mobius.daf',
'dis' => 'application/vnd.mobius.dis',
'mbk' => 'application/vnd.mobius.mbk',
'mqy' => 'application/vnd.mobius.mqy',
'msl' => 'application/vnd.mobius.msl',
'plc' => 'application/vnd.mobius.plc',
'txf' => 'application/vnd.mobius.txf',
'mpn' => 'application/vnd.mophun.application',
'mpc' => 'application/vnd.mophun.certificate',
'xul' => 'application/vnd.mozilla.xul+xml',
'cil' => 'application/vnd.ms-artgalry',
'asf' => 'application/vnd.ms-asf',
'cab' => 'application/vnd.ms-cab-compressed',
'xls' => 'application/vnd.ms-excel',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xlm' => 'application/vnd.ms-excel',
'xla' => 'application/vnd.ms-excel',
'xlc' => 'application/vnd.ms-excel',
'xlt' => 'application/vnd.ms-excel',
'xlw' => 'application/vnd.ms-excel',
'eot' => 'application/vnd.ms-fontobject',
'chm' => 'application/vnd.ms-htmlhelp',
'ims' => 'application/vnd.ms-ims',
'lrm' => 'application/vnd.ms-lrm',
'ppt' => 'application/vnd.ms-powerpoint',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'pps' => 'application/vnd.ms-powerpoint',
'pot' => 'application/vnd.ms-powerpoint',
'mpp' => 'application/vnd.ms-project',
'mpt' => 'application/vnd.ms-project',
'wps' => 'application/vnd.ms-works',
'wks' => 'application/vnd.ms-works',
'wcm' => 'application/vnd.ms-works',
'wdb' => 'application/vnd.ms-works',
'wpl' => 'application/vnd.ms-wpl',
'xps' => 'application/vnd.ms-xpsdocument',
'mseq' => 'application/vnd.mseq',
'mus' => 'application/vnd.musician',
'nlu' => 'application/vnd.neurolanguage.nlu',
'nnd' => 'application/vnd.noblenet-directory',
'nns' => 'application/vnd.noblenet-sealer',
'nnw' => 'application/vnd.noblenet-web',
'ngdat' => 'application/vnd.nokia.n-gage.data',
'n-gage' => 'application/vnd.nokia.n-gage.symbian.install',
'rpst' => 'application/vnd.nokia.radio-preset',
'rpss' => 'application/vnd.nokia.radio-presets',
'edm' => 'application/vnd.novadigm.edm',
'edx' => 'application/vnd.novadigm.edx',
'ext' => 'application/vnd.novadigm.ext',
'odc' => 'application/vnd.oasis.opendocument.chart',
'otc' => 'application/vnd.oasis.opendocument.chart-template',
'odf' => 'application/vnd.oasis.opendocument.formula',
'otf' => 'application/vnd.oasis.opendocument.formula-template',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'otg' => 'application/vnd.oasis.opendocument.graphics-template',
'odi' => 'application/vnd.oasis.opendocument.image',
'oti' => 'application/vnd.oasis.opendocument.image-template',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'otp' => 'application/vnd.oasis.opendocument.presentation-template',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
'odt' => 'application/vnd.oasis.opendocument.text',
'otm' => 'application/vnd.oasis.opendocument.text-master',
'ott' => 'application/vnd.oasis.opendocument.text-template',
'oth' => 'application/vnd.oasis.opendocument.text-web',
'xo' => 'application/vnd.olpc-sugar',
'dd2' => 'application/vnd.oma.dd2+xml',
'oxt' => 'application/vnd.openofficeorg.extension',
'dp' => 'application/vnd.osgi.dp',
'prc' => 'application/vnd.palm',
'pdb' => 'application/vnd.palm',
'pqa' => 'application/vnd.palm',
'oprc' => 'application/vnd.palm',
'str' => 'application/vnd.pg.format',
'ei6' => 'application/vnd.pg.osasli',
'efif' => 'application/vnd.picsel',
'plf' => 'application/vnd.pocketlearn',
'pbd' => 'application/vnd.powerbuilder6',
'box' => 'application/vnd.previewsystems.box',
'mgz' => 'application/vnd.proteus.magazine',
'qps' => 'application/vnd.publishare-delta-tree',
'ptid' => 'application/vnd.pvi.ptid1',
'qxd' => 'application/vnd.quark.quarkxpress',
'qxt' => 'application/vnd.quark.quarkxpress',
'qwd' => 'application/vnd.quark.quarkxpress',
'qwt' => 'application/vnd.quark.quarkxpress',
'qxl' => 'application/vnd.quark.quarkxpress',
'qxb' => 'application/vnd.quark.quarkxpress',
'mxl' => 'application/vnd.recordare.musicxml',
'rm' => 'application/vnd.rn-realmedia',
'see' => 'application/vnd.seemail',
'sema' => 'application/vnd.sema',
'semd' => 'application/vnd.semd',
'semf' => 'application/vnd.semf',
'ifm' => 'application/vnd.shana.informed.formdata',
'itp' => 'application/vnd.shana.informed.formtemplate',
'iif' => 'application/vnd.shana.informed.interchange',
'ipk' => 'application/vnd.shana.informed.package',
'twd' => 'application/vnd.simtech-mindmapper',
'twds' => 'application/vnd.simtech-mindmapper',
'mmf' => 'application/vnd.smaf',
'sdkm' => 'application/vnd.solent.sdkm+xml',
'sdkd' => 'application/vnd.solent.sdkm+xml',
'dxp' => 'application/vnd.spotfire.dxp',
'sfs' => 'application/vnd.spotfire.sfs',
'sus' => 'application/vnd.sus-calendar',
'susp' => 'application/vnd.sus-calendar',
'svd' => 'application/vnd.svd',
'xsm' => 'application/vnd.syncml+xml',
'bdm' => 'application/vnd.syncml.dm+wbxml',
'xdm' => 'application/vnd.syncml.dm+xml',
'tao' => 'application/vnd.tao.intent-module-archive',
'tmo' => 'application/vnd.tmobile-livetv',
'tpt' => 'application/vnd.trid.tpt',
'mxs' => 'application/vnd.triscape.mxs',
'tra' => 'application/vnd.trueapp',
'ufd' => 'application/vnd.ufdl',
'ufdl' => 'application/vnd.ufdl',
'utz' => 'application/vnd.uiq.theme',
'umj' => 'application/vnd.umajin',
'unityweb' => 'application/vnd.unity',
'uoml' => 'application/vnd.uoml+xml',
'vcx' => 'application/vnd.vcx',
'vsd' => 'application/vnd.visio',
'vst' => 'application/vnd.visio',
'vss' => 'application/vnd.visio',
'vsw' => 'application/vnd.visio',
'vis' => 'application/vnd.visionary',
'vsf' => 'application/vnd.vsf',
'wbxml' => 'application/vnd.wap.wbxml',
'wmlc' => 'application/vnd.wap.wmlc',
'wmlsc' => 'application/vnd.wap.wmlscriptc',
'wtb' => 'application/vnd.webturbo',
'wpd' => 'application/vnd.wordperfect',
'wqd' => 'application/vnd.wqd',
'stf' => 'application/vnd.wt.stf',
'xar' => 'application/vnd.xara',
'xfdl' => 'application/vnd.xfdl',
'hvd' => 'application/vnd.yamaha.hv-dic',
'hvs' => 'application/vnd.yamaha.hv-script',
'hvp' => 'application/vnd.yamaha.hv-voice',
'saf' => 'application/vnd.yamaha.smaf-audio',
'spf' => 'application/vnd.yamaha.smaf-phrase',
'cmp' => 'application/vnd.yellowriver-custom-menu',
'zaz' => 'application/vnd.zzazz.deck+xml',
'vxml' => 'application/voicexml+xml',
'hlp' => 'application/winhlp',
'wsdl' => 'application/wsdl+xml',
'wspolicy' => 'application/wspolicy+xml',
'ace' => 'application/x-ace-compressed',
'bcpio' => 'application/x-bcpio',
'torrent' => 'application/x-bittorrent',
'bz' => 'application/x-bzip',
'bz2' => 'application/x-bzip2',
'boz' => 'application/x-bzip2',
'vcd' => 'application/x-cdlink',
'chat' => 'application/x-chat',
'pgn' => 'application/x-chess-pgn',
'cpio' => 'application/x-cpio',
'csh' => 'application/x-csh',
'dcr' => 'application/x-director',
'dir' => 'application/x-director',
'dxr' => 'application/x-director',
'fgd' => 'application/x-director',
'dvi' => 'application/x-dvi',
'spl' => 'application/x-futuresplash',
'gtar' => 'application/x-gtar',
'hdf' => 'application/x-hdf',
'jnlp' => 'application/x-java-jnlp-file',
'latex' => 'application/x-latex',
'wmd' => 'application/x-ms-wmd',
'wmz' => 'application/x-ms-wmz',
'mdb' => 'application/x-msaccess',
'obd' => 'application/x-msbinder',
'crd' => 'application/x-mscardfile',
'clp' => 'application/x-msclip',
'exe' => 'application/x-msdownload',
'dll' => 'application/x-msdownload',
'com' => 'application/x-msdownload',
'bat' => 'application/x-msdownload',
'msi' => 'application/x-msdownload',
'mvb' => 'application/x-msmediaview',
'm13' => 'application/x-msmediaview',
'm14' => 'application/x-msmediaview',
'wmf' => 'application/x-msmetafile',
'mny' => 'application/x-msmoney',
'pub' => 'application/x-mspublisher',
'scd' => 'application/x-msschedule',
'trm' => 'application/x-msterminal',
'wri' => 'application/x-mswrite',
'nc' => 'application/x-netcdf',
'cdf' => 'application/x-netcdf',
'p12' => 'application/x-pkcs12',
'pfx' => 'application/x-pkcs12',
'p7b' => 'application/x-pkcs7-certificates',
'spc' => 'application/x-pkcs7-certificates',
'p7r' => 'application/x-pkcs7-certreqresp',
'rar' => 'application/x-rar-compressed',
'sh' => 'application/x-sh',
'shar' => 'application/x-shar',
'swf' => 'application/x-shockwave-flash',
'sit' => 'application/x-stuffit',
'sitx' => 'application/x-stuffitx',
'sv4cpio' => 'application/x-sv4cpio',
'sv4crc' => 'application/x-sv4crc',
'tar' => 'application/x-tar',
'tcl' => 'application/x-tcl',
'tex' => 'application/x-tex',
'texinfo' => 'application/x-texinfo',
'texi' => 'application/x-texinfo',
'ustar' => 'application/x-ustar',
'src' => 'application/x-wais-source',
'der' => 'application/x-x509-ca-cert',
'crt' => 'application/x-x509-ca-cert',
'xenc' => 'application/xenc+xml',
'xhtml' => 'application/xhtml+xml',
'xht' => 'application/xhtml+xml',
'xml' => 'application/xml',
'xsl' => 'application/xml',
'dtd' => 'application/xml-dtd',
'xop' => 'application/xop+xml',
'xslt' => 'application/xslt+xml',
'xspf' => 'application/xspf+xml',
'mxml' => 'application/xv+xml',
'xhvml' => 'application/xv+xml',
'xvml' => 'application/xv+xml',
'xvm' => 'application/xv+xml',
'zip' => 'application/zip',
'au' => 'audio/basic',
'snd' => 'audio/basic',
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'kar' => 'audio/midi',
'rmi' => 'audio/midi',
'mp4a' => 'audio/mp4',
'm4a' => 'audio/mp4a-latm',
'm4p' => 'audio/mp4a-latm',
'mpga' => 'audio/mpeg',
'mp2' => 'audio/mpeg',
'mp2a' => 'audio/mpeg',
'mp3' => 'audio/mpeg',
'm2a' => 'audio/mpeg',
'm3a' => 'audio/mpeg',
'eol' => 'audio/vnd.digital-winds',
'lvp' => 'audio/vnd.lucent.voice',
'ecelp4800' => 'audio/vnd.nuera.ecelp4800',
'ecelp7470' => 'audio/vnd.nuera.ecelp7470',
'ecelp9600' => 'audio/vnd.nuera.ecelp9600',
'wav' => 'audio/wav',
'aif' => 'audio/x-aiff',
'aiff' => 'audio/x-aiff',
'aifc' => 'audio/x-aiff',
'm3u' => 'audio/x-mpegurl',
'wax' => 'audio/x-ms-wax',
'wma' => 'audio/x-ms-wma',
'ram' => 'audio/x-pn-realaudio',
'ra' => 'audio/x-pn-realaudio',
'rmp' => 'audio/x-pn-realaudio-plugin',
'cdx' => 'chemical/x-cdx',
'cif' => 'chemical/x-cif',
'cmdf' => 'chemical/x-cmdf',
'cml' => 'chemical/x-cml',
'csml' => 'chemical/x-csml',
'xyz' => 'chemical/x-xyz',
'bmp' => 'image/bmp',
'cgm' => 'image/cgm',
'g3' => 'image/g3fax',
'gif' => 'image/gif',
'ief' => 'image/ief',
'jp2' => 'image/jp2',
'jpeg' => 'image/jpeg',
'jpe' => 'image/jpeg',
'jpg' => 'image/jpeg',
'pict' => 'image/pict',
'pic' => 'image/pict',
'pct' => 'image/pict',
'png' => 'image/png',
'btif' => 'image/prs.btif',
'svg' => 'image/svg+xml',
'svgz' => 'image/svg+xml',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'psd' => 'image/vnd.adobe.photoshop',
'djvu' => 'image/vnd.djvu',
'djv' => 'image/vnd.djvu',
'dwg' => 'image/vnd.dwg',
'dxf' => 'image/vnd.dxf',
'fbs' => 'image/vnd.fastbidsheet',
'fpx' => 'image/vnd.fpx',
'fst' => 'image/vnd.fst',
'mmr' => 'image/vnd.fujixerox.edmics-mmr',
'rlc' => 'image/vnd.fujixerox.edmics-rlc',
'ico' => 'image/vnd.microsoft.icon',
'mdi' => 'image/vnd.ms-modi',
'npx' => 'image/vnd.net-fpx',
'wbmp' => 'image/vnd.wap.wbmp',
'xif' => 'image/vnd.xiff',
'ras' => 'image/x-cmu-raster',
'cmx' => 'image/x-cmx',
'pntg' => 'image/x-macpaint',
'pnt' => 'image/x-macpaint',
'mac' => 'image/x-macpaint',
'pcx' => 'image/x-pcx',
'pnm' => 'image/x-portable-anymap',
'pbm' => 'image/x-portable-bitmap',
'pgm' => 'image/x-portable-graymap',
'ppm' => 'image/x-portable-pixmap',
'qtif' => 'image/x-quicktime',
'qti' => 'image/x-quicktime',
'rgb' => 'image/x-rgb',
'xbm' => 'image/x-xbitmap',
'xpm' => 'image/x-xpixmap',
'xwd' => 'image/x-xwindowdump',
'eml' => 'message/rfc822',
'mime' => 'message/rfc822',
'igs' => 'model/iges',
'iges' => 'model/iges',
'msh' => 'model/mesh',
'mesh' => 'model/mesh',
'silo' => 'model/mesh',
'dwf' => 'model/vnd.dwf',
'gdl' => 'model/vnd.gdl',
'gtw' => 'model/vnd.gtw',
'mts' => 'model/vnd.mts',
'vtu' => 'model/vnd.vtu',
'wrl' => 'model/vrml',
'vrml' => 'model/vrml',
'ics' => 'text/calendar',
'ifb' => 'text/calendar',
'css' => 'text/css',
'csv' => 'text/csv',
'html' => 'text/html',
'htm' => 'text/html',
'txt' => 'text/plain',
'text' => 'text/plain',
'conf' => 'text/plain',
'def' => 'text/plain',
'list' => 'text/plain',
'log' => 'text/plain',
'in' => 'text/plain',
'dsc' => 'text/prs.lines.tag',
'rtx' => 'text/richtext',
'sgml' => 'text/sgml',
'sgm' => 'text/sgml',
'tsv' => 'text/tab-separated-values',
't' => 'text/troff',
'tr' => 'text/troff',
'roff' => 'text/troff',
'man' => 'text/troff',
'me' => 'text/troff',
'ms' => 'text/troff',
'uri' => 'text/uri-list',
'uris' => 'text/uri-list',
'urls' => 'text/uri-list',
'fly' => 'text/vnd.fly',
'flx' => 'text/vnd.fmi.flexstor',
'3dml' => 'text/vnd.in3d.3dml',
'spot' => 'text/vnd.in3d.spot',
'jad' => 'text/vnd.sun.j2me.app-descriptor',
'wml' => 'text/vnd.wap.wml',
'wmls' => 'text/vnd.wap.wmlscript',
's' => 'text/x-asm',
'asm' => 'text/x-asm',
'c' => 'text/x-c',
'cc' => 'text/x-c',
'cxx' => 'text/x-c',
'cpp' => 'text/x-c',
'h' => 'text/x-c',
'hh' => 'text/x-c',
'dic' => 'text/x-c',
'f' => 'text/x-fortran',
'for' => 'text/x-fortran',
'f77' => 'text/x-fortran',
'f90' => 'text/x-fortran',
'p' => 'text/x-pascal',
'pas' => 'text/x-pascal',
'java' => 'text/x-java-source',
'etx' => 'text/x-setext',
'uu' => 'text/x-uuencode',
'vcs' => 'text/x-vcalendar',
'vcf' => 'text/x-vcard',
'3gp' => 'video/3gpp',
'3g2' => 'video/3gpp2',
'h261' => 'video/h261',
'h263' => 'video/h263',
'h264' => 'video/h264',
'jpgv' => 'video/jpeg',
'jpm' => 'video/jpm',
'jpgm' => 'video/jpm',
'mj2' => 'video/mj2',
'mjp2' => 'video/mj2',
'mp4' => 'video/mp4',
'mp4v' => 'video/mp4',
'mpg4' => 'video/mp4',
'm4v' => 'video/mp4',
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpe' => 'video/mpeg',
'm1v' => 'video/mpeg',
'm2v' => 'video/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
'fvt' => 'video/vnd.fvt',
'mxu' => 'video/vnd.mpegurl',
'm4u' => 'video/vnd.mpegurl',
'viv' => 'video/vnd.vivo',
'dv' => 'video/x-dv',
'dif' => 'video/x-dv',
'fli' => 'video/x-fli',
'asx' => 'video/x-ms-asf',
'wm' => 'video/x-ms-wm',
'wmv' => 'video/x-ms-wmv',
'wmx' => 'video/x-ms-wmx',
'wvx' => 'video/x-ms-wvx',
'avi' => 'video/x-msvideo',
'movie' => 'video/x-sgi-movie',
'ice' => 'x-conference/x-cooltalk',
];
/**
* Returns extensions for given mimes types
*
* @param array $mimesTypes The mimes types, e.g. ['video/mpeg', 'image/jpeg']
* @param bool $asUpperCase (optional) If is set to true, extensions are returned as upper case. Otherwise - lower
* case.
* @return array
*/
public static function getExtensions(array $mimesTypes, $asUpperCase = false)
{
if (empty($mimesTypes)) {
return [];
}
$extensions = [];
foreach ($mimesTypes as $mimeType) {
$extension = self::getExtension($mimeType);
/*
* No extension for given mime type?
* Nothing to do
*/
if (empty($extension)) {
continue;
}
/*
* Extensions should be returned as upper case?
*/
if ($asUpperCase) {
if (is_array($extension)) {
array_walk($extension, function (&$value) {
$value = strtoupper($value);
});
} else {
$extension = strtoupper($extension);
}
}
$extensions[$mimeType] = $extension;
}
return $extensions;
}
/**
* Returns extension for given mime type
*
* @param string $mimeType The mime type, e.g. "video/mpeg"
* @return string|array
*/
public static function getExtension($mimeType)
{
if (is_string($mimeType) && in_array($mimeType, self::$mimeTypes)) {
$data = Arrays::setKeysAsValues(self::$mimeTypes, false);
return $data[$mimeType];
}
return '';
}
/**
* Returns information whether file with the given path is an image
*
* @param string $path Path of the file to check
* @return bool
*/
public static function isImagePath($path)
{
$mimeType = self::getMimeType($path);
return self::isImage($mimeType);
}
/**
* Returns mime type of given file
*
* @param string $filePath Path of the file to check
* @return string
*
* @throws \RuntimeException
*/
public static function getMimeType($filePath)
{
/*
* The file does not exist?
* Nothing to do
*/
if (!is_string($filePath) || !is_readable($filePath)) {
return '';
}
/*
* 1st possibility: the finfo class
*/
if (class_exists('finfo')) {
$finfo = new \finfo();
return $finfo->file($filePath, FILEINFO_MIME_TYPE);
}
/*
* 2nd possibility: the mime_content_type function
*/
if (function_exists('mime_content_type')) {
return mime_content_type($filePath);
}
/*
* Oops, there is no possibility to read the mime type
*/
$template = 'Neither \'finfo\' class nor \'mime_content_type\' function exists. There is no way to read the'
. ' mime type of file \'%s\'.';
$message = sprintf($template, $filePath);
throw new \RuntimeException($message);
}
/**
* Returns information whether the given file type is an image
*
* @param string $mimeType The mime type of file
* @return bool
*/
public static function isImage($mimeType)
{
if (in_array($mimeType, self::$mimeTypes)) {
return (bool)preg_match('|^image/.+$|', $mimeType);
}
return false;
}
}

View File

@@ -1,633 +0,0 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Utilities;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\Common\Util\Inflector;
use Meritoo\Common\Exception\Reflection\CannotResolveClassNameException;
use Meritoo\Common\Exception\Reflection\MissingChildClassesException;
use Meritoo\Common\Exception\Reflection\TooManyChildClassesException;
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
use ReflectionObject;
use ReflectionProperty;
/**
* Useful reflection methods
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Reflection
{
/**
* Returns names of methods for given class / object
*
* @param object|string $class The object or name of object's class
* @param bool $withoutInheritance (optional) If is set to true, only methods for given class are returned.
* Otherwise - all methods, with inherited methods too.
* @return array
*/
public static function getMethods($class, $withoutInheritance = false)
{
$effect = [];
$reflection = new ReflectionClass($class);
$methods = $reflection->getMethods();
if (!empty($methods)) {
$className = self::getClassName($class);
foreach ($methods as $method) {
if ($method instanceof ReflectionMethod) {
if ($withoutInheritance && $className !== $method->class) {
continue;
}
$effect[] = $method->name;
}
}
}
return $effect;
}
/**
* Returns constants of given class / object
*
* @param object|string $class The object or name of object's class
* @return array
*/
public static function getConstants($class)
{
$reflection = new ReflectionClass($class);
return $reflection->getConstants();
}
/**
* Returns maximum constant from all constants of given class / object.
* Values of constants should be integers.
*
* @param object|string $class The object or name of object's class
* @return int|null
*/
public static function getMaxNumberConstant($class)
{
$constants = self::getConstants($class);
if (empty($constants)) {
return null;
}
$maxNumber = 0;
foreach ($constants as $constant) {
if (is_numeric($constant) && $constant > $maxNumber) {
$maxNumber = $constant;
}
}
return $maxNumber;
}
/**
* Returns information if given class / object has given method
*
* @param object|string $class The object or name of object's class
* @param string $method Name of the method to find
* @return bool
*/
public static function hasMethod($class, $method)
{
$reflection = new ReflectionClass($class);
return $reflection->hasMethod($method);
}
/**
* Returns information if given class / object has given property
*
* @param object|string $class The object or name of object's class
* @param string $property Name of the property to find
* @return bool
*/
public static function hasProperty($class, $property)
{
$reflection = new ReflectionClass($class);
return $reflection->hasProperty($property);
}
/**
* Returns information if given class / object has given constant
*
* @param object|string $class The object or name of object's class
* @param string $constant Name of the constant to find
* @return bool
*/
public static function hasConstant($class, $constant)
{
$reflection = new ReflectionClass($class);
return $reflection->hasConstant($constant);
}
/**
* Returns value of given constant
*
* @param object|string $class The object or name of object's class
* @param string $constant Name of the constant that contains a value
* @return mixed
*/
public static function getConstantValue($class, $constant)
{
$reflection = new ReflectionClass($class);
if (self::hasConstant($class, $constant)) {
return $reflection->getConstant($constant);
}
return null;
}
/**
* Returns value of given property.
* Looks for proper getter for the property.
*
* @param mixed $object Object that should contains given property
* @param string $property Name of the property that contains a value. It may be also multiple properties
* dot-separated, e.g. "invoice.user.email".
* @param bool $force (optional) If is set to true, try to retrieve value even if the object doesn't have
* property. Otherwise - not.
* @return mixed
*/
public static function getPropertyValue($object, $property, $force = false)
{
$value = null;
/*
* Property is a dot-separated string?
* Let's find all values of the chain, of the dot-separated properties
*/
if (Regex::contains($property, '.')) {
$exploded = explode('.', $property);
$property = $exploded[0];
$object = self::getPropertyValue($object, $property, $force);
/*
* Value of processed property from the chain is not null?
* Let's dig more and get proper value
*
* Required to avoid bug:
* ReflectionObject::__construct() expects parameter 1 to be object, null given
* (...)
* 4. at ReflectionObject->__construct (null)
* 5. at Reflection ::getPropertyValue (null, 'name', true)
* 6. at ListService->getItemValue (object(Deal), 'project.name', '0')
*
* while using "project.name" as property - $project has $name property ($project exists in the Deal class)
* and the $project equals null
*
* Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* 2016-11-07
*/
if ($object !== null) {
unset($exploded[0]);
$property = implode('.', $exploded);
$value = self::getPropertyValue($object, $property, $force);
}
} else {
$className = self::getClassName($object);
$reflectionProperty = null;
/*
* 1st try:
* Use \ReflectionObject class
*/
try {
$reflectionProperty = new ReflectionProperty($className, $property);
$value = $reflectionProperty->getValue($object);
} catch (ReflectionException $exception) {
/*
* 2nd try:
* Look for the get / has / is methods
*/
$class = new ReflectionObject($object);
$valueFound = false;
if ($class->hasProperty($property) || $force) {
$property = Inflector::classify($property);
$methodPrefixes = [
'get',
'has',
'is',
];
foreach ($methodPrefixes as $prefix) {
$method = sprintf('%s%s', $prefix, $property);
if ($class->hasMethod($method)) {
$value = $object->{$method}();
$valueFound = true;
break;
}
}
}
if (!$valueFound && $reflectionProperty !== null) {
/*
* Oops, we have got exception.
*
* 3rd try:
* Let's try modify accessibility of the property and try again to get value.
*/
$reflectionProperty->setAccessible(true);
$value = $reflectionProperty->getValue($object);
}
}
}
return $value;
}
/**
* Returns values of given property for given objects.
* Looks for proper getter for the property.
*
* @param Collection|object|array $objects The objects that should contain given property. It may be also one
* object.
* @param string $property Name of the property that contains a value
* @param bool $force (optional) If is set to true, try to retrieve value even if the
* object does not have property. Otherwise - not.
* @return array
*/
public static function getPropertyValues($objects, $property, $force = false)
{
if ($objects instanceof Collection) {
$objects = $objects->toArray();
}
$values = [];
$objects = Arrays::makeArray($objects);
foreach ($objects as $entity) {
$value = self::getPropertyValue($entity, $property, $force);
if ($value !== null) {
$values[] = $value;
}
}
return $values;
}
/**
* Returns a class name for given source
*
* @param array|object|string $source An array of objects, namespaces, object or namespace
* @param bool $withoutNamespace (optional) If is set to true, namespace is omitted. Otherwise -
* not, full name of class is returned, with namespace.
* @return string|null
*/
public static function getClassName($source, $withoutNamespace = false)
{
/*
* First argument is not proper source of class?
* Nothing to do
*/
if (empty($source) || (!is_array($source) && !is_object($source) && !is_string($source))) {
return null;
}
$name = '';
/*
* An array of objects was provided?
* Let's use first of them
*/
if (is_array($source)) {
$source = Arrays::getFirstElement($source);
}
/*
* Let's prepare name of class
*/
if (is_object($source)) {
$name = get_class($source);
} elseif (is_string($source) && (class_exists($source) || trait_exists($source))) {
$name = $source;
}
/*
* Name of class is still unknown?
* Nothing to do
*/
if (empty($name)) {
return null;
}
/*
* Namespace is not required?
* Let's return name of class only
*/
if ($withoutNamespace) {
$classOnly = Miscellaneous::getLastElementOfString($name, '\\');
if ($classOnly !== null) {
$name = $classOnly;
}
return $name;
}
return ClassUtils::getRealClass($name);
}
/**
* Returns namespace of class for given source
*
* @param array|object|string $source An array of objects, namespaces, object or namespace
* @return string
*/
public static function getClassNamespace($source)
{
$fullClassName = self::getClassName($source);
if (empty($fullClassName)) {
return '';
}
$className = self::getClassName($source, true);
if ($className == $fullClassName) {
return $className;
}
return Miscellaneous::getStringWithoutLastElement($fullClassName, '\\');
}
/**
* Returns information if given interface is implemented by given class / object
*
* @param array|object|string $source An array of objects, namespaces, object or namespace
* @param string $interface The interface that should be implemented
* @return bool
*/
public static function isInterfaceImplemented($source, $interface)
{
$className = self::getClassName($source);
$interfaces = class_implements($className);
return in_array($interface, $interfaces);
}
/**
* Returns information if given child class is a subclass of given parent class
*
* @param array|object|string $childClass The child class. An array of objects, namespaces, object or namespace.
* @param array|object|string $parentClass The parent class. An array of objects, namespaces, object or namespace.
* @return bool
*/
public static function isChildOfClass($childClass, $parentClass)
{
$childClassName = self::getClassName($childClass);
$parentClassName = self::getClassName($parentClass);
$parents = class_parents($childClassName);
if (is_array($parents)) {
return in_array($parentClassName, $parents);
}
return false;
}
/**
* Returns given object properties
*
* @param array|object|string $source An array of objects, namespaces, object or namespace
* @param int $filter (optional) Filter of properties. Uses ReflectionProperty class constants.
* By default all properties are returned.
* @return array|ReflectionProperty
*/
public static function getProperties($source, $filter = null)
{
$className = self::getClassName($source);
$reflection = new ReflectionClass($className);
if ($filter === null) {
$filter = ReflectionProperty::IS_PRIVATE
+ ReflectionProperty::IS_PROTECTED
+ ReflectionProperty::IS_PUBLIC
+ ReflectionProperty::IS_STATIC;
}
return $reflection->getProperties($filter);
}
/**
* Returns a parent class
*
* @param array|object|string $source An array of objects, namespaces, object or namespace
* @return ReflectionClass
*/
public static function getParentClass($source)
{
$className = self::getClassName($source);
$reflection = new ReflectionClass($className);
return $reflection->getParentClass();
}
/**
* Returns child classes of given class.
* It's an array of namespaces of the child classes or null (if given class has not child classes).
*
* @param array|object|string $class Class who child classes should be returned. An array of objects, strings,
* object or string.
* @return array|null
* @throws CannotResolveClassNameException
*/
public static function getChildClasses($class)
{
$allClasses = get_declared_classes();
/*
* No classes?
* Nothing to do
*/
if (empty($allClasses)) {
return null;
}
$className = self::getClassName($class);
/*
* Oops, cannot resolve class
*/
if ($className === null) {
throw new CannotResolveClassNameException($class);
}
$childClasses = [];
foreach ($allClasses as $oneClass) {
if (self::isChildOfClass($oneClass, $className)) {
/*
* Attention. I have to use ClassUtils::getRealClass() method to avoid problem with the proxy / cache
* classes. Example:
* - My\ExtraBundle\Entity\MyEntity
* - Proxies\__CG__\My\ExtraBundle\Entity\MyEntity
*
* It's actually the same class, so I have to skip it.
*/
$realClass = ClassUtils::getRealClass($oneClass);
if (in_array($realClass, $childClasses)) {
continue;
}
$childClasses[] = $realClass;
}
}
return $childClasses;
}
/**
* Returns namespace of one child class which extends given class.
* Extended class should has only one child class.
*
* @param array|object|string $parentClass Class who child class should be returned. An array of objects,
* namespaces, object or namespace.
* @return mixed
*
* @throws MissingChildClassesException
* @throws TooManyChildClassesException
*/
public static function getOneChildClass($parentClass)
{
$childClasses = self::getChildClasses($parentClass);
/*
* No child classes?
* Oops, the base / parent class hasn't child class
*/
if (empty($childClasses)) {
throw new MissingChildClassesException($parentClass);
}
/*
* More than 1 child class?
* Oops, the base / parent class has too many child classes
*/
if (count($childClasses) > 1) {
throw new TooManyChildClassesException($parentClass, $childClasses);
}
return trim($childClasses[0]);
}
/**
* Returns property, the ReflectionProperty instance, of given object
*
* @param array|object|string $class An array of objects, namespaces, object or namespace
* @param string $property Name of the property
* @param int $filter (optional) Filter of properties. Uses ReflectionProperty class constants.
* By default all properties are allowed / processed.
* @return null|ReflectionProperty
*/
public static function getProperty($class, $property, $filter = null)
{
$className = self::getClassName($class);
$properties = self::getProperties($className, $filter);
if (!empty($properties)) {
/* @var $reflectionProperty ReflectionProperty */
foreach ($properties as $reflectionProperty) {
if ($reflectionProperty->getName() == $property) {
return $reflectionProperty;
}
}
}
return null;
}
/**
* Returns information if given class / object uses / implements given trait
*
* @param array|object|string $class An array of objects, namespaces, object or namespace
* @param array|string $trait An array of strings or string
* @param bool $verifyParents If is set to true, parent classes are verified if they use given
* trait. Otherwise - not.
* @return bool|null
* @throws CannotResolveClassNameException
*/
public static function usesTrait($class, $trait, $verifyParents = false)
{
$className = self::getClassName($class);
$traitName = self::getClassName($trait);
/*
* Oops, cannot resolve class
*/
if (empty($className)) {
throw new CannotResolveClassNameException($class);
}
/*
* Oops, cannot resolve trait
*/
if (empty($traitName)) {
throw new CannotResolveClassNameException($class, false);
}
$reflection = new ReflectionClass($className);
$traitsNames = $reflection->getTraitNames();
$uses = in_array($traitName, $traitsNames);
if (!$uses && $verifyParents) {
$parentClassName = self::getParentClassName($className);
if ($parentClassName !== null) {
return self::usesTrait($parentClassName, $trait, true);
}
}
return $uses;
}
/**
* Returns name of the parent class.
* If given class does not extend another, returns null.
*
* @param array|object|string $class An array of objects, namespaces, object or namespace
* @return string|null
*/
public static function getParentClassName($class)
{
$className = self::getClassName($class);
$reflection = new ReflectionClass($className);
$parentClass = $reflection->getParentClass();
if ($parentClass === null || $parentClass === false) {
return null;
}
return $parentClass->getName();
}
}

View File

@@ -1,109 +0,0 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Utilities;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
/**
* Useful methods for repository
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Repository
{
/**
* Replenishes positions of given items
*
* @param array $items The items
* @param bool $asLast (optional) If is set to true, items are placed at the end. Otherwise - at the top.
* @param bool $force (optional) If is set to true, positions are set even there is no extreme position.
* Otherwise - if extreme position is not found (is null) replenishment is stopped / skipped.
*/
public static function replenishPositions($items, $asLast = true, $force = false)
{
$position = self::getExtremePosition($items, $asLast);
if ($position === null && $force) {
$position = 0;
}
if ($position !== null && !empty($items)) {
foreach ($items as $item) {
if (method_exists($item, 'getPosition')) {
if ($item->getPosition() === null) {
if ($asLast) {
++$position;
} else {
--$position;
}
if (method_exists($item, 'setPosition')) {
$item->setPosition($position);
}
}
}
}
}
}
/**
* Returns extreme position (max or min) of given items
*
* @param array $items The items
* @param bool $max (optional) If is set to true, maximum value is returned. Otherwise - minimum.
* @return int
*/
public static function getExtremePosition($items, $max = true)
{
$extreme = null;
if (!empty($items)) {
foreach ($items as $item) {
if (Reflection::hasMethod($item, 'getPosition')) {
$position = $item->getPosition();
if ($max) {
if ($position > $extreme) {
$extreme = $position;
}
} else {
if ($position < $extreme) {
$extreme = $position;
}
}
}
}
}
return $extreme;
}
/**
* Returns query builder for given entity's repository.
* The entity should contain given property, e.g. "name".
*
* @param EntityRepository $repository Repository of the entity
* @param string $property (optional) Name of property used by the ORDER BY clause
* @param string $direction (optional) Direction used by the ORDER BY clause ("ASC" or "DESC")
* @return QueryBuilder
*/
public static function getEntityOrderedQueryBuilder(
EntityRepository $repository,
$property = 'name',
$direction = 'ASC'
) {
$alias = 'qb';
return $repository
->createQueryBuilder($alias)
->orderBy(sprintf('%s.%s', $alias, $property), $direction);
}
}

View File

@@ -1,103 +0,0 @@
<?php
namespace Meritoo\Common\Utilities;
use DateTime;
use Generator;
/**
* Test case with common methods and data providers
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class TestCase extends \PHPUnit_Framework_TestCase
{
/**
* Provides an empty value
*
* @return Generator
*/
public function provideEmptyValue()
{
yield[''];
yield[' '];
yield[null];
yield[0];
yield[false];
yield[[]];
}
/**
* Provides boolean value
*
* @return Generator
*/
public function provideBooleanValue()
{
yield[false];
yield[true];
}
/**
* Provides instance of DateTime class
*
* @return Generator
*/
public function provideDateTimeInstance()
{
yield[new DateTime()];
yield[new DateTime('yesterday')];
yield[new DateTime('now')];
yield[new DateTime('tomorrow')];
}
/**
* Provides relative / compound format of DateTime
*
* @return Generator
*/
public function provideDateTimeRelativeFormat()
{
yield['now'];
yield['yesterday'];
yield['tomorrow'];
yield['back of 10'];
yield['front of 10'];
yield['last day of February'];
yield['first day of next month'];
yield['last day of previous month'];
yield['last day of next month'];
yield['Y-m-d'];
yield['Y-m-d 10:00'];
}
/**
* Provides path of not existing file, e.g. "lorem/ipsum.jpg"
*
* @return Generator
*/
public function provideNotExistingFilePath()
{
yield['lets-test.doc'];
yield['lorem/ipsum.jpg'];
yield['suprise/me/one/more/time.txt'];
}
/**
* Returns path of file used by tests.
* It should be placed in /data/tests directory of this project.
*
* @param string $fileName Name of file
* @param string $directoryPath (optional) Path of directory containing the file
* @return string
*/
public function getFilePathToTests($fileName, $directoryPath = '')
{
if (!empty($directoryPath)) {
$directoryPath = '/' . $directoryPath;
}
return sprintf('%s/../../../../data/tests/%s%s', __DIR__, $fileName, $directoryPath);
}
}

View File

@@ -0,0 +1,23 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Test\Base;
use Meritoo\Common\Traits\Test\Base\BaseTestCaseTrait;
use PHPUnit\Framework\TestCase;
/**
* Base test case with common methods and data providers
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
abstract class BaseTestCase extends TestCase
{
use BaseTestCaseTrait;
}

View File

@@ -0,0 +1,22 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Test\Base;
use Meritoo\Common\Traits\Test\Base\BaseTypeTestCaseTrait;
/**
* Base test case for the type of something
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
abstract class BaseTypeTestCase extends BaseTestCase
{
use BaseTypeTestCaseTrait;
}

View File

@@ -0,0 +1,110 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Traits\CssSelector;
/**
* Useful methods related to CSS selectors of form
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
trait FormCssSelector
{
/**
* Returns selector of field-set using index/position of the field-set
*
* @param string $formName Name of form (value of the "name" attribute)
* @param int $fieldSetIndex Index/Position of the field-set
* @return string
*/
public static function getFieldSetByIndexSelector($formName, $fieldSetIndex)
{
$formSelector = static::getFormByNameSelector($formName);
if (empty($formSelector) || 0 > $fieldSetIndex) {
return '';
}
return sprintf('%s fieldset:nth-of-type(%d)', $formSelector, $fieldSetIndex);
}
/**
* Returns selector of form based on its name
*
* @param string $formName Name of form (value of the "name" attribute)
* @return string
*/
public static function getFormByNameSelector($formName)
{
$formName = trim($formName);
if (empty($formName)) {
return '';
}
return sprintf('form[name="%s"]', $formName);
}
/**
* Returns selector of the input field based on its ID
*
* @param string $formName Name of form (value of the "name" attribute)
* @param string $fieldId ID of field (value of the "id" attribute)
* @return string
*/
public static function getInputByIdSelector($formName, $fieldId)
{
$formSelector = static::getFormByNameSelector($formName);
$fieldId = trim($fieldId);
if (empty($formSelector) || empty($fieldId)) {
return '';
}
return sprintf('%s input#%s', $formSelector, $fieldId);
}
/**
* Returns selector of the input field based on its name
*
* @param string $formName Name of form (value of the "name" attribute)
* @param string $fieldName Name of field (value of the "name" attribute)
* @return string
*/
public static function getInputByNameSelector($formName, $fieldName)
{
$formSelector = static::getFormByNameSelector($formName);
$fieldName = trim($fieldName);
if (empty($formSelector) || empty($fieldName)) {
return '';
}
return sprintf('%s input[name="%s"]', $formSelector, $fieldName);
}
/**
* Returns selector of label
*
* @param string $formName Name of form (value of the "name" attribute)
* @param string $fieldId ID of field (value of the "id" attribute)
* @return string
*/
public static function getLabelSelector($formName, $fieldId)
{
$formSelector = static::getFormByNameSelector($formName);
$fieldId = trim($fieldId);
if (empty($formSelector) || empty($fieldId)) {
return '';
}
return sprintf('%s label[for="%s"]', $formSelector, $fieldId);
}
}

View File

@@ -0,0 +1,258 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Traits\Test\Base;
use DateTime;
use Generator;
use Meritoo\Common\Exception\Reflection\ClassWithoutConstructorException;
use Meritoo\Common\Exception\Type\UnknownOopVisibilityTypeException;
use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\Common\Utilities\Miscellaneous;
use ReflectionClass;
use ReflectionMethod;
use RuntimeException;
use stdClass;
/**
* Trait for the base test case
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
trait BaseTestCaseTrait
{
/**
* Path of directory with data used by test cases
*
* @var string
*/
private static $testsDataDirPath = 'data/tests';
/**
* Provides boolean value
*
* @return Generator
*/
public function provideBooleanValue(): ?Generator
{
yield [false];
yield [true];
}
/**
* Provides instance of DateTime class
*
* @return Generator
*/
public function provideDateTimeInstance(): ?Generator
{
yield [new DateTime()];
yield [new DateTime('yesterday')];
yield [new DateTime('now')];
yield [new DateTime('tomorrow')];
}
/**
* Provides relative / compound format of DateTime
*
* @return Generator
*/
public function provideDateTimeRelativeFormat(): ?Generator
{
yield ['now'];
yield ['yesterday'];
yield ['tomorrow'];
yield ['back of 10'];
yield ['front of 10'];
yield ['last day of February'];
yield ['first day of next month'];
yield ['last day of previous month'];
yield ['last day of next month'];
yield ['Y-m-d'];
yield ['Y-m-d 10:00'];
}
/**
* Provides an empty scalar value
*
* @return Generator
*/
public function provideEmptyScalarValue(): ?Generator
{
yield [''];
yield [' '];
yield [null];
yield [0];
yield [false];
}
/**
* Provides an empty value
*
* @return Generator
*/
public function provideEmptyValue(): ?Generator
{
yield [''];
yield [' '];
yield [null];
yield [0];
yield [false];
yield [[]];
}
/**
* Provides non scalar value, e.g. [] or null
*
* @return Generator
*/
public function provideNonScalarValue(): ?Generator
{
yield [[]];
yield [null];
yield [new stdClass()];
}
/**
* Provides path of not existing file, e.g. "lorem/ipsum.jpg"
*
* @return Generator
*/
public function provideNotExistingFilePath(): ?Generator
{
yield ['lets-test.doc'];
yield ['lorem/ipsum.jpg'];
yield ['surprise/me/one/more/time.txt'];
}
/**
* Verifies visibility and arguments of class constructor
*
* @param string $className Fully-qualified name of class that contains constructor to verify
* @param string $visibilityType Expected visibility of verified method. One of OopVisibilityType class
* constants.
* @param int $argumentsCount (optional) Expected count/amount of arguments of the verified method
* @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments of the verified
* method
* @throws ClassWithoutConstructorException
*/
protected static function assertConstructorVisibilityAndArguments(
string $className,
string $visibilityType,
int $argumentsCount = 0,
int $requiredArgumentsCount = 0
): void {
$reflection = new ReflectionClass($className);
$method = $reflection->getConstructor();
if (null === $method) {
throw ClassWithoutConstructorException::create($className);
}
static::assertMethodVisibility($method, $visibilityType);
static::assertMethodArgumentsCount($method, $argumentsCount, $requiredArgumentsCount);
}
/**
* Asserts that class with given namespace has no constructor
*
* @param string $className Fully-qualified name of class that contains constructor to verify
*/
protected static function assertHasNoConstructor(string $className): void
{
$reflection = new ReflectionClass($className);
$constructor = $reflection->getConstructor();
static::assertNull($constructor);
}
/**
* Verifies count of method's arguments
*
* @param ReflectionMethod $method Name of method or just the method to verify
* @param int $argumentsCount (optional) Expected count/amount of arguments of the verified method
* @param int $requiredCount (optional) Expected count/amount of required arguments of the verified
* method
* @throws RuntimeException
*/
protected static function assertMethodArgumentsCount(
ReflectionMethod $method,
int $argumentsCount = 0,
int $requiredCount = 0
): void {
static::assertSame($argumentsCount, $method->getNumberOfParameters());
static::assertSame($requiredCount, $method->getNumberOfRequiredParameters());
}
/**
* Verifies visibility of method
*
* @param ReflectionMethod $method Name of method or just the method to verify
* @param string $visibilityType Expected visibility of verified method. One of OopVisibilityType
* class constants.
* @throws UnknownOopVisibilityTypeException
* @throws RuntimeException
*/
protected static function assertMethodVisibility(ReflectionMethod $method, string $visibilityType): void
{
// Type of visibility is not correct?
if (!OopVisibilityType::isCorrectType($visibilityType)) {
throw UnknownOopVisibilityTypeException::createException($visibilityType);
}
switch ($visibilityType) {
case OopVisibilityType::IS_PUBLIC:
static::assertTrue($method->isPublic());
break;
case OopVisibilityType::IS_PROTECTED:
static::assertTrue($method->isProtected());
break;
case OopVisibilityType::IS_PRIVATE:
static::assertTrue($method->isPrivate());
break;
}
}
/**
* Returns path of file used by tests.
* It should be placed in /data/tests directory of this project.
*
* @param string $fileName Name of file
* @param string $directoryPath (optional) Path of directory containing the file
* @return string
*/
protected function getFilePathForTesting(string $fileName, string $directoryPath = ''): string
{
$rootPath = Miscellaneous::getProjectRootPath();
$paths = [
$rootPath,
self::$testsDataDirPath,
$directoryPath,
$fileName,
];
return Miscellaneous::concatenatePaths($paths);
}
/**
* Sets path of directory with data used by test cases
*
* @param string $testsDataDirPath Path of directory with data used by test cases
*/
protected static function setTestsDataDirPath(string $testsDataDirPath): void
{
static::$testsDataDirPath = $testsDataDirPath;
}
}

View File

@@ -0,0 +1,68 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Traits\Test\Base;
use Generator;
use Meritoo\Common\Type\Base\BaseType;
/**
* Trait for the base test case for the type of something
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
trait BaseTypeTestCaseTrait
{
/**
* Provides type to verify and information if it's correct
*
* @return Generator
*/
abstract public function provideTypeToVerify(): Generator;
/**
* Verifies availability of all types
*/
public function testAvailabilityOfAllTypes(): void
{
$available = $this->getTestedTypeInstance()->getAll();
$all = $this->getAllExpectedTypes();
static::assertEquals($all, $available);
}
/**
* Verifies whether given type is correct or not
*
* @param bool $isCorrect Information if processed type is correct
* @param bool $expected Expected information if processed type is correct
*
* @dataProvider provideTypeToVerify
*/
public function testIfGivenTypeIsCorrect(bool $isCorrect, bool $expected): void
{
static::assertEquals($expected, $isCorrect);
}
/**
* Returns all expected types of the tested type
*
* @return array
*/
abstract protected function getAllExpectedTypes(): array;
/**
* Returns instance of the tested type
*
* @return BaseType
*/
abstract protected function getTestedTypeInstance(): BaseType;
}

View File

@@ -0,0 +1,144 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Meritoo\Common\Traits\ValueObject;
use DateTime;
/**
* Methods and properties related to human
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
trait HumanTrait
{
/**
* First name
*
* @var string
*/
protected $firstName;
/**
* Last name
*
* @var string
*/
protected $lastName;
/**
* Email address
*
* @var null|string
*/
protected $email;
/**
* Birth date
*
* @var null|DateTime
*/
protected $birthDate;
/**
* Class constructor
*
* @param string $firstName First name
* @param string $lastName Last name
* @param null|string $email (optional) Email address. Default: null.
* @param null|DateTime $birthDate (optional) Birth date. Default: null.
*/
public function __construct(string $firstName, string $lastName, ?string $email = null, ?DateTime $birthDate = null)
{
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->email = $email;
$this->birthDate = $birthDate;
}
/**
* Returns representation of object as string
*
* @return string
*/
public function __toString()
{
$template = '%s';
$email = '';
if ('' !== $this->email && null !== $this->email) {
$template .= ' <%s>';
$email = $this->email;
}
return sprintf($template, $this->getFullName(), $email);
}
/**
* Returns birth date
*
* @return null|DateTime
*/
public function getBirthDate(): ?DateTime
{
return $this->birthDate;
}
/**
* Returns email address
*
* @return null|string
*/
public function getEmail(): ?string
{
return $this->email;
}
/**
* Returns first name
*
* @return string
*/
public function getFirstName(): string
{
return $this->firstName;
}
/**
* Returns the full name
*
* @param bool $firstNameFirst (optional) If is set to true, first name is the first part (default behaviour).
* Otherwise - name.
* @return string
*/
public function getFullName(bool $firstNameFirst = true): string
{
$beginning = $this->lastName;
$finish = $this->firstName;
if ($firstNameFirst) {
$beginning = $this->firstName;
$finish = $this->lastName;
}
return trim(sprintf('%s %s', $beginning, $finish));
}
/**
* Returns last name
*
* @return string
*/
public function getLastName(): string
{
return $this->lastName;
}
}

View File

@@ -14,15 +14,15 @@ use Meritoo\Common\Utilities\Reflection;
* Base / abstract type of something, e.g. type of button, order, date etc.
* Child class should contain constants - each of them represent one type.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
abstract class BaseType
{
/**
* All types
*
* @var array
* @var null|array
*/
private $all;
@@ -31,9 +31,9 @@ abstract class BaseType
*
* @return array
*/
public function getAll()
public function getAll(): array
{
if ($this->all === null) {
if (null === $this->all) {
$this->all = Reflection::getConstants($this);
}
@@ -43,11 +43,11 @@ abstract class BaseType
/**
* Returns information if given type is correct
*
* @param string $type The type to check
* @param null|string $type The type to check
* @return bool
*/
public function isCorrectType($type)
public static function isCorrectType(?string $type): bool
{
return in_array($type, $this->getAll(), true);
return in_array($type, (new static())->getAll());
}
}

View File

@@ -1,5 +1,11 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Type;
use Meritoo\Common\Type\Base\BaseType;
@@ -7,8 +13,8 @@ use Meritoo\Common\Type\Base\BaseType;
/**
* Type of date part, e.g. "year"
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class DatePartType extends BaseType
{
@@ -17,40 +23,40 @@ class DatePartType extends BaseType
*
* @var string
*/
const DAY = 'day';
public const DAY = 'day';
/**
* The "hour" date part
*
* @var string
*/
const HOUR = 'hour';
public const HOUR = 'hour';
/**
* The "minute" date part
*
* @var string
*/
const MINUTE = 'minute';
public const MINUTE = 'minute';
/**
* The "month" date part
*
* @var string
*/
const MONTH = 'month';
public const MONTH = 'month';
/**
* The "second" date part
*
* @var string
*/
const SECOND = 'second';
public const SECOND = 'second';
/**
* The "year" date part
*
* @var string
*/
const YEAR = 'year';
public const YEAR = 'year';
}

View File

@@ -6,153 +6,116 @@
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Utilities;
namespace Meritoo\Common\Type;
use DateTime;
use Meritoo\Common\Type\Base\BaseType;
use Meritoo\Common\Utilities\Date;
/**
* A date's period.
* Contains start and end date of the period.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class DatePeriod
class DatePeriod extends BaseType
{
/**
* The period constant: last month
*
* @var int
* @var string
*/
const LAST_MONTH = 4;
public const LAST_MONTH = '4';
/**
* The period constant: last week
*
* @var int
* @var string
*/
const LAST_WEEK = 1;
public const LAST_WEEK = '1';
/**
* The period constant: last year
*
* @var int
* @var string
*/
const LAST_YEAR = 7;
public const LAST_YEAR = '7';
/**
* The period constant: next month
*
* @var int
* @var string
*/
const NEXT_MONTH = 6;
public const NEXT_MONTH = '6';
/**
* The period constant: next week
*
* @var int
* @var string
*/
const NEXT_WEEK = 3;
public const NEXT_WEEK = '3';
/**
* The period constant: next year
*
* @var int
* @var string
*/
const NEXT_YEAR = 9;
public const NEXT_YEAR = '9';
/**
* The period constant: this month
*
* @var int
* @var string
*/
const THIS_MONTH = 5;
public const THIS_MONTH = '5';
/**
* The period constant: this week
*
* @var int
* @var string
*/
const THIS_WEEK = 2;
public const THIS_WEEK = '2';
/**
* The period constant: this year
*
* @var int
* @var string
*/
const THIS_YEAR = 8;
public const THIS_YEAR = '8';
/**
* The start date of period
*
* @var DateTime
* @var null|DateTime
*/
private $startDate;
/**
* The end date of period
*
* @var DateTime
* @var null|DateTime
*/
private $endDate;
/**
* Class constructor
*
* @param DateTime $startDate (optional) The start date of period
* @param DateTime $endDate (optional) The end date of period
* @param null|DateTime $startDate (optional) The start date of period
* @param null|DateTime $endDate (optional) The end date of period
*/
public function __construct(DateTime $startDate = null, DateTime $endDate = null)
public function __construct(?DateTime $startDate = null, ?DateTime $endDate = null)
{
$this->startDate = $startDate;
$this->endDate = $endDate;
}
/**
* Returns information if given period is correct
*
* @param int $period The period to verify
* @return bool
*/
public static function isCorrectPeriod($period)
{
return in_array($period, Reflection::getConstants(__CLASS__));
}
/**
* Returns formatted one of the period's date: start date or end date
*
* @param string $format Format used to format the date
* @param bool $startDate (optional) If is set to true, start date is formatted. Otherwise - end date.
* @return string
*/
public function getFormattedDate($format, $startDate = true)
{
$date = $this->getEndDate();
/*
* Start date should be formatted?
*/
if ($startDate) {
$date = $this->getStartDate();
}
/*
* Unknown date or format is invalid?
*/
if ($date === null || !Date::isValidDateFormat($format)) {
return '';
}
return $date->format($format);
}
/**
* Returns the end date of period
*
* @return DateTime
* @return null|DateTime
*/
public function getEndDate()
public function getEndDate(): ?DateTime
{
return $this->endDate;
}
@@ -160,22 +123,48 @@ class DatePeriod
/**
* Sets the end date of period
*
* @param DateTime $endDate (optional) The end date of period
* @param null|DateTime $endDate (optional) The end date of period. Default: null.
* @return $this
*/
public function setEndDate(DateTime $endDate = null)
public function setEndDate(?DateTime $endDate = null): self
{
$this->endDate = $endDate;
return $this;
}
/**
* Returns formatted one of the period's date: start date or end date
*
* @param string $format Format used to format the date
* @param bool $startDate (optional) If is set to true, start date will be formatted (default behaviour).
* Otherwise - end date.
* @return string
*/
public function getFormattedDate(string $format, bool $startDate = true): string
{
$date = $this->getEndDate();
// Start date should be formatted?
if ($startDate) {
$date = $this->getStartDate();
}
// Unknown date or format is invalid?
// Nothing to do
if (null === $date || !Date::isValidDateFormat($format)) {
return '';
}
return $date->format($format);
}
/**
* Returns the start date of period
*
* @return DateTime
* @return null|DateTime
*/
public function getStartDate()
public function getStartDate(): ?DateTime
{
return $this->startDate;
}
@@ -183,10 +172,10 @@ class DatePeriod
/**
* Sets the start date of period
*
* @param DateTime $startDate (optional) The start date of period
* @param null|DateTime $startDate (optional) The start date of period. Default: null.
* @return $this
*/
public function setStartDate(DateTime $startDate = null)
public function setStartDate(?DateTime $startDate = null): self
{
$this->startDate = $startDate;

View File

@@ -0,0 +1,37 @@
<?php
namespace Meritoo\Common\Type;
use Meritoo\Common\Type\Base\BaseType;
/**
* The visibility of a property, a method or (as of PHP 7.1.0) a constant
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*
* @see http://php.net/manual/en/language.oop5.visibility.php
*/
class OopVisibilityType extends BaseType
{
/**
* The "private" visibility of OOP
*
* @var string
*/
public const IS_PRIVATE = '3';
/**
* The "protected" visibility of OOP
*
* @var string
*/
public const IS_PROTECTED = '2';
/**
* The "public" visibility of OOP
*
* @var string
*/
public const IS_PUBLIC = '1';
}

View File

@@ -0,0 +1,85 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Utilities;
/**
* Useful methods related to CSS selectors and the Bootstrap4 (front-end component library)
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class Bootstrap4CssSelector
{
/**
* Returns selector of container with field's validation error
*
* @return string
*/
public static function getFieldErrorContainerSelector()
{
return '.invalid-feedback .form-error-message';
}
/**
* Returns selector of field's validation error
*
* @param string $formName Name of form (value of the "name" attribute)
* @param string $fieldId ID of field (value of the "id" attribute)
* @return string
*/
public static function getFieldErrorSelector($formName, $fieldId)
{
$labelSelector = CssSelector::getLabelSelector($formName, $fieldId);
if (empty($labelSelector)) {
return '';
}
$errorContainerSelector = static::getFieldErrorContainerSelector();
return sprintf('%s %s', $labelSelector, $errorContainerSelector);
}
/**
* Returns selector of field's group
*
* @param string $formName Name of form (value of the "name" attribute)
* @return string
*/
public static function getFieldGroupSelector($formName)
{
$formSelector = CssSelector::getFormByNameSelector($formName);
if (empty($formSelector)) {
return '';
}
return sprintf('%s .form-group', $formSelector);
}
/**
* Returns selector of radio-button's validation error
*
* @param string $formName Name of form (value of the "name" attribute)
* @param int $fieldSetIndex Index/Position of the field-set
* @return string
*/
public static function getRadioButtonErrorSelector($formName, $fieldSetIndex)
{
$fieldSetSelector = CssSelector::getFieldSetByIndexSelector($formName, $fieldSetIndex);
if (empty($fieldSetSelector)) {
return '';
}
$errorContainerSelector = static::getFieldErrorContainerSelector();
return sprintf('%s legend.col-form-label %s', $fieldSetSelector, $errorContainerSelector);
}
}

77
src/Utilities/Bundle.php Normal file
View File

@@ -0,0 +1,77 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Utilities;
use Meritoo\Common\Exception\Bundle\IncorrectBundleNameException;
/**
* Useful methods for bundle
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class Bundle
{
/**
* Returns path of given bundle to view / template with given extension
*
* @param string $viewPath Path of the view / template, e.g. "MyDirectory/my-template". Extension is not required.
* @param string $bundleName Full name of the bundle, e.g. "MyExtraBundle"
* @param string $extension (optional) Extension of the view / template (default: "html.twig")
* @return null|string
* @throws IncorrectBundleNameException
*/
public static function getBundleViewPath(
string $viewPath,
string $bundleName,
string $extension = 'html.twig'
): ?string {
// Nothing to do, because at least one unknown argument provided
if (empty($viewPath) || empty($bundleName) || empty($extension)) {
return null;
}
// Oops, given name of bundle is invalid
if (!Regex::isValidBundleName($bundleName)) {
throw IncorrectBundleNameException::create($bundleName);
}
// Make sure that path of the view / template ends with given extension
if (!Regex::endsWith($viewPath, $extension)) {
$viewPath = sprintf('%s.%s', $viewPath, $extension);
}
// Prepare short name of bundle and path of view / template with "/" (instead of ":")
$shortName = static::getShortBundleName($bundleName);
$path = str_replace(':', '/', $viewPath);
return sprintf('@%s/%s', $shortName, $path);
}
/**
* Returns short name of bundle (without "Bundle")
*
* @param string $fullBundleName Full name of the bundle, e.g. "MyExtraBundle"
* @return null|string
* @throws IncorrectBundleNameException
*/
public static function getShortBundleName(string $fullBundleName): ?string
{
// Oops, given name of bundle is invalid
if (!Regex::isValidBundleName($fullBundleName)) {
throw new IncorrectBundleNameException($fullBundleName);
}
$matches = [];
$pattern = Regex::getBundleNamePattern();
preg_match($pattern, $fullBundleName, $matches);
return $matches[1];
}
}

View File

@@ -8,13 +8,11 @@
namespace Meritoo\Common\Utilities;
use stdClass;
/**
* Useful Composer-related methods (only static functions)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class Composer
{
@@ -23,23 +21,18 @@ class Composer
*
* @var string
*/
const FILE_NAME_MAIN = 'composer.json';
public const FILE_NAME_MAIN = 'composer.json';
/**
* Returns value from composer.json file
*
* @param string $composerJsonPath Path of composer.json file
* @param string $nodeName Name of node who value should be returned
* @return string|null
* @return null|string
*/
public static function getValue($composerJsonPath, $nodeName)
public static function getValue(string $composerJsonPath, string $nodeName): ?string
{
$composerJsonString = is_string($composerJsonPath);
$composerJsonReadable = false;
if ($composerJsonString) {
$composerJsonReadable = is_readable($composerJsonPath);
}
$composerJsonReadable = is_readable($composerJsonPath);
/*
* Provided path or name of node are invalid?
@@ -48,22 +41,21 @@ class Composer
*
* Nothing to do
*/
if (!$composerJsonString || !is_string($nodeName) || !$composerJsonReadable || empty($nodeName)) {
if (!$composerJsonReadable || empty($nodeName)) {
return null;
}
$content = file_get_contents($composerJsonPath);
$data = json_decode($content);
$data = json_decode($content, false);
/*
* Unknown data from the composer.json file or there is no node with given name?
* Nothing to do
*/
if ($data === null || !isset($data->{$nodeName})) {
if (null === $data || !isset($data->{$nodeName})) {
return null;
}
/* @var stdClass $data */
return $data->{$nodeName};
}
}

View File

@@ -0,0 +1,22 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Utilities;
use Meritoo\Common\Traits\CssSelector\FormCssSelector;
/**
* Useful methods related to CSS selectors
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class CssSelector
{
use FormCssSelector;
}

View File

@@ -10,14 +10,16 @@ namespace Meritoo\Common\Utilities;
use DateInterval;
use DateTime;
use Meritoo\Common\Exception\Date\IncorrectDatePartException;
use Exception;
use Meritoo\Common\Exception\Type\UnknownDatePartTypeException;
use Meritoo\Common\Type\DatePartType;
use Meritoo\Common\Type\DatePeriod;
/**
* Useful date methods
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class Date
{
@@ -27,7 +29,7 @@ class Date
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_DAYS = 'days';
public const DATE_DIFFERENCE_UNIT_DAYS = 'days';
/**
* The 'hours' unit of date difference.
@@ -35,7 +37,7 @@ class Date
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_HOURS = 'hours';
public const DATE_DIFFERENCE_UNIT_HOURS = 'hours';
/**
* The 'minutes' unit of date difference.
@@ -43,7 +45,7 @@ class Date
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_MINUTES = 'minutes';
public const DATE_DIFFERENCE_UNIT_MINUTES = 'minutes';
/**
* The 'months' unit of date difference.
@@ -51,7 +53,7 @@ class Date
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_MONTHS = 'months';
public const DATE_DIFFERENCE_UNIT_MONTHS = 'months';
/**
* The 'years' unit of date difference.
@@ -59,114 +61,16 @@ class Date
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_YEARS = 'years';
/**
* Returns start and end date for given period.
* The dates are returned in an array with indexes 'start' and 'end'.
*
* @param int $period The period, type of period. One of DatePeriod class constants, e.g. DatePeriod::LAST_WEEK.
* @return DatePeriod
*/
public static function getDatesForPeriod($period)
{
$datePeriod = null;
if (DatePeriod::isCorrectPeriod($period)) {
$dateStart = null;
$dateEnd = null;
switch ($period) {
case DatePeriod::LAST_WEEK:
$thisWeekStart = new DateTime('this week');
$dateStart = clone $thisWeekStart;
$dateEnd = clone $thisWeekStart;
$dateStart->sub(new DateInterval('P7D'));
$dateEnd->sub(new DateInterval('P1D'));
break;
case DatePeriod::THIS_WEEK:
$dateStart = new DateTime('this week');
$dateEnd = clone $dateStart;
$dateEnd->add(new DateInterval('P6D'));
break;
case DatePeriod::NEXT_WEEK:
$dateStart = new DateTime('this week');
$dateStart->add(new DateInterval('P7D'));
$dateEnd = clone $dateStart;
$dateEnd->add(new DateInterval('P6D'));
break;
case DatePeriod::LAST_MONTH:
$dateStart = new DateTime('first day of last month');
$dateEnd = new DateTime('last day of last month');
break;
case DatePeriod::THIS_MONTH:
$lastMonth = self::getDatesForPeriod(DatePeriod::LAST_MONTH);
$nextMonth = self::getDatesForPeriod(DatePeriod::NEXT_MONTH);
$dateStart = $lastMonth->getEndDate();
$dateStart->add(new DateInterval('P1D'));
$dateEnd = $nextMonth->getStartDate();
$dateEnd->sub(new DateInterval('P1D'));
break;
case DatePeriod::NEXT_MONTH:
$dateStart = new DateTime('first day of next month');
$dateEnd = new DateTime('last day of next month');
break;
case DatePeriod::LAST_YEAR:
case DatePeriod::THIS_YEAR:
case DatePeriod::NEXT_YEAR:
$dateStart = new DateTime();
$dateEnd = new DateTime();
if ($period == DatePeriod::LAST_YEAR || $period == DatePeriod::NEXT_YEAR) {
$yearDifference = 1;
if ($period == DatePeriod::LAST_YEAR) {
$yearDifference *= -1;
}
$modifyString = sprintf('%s year', $yearDifference);
$dateStart->modify($modifyString);
$dateEnd->modify($modifyString);
}
$year = $dateStart->format('Y');
$dateStart->setDate($year, 1, 1);
$dateEnd->setDate($year, 12, 31);
break;
}
if ($dateStart !== null && $dateEnd !== null) {
$dateStart->setTime(0, 0, 0);
$dateEnd->setTime(23, 59, 59);
$datePeriod = new DatePeriod($dateStart, $dateEnd);
}
}
return $datePeriod;
}
public const DATE_DIFFERENCE_UNIT_YEARS = 'years';
/**
* Generates and returns random time (the hour, minute and second values)
*
* @param string $format (optional) Format of returned value. A string acceptable by the DateTime::format()
* method.
* @return string|null
* @return null|string
*/
public static function generateRandomTime($format = 'H:i:s')
public static function generateRandomTime($format = 'H:i:s'): ?string
{
$dateTime = new DateTime();
@@ -194,16 +98,15 @@ class Date
$seconds[] = $i;
}
/*
* Prepare random time (hour, minute and second)
*/
// Prepare random time (hour, minute and second)
$hour = $hours[array_rand($hours)];
$minute = $minutes[array_rand($minutes)];
$second = $seconds[array_rand($seconds)];
return $dateTime
->setTime($hour, $minute, $second)
->format($format);
->format($format)
;
}
/**
@@ -211,113 +114,33 @@ class Date
*
* @return int
*/
public static function getCurrentDayOfWeek()
public static function getCurrentDayOfWeek(): int
{
$now = new DateTime();
$year = $now->format('Y');
$month = $now->format('m');
$day = $now->format('d');
$year = (int) $now->format('Y');
$month = (int) $now->format('m');
$day = (int) $now->format('d');
return self::getDayOfWeek($year, $month, $day);
}
/**
* Returns day of week (number 0 to 6, 0 - sunday, 6 - saturday).
* Based on the Zeller's algorithm (http://pl.wikipedia.org/wiki/Kalendarz_wieczny).
*
* @param int $year The year value
* @param int $month The month value
* @param int $day The day value
*
* @return int
* @throws IncorrectDatePartException
*/
public static function getDayOfWeek($year, $month, $day)
{
$year = (int)$year;
$month = (int)$month;
$day = (int)$day;
/*
* Oops, incorrect year
*/
if ($year <= 0) {
throw new IncorrectDatePartException($year, DatePartType::YEAR);
}
/*
* Oops, incorrect month
*/
if ($month < 1 || $month > 12) {
throw new IncorrectDatePartException($month, DatePartType::MONTH);
}
/*
* Oops, incorrect day
*/
if ($day < 1 || $day > 31) {
throw new IncorrectDatePartException($day, DatePartType::DAY);
}
if ($month < 3) {
$count = 0;
$yearValue = $year - 1;
} else {
$count = 2;
$yearValue = $year;
}
$firstPart = floor(23 * $month / 9);
$secondPart = floor($yearValue / 4);
$thirdPart = floor($yearValue / 100);
$fourthPart = floor($yearValue / 400);
return ($firstPart + $day + 4 + $year + $secondPart - $thirdPart + $fourthPart - $count) % 7;
}
/**
* Returns based on locale name of current weekday
*
* @return string
*/
public static function getCurrentDayOfWeekName()
public static function getCurrentDayOfWeekName(): string
{
$now = new DateTime();
$year = $now->format('Y');
$month = $now->format('m');
$day = $now->format('d');
$year = (int) $now->format('Y');
$month = (int) $now->format('m');
$day = (int) $now->format('d');
return self::getDayOfWeekName($year, $month, $day);
}
/**
* Returns name of weekday based on locale
*
* @param int $year The year value
* @param int $month The month value
* @param int $day The day value
* @return string
*/
public static function getDayOfWeekName($year, $month, $day)
{
$hour = 0;
$minute = 0;
$second = 0;
$time = mktime($hour, $minute, $second, $month, $day, $year);
$name = strftime('%A', $time);
$encoding = mb_detect_encoding($name);
if ($encoding === false) {
$name = mb_convert_encoding($name, 'UTF-8', 'ISO-8859-2');
}
return $name;
}
/**
* Returns difference between given dates.
*
@@ -333,9 +156,9 @@ class Date
* If the unit of date difference is null, all units are returned in array (units are keys of the array).
* Otherwise - one, integer value is returned.
*
* @param string|DateTime $dateStart The start date
* @param string|DateTime $dateEnd The end date
* @param int $differenceUnit (optional) Unit of date difference. One of this class
* @param DateTime|string $dateStart The start date
* @param DateTime|string $dateEnd The end date
* @param string $differenceUnit (optional) Unit of date difference. One of this class
* DATE_DIFFERENCE_UNIT_* constants. If is set to null all units are
* returned in the array.
* @return array|int
@@ -356,11 +179,11 @@ class Date
return null;
}
$dateStart = self::getDateTime($dateStart, true);
$dateEnd = self::getDateTime($dateEnd, true);
$start = self::getDateTime($dateStart, true);
$end = self::getDateTime($dateEnd, true);
$difference = [];
$dateDiff = $dateEnd->getTimestamp() - $dateStart->getTimestamp();
$dateDiff = $end->getTimestamp() - $start->getTimestamp();
$daysInSeconds = 0;
$hoursInSeconds = 0;
@@ -378,85 +201,71 @@ class Date
self::DATE_DIFFERENCE_UNIT_MINUTES,
];
if ($differenceUnit === null || $differenceUnit == self::DATE_DIFFERENCE_UNIT_YEARS) {
$diff = $dateEnd->diff($dateStart);
$differenceYear = self::DATE_DIFFERENCE_UNIT_YEARS === $differenceUnit;
$differenceMonth = self::DATE_DIFFERENCE_UNIT_MONTHS === $differenceUnit;
$differenceMinutes = self::DATE_DIFFERENCE_UNIT_MINUTES === $differenceUnit;
/*
* Difference between dates in years should be returned only?
*/
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_YEARS) {
if (null === $differenceUnit || $differenceYear) {
$diff = $end->diff($start);
// Difference between dates in years should be returned only?
if ($differenceYear) {
return $diff->y;
}
$difference[self::DATE_DIFFERENCE_UNIT_YEARS] = $diff->y;
}
if ($differenceUnit === null || $differenceUnit == self::DATE_DIFFERENCE_UNIT_MONTHS) {
$diff = $dateEnd->diff($dateStart);
if (null === $differenceUnit || $differenceMonth) {
$diff = $end->diff($start);
/*
* Difference between dates in months should be returned only?
*/
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_MONTHS) {
// Difference between dates in months should be returned only?
if ($differenceMonth) {
return $diff->m;
}
$difference[self::DATE_DIFFERENCE_UNIT_MONTHS] = $diff->m;
}
if ($differenceUnit === null || in_array($differenceUnit, $relatedUnits)) {
$days = (int)floor($dateDiff / $daySeconds);
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
$days = (int) floor($dateDiff / $daySeconds);
/*
* Difference between dates in days should be returned only?
*/
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_DAYS) {
// Difference between dates in days should be returned only?
if (self::DATE_DIFFERENCE_UNIT_DAYS === $differenceUnit) {
return $days;
}
/*
* All units should be returned?
*/
if ($differenceUnit === null) {
// All units should be returned?
if (null === $differenceUnit) {
$difference[self::DATE_DIFFERENCE_UNIT_DAYS] = $days;
}
/*
* Calculation for later usage
*/
// Calculation for later usage
$daysInSeconds = $days * $daySeconds;
}
if ($differenceUnit === null || in_array($differenceUnit, $relatedUnits)) {
$hours = (int)floor(($dateDiff - $daysInSeconds) / $hourSeconds);
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
$hours = (int) floor(($dateDiff - $daysInSeconds) / $hourSeconds);
/*
* Difference between dates in hours should be returned only?
*/
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_HOURS) {
// Difference between dates in hours should be returned only?
if (self::DATE_DIFFERENCE_UNIT_HOURS === $differenceUnit) {
return $hours;
}
/*
* All units should be returned?
*/
if ($differenceUnit === null) {
// All units should be returned?
if (null === $differenceUnit) {
$difference[self::DATE_DIFFERENCE_UNIT_HOURS] = $hours;
}
/*
* Calculation for later usage
*/
// Calculation for later usage
$hoursInSeconds = $hours * $hourSeconds;
}
if ($differenceUnit === null || $differenceUnit == self::DATE_DIFFERENCE_UNIT_MINUTES) {
$minutes = (int)floor(($dateDiff - $daysInSeconds - $hoursInSeconds) / 60);
if (null === $differenceUnit || $differenceMinutes) {
$minutes = (int) floor(($dateDiff - $daysInSeconds - $hoursInSeconds) / 60);
/*
* Difference between dates in minutes should be returned only?
*/
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_MINUTES) {
// Difference between dates in minutes should be returned only?
if ($differenceMinutes) {
return $minutes;
}
@@ -466,85 +275,6 @@ class Date
return $difference;
}
/**
* Returns collection / set of dates for given start date and count of dates.
* Start from given date, add next, iterated value to given date interval and returns requested count of dates.
*
* @param DateTime $startDate The start date. Start of the collection / set.
* @param int $datesCount Count of dates in resulting collection / set
* @param string $intervalTemplate (optional) Template used to build date interval. It should contain "%d" as the
* placeholder which is replaced with a number that represents each iteration.
* Default: interval for days.
* @return array
*/
public static function getDatesCollection(DateTime $startDate, $datesCount, $intervalTemplate = 'P%dD')
{
$dates = [];
/*
* The template used to build date interval have to be string.
* Otherwise cannot run preg_match() function and an error occurs.
*/
if (is_string($intervalTemplate)) {
/*
* Let's verify the interval template. It should contains the "%d" placeholder and something before and
* after it.
*
* Examples:
* - P%dD
* - P%dM
* - P1Y%dMT1H
*/
$intervalPattern = '/^(\w*)\%d(\w*)$/';
$matches = [];
$matchCount = preg_match($intervalPattern, $intervalTemplate, $matches);
if ($matchCount > 0 && (!empty($matches[1]) || !empty($matches[2]))) {
$datesCount = (int)$datesCount;
for ($index = 1; $index <= $datesCount; ++$index) {
$date = clone $startDate;
$dates[$index] = $date->add(new DateInterval(sprintf($intervalTemplate, $index)));
}
}
}
return $dates;
}
/**
* Returns random date based on given start date
*
* @param DateTime $startDate The start date. Start of the random date.
* @param int $start (optional) Start of random partition
* @param int $end (optional) End of random partition
* @param string $intervalTemplate (optional) Template used to build date interval. The placeholder is replaced
* with next, iterated value.
* @return DateTime
*/
public static function getRandomDate(DateTime $startDate = null, $start = 1, $end = 100, $intervalTemplate = 'P%sD')
{
if ($startDate === null) {
$startDate = new DateTime();
}
$start = (int)$start;
$end = (int)$end;
/*
* Incorrect end of random partition?
* Use start as the end of random partition
*/
if ($end < $start) {
$end = $start;
}
$randomDate = clone $startDate;
$randomInterval = new DateInterval(sprintf($intervalTemplate, rand($start, $end)));
return $randomDate->add($randomInterval);
}
/**
* Returns the DateTime object for given value.
* If the DateTime object cannot be created, false is returned.
@@ -552,11 +282,12 @@ class Date
* @param mixed $value The value which maybe is a date
* @param bool $allowCompoundFormats (optional) If is set to true, the compound formats used to create an
* instance of DateTime class are allowed (e.g. "now", "last day of next
* month", "yyyy"). Otherwise - not and every incorrect value is refused.
* month", "yyyy"). Otherwise - not and every incorrect value is refused
* (default behaviour).
* @param string $dateFormat (optional) Format of date used to verify if given value is actually a date.
* It should be format matched to the given value, e.g. "Y-m-d H:i" for
* "2015-01-01 10:00" value.
* @return DateTime|bool
* "2015-01-01 10:00" value. Default: "Y-m-d".
* @return bool|DateTime
*/
public static function getDateTime($value, $allowCompoundFormats = false, $dateFormat = 'Y-m-d')
{
@@ -590,7 +321,7 @@ class Date
*/
$dateFromFormat = DateTime::createFromFormat($dateFormat, $value);
if ($dateFromFormat === false) {
if (false === $dateFromFormat) {
/*
* Nothing to do more, because:
* a) instance of the DateTime was created
@@ -623,7 +354,7 @@ class Date
* So, I have to refuse those special compound formats if they are not explicitly declared as
* compound (2nd argument of this method, set to false by default)
*/
if (in_array($value, $specialFormats)) {
if (in_array($value, $specialFormats, true)) {
return false;
}
}
@@ -631,12 +362,10 @@ class Date
* Verify instance of the DateTime created by constructor and by createFromFormat() method.
* After formatting, these dates should be the same.
*/
else {
if ($dateFromFormat->format($dateFormat) === $value) {
return $date;
}
elseif ($dateFromFormat->format($dateFormat) === $value) {
return $date;
}
} catch (\Exception $exception) {
} catch (Exception $exception) {
if (!$allowCompoundFormats) {
return false;
}
@@ -648,15 +377,284 @@ class Date
*/
$dateString = (new DateTime())->format($value);
if ($dateString != $value) {
if ($dateString !== (string) $value) {
return new DateTime($dateString);
}
} catch (\Exception $exception) {
} catch (Exception $exception) {
}
return false;
}
/**
* Returns collection / set of dates for given start date and count of dates.
* Start from given date, add next, iterated value to given date interval and returns requested count of dates.
*
* @param DateTime $startDate The start date. Start of the collection / set.
* @param int $datesCount Count of dates in resulting collection / set
* @param string $intervalTemplate (optional) Template used to build date interval. It should contain "%d" as the
* placeholder which is replaced with a number that represents each iteration.
* Default: interval for days.
* @return array
* @throws Exception
*/
public static function getDatesCollection(DateTime $startDate, $datesCount, $intervalTemplate = 'P%dD'): array
{
$dates = [];
/*
* The template used to build date interval have to be string.
* Otherwise cannot run preg_match() function and an error occurs.
*/
if (is_string($intervalTemplate)) {
/*
* Let's verify the interval template. It should contains the "%d" placeholder and something before and
* after it.
*
* Examples:
* - P%dD
* - P%dM
* - P1Y%dMT1H
*/
$intervalPattern = '/^(\w*)\%d(\w*)$/';
$matches = [];
$matchCount = preg_match($intervalPattern, $intervalTemplate, $matches);
if ($matchCount > 0 && (!empty($matches[1]) || !empty($matches[2]))) {
$datesCount = (int) $datesCount;
for ($index = 1; $index <= $datesCount; ++$index) {
$date = clone $startDate;
$dates[$index] = $date->add(new DateInterval(sprintf($intervalTemplate, $index)));
}
}
}
return $dates;
}
/**
* Returns date's period (that contains start and end date) for given period
*
* @param string $period The period, type of period. One of DatePeriod class constants, e.g. DatePeriod::LAST_WEEK.
* @return null|DatePeriod
* @throws Exception
*/
public static function getDatesForPeriod(string $period): ?DatePeriod
{
/*
* Type of period is incorrect?
* Nothing to do
*/
if (!DatePeriod::isCorrectType($period)) {
return null;
}
$dateStart = null;
$dateEnd = null;
switch ($period) {
case DatePeriod::LAST_WEEK:
$thisWeekStart = new DateTime('this week');
$dateStart = clone $thisWeekStart;
$dateEnd = clone $thisWeekStart;
$dateStart->sub(new DateInterval('P7D'));
$dateEnd->sub(new DateInterval('P1D'));
break;
case DatePeriod::THIS_WEEK:
$dateStart = new DateTime('this week');
$dateEnd = clone $dateStart;
$dateEnd->add(new DateInterval('P6D'));
break;
case DatePeriod::NEXT_WEEK:
$dateStart = new DateTime('this week');
$dateStart->add(new DateInterval('P7D'));
$dateEnd = clone $dateStart;
$dateEnd->add(new DateInterval('P6D'));
break;
case DatePeriod::LAST_MONTH:
$dateStart = new DateTime('first day of last month');
$dateEnd = new DateTime('last day of last month');
break;
case DatePeriod::THIS_MONTH:
$lastMonth = self::getDatesForPeriod(DatePeriod::LAST_MONTH);
$nextMonth = self::getDatesForPeriod(DatePeriod::NEXT_MONTH);
if (null !== $lastMonth) {
$dateStart = $lastMonth->getEndDate();
if (null !== $dateStart) {
$dateStart->add(new DateInterval('P1D'));
}
}
if (null !== $nextMonth) {
$dateEnd = $nextMonth->getStartDate();
if (null !== $dateEnd) {
$dateEnd->sub(new DateInterval('P1D'));
}
}
break;
case DatePeriod::NEXT_MONTH:
$dateStart = new DateTime('first day of next month');
$dateEnd = new DateTime('last day of next month');
break;
case DatePeriod::LAST_YEAR:
case DatePeriod::THIS_YEAR:
case DatePeriod::NEXT_YEAR:
$dateStart = new DateTime();
$dateEnd = new DateTime();
$yearPeriod = [
DatePeriod::LAST_YEAR,
DatePeriod::NEXT_YEAR,
];
if (in_array($period, $yearPeriod, true)) {
$yearDifference = 1;
if (DatePeriod::LAST_YEAR === $period) {
$yearDifference *= -1;
}
$modifyString = sprintf('%s year', $yearDifference);
$dateStart->modify($modifyString);
$dateEnd->modify($modifyString);
}
$year = (int) $dateStart->format('Y');
$dateStart->setDate($year, 1, 1);
$dateEnd->setDate($year, 12, 31);
break;
}
/*
* Start or end date is unknown?
* Nothing to do
*/
if (null === $dateStart || null === $dateEnd) {
return null;
}
$dateStart->setTime(0, 0);
$dateEnd->setTime(23, 59, 59);
return new DatePeriod($dateStart, $dateEnd);
}
/**
* Returns day of week (number 0 to 6, 0 - sunday, 6 - saturday).
* Based on the Zeller's algorithm (https://en.wikipedia.org/wiki/Perpetual_calendar).
*
* @param int $year The year value
* @param int $month The month value
* @param int $day The day value
*
* @return int
* @throws UnknownDatePartTypeException
*/
public static function getDayOfWeek(int $year, int $month, int $day): int
{
static::validateYear($year);
static::validateMonth($month);
static::validateDay($day);
if ($month < 3) {
$count = 0;
$yearValue = $year - 1;
} else {
$count = 2;
$yearValue = $year;
}
$firstPart = floor(23 * $month / 9);
$secondPart = floor($yearValue / 4);
$thirdPart = floor($yearValue / 100);
$fourthPart = floor($yearValue / 400);
return ($firstPart + $day + 4 + $year + $secondPart - $thirdPart + $fourthPart - $count) % 7;
}
/**
* Returns name of weekday based on locale
*
* @param int $year The year value
* @param int $month The month value
* @param int $day The day value
* @return string
*/
public static function getDayOfWeekName($year, $month, $day): string
{
$hour = 0;
$minute = 0;
$second = 0;
$time = mktime($hour, $minute, $second, $month, $day, $year);
$name = strftime('%A', $time);
$encoding = mb_detect_encoding($name);
if (false === $encoding) {
$name = mb_convert_encoding($name, 'UTF-8', 'ISO-8859-2');
}
return $name;
}
/**
* Returns random date based on given start date
*
* @param DateTime $startDate (optional) Beginning of the random date. If not provided, current date will
* be used (default behaviour).
* @param int $start (optional) Start of random partition. If not provided, 1 will be used
* (default behaviour).
* @param int $end (optional) End of random partition. If not provided, 100 will be used
* (default behaviour).
* @param string $intervalTemplate (optional) Template used to build date interval. The placeholder is replaced
* with next, iterated value. If not provided, "P%sD" will be used (default
* behaviour).
* @return DateTime
* @throws Exception
*/
public static function getRandomDate(
DateTime $startDate = null,
$start = 1,
$end = 100,
$intervalTemplate = 'P%sD'
): DateTime {
if (null === $startDate) {
$startDate = new DateTime();
}
$start = (int) $start;
$end = (int) $end;
/*
* Incorrect end of random partition?
* Use start as the end of random partition
*/
if ($end < $start) {
$end = $start;
}
$randomDate = clone $startDate;
$randomInterval = new DateInterval(sprintf($intervalTemplate, random_int($start, $end)));
return $randomDate->add($randomInterval);
}
/**
* Returns information if given value is valid date
*
@@ -666,7 +664,7 @@ class Date
* month", "yyyy"). Otherwise - not and every incorrect value is refused.
* @return bool
*/
public static function isValidDate($value, $allowCompoundFormats = false)
public static function isValidDate($value, $allowCompoundFormats = false): bool
{
return self::getDateTime($value, $allowCompoundFormats) instanceof DateTime;
}
@@ -677,38 +675,77 @@ class Date
* @param string $format The validated format of date
* @return bool
*/
public static function isValidDateFormat($format)
public static function isValidDateFormat($format): bool
{
if (empty($format) || !is_string($format)) {
return false;
}
/*
* Datetime to string
*/
$formatted = (new DateTime())->format($format);
/*
* Formatted date it's the format who is validated?
* The format is invalid
*/
if ($formatted == $format) {
// Formatted date it's the format who is validated?
// The format is invalid
if ($formatted === $format) {
return false;
}
/*
* Validate the format used to create the datetime
*/
// Validate the format used to create the datetime
$fromFormat = DateTime::createFromFormat($format, $formatted);
/*
* It's instance of DateTime?
* The format is valid
*/
// It's instance of DateTime?
// The format is valid
if ($fromFormat instanceof DateTime) {
return true;
}
return $fromFormat instanceof DateTime;
}
/**
* Verifies/validates given day
*
* @param int $day Day to verify/validate
* @throws UnknownDatePartTypeException
*/
private static function validateDay(int $day): void
{
// Oops, given day is incorrect
if ($day >= 1 && $day <= 31) {
return;
}
throw UnknownDatePartTypeException::createException(DatePartType::DAY, $day);
}
/**
* Verifies/validates given month
*
* @param int $month Month to verify/validate
* @throws UnknownDatePartTypeException
*/
private static function validateMonth(int $month): void
{
// Oops, given month is incorrect
if ($month >= 1 && $month <= 12) {
return;
}
throw UnknownDatePartTypeException::createException(DatePartType::MONTH, $month);
}
/**
* Verifies/validates given year
*
* @param int $year Year to verify/validate
* @throws UnknownDatePartTypeException
*/
private static function validateYear(int $year): void
{
// Oops, given year is incorrect
if ($year >= 0) {
return;
}
throw UnknownDatePartTypeException::createException(DatePartType::YEAR, $year);
}
}

View File

@@ -13,8 +13,8 @@ use Generator;
/**
* Useful methods for the Generator class (only static functions)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class GeneratorUtility
{

Some files were not shown because too many files have changed in this diff Show More