13 Commits
0.1.1 ... 0.1.3

Author SHA1 Message Date
Krzysztof Nizioł
e31af27c01 Merge branch 'master' of github.com:meritoo/common-library
# Conflicts:
#	README.md
2018-09-06 22:01:00 +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
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
23 changed files with 1326 additions and 362 deletions

View File

@@ -2,6 +2,18 @@
Common and useful classes, methods, exceptions etc.
# 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

View File

@@ -6,10 +6,22 @@ Common and useful classes, methods, exceptions etc.
# Installation
In your `composer.json` add address of repository into `repositories` section:
```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 meritoo/common-library
composer require wiosna-dev/common-library
```
> [How to install Composer?](https://getcomposer.org/download)
@@ -20,6 +32,7 @@ composer require meritoo/common-library
2. [Collection of elements](docs/Collection-of-elements.md)
3. [Exceptions](docs/Static-methods.md)
4. [Static methods](docs/Static-methods.md)
5. [Value Objects](docs/Value-Objects.md)
# Development

View File

@@ -1 +1 @@
0.1.1
0.1.3

View File

@@ -1,5 +1,5 @@
{
"name": "meritoo/common-library",
"name": "wiosna-dev/common-library",
"description": "Useful classes, methods, extensions etc.",
"license": "MIT",
"authors": [
@@ -11,6 +11,7 @@
],
"require": {
"php": ">=5.6",
"ext-intl": "*",
"ext-pcre": "*",
"doctrine/orm": "^2.5",
"gedmo/doctrine-extensions": "^2.4"

View File

@@ -9,12 +9,12 @@ services:
build:
context: ./docker/config
args:
- TIMEZONE=$TIMEZONE
- TIMEZONE=${TIMEZONE}
volumes:
- .:/project
- .:/project:cached
composer:
image: ${DOCKER_CONTAINER_OWNER}/${DOCKER_CONTAINER_PROJECT}-php
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-composer
entrypoint: composer
volumes:
- .:/project
- .:/project:cached

View File

@@ -48,5 +48,6 @@ class MimeTypesTest extends BaseTestCase
2. [Collection of elements](Collection-of-elements.md)
3. [Exceptions](Exceptions.md)
4. [Static methods](Static-methods.md)
5. [Value Objects](Value-Objects.md)
[‹ Back to `Readme`](../README.md)

View File

@@ -46,5 +46,6 @@ var_dump($simpleCollection->has('dolor')); // bool(true)
2. [**Collection of elements**](Collection-of-elements.md)
3. [Exceptions](Exceptions.md)
4. [Static methods](Static-methods.md)
5. [Value Objects](Value-Objects.md)
[‹ Back to `Readme`](../README.md)

View File

@@ -57,5 +57,6 @@ class UnknownSimpleTypeException extends UnknownTypeException
2. [Collection of elements](Collection-of-elements.md)
3. [**Exceptions**](Exceptions.md)
4. [Static methods](Static-methods.md)
5. [Value Objects](Value-Objects.md)
[‹ Back to `Readme`](../README.md)

View File

@@ -19,5 +19,6 @@ var_dump($firstElement); // string(5) "lorem"
2. [Collection of elements](Collection-of-elements.md)
3. [Exceptions](Exceptions.md)
4. [**Static methods**](Static-methods.md)
5. [Value Objects](Value-Objects.md)
[‹ Back to `Readme`](../README.md)

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

@@ -0,0 +1,53 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# Value Objects
Located in `Meritoo\Common\ValueObject` namespace.
### Version
##### Namespace
`Meritoo\Common\ValueObject\Version`
##### Info
Represents version of software. Contains 3 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()` - creates new instance using given version as array
```php
Version::fromArray([1, 0, 2]);
```
2. `fromString()` - creates new instance using given version as string:
```php
Version::fromString('1.0.2');
```
# More
1. [Base test case (with common methods and data providers)](Base-test-case.md)
2. [Collection of elements](Collection-of-elements.md)
3. [Exceptions](Exceptions.md)
4. [Static methods](Static-methods.md)
5. [**Value Objects**](Value-Objects.md)
[‹ Back to `Readme`](../README.md)

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\Reflection;
/**
* 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 string $property Name of the property
* @return NotExistingPropertyException
*/
public static function create($object, $property)
{
$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

@@ -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 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 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 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 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);
}
/**
* 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);
}
}

View File

@@ -49,6 +49,20 @@ trait BaseTestCaseTrait
yield[[]];
}
/**
* Provides an empty scalar value
*
* @return Generator
*/
public function provideEmptyScalarValue()
{
yield[''];
yield[' '];
yield[null];
yield[0];
yield[false];
}
/**
* Provides boolean value
*

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 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);
}
/**
* 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);
}
}

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

@@ -119,11 +119,15 @@ class Date
$lastMonth = self::getDatesForPeriod(DatePeriod::LAST_MONTH);
$nextMonth = self::getDatesForPeriod(DatePeriod::NEXT_MONTH);
$dateStart = $lastMonth->getEndDate();
$dateStart->add(new DateInterval('P1D'));
if (null !== $lastMonth) {
$dateStart = $lastMonth->getEndDate();
$dateStart->add(new DateInterval('P1D'));
}
$dateEnd = $nextMonth->getStartDate();
$dateEnd->sub(new DateInterval('P1D'));
if (null !== $nextMonth) {
$dateEnd = $nextMonth->getStartDate();
$dateEnd->sub(new DateInterval('P1D'));
}
break;
case DatePeriod::NEXT_MONTH:
@@ -137,10 +141,10 @@ class Date
$dateStart = new DateTime();
$dateEnd = new DateTime();
if (DatePeriod::LAST_YEAR == $period || DatePeriod::NEXT_YEAR == $period) {
if (DatePeriod::LAST_YEAR === $period || DatePeriod::NEXT_YEAR === $period) {
$yearDifference = 1;
if (DatePeriod::LAST_YEAR == $period) {
if (DatePeriod::LAST_YEAR === $period) {
$yearDifference *= -1;
}
@@ -220,7 +224,6 @@ class Date
/**
* Returns current day of week
*
* @throws UnknownDatePartTypeException
* @return int
*/
public static function getCurrentDayOfWeek()
@@ -368,11 +371,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;
@@ -390,39 +393,39 @@ class Date
self::DATE_DIFFERENCE_UNIT_MINUTES,
];
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_YEARS == $differenceUnit) {
$diff = $dateEnd->diff($dateStart);
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_YEARS === $differenceUnit) {
$diff = $end->diff($start);
/*
* Difference between dates in years should be returned only?
*/
if (self::DATE_DIFFERENCE_UNIT_YEARS == $differenceUnit) {
if (self::DATE_DIFFERENCE_UNIT_YEARS === $differenceUnit) {
return $diff->y;
}
$difference[self::DATE_DIFFERENCE_UNIT_YEARS] = $diff->y;
}
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MONTHS == $differenceUnit) {
$diff = $dateEnd->diff($dateStart);
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MONTHS === $differenceUnit) {
$diff = $end->diff($start);
/*
* Difference between dates in months should be returned only?
*/
if (self::DATE_DIFFERENCE_UNIT_MONTHS == $differenceUnit) {
if (self::DATE_DIFFERENCE_UNIT_MONTHS === $differenceUnit) {
return $diff->m;
}
$difference[self::DATE_DIFFERENCE_UNIT_MONTHS] = $diff->m;
}
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits)) {
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
$days = (int)floor($dateDiff / $daySeconds);
/*
* Difference between dates in days should be returned only?
*/
if (self::DATE_DIFFERENCE_UNIT_DAYS == $differenceUnit) {
if (self::DATE_DIFFERENCE_UNIT_DAYS === $differenceUnit) {
return $days;
}
@@ -439,13 +442,13 @@ class Date
$daysInSeconds = $days * $daySeconds;
}
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits)) {
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
$hours = (int)floor(($dateDiff - $daysInSeconds) / $hourSeconds);
/*
* Difference between dates in hours should be returned only?
*/
if (self::DATE_DIFFERENCE_UNIT_HOURS == $differenceUnit) {
if (self::DATE_DIFFERENCE_UNIT_HOURS === $differenceUnit) {
return $hours;
}
@@ -462,13 +465,13 @@ class Date
$hoursInSeconds = $hours * $hourSeconds;
}
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MINUTES == $differenceUnit) {
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MINUTES === $differenceUnit) {
$minutes = (int)floor(($dateDiff - $daysInSeconds - $hoursInSeconds) / 60);
/*
* Difference between dates in minutes should be returned only?
*/
if (self::DATE_DIFFERENCE_UNIT_MINUTES == $differenceUnit) {
if (self::DATE_DIFFERENCE_UNIT_MINUTES === $differenceUnit) {
return $minutes;
}
@@ -554,7 +557,7 @@ class Date
}
$randomDate = clone $startDate;
$randomInterval = new DateInterval(sprintf($intervalTemplate, rand($start, $end)));
$randomInterval = new DateInterval(sprintf($intervalTemplate, mt_rand($start, $end)));
return $randomDate->add($randomInterval);
}
@@ -637,7 +640,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;
}
}
@@ -662,7 +665,7 @@ class Date
*/
$dateString = (new DateTime())->format($value);
if ($dateString != $value) {
if ($dateString !== (string)$value) {
return new DateTime($dateString);
}
} catch (\Exception $exception) {
@@ -706,7 +709,7 @@ class Date
* Formatted date it's the format who is validated?
* The format is invalid
*/
if ($formatted == $format) {
if ($formatted === $format) {
return false;
}

View File

@@ -9,8 +9,6 @@
namespace Meritoo\Common\Utilities;
use Gedmo\Sluggable\Util\Urlizer;
use Meritoo\Common\Exception\Regex\IncorrectColorHexLengthException;
use Meritoo\Common\Exception\Regex\InvalidColorHexValueException;
use Transliterator;
/**
@@ -62,15 +60,15 @@ class Miscellaneous
$startFileName = mb_substr($startFileName, 1);
}
$directoryContent = scandir($directoryPath);
$directoryContent = scandir($directoryPath, SCANDIR_SORT_ASCENDING);
if (!empty($directoryContent)) {
foreach ($directoryContent as $fileName) {
if ('.' != $fileName && '..' != $fileName) {
if ('.' !== $fileName && '..' !== $fileName) {
$content = null;
if (!empty($startFileName) && !$startFileFound) {
if ($fileName == $startFileName) {
if ($fileName === $startFileName) {
$startFileFound = true;
}
@@ -84,18 +82,18 @@ class Miscellaneous
if (null !== $content) {
$files[$fileName] = $content;
if (!empty($maxFilesCount)) {
if (null !== $maxFilesCount) {
$count += Arrays::getNonArrayElementsCount($content);
}
} else {
$files[] = $fileName;
if (!empty($maxFilesCount)) {
if (null !== $maxFilesCount) {
++$count;
}
}
if (!empty($maxFilesCount) && $count >= $maxFilesCount) {
if (null !== $maxFilesCount && $count >= $maxFilesCount) {
break;
}
}
@@ -160,11 +158,17 @@ class Miscellaneous
*/
public static function includeFileExtension($fileName, $extension)
{
if (self::getFileExtension($fileName, true) != strtolower($extension)) {
return sprintf('%s.%s', $fileName, $extension);
$fileExtension = self::getFileExtension($fileName, true);
/*
* File has given extension?
* Nothing to do
*/
if ($fileExtension === strtolower($extension)) {
return $fileName;
}
return $fileName;
return sprintf('%s.%s', $fileName, $extension);
}
/**
@@ -229,31 +233,28 @@ class Miscellaneous
/*
* Let's clear name of file
*
* Attention. The name without extension may be cleared / urlized only
* to avoid incorrect name by replacing "." with "-".
* Attention.
* The name without extension may be cleared / urlized only to avoid incorrect name by replacing "." with "-".
*/
$withoutExtension = Urlizer::urlize($withoutExtension);
/*
* Now I have to complete the template used to build / generate unique name
*/
$template = '%s-%s'; // file's name and unique key
if ($objectId > 0) {
$template .= '-%s'; // object ID
}
$template .= '.%s'; // file's extension
$template = '%s-%s.%s'; // [file's name]-[unique key].[file's extension]
/*
* Add some uniqueness
*/
$unique = uniqid(mt_rand(), true);
$unique = self::getUniqueString(mt_rand());
/*
* Finally build and return the unique name
*/
if ($objectId > 0) {
$template = '%s-%s-%s.%s'; // [file's name]-[unique key]-[object ID].[file's extension]
return sprintf($template, $withoutExtension, $unique, $objectId, $extension);
}
@@ -333,7 +334,7 @@ class Miscellaneous
{
$phpModulesArray = get_loaded_extensions();
return in_array($phpModuleName, $phpModulesArray);
return in_array($phpModuleName, $phpModulesArray, false);
}
/**
@@ -461,7 +462,7 @@ class Miscellaneous
* Value to find is neither a string nor an array OR it's an empty string?
* Nothing to do
*/
if ((!$searchIsString && !$searchIsArray) || ($searchIsString && 0 == strlen($search))) {
if ((!$searchIsString && !$searchIsArray) || ($searchIsString && '' === $search)) {
return $effect;
}
@@ -486,7 +487,7 @@ class Miscellaneous
* Second step: replace with regular expressions.
* Attention. Searched and replacement value should be the same type: strings or arrays.
*/
if ($effect == $subject && ($bothAreStrings || $bothAreArrays)) {
if ($effect === $subject && ($bothAreStrings || $bothAreArrays)) {
if ($quoteStrings && $replacementIsString) {
$replacement = '\'' . $replacement . '\'';
}
@@ -504,7 +505,7 @@ class Miscellaneous
* Third step: complex replace of the replacement defined as an array.
* It may be useful when you want to search for a one string and replace the string with multiple values.
*/
if ($effect == $subject && $searchIsString && $replacementIsArray) {
if ($effect === $subject && $searchIsString && $replacementIsArray) {
$subjectIsArray = is_array($subject);
$effect = '';
@@ -589,7 +590,12 @@ class Miscellaneous
*/
public static function getOperatingSystemNameServer()
{
return php_uname('s');
return PHP_OS;
/*
* Previous version:
* return php_uname('s');
*/
}
/**
@@ -681,7 +687,8 @@ class Miscellaneous
$spacePosition = mb_strrpos($lineWithAberration, ' ', 0, $encoding);
if ($spacePosition > 0) {
if (false !== $spacePosition && 0 < $spacePosition) {
/* @var int $spacePosition */
$perLine = $spacePosition;
$insertSeparator = true;
}
@@ -738,8 +745,8 @@ class Miscellaneous
return unlink($directoryPath);
}
foreach (scandir($directoryPath) as $item) {
if ('.' == $item || '..' == $item) {
foreach (scandir($directoryPath, SCANDIR_SORT_ASCENDING) as $item) {
if ('.' === $item || '..' === $item) {
continue;
}
@@ -788,7 +795,7 @@ class Miscellaneous
foreach ($members as $key => $value) {
$value = mb_strtolower($value);
if (0 == $key) {
if (0 === $key) {
$effect .= self::lowercaseFirst($value);
} else {
$effect .= self::uppercaseFirst($value);
@@ -809,10 +816,6 @@ class Miscellaneous
* - null (default): nothing is done with the string
* - true: the rest of string is lowercased
* - false: the rest of string is uppercased
*
* Some explanation:
* Function lcfirst() is available for PHP >= 5.30, so I wrote my own function that lowercases first character of
* the string.
*/
public static function lowercaseFirst($text, $restLowercase = null)
{
@@ -828,16 +831,7 @@ class Miscellaneous
$effect = mb_strtoupper($effect);
}
if (function_exists('lcfirst')) {
$effect = lcfirst($effect);
} else {
$first = mb_strtolower($effect[0]);
$rest = mb_substr($effect, 1);
$effect = $first . $rest;
}
return $effect;
return lcfirst($effect);
}
/**
@@ -866,16 +860,7 @@ class Miscellaneous
$effect = mb_strtoupper($effect);
}
if (function_exists('ucfirst')) {
$effect = ucfirst($effect);
} else {
$first = mb_strtoupper($effect[0]);
$rest = mb_substr($effect, 1);
$effect = $first . $rest;
}
return $effect;
return ucfirst($effect);
}
/**
@@ -916,9 +901,9 @@ class Miscellaneous
'TB',
'PB',
];
$index = floor(log($sizeInBytes, 1024));
$size = round($sizeInBytes / pow(1024, $index), 2);
$index = floor(log($sizeInBytes, 1024));
$size = round($sizeInBytes / (1024 ** $index), 2);
$unit = $units[(int)$index];
return sprintf('%s %s', $size, $unit);
@@ -1194,10 +1179,6 @@ class Miscellaneous
if (null !== $globalSource && isset($globalSource[$variableName])) {
$value = $globalSource[$variableName];
if (!ini_get('magic_quotes_gpc')) {
$value = addslashes($value);
}
}
}
@@ -1243,7 +1224,7 @@ class Miscellaneous
continue;
}
$text = $text . '0';
$text .= '0';
}
return $text;
@@ -1298,8 +1279,8 @@ class Miscellaneous
if ($asHexadecimal) {
$hexadecimal = dechex($colorComponent);
if (1 == strlen($hexadecimal)) {
return sprintf('0%s', $hexadecimal, $hexadecimal);
if (1 === strlen($hexadecimal)) {
return sprintf('0%s', $hexadecimal);
}
return $hexadecimal;
@@ -1312,8 +1293,6 @@ class Miscellaneous
* Returns inverted value of color for given color
*
* @param string $color Hexadecimal value of color to invert (with or without hash), e.g. "dd244c" or "#22a5fe"
* @throws IncorrectColorHexLengthException
* @throws InvalidColorHexValueException
* @return string
*/
public static function getInvertedColor($color)
@@ -1328,14 +1307,14 @@ class Miscellaneous
* Verify and get valid value of color.
* An exception will be thrown if the value is not a color.
*/
$color = Regex::getValidColorHexValue($color);
$validColor = Regex::getValidColorHexValue($color);
/*
* Grab color's components
*/
$red = hexdec(substr($color, 0, 2));
$green = hexdec(substr($color, 2, 2));
$blue = hexdec(substr($color, 4, 2));
$red = hexdec(substr($validColor, 0, 2));
$green = hexdec(substr($validColor, 2, 2));
$blue = hexdec(substr($validColor, 4, 2));
/*
* Calculate inverted color's components

View File

@@ -13,12 +13,8 @@ use Doctrine\Common\Util\Inflector;
use Meritoo\Common\Collection\Collection;
use Meritoo\Common\Exception\Reflection\CannotResolveClassNameException;
use Meritoo\Common\Exception\Reflection\MissingChildClassesException;
use Meritoo\Common\Exception\Reflection\NotExistingPropertyException;
use Meritoo\Common\Exception\Reflection\TooManyChildClassesException;
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
use ReflectionObject;
use ReflectionProperty;
/**
* Useful reflection methods
@@ -34,21 +30,20 @@ class Reflection
* @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.
* @throws ReflectionException
* @return array
*/
public static function getMethods($class, $withoutInheritance = false)
{
$effect = [];
$reflection = new ReflectionClass($class);
$reflection = new \ReflectionClass($class);
$methods = $reflection->getMethods();
if (!empty($methods)) {
$className = self::getClassName($class);
foreach ($methods as $method) {
if ($method instanceof ReflectionMethod) {
if ($method instanceof \ReflectionMethod) {
if ($withoutInheritance && $className !== $method->class) {
continue;
}
@@ -65,12 +60,11 @@ class Reflection
* Returns constants of given class / object
*
* @param object|string $class The object or name of object's class
* @throws ReflectionException
* @return array
*/
public static function getConstants($class)
{
$reflection = new ReflectionClass($class);
$reflection = new \ReflectionClass($class);
return $reflection->getConstants();
}
@@ -80,7 +74,6 @@ class Reflection
* Constants whose values are integers are considered only.
*
* @param object|string $class The object or name of object's class
* @throws ReflectionException
* @return int|null
*/
public static function getMaxNumberConstant($class)
@@ -107,12 +100,11 @@ class Reflection
*
* @param object|string $class The object or name of object's class
* @param string $method Name of the method to find
* @throws ReflectionException
* @return bool
*/
public static function hasMethod($class, $method)
{
$reflection = new ReflectionClass($class);
$reflection = new \ReflectionClass($class);
return $reflection->hasMethod($method);
}
@@ -122,12 +114,11 @@ class Reflection
*
* @param object|string $class The object or name of object's class
* @param string $property Name of the property to find
* @throws ReflectionException
* @return bool
*/
public static function hasProperty($class, $property)
{
$reflection = new ReflectionClass($class);
$reflection = new \ReflectionClass($class);
return $reflection->hasProperty($property);
}
@@ -137,12 +128,11 @@ class Reflection
*
* @param object|string $class The object or name of object's class
* @param string $constant Name of the constant to find
* @throws ReflectionException
* @return bool
*/
public static function hasConstant($class, $constant)
{
$reflection = new ReflectionClass($class);
$reflection = new \ReflectionClass($class);
return $reflection->hasConstant($constant);
}
@@ -152,12 +142,11 @@ class Reflection
*
* @param object|string $class The object or name of object's class
* @param string $constant Name of the constant that contains a value
* @throws ReflectionException
* @return mixed
*/
public static function getConstantValue($class, $constant)
{
$reflection = new ReflectionClass($class);
$reflection = new \ReflectionClass($class);
if (self::hasConstant($class, $constant)) {
return $reflection->getConstant($constant);
@@ -175,7 +164,6 @@ class Reflection
* 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.
* @throws ReflectionException
* @return mixed
*/
public static function getPropertyValue($object, $property, $force = false)
@@ -197,9 +185,9 @@ class Reflection
* Let's dig more and get proper value
*
* Required to avoid bug:
* ReflectionObject::__construct() expects parameter 1 to be object, null given
* \ReflectionObject::__construct() expects parameter 1 to be object, null given
* (...)
* 4. at ReflectionObject->__construct (null)
* 4. at \ReflectionObject->__construct (null)
* 5. at Reflection ::getPropertyValue (null, 'name', true)
* 6. at ListService->getItemValue (object(Deal), 'project.name', '0')
*
@@ -224,17 +212,17 @@ class Reflection
* Use \ReflectionObject class
*/
try {
$reflectionProperty = new ReflectionProperty($className, $property);
$reflectionProperty = new \ReflectionProperty($className, $property);
$value = $reflectionProperty->getValue($object);
} catch (ReflectionException $exception) {
} catch (\ReflectionException $exception) {
/*
* 2nd try:
* Look for the get / has / is methods
*/
$class = new ReflectionObject($object);
$class = new \ReflectionObject($object);
$valueFound = false;
if ($class->hasProperty($property) || $force) {
if ($force || $class->hasProperty($property)) {
$property = Inflector::classify($property);
$getterPrefixes = [
@@ -247,7 +235,7 @@ class Reflection
$getterName = sprintf('%s%s', $prefix, $property);
if ($class->hasMethod($getterName)) {
$method = new ReflectionMethod($object, $getterName);
$method = new \ReflectionMethod($object, $getterName);
/*
* Getter is not accessible publicly?
@@ -292,7 +280,6 @@ class Reflection
* @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.
* @throws ReflectionException
* @return array
*/
public static function getPropertyValues($objects, $property, $force = false)
@@ -395,13 +382,13 @@ class Reflection
{
$fullClassName = self::getClassName($source);
if (empty($fullClassName)) {
if (null === $fullClassName || '' === $fullClassName) {
return '';
}
$className = self::getClassName($source, true);
if ($className == $fullClassName) {
if ($className === $fullClassName) {
return $className;
}
@@ -420,7 +407,7 @@ class Reflection
$className = self::getClassName($source);
$interfaces = class_implements($className);
return in_array($interface, $interfaces);
return in_array($interface, $interfaces, true);
}
/**
@@ -438,7 +425,7 @@ class Reflection
$parents = class_parents($childClassName);
if (is_array($parents) && 0 < count($parents)) {
return in_array($parentClassName, $parents);
return in_array($parentClassName, $parents, true);
}
return false;
@@ -448,23 +435,22 @@ class Reflection
* 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
* @param int $filter (optional) Filter of properties. Uses \ReflectionProperty class
* constants. By default all properties are returned.
* @param bool $includeParents (optional) If is set to true, properties of parent classes are
* included (recursively). Otherwise - not.
* @throws ReflectionException
* @return array|ReflectionProperty
* @return array|\ReflectionProperty
*/
public static function getProperties($source, $filter = null, $includeParents = false)
{
$className = self::getClassName($source);
$reflection = new ReflectionClass($className);
$reflection = new \ReflectionClass($className);
if (null === $filter) {
$filter = ReflectionProperty::IS_PRIVATE
+ ReflectionProperty::IS_PROTECTED
+ ReflectionProperty::IS_PUBLIC
+ ReflectionProperty::IS_STATIC;
$filter = \ReflectionProperty::IS_PRIVATE
+ \ReflectionProperty::IS_PROTECTED
+ \ReflectionProperty::IS_PUBLIC
+ \ReflectionProperty::IS_STATIC;
}
$properties = $reflection->getProperties($filter);
@@ -486,13 +472,12 @@ class Reflection
* Returns a parent class or false if there is no parent class
*
* @param array|object|string $source An array of objects, namespaces, object or namespace
* @throws ReflectionException
* @return ReflectionClass|bool
* @return \ReflectionClass|bool
*/
public static function getParentClass($source)
{
$className = self::getClassName($source);
$reflection = new ReflectionClass($className);
$reflection = new \ReflectionClass($className);
return $reflection->getParentClass();
}
@@ -541,7 +526,7 @@ class Reflection
*/
$realClass = ClassUtils::getRealClass($oneClass);
if (in_array($realClass, $childClasses)) {
if (in_array($realClass, $childClasses, true)) {
continue;
}
@@ -586,14 +571,13 @@ class Reflection
}
/**
* Returns property, the ReflectionProperty instance, of given object
* 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.
* @param int $filter (optional) Filter of properties. Uses \ReflectionProperty class constants.
* By default all properties are allowed / processed.
* @throws ReflectionException
* @return null|ReflectionProperty
* @return null|\ReflectionProperty
*/
public static function getProperty($class, $property, $filter = null)
{
@@ -601,9 +585,9 @@ class Reflection
$properties = self::getProperties($className, $filter);
if (!empty($properties)) {
/* @var $reflectionProperty ReflectionProperty */
/* @var $reflectionProperty \ReflectionProperty */
foreach ($properties as $reflectionProperty) {
if ($reflectionProperty->getName() == $property) {
if ($reflectionProperty->getName() === $property) {
return $reflectionProperty;
}
}
@@ -630,21 +614,21 @@ class Reflection
/*
* Oops, cannot resolve class
*/
if (empty($className)) {
if (null === $className || '' === $className) {
throw CannotResolveClassNameException::create($class);
}
/*
* Oops, cannot resolve trait
*/
if (empty($traitName)) {
if (null === $traitName || '' === $traitName) {
throw new CannotResolveClassNameException($class, false);
}
$reflection = new ReflectionClass($className);
$reflection = new \ReflectionClass($className);
$traitsNames = $reflection->getTraitNames();
$uses = in_array($traitName, $traitsNames);
$uses = in_array($traitName, $traitsNames, true);
if (!$uses && $verifyParents) {
$parentClassName = self::getParentClassName($className);
@@ -662,13 +646,12 @@ class Reflection
* If given class does not extend another, returns null.
*
* @param array|object|string $class An array of objects, namespaces, object or namespace
* @throws ReflectionException
* @return string|null
*/
public static function getParentClassName($class)
{
$className = self::getClassName($class);
$reflection = new ReflectionClass($className);
$reflection = new \ReflectionClass($className);
$parentClass = $reflection->getParentClass();
if (null === $parentClass || false === $parentClass) {
@@ -677,4 +660,36 @@ class Reflection
return $parentClass->getName();
}
/**
* Sets value of given property
*
* @param mixed $object Object that should contains given property
* @param string $property Name of the property
* @param mixed $value Value of the property
* @throws NotExistingPropertyException
*/
public static function setPropertyValue($object, $property, $value)
{
$reflectionProperty = self::getProperty($object, $property);
/*
* Oops, property does not exist
*/
if (null === $reflectionProperty) {
throw NotExistingPropertyException::create($object, $property);
}
$notAccessible = $reflectionProperty->isPrivate() || $reflectionProperty->isProtected();
if ($notAccessible) {
$reflectionProperty->setAccessible(true);
}
$reflectionProperty->setValue($object, $value);
if ($notAccessible) {
$reflectionProperty->setAccessible(false);
}
}
}

View File

@@ -517,7 +517,12 @@ letsTest[2] = value_2;';
self::assertTrue(Arrays::areKeysInArray($keys17, $this->complexArray, false));
}
public function testGetLastElementsPaths()
public function testGetLastElementsPathsUsingEmptyArray()
{
self::assertSame([], Arrays::getLastElementsPaths([]));
}
public function testGetLastElementsPathsUsingDefaults()
{
/*
* Using default separator and other default arguments
@@ -536,7 +541,10 @@ letsTest[2] = value_2;';
];
self::assertEquals($expected, Arrays::getLastElementsPaths($this->complexArray));
}
public function testGetLastElementsPathsUsingCustomSeparator()
{
/*
* Using custom separator
*/
@@ -555,204 +563,20 @@ letsTest[2] = value_2;';
];
self::assertEquals($expected, Arrays::getLastElementsPaths($this->complexArray, $separator));
}
/*
* Special exception: do not use, stop recursive on the "diam" key
*/
$expected = [
'lorem.ipsum.dolor' => 'sit',
'consectetur' => 'adipiscing',
'mollis' => 1234,
2 => [],
'sit.nullam' => 'donec',
'sit.aliquet.vitae.ligula' => 'quis',
'sit.0' => 'elit',
'amet.0' => 'iaculis',
'amet.1' => 'primis',
'lorem.ipsum.diam' => [
'non' => 'egestas',
],
];
$stopIfMatchedBy = 'diam';
self::assertEquals($expected, Arrays::getLastElementsPaths($this->complexArray, '.', '', $stopIfMatchedBy));
/*
* Stop building of paths on these keys:
* - "diam"
* - "aliquet"
*/
$expected = [
'lorem . ipsum . dolor' => 'sit',
'consectetur' => 'adipiscing',
'mollis' => 1234,
2 => [],
'sit . nullam' => 'donec',
'sit . 0' => 'elit',
'amet . 0' => 'iaculis',
'amet . 1' => 'primis',
'lorem . ipsum . diam' => [
'non' => 'egestas',
],
'sit . aliquet' => [
'vitae' => [
'ligula' => 'quis',
],
],
];
$stopIfMatchedBy = [
'diam',
'aliquet',
];
self::assertEquals($expected, Arrays::getLastElementsPaths($this->complexArray, ' . ', '', $stopIfMatchedBy));
$expected = [
'ipsum > quis > vestibulum > porta-1' => [
'turpis',
'urna',
],
'ipsum > quis > vestibulum > porta-2' => [
'tortor' => [
'in' => [
'dui',
'dolor' => [
'aliquam',
],
],
],
],
'ipsum > quis > vestibulum > porta-3' => [
1,
2,
3,
],
'primis > 0' => [
'in',
'faucibus',
'orci',
],
'primis > 1' => [
'luctus',
'et',
'ultrices',
],
];
/*
* Stop building of paths on more sophisticated keys
*/
$stopIfMatchedBy = [
'porta\-\d+',
'^\d+$',
];
self::assertEquals($expected, Arrays::getLastElementsPaths($this->superComplexArray, ' > ', '', $stopIfMatchedBy));
/*
* Stop building of paths on these:
* - keys
* and
* - paths (verify paths too)
*/
$expected = [
'lorem > ipsum > dolor' => 'sit',
'consectetur' => 'adipiscing',
'mollis' => 1234,
2 => [],
'sit > nullam' => 'donec',
'sit > 0' => 'elit',
'amet > 0' => 'iaculis',
'amet > 1' => 'primis',
'lorem > ipsum > diam' => [
'non' => 'egestas',
],
'sit > aliquet > vitae' => [
'ligula' => 'quis',
],
];
$stopIfMatchedBy = [
'diam',
'sit > aliquet > vitae',
];
self::assertEquals($expected, Arrays::getLastElementsPaths($this->complexArray, ' > ', '', $stopIfMatchedBy));
/*
* Stop building of paths on these paths (verify paths only)
*/
$expected = [
'ipsum > quis > vestibulum > porta-1' => [
'turpis',
'urna',
],
'ipsum > quis > vestibulum > porta-2 > tortor' => [
'in' => [
'dui',
'dolor' => [
'aliquam',
],
],
],
'ipsum > quis > vestibulum > porta-3 > 0' => 1,
'ipsum > quis > vestibulum > porta-3 > 1' => 2,
'ipsum > quis > vestibulum > porta-3 > 2' => 3,
'primis > 0 > 0' => 'in',
'primis > 0 > 1' => 'faucibus',
'primis > 0 > 2' => 'orci',
'primis > 1' => [
'luctus',
'et',
'ultrices',
],
];
$stopIfMatchedBy = [
'ipsum > quis > vestibulum > porta-1',
'ipsum > quis > vestibulum > porta-2 > tortor',
'primis > 1',
];
self::assertEquals($expected, Arrays::getLastElementsPaths($this->superComplexArray, ' > ', '', $stopIfMatchedBy));
/*
* Stop building of paths if path contains any of these part (verify part of paths only)
*/
$expected = [
'ipsum > quis > vestibulum > porta-1' => [
'turpis',
'urna',
],
'ipsum > quis > vestibulum > porta-2 > tortor > in' => [
'dui',
'dolor' => [
'aliquam',
],
],
'ipsum > quis > vestibulum > porta-3 > 0' => 1,
'ipsum > quis > vestibulum > porta-3 > 1' => 2,
'ipsum > quis > vestibulum > porta-3 > 2' => 3,
'primis > 0' => [
'in',
'faucibus',
'orci',
],
'primis > 1' => [
'luctus',
'et',
'ultrices',
],
];
$stopIfMatchedBy = [
'vestibulum > porta-1',
'tortor > in',
'[a-z]+ > \d+',
];
self::assertEquals($expected, Arrays::getLastElementsPaths($this->superComplexArray, ' > ', '', $stopIfMatchedBy));
/**
* @param string|array $stopIfMatchedBy Patterns of keys or paths that matched will stop the process of path
* building and including children of those keys or paths (recursive will
* not be used for keys in lower level of given array)
* @param string $separator Separator used in resultant strings. Default: ".".
* @param array $expected Expected array
*
* @dataProvider provideStopIfMatchedByForGetLastElementsPaths
*/
public function testGetLastElementsPathsUsingStopIfMatchedBy($stopIfMatchedBy, $separator, array $expected)
{
self::assertEquals($expected, Arrays::getLastElementsPaths($this->superComplexArray, $separator, '', $stopIfMatchedBy));
}
public function testAreAllKeysMatchedByPattern()
@@ -1760,6 +1584,229 @@ letsTest[2] = value_2;';
];
}
/**
* Provides patterns of keys or paths that matched will stop the process and the expected array for the
* getLastElementsPaths() method
*
* @return \Generator
*/
public function provideStopIfMatchedByForGetLastElementsPaths()
{
/*
* Special exception: do not use, stop recursive on the "diam" key
*/
yield[
'diam',
'.',
[
'ipsum.quis.vestibulum.porta-1.0' => 'turpis',
'ipsum.quis.vestibulum.porta-1.1' => 'urna',
'ipsum.quis.vestibulum.porta-2.tortor.in.0' => 'dui',
'ipsum.quis.vestibulum.porta-2.tortor.in.dolor.0' => 'aliquam',
'ipsum.quis.vestibulum.porta-3.0' => 1,
'ipsum.quis.vestibulum.porta-3.1' => 2,
'ipsum.quis.vestibulum.porta-3.2' => 3,
'primis.0.0' => 'in',
'primis.0.1' => 'faucibus',
'primis.0.2' => 'orci',
'primis.1.0' => 'luctus',
'primis.1.1' => 'et',
'primis.1.2' => 'ultrices',
],
];
/*
* Stop building of paths on these keys:
* - "tortor"
* - "primis"
*/
yield[
[
'tortor',
'primis',
],
' . ',
[
'ipsum . quis . vestibulum . porta-1 . 0' => 'turpis',
'ipsum . quis . vestibulum . porta-1 . 1' => 'urna',
'ipsum . quis . vestibulum . porta-2 . tortor' => [
'in' => [
'dui',
'dolor' => [
'aliquam',
],
],
],
'ipsum . quis . vestibulum . porta-3 . 0' => 1,
'ipsum . quis . vestibulum . porta-3 . 1' => 2,
'ipsum . quis . vestibulum . porta-3 . 2' => 3,
'primis' => [
[
'in',
'faucibus',
'orci',
],
[
'luctus',
'et',
'ultrices',
],
],
],
];
/*
* Stop building of paths on more sophisticated keys
*/
yield[
[
'porta\-\d+',
'^\d+$',
],
' > ',
[
'ipsum > quis > vestibulum > porta-1' => [
'turpis',
'urna',
],
'ipsum > quis > vestibulum > porta-2' => [
'tortor' => [
'in' => [
'dui',
'dolor' => [
'aliquam',
],
],
],
],
'ipsum > quis > vestibulum > porta-3' => [
1,
2,
3,
],
'primis > 0' => [
'in',
'faucibus',
'orci',
],
'primis > 1' => [
'luctus',
'et',
'ultrices',
],
],
];
/*
* Stop building of paths on these:
* - keys
* and
* - paths (verify paths too)
*/
yield[
[
'porta-1',
'porta-2 > tortor > in',
],
' > ',
[
'ipsum > quis > vestibulum > porta-1' => [
'turpis',
'urna',
],
'ipsum > quis > vestibulum > porta-2 > tortor > in' => [
'dui',
'dolor' => [
'aliquam',
],
],
'ipsum > quis > vestibulum > porta-3 > 0' => 1,
'ipsum > quis > vestibulum > porta-3 > 1' => 2,
'ipsum > quis > vestibulum > porta-3 > 2' => 3,
'primis > 0 > 0' => 'in',
'primis > 0 > 1' => 'faucibus',
'primis > 0 > 2' => 'orci',
'primis > 1 > 0' => 'luctus',
'primis > 1 > 1' => 'et',
'primis > 1 > 2' => 'ultrices',
],
];
/*
* Stop building of paths on these paths (verify paths only)
*/
yield[
[
'ipsum > quis > vestibulum > porta-1',
'ipsum > quis > vestibulum > porta-2 > tortor',
'primis > 1',
],
' > ',
[
'ipsum > quis > vestibulum > porta-1' => [
'turpis',
'urna',
],
'ipsum > quis > vestibulum > porta-2 > tortor' => [
'in' => [
'dui',
'dolor' => [
'aliquam',
],
],
],
'ipsum > quis > vestibulum > porta-3 > 0' => 1,
'ipsum > quis > vestibulum > porta-3 > 1' => 2,
'ipsum > quis > vestibulum > porta-3 > 2' => 3,
'primis > 0 > 0' => 'in',
'primis > 0 > 1' => 'faucibus',
'primis > 0 > 2' => 'orci',
'primis > 1' => [
'luctus',
'et',
'ultrices',
],
],
];
/*
* Stop building of paths if path contains any of these part (verify part of paths only)
*/
yield[
[
'vestibulum > porta-1',
'tortor > in',
'[a-z]+ > \d+',
],
' > ',
[
'ipsum > quis > vestibulum > porta-1' => [
'turpis',
'urna',
],
'ipsum > quis > vestibulum > porta-2 > tortor > in' => [
'dui',
'dolor' => [
'aliquam',
],
],
'ipsum > quis > vestibulum > porta-3 > 0' => 1,
'ipsum > quis > vestibulum > porta-3 > 1' => 2,
'ipsum > quis > vestibulum > porta-3 > 2' => 3,
'primis > 0' => [
'in',
'faucibus',
'orci',
],
'primis > 1' => [
'luctus',
'et',
'ultrices',
],
],
];
}
/**
* {@inheritdoc}
*/
@@ -1877,10 +1924,12 @@ letsTest[2] = value_2;';
{
parent::tearDown();
unset($this->simpleArray);
unset($this->simpleArrayWithKeys);
unset($this->twoDimensionsArray);
unset($this->complexArray);
unset($this->superComplexArray);
unset(
$this->simpleArray,
$this->simpleArrayWithKeys,
$this->twoDimensionsArray,
$this->complexArray,
$this->superComplexArray
);
}
}

View File

@@ -0,0 +1,185 @@
<?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\Utilities;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Utilities\Bootstrap4CssSelector;
/**
* Test case of the 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 Bootstrap4CssSelectorTest extends BaseTestCase
{
public function testConstructor()
{
static::assertHasNoConstructor(Bootstrap4CssSelector::class);
}
/**
* @param string $emptyValue Name of form (value of the "name" attribute)
* @dataProvider provideEmptyScalarValue
*/
public function testGetRadioButtonErrorSelectorUsingEmptyFormName($emptyValue)
{
$fieldSetIndex = 1;
static::assertSame('', Bootstrap4CssSelector::getRadioButtonErrorSelector($emptyValue, $fieldSetIndex));
}
public function testGetRadioButtonErrorSelectorUsingNegativeFieldSetIndex()
{
static::assertSame('', Bootstrap4CssSelector::getRadioButtonErrorSelector('test-test', -1));
}
/**
* @param string $formName Name of form (value of the "name" attribute)
* @param int $fieldSetIndex Index/Position of the field-set
* @param string $expected Expected selector
*
* @dataProvider provideFormNameFieldSetIndexAndSelector
*/
public function testGetRadioButtonErrorSelector($formName, $fieldSetIndex, $expected)
{
static::assertSame($expected, Bootstrap4CssSelector::getRadioButtonErrorSelector($formName, $fieldSetIndex));
}
/**
* @param string $emptyValue Name of form (value of the "name" attribute)
* @dataProvider provideEmptyScalarValue
*/
public function testGetFieldErrorSelectorUsingEmptyFormName($emptyValue)
{
$fieldName = 'test';
static::assertSame('', Bootstrap4CssSelector::getFieldErrorSelector($emptyValue, $fieldName));
}
/**
* @param string $emptyValue Name of field (value of the "name" attribute)
* @dataProvider provideEmptyScalarValue
*/
public function testGetFieldErrorSelectorUsingEmptyFieldName($emptyValue)
{
$formName = 'test';
static::assertSame('', Bootstrap4CssSelector::getFieldErrorSelector($formName, $emptyValue));
}
/**
* @param string $formName Name of form (value of the "name" attribute)
* @param string $fieldName Name of field (value of the "name" attribute)
* @param string $expected Expected selector
*
* @dataProvider provideFormNameFieldNameAndSelector
*/
public function testGetFieldErrorSelector($formName, $fieldName, $expected)
{
static::assertSame($expected, Bootstrap4CssSelector::getFieldErrorSelector($formName, $fieldName));
}
/**
* @param string $emptyValue Name of form (value of the "name" attribute)
* @dataProvider provideEmptyScalarValue
*/
public function testGetFieldGroupSelectorUsingEmptyFormName($emptyValue)
{
static::assertSame('', Bootstrap4CssSelector::getFieldGroupSelector($emptyValue));
}
/**
* @param string $formName Name of form (value of the "name" attribute)
* @param string $expected Expected selector
*
* @dataProvider provideFormNameAndSelector
*/
public function testGetFieldGroupSelector($formName, $expected)
{
static::assertSame($expected, Bootstrap4CssSelector::getFieldGroupSelector($formName));
}
public function testGetFieldErrorContainerSelector()
{
static::assertSame('.invalid-feedback .form-error-message', Bootstrap4CssSelector::getFieldErrorContainerSelector());
}
/**
* Provides name of form, index/position of the field-set and expected selector
*
* @return \Generator
*/
public function provideFormNameFieldSetIndexAndSelector()
{
yield[
'test',
0,
'form[name="test"] fieldset:nth-of-type(0) legend.col-form-label .invalid-feedback .form-error-message',
];
yield[
'test-123-test-456',
1,
'form[name="test-123-test-456"] fieldset:nth-of-type(1) legend.col-form-label .invalid-feedback .form-error-message',
];
yield[
'test_something_098_different',
1245,
'form[name="test_something_098_different"] fieldset:nth-of-type(1245) legend.col-form-label .invalid-feedback .form-error-message',
];
}
/**
* Provides name of form, name of field and expected selector
*
* @return \Generator
*/
public function provideFormNameFieldNameAndSelector()
{
yield[
'test',
'test',
'form[name="test"] label[for="test"] .invalid-feedback .form-error-message',
];
yield[
'test-123-test-456',
'great-000-field',
'form[name="test-123-test-456"] label[for="great-000-field"] .invalid-feedback .form-error-message',
];
yield[
'test_something_098_different',
'this-is-the-123789-field',
'form[name="test_something_098_different"] label[for="this-is-the-123789-field"] .invalid-feedback .form-error-message',
];
}
/**
* Provides name of form and expected selector
*
* @return \Generator
*/
public function provideFormNameAndSelector()
{
yield[
'test',
'form[name="test"] .form-group',
];
yield[
'test-123-test-456',
'form[name="test-123-test-456"] .form-group',
];
yield[
'test_something_098_different',
'form[name="test_something_098_different"] .form-group',
];
}
}

View File

@@ -0,0 +1,296 @@
<?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\Utilities;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Utilities\CssSelector;
/**
* Test case of the useful methods related to CSS selectors
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class CssSelectorTest extends BaseTestCase
{
public function testConstructor()
{
static::assertHasNoConstructor(CssSelector::class);
}
/**
* @param string $emptyValue Name of form (value of the "name" attribute)
* @dataProvider provideEmptyScalarValue
*/
public function testGetFormByNameSelectorUsingEmptyName($emptyValue)
{
static::assertSame('', CssSelector::getFormByNameSelector($emptyValue));
}
/**
* @param string $formName Name of form (value of the "name" attribute)
* @param string $expected Expected selector
*
* @dataProvider provideFormNameAndSelector
*/
public function testGetFormByNameSelector($formName, $expected)
{
static::assertSame($expected, CssSelector::getFormByNameSelector($formName));
}
/**
* @param string $emptyValue Name of form (value of the "name" attribute)
* @dataProvider provideEmptyScalarValue
*/
public function testGetInputByNameSelectorUsingEmptyFormName($emptyValue)
{
$fieldName = 'test-test';
static::assertSame('', CssSelector::getInputByNameSelector($emptyValue, $fieldName));
}
/**
* @param string $emptyValue Name of field (value of the "name" attribute)
* @dataProvider provideEmptyScalarValue
*/
public function testGetInputByNameSelectorUsingEmptyFieldName($emptyValue)
{
$formName = 'test-test';
static::assertSame('', CssSelector::getInputByNameSelector($formName, $emptyValue));
}
/**
* @param string $formName Name of form (value of the "name" attribute)
* @param string $fieldName Name of field (value of the "name" attribute)
* @param string $expected Expected selector
*
* @dataProvider provideFormNameFieldNameAndSelector
*/
public function testGetInputByNameSelector($formName, $fieldName, $expected)
{
static::assertSame($expected, CssSelector::getInputByNameSelector($formName, $fieldName));
}
/**
* @param string $emptyValue Name of form (value of the "name" attribute)
* @dataProvider provideEmptyScalarValue
*/
public function testGetInputByIdSelectorUsingEmptyFormName($emptyValue)
{
$fieldId = 'test-test';
static::assertSame('', CssSelector::getInputByIdSelector($emptyValue, $fieldId));
}
/**
* @param string $emptyValue ID of field (value of the "id" attribute)
* @dataProvider provideEmptyScalarValue
*/
public function testGetInputByIdSelectorUsingEmptyFieldName($emptyValue)
{
$formName = 'test-test';
static::assertSame('', CssSelector::getInputByIdSelector($formName, $emptyValue));
}
/**
* @param string $formName Name of form (value of the "name" attribute)
* @param string $fieldId ID of field (value of the "id" attribute)
* @param string $expected Expected selector
*
* @dataProvider provideFormNameFieldIdAndSelector
*/
public function testGetInputByIdSelector($formName, $fieldId, $expected)
{
static::assertSame($expected, CssSelector::getInputByIdSelector($formName, $fieldId));
}
/**
* @param string $emptyValue Name of form (value of the "name" attribute)
* @dataProvider provideEmptyScalarValue
*/
public function testGetLabelSelectorUsingEmptyFormName($emptyValue)
{
$fieldId = 'test-test';
static::assertSame('', CssSelector::getLabelSelector($emptyValue, $fieldId));
}
/**
* @param string $emptyValue ID of field (value of the "id" attribute)
* @dataProvider provideEmptyScalarValue
*/
public function testGetLabelSelectorUsingEmptyFieldId($emptyValue)
{
$formName = 'test-test';
static::assertSame('', CssSelector::getLabelSelector($formName, $emptyValue));
}
/**
* @param string $formName Name of form (value of the "name" attribute)
* @param string $fieldId ID of field (value of the "id" attribute)
* @param string $expected Expected selector
*
* @dataProvider provideFormNameFieldIdAndLabelSelector
*/
public function testGetLabelSelector($formName, $fieldId, $expected)
{
static::assertSame($expected, CssSelector::getLabelSelector($formName, $fieldId));
}
/**
* @param string $emptyValue Name of form (value of the "name" attribute)
* @dataProvider provideEmptyScalarValue
*/
public function testGetFieldSetByIndexSelectorUsingEmptyFormName($emptyValue)
{
$fieldSetIndex = 1;
static::assertSame('', CssSelector::getFieldSetByIndexSelector($emptyValue, $fieldSetIndex));
}
public function testGetFieldSetByIndexSelectorUsingNegativeFieldSetIndex()
{
static::assertSame('', CssSelector::getFieldSetByIndexSelector('test-test', -1));
}
/**
* @param string $formName Name of form (value of the "name" attribute)
* @param int $fieldSetIndex Index/Position of the field-set
* @param string $expected Expected selector
*
* @dataProvider provideFormNameFieldSetIndexAndSelector
*/
public function testGetFieldSetByIndexSelector($formName, $fieldSetIndex, $expected)
{
static::assertSame($expected, CssSelector::getFieldSetByIndexSelector($formName, $fieldSetIndex));
}
/**
* Provides name of form and selector of the form
*
* @return \Generator
*/
public function provideFormNameAndSelector()
{
yield[
'test',
'form[name="test"]',
];
yield[
'test-123-test-456',
'form[name="test-123-test-456"]',
];
yield[
'test_something_098_different',
'form[name="test_something_098_different"]',
];
}
/**
* Provides name of form, name of field and expected selector
*
* @return \Generator
*/
public function provideFormNameFieldNameAndSelector()
{
yield[
'test',
'test',
'form[name="test"] input[name="test"]',
];
yield[
'test-123-test-456',
'great-000-field',
'form[name="test-123-test-456"] input[name="great-000-field"]',
];
yield[
'test_something_098_different',
'this-is-the-123789-field',
'form[name="test_something_098_different"] input[name="this-is-the-123789-field"]',
];
}
/**
* Provides name of form, ID of field and expected selector of label
*
* @return \Generator
*/
public function provideFormNameFieldIdAndLabelSelector()
{
yield[
'test',
'test',
'form[name="test"] label[for="test"]',
];
yield[
'test-123-test-456',
'great-000-field',
'form[name="test-123-test-456"] label[for="great-000-field"]',
];
yield[
'test_something_098_different',
'this-is-the-123789-field',
'form[name="test_something_098_different"] label[for="this-is-the-123789-field"]',
];
}
/**
* Provides name of form, index/position of the field-set and expected selector
*
* @return \Generator
*/
public function provideFormNameFieldSetIndexAndSelector()
{
yield[
'test',
0,
'form[name="test"] fieldset:nth-of-type(0)',
];
yield[
'test-123-test-456',
1,
'form[name="test-123-test-456"] fieldset:nth-of-type(1)',
];
yield[
'test_something_098_different',
1245,
'form[name="test_something_098_different"] fieldset:nth-of-type(1245)',
];
}
/**
* Provides name of form, ID of field and expected selector
*
* @return \Generator
*/
public function provideFormNameFieldIdAndSelector()
{
yield[
'test',
'test',
'form[name="test"] input#test',
];
yield[
'test-123-test-456',
'great-000-field',
'form[name="test-123-test-456"] input#great-000-field',
];
yield[
'test_something_098_different',
'this-is-the-123789-field',
'form[name="test_something_098_different"] input#this-is-the-123789-field',
];
}
}

View File

@@ -164,7 +164,7 @@ class MiscellaneousTest extends BaseTestCase
$expected = "int(123)\n";
if ($xdebugLoaded) {
$libraryPath = realpath(sprintf('%s%s', dirname(__FILE__), '/../..'));
$libraryPath = realpath(sprintf('%s%s', __DIR__, '/../..'));
$filePath = sprintf('%s%s', $libraryPath, '/src/Utilities/Miscellaneous.php:');
/*
@@ -348,7 +348,10 @@ class MiscellaneousTest extends BaseTestCase
public function testGetOperatingSystemNameServer()
{
self::assertEquals(php_uname('s'), Miscellaneous::getOperatingSystemNameServer());
/*
* While running Docker OS is a Linux
*/
self::assertEquals('Linux', Miscellaneous::getOperatingSystemNameServer());
}
public function testSubstringToWord()

View File

@@ -13,6 +13,7 @@ use Generator;
use Meritoo\Common\Collection\Collection;
use Meritoo\Common\Exception\Reflection\CannotResolveClassNameException;
use Meritoo\Common\Exception\Reflection\MissingChildClassesException;
use Meritoo\Common\Exception\Reflection\NotExistingPropertyException;
use Meritoo\Common\Exception\Reflection\TooManyChildClassesException;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Test\Utilities\Reflection\A;
@@ -474,6 +475,37 @@ class ReflectionTest extends BaseTestCase
static::assertEquals('name', $property->getName());
}
/**
* @param mixed $object Object that should contains given property
* @param string $property Name of the property
*
* @dataProvider provideObjectAndNotExistingProperty
*/
public function testSetPropertyValueUsingNotExistingProperty($object, $property)
{
$this->setExpectedException(NotExistingPropertyException::class);
$object = new \stdClass();
Reflection::setPropertyValue($object, 'test', 'test test test');
}
/**
* @param mixed $object Object that should contains given property
* @param string $property Name of the property
* @param mixed $value Value of the property
*
* @dataProvider provideObjectPropertyAndValue
*/
public function testSetPropertyValue($object, $property, $value)
{
$oldValue = Reflection::getPropertyValue($object, $property);
Reflection::setPropertyValue($object, $property, $value);
$newValue = Reflection::getPropertyValue($object, $property);
static::assertNotSame($oldValue, $value);
static::assertSame($newValue, $value);
}
/**
* Provides invalid class and trait
*
@@ -501,4 +533,59 @@ class ReflectionTest extends BaseTestCase
[],
];
}
/**
* Provides object and name of not existing property
*
* @return Generator
*/
public function provideObjectAndNotExistingProperty()
{
yield[
new \stdClass(),
'test',
];
yield[
new A(),
'test',
];
yield[
new B(),
'firstName',
];
}
/**
* Provides object, name of property and value of the property
*
* @return Generator
*/
public function provideObjectPropertyAndValue()
{
yield[
new A(),
'count',
123,
];
yield[
new B(),
'name',
'test test',
];
yield[
new G(),
'firstName',
'Jane',
];
yield[
new G(),
'lastName',
'Smith',
];
}
}