100 Commits

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
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
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
119 changed files with 7208 additions and 1621 deletions

View File

@@ -1,64 +0,0 @@
FROM php:5.5-cli
#
# Tools & libraries
#
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
vim \
git \
zip \
unzip \
zlib1g-dev \
libicu-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
#
# PHP extensions
#
RUN docker-php-ext-install \
zip \
intl \
mbstring
#
# PHP configuration:
# - default configuration
# - timezone
#
COPY php.ini /usr/local/etc/php/php.ini
ARG TIMEZONE
RUN echo "\n""date.timezone = $TIMEZONE""\n" >> /usr/local/etc/php/php.ini
#
# Xdebug
#
RUN pecl install xdebug \
&& docker-php-ext-enable xdebug
COPY xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
#
# Phing
#
RUN pear channel-discover pear.phing.info \
&& pear install [--alldeps] phing/phing
#
# Composer + https://packagist.org/packages/hirak/prestissimo package
#
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php -r "if (hash_file('SHA384', 'composer-setup.php') === \
'544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo \
'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
&& php -r "unlink('composer-setup.php');" \
&& composer global require --no-plugins --no-scripts hirak/prestissimo \
&& rm -rf /root/.composer/cache/*
#
# Bash
#
RUN sed -i 's/^# export/export/g' /root/.bashrc \
&& sed -i 's/^# alias/alias/g' /root/.bashrc \
&& echo "\n"'export PATH=/project/vendor/bin:$PATH'"\n" >> /root/.bashrc

1
.env
View File

@@ -1 +0,0 @@
TIMEZONE=Europe/Warsaw

15
.env.dist Normal file
View File

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

72
.gitignore vendored
View File

@@ -1,51 +1,58 @@
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
# Environment-related parameters
# ------------------------------------------------------------------------------
.env
# ------------------------------------------------------------------------------
### Vendors ### Vendors
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
/vendor/ /vendor/
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
### Composer ### Composer
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
/composer.lock /composer.lock
/composer.phar /composer.phar
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
### Phing ### Phing
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
/.phing/properties /phing/properties
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
### PHPUnit ### PHPUnit
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
/phpunit.xml /phpunit.xml
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
### PHP Coding Standards Fixer generated files ### PHP Coding Standards Fixer
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
/.php_cs
/.php_cs.cache /.php_cs.cache
# ---------------------------------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------
### Build files ### Build files
# ---------------------------------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------
/.build/ /build/
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
### Generated databases ### Generated databases
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
/.data/tmp /data/tmp
*.sql *.sql
*.sqlite *.sqlite
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
### Compiled source ### Compiled source
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
*.com *.com
*.class *.class
*.dll *.dll
@@ -54,23 +61,22 @@
*.so *.so
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
### Shell scripts ### Shell scripts
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
/*.sh /*.sh
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
### JetBrains ### JetBrains
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
/.idea /.idea
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
### NetBeans template ### NetBeans template
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
nbproject/private/ nbproject/private/
build/
nbbuild/ nbbuild/
dist/ dist/
nbdist/ nbdist/
@@ -78,9 +84,9 @@ nbactions.xml
.nb-gradle/ .nb-gradle/
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
### OSX template ### OSX template
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
.DS_Store .DS_Store
.AppleDouble .AppleDouble
.LSOverride .LSOverride
@@ -107,9 +113,9 @@ Temporary Items
.apdisk .apdisk
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
### Linux template ### Linux template
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
*~ *~
# temporary files which can be created if a process still has a handle open of a deleted file # temporary files which can be created if a process still has a handle open of a deleted file
@@ -122,9 +128,9 @@ Temporary Items
.Trash-* .Trash-*
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
### Windows template ### Windows template
# ---------------------------------------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------
# Windows image file caches # Windows image file caches
Thumbs.db Thumbs.db
ehthumbs.db ehthumbs.db

View File

@@ -1,13 +1,6 @@
<?php <?php
$finder = PhpCsFixer\Finder::create() $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([ ->in([
__DIR__ . '/src', __DIR__ . '/src',
__DIR__ . '/tests', __DIR__ . '/tests',
@@ -16,15 +9,19 @@ $finder = PhpCsFixer\Finder::create()
return PhpCsFixer\Config::create() return PhpCsFixer\Config::create()
->setRules([ ->setRules([
'@Symfony' => true, '@Symfony' => true,
'phpdoc_summary' => false,
'phpdoc_separation' => false,
'phpdoc_align' => false,
'cast_spaces' => false,
'binary_operator_spaces' => [ 'binary_operator_spaces' => [
'align_double_arrow' => true, 'align_double_arrow' => true,
], ],
'blank_line_before_return' => false,
'cast_spaces' => false,
'concat_space' => [ 'concat_space' => [
'spacing' => 'one', 'spacing' => 'one',
], ],
'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);

View File

@@ -1,8 +0,0 @@
preset: symfony
disabled:
- phpdoc_annotation_without_dot
- cast_spaces
- concat_without_spaces
- blank_line_before_return
- trim_array_spaces

View File

@@ -4,9 +4,14 @@ php:
- 5.6 - 5.6
- 7.0 - 7.0
- 7.1 - 7.1
- 7.2
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
- composer global require hirak/prestissimo
install: install:
- composer install - travis_wait 30 composer install
script: script:
- php ./vendor/bin/phpunit - php ./vendor/bin/phpunit

49
CHANGELOG.md Normal file
View File

@@ -0,0 +1,49 @@
# Meritoo Common Library
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
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

111
README.md
View File

@@ -1,9 +1,10 @@
# Meritoo Common Library # Meritoo Common Library
Common and useful classes, methods, exceptions etc. Common and useful classes, methods, exceptions etc.
[![Travis](https://img.shields.io/travis/rust-lang/rust.svg?style=flat-square)](https://travis-ci.org/meritoo/common-library) [![Packagist](https://img.shields.io/packagist/v/meritoo/common-library.svg?style=flat-square)](https://packagist.org/packages/meritoo/common-library) [![StyleCI](https://styleci.io/repos/101790028/shield?branch=master)](https://styleci.io/repos/101790028) [![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)](https://coveralls.io/github/meritoo/common-library?branch=master) [![Travis](https://img.shields.io/travis/rust-lang/rust.svg?style=flat-square)](https://travis-ci.org/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)](https://coveralls.io/github/meritoo/common-library?branch=master)
## Installation # Installation
In your `composer.json` add address of repository into `repositories` section: In your `composer.json` add address of repository into `repositories` section:
@@ -20,107 +21,21 @@ In your `composer.json` add address of repository into `repositories` section:
Run [Composer](https://getcomposer.org) to install this package in your project: Run [Composer](https://getcomposer.org) to install this package in your project:
```bash ```bash
$ composer require wiosna-dev/common-library composer require wiosna-dev/common-library
``` ```
> How to install Composer: https://getcomposer.org/download > [How to install Composer?](https://getcomposer.org/download)
## Rebuilding project and tests running # Usage
```bash 1. [Base test case (with common methods and data providers)](docs/Base-test-case.md)
$ docker-compose up -d 2. [Collection of elements](docs/Collection-of-elements.md)
$ docker-compose exec php-cli phing 3. [Exceptions](docs/Static-methods.md)
``` 4. [Static methods](docs/Static-methods.md)
5. [Value Objects](docs/Value-Objects.md)
> What is Docker? https://www.docker.com/what-docker # Development
## Static methods More information [you can find here](docs/Development.md)
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"
```
## Base test case with common methods and data providers
Located here: `Meritoo\Common\Test\Base\BaseTestCase`. Just extend the `BaseTestCase` class and use it like in `Meritoo\Common\Test\Utilities\DateTest` class:
```php
class DateTest extends BaseTestCase
{
/**
* @param mixed $value Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetDateTimeEmptyValue($value)
{
self::assertFalse(Date::getDateTime($value));
}
(...)
}
```
or in `Meritoo\Common\Test\Utilities\MimeTypesTest` class:
```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));
}
(...)
}
```
## Collection of elements
Located here: `Meritoo\Common\Collection\Collection`. It's a set of some elements, 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
Examples of usage below.
#### An empty collection
```php
use Meritoo\Common\Collection\Collection;
$emptyCollection = new Collection();
var_dump($emptyCollection->isEmpty()); // bool(true)
```
#### Simple collection
```php
use Meritoo\Common\Collection\Collection;
$elements = [
'lorem',
'ipsum',
123 => 'dolor',
345 => 'sit',
];
$simpleCollection = new Collection($elements);
var_dump($simpleCollection->has('dolor')); // bool(true)
```
Enjoy! Enjoy!

1
VERSION Normal file
View File

@@ -0,0 +1 @@
0.1.3

View File

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

View File

@@ -2,7 +2,6 @@
"name": "wiosna-dev/common-library", "name": "wiosna-dev/common-library",
"description": "Useful classes, methods, extensions etc.", "description": "Useful classes, methods, extensions etc.",
"license": "MIT", "license": "MIT",
"version": "0.0.17",
"authors": [ "authors": [
{ {
"name": "Meritoo.pl", "name": "Meritoo.pl",
@@ -11,10 +10,11 @@
} }
], ],
"require": { "require": {
"php": ">=5.5.9", "php": ">=5.6",
"ext-intl": "*",
"ext-pcre": "*",
"doctrine/orm": "^2.5", "doctrine/orm": "^2.5",
"gedmo/doctrine-extensions": "^2.4", "gedmo/doctrine-extensions": "^2.4"
"symfony/http-foundation": "^3.3"
}, },
"require-dev": { "require-dev": {
"friendsofphp/php-cs-fixer": "^2.2", "friendsofphp/php-cs-fixer": "^2.2",

View File

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -1,15 +1,20 @@
version: '3' version: '3'
services: services:
php-cli: php:
image: meritoo/common-library image: ${DOCKER_CONTAINER_OWNER}/${DOCKER_CONTAINER_PROJECT}-php
container_name: meritoo-common-library container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-php
working_dir: /project
entrypoint: php entrypoint: php
command: -S 0.0.0.0:9999 command: -S 0.0.0.0:9999
build: build:
context: ./.docker/config context: ./docker/config
args: args:
- TIMEZONE=$TIMEZONE - TIMEZONE=${TIMEZONE}
volumes: 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:cached

131
docker/config/Dockerfile Normal file
View File

@@ -0,0 +1,131 @@
FROM php:5.6-cli
MAINTAINER Meritoo <github@meritoo.pl>
#
# Tools & libraries
#
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
vim \
git \
unzip \
libicu-dev \
locales \
&& apt-get clean \
&& rm -rf \
/var/lib/apt/lists/* \
/tmp/* \
/var/tmp/*
#
# Generating locales:
# - de_DE
# - es_ES
# - en_GB
# - en_US
# - fr_FR
# - it_IT
# - pl_PL
# - ru_RU
#
RUN sed -i 's/^# de_DE/de_DE/g; \
s/^# es_ES/es_ES/g; \
s/^# en_GB/en_GB/g; \
s/^# en_US/en_US/g; \
s/^# fr_FR/fr_FR/g; \
s/^# it_IT/it_IT/g; \
s/^# pl_PL/pl_PL/g; \
s/^# ru_RU/ru_RU/g;' /etc/locale.gen \
&& locale-gen
#
# Set default language
#
# Required to avoid problem with using strange language by error messages.
# Example: "chmod(): Aucun fichier ou dossier de ce type"
#
ENV LANGUAGE=en_US.UTF-8
#
# PHP extensions
#
RUN docker-php-ext-install \
intl \
mbstring
#
# PHP extensions (PECL):
# - Xdebug
#
RUN pecl install \
xdebug-2.5.5 \
&& docker-php-ext-enable \
xdebug
COPY xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
#
# PHP configuration:
# - default configuration
# - timezone
#
COPY php.ini /usr/local/etc/php/php.ini
ARG TIMEZONE
RUN ln -snf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
&& echo ${TIMEZONE} > /etc/timezone \
&& printf '[PHP]\ndate.timezone = "%s"\n' ${TIMEZONE} > /usr/local/etc/php/conf.d/tzone.ini \
&& "date"
#RUN echo "\n""date.timezone = $TIMEZONE""\n" >> /usr/local/etc/php/php.ini
#
# Phing
#
RUN pear channel-discover pear.phing.info \
&& pear install [--alldeps] phing/phing
#
# Composer - environment variables:
# - disable warning about running commands as root/super user
# - disable automatic clearing of sudo sessions
#
# More:
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
#
ENV COMPOSER_ALLOW_SUPERUSER 1
#
# Composer + https://packagist.org/packages/hirak/prestissimo package
#
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php -r "if (hash_file('SHA384', 'composer-setup.php') === \
'544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo \
'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
&& php -r "unlink('composer-setup.php');" \
&& composer global require \
--no-plugins \
--no-scripts \
--no-progress \
--no-suggest \
--no-interaction \
--prefer-dist \
--optimize-autoloader \
--classmap-authoritative \
hirak/prestissimo \
&& rm -rf ~/.composer/cache/* \
&& composer clear-cache \
&& composer --version
#
# Bash
#
RUN sed -i 's/^# export/export/g; \
s/^# alias/alias/g;' ~/.bashrc \
&& echo 'COLUMNS=200'"\n" >> ~/.bashrc
#
# Use project-related binaries globally
#
ENV PATH="/project/vendor/bin:${PATH}"
WORKDIR /project

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

@@ -0,0 +1,53 @@
# 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`. Just extend the `BaseTestCase` class and use it like in `Meritoo\Common\Test\Utilities\DateTest` class:
```php
class DateTest extends BaseTestCase
{
/**
* @param mixed $value Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetDateTimeEmptyValue($value)
{
self::assertFalse(Date::getDateTime($value));
}
(...)
}
```
or in `Meritoo\Common\Test\Utilities\MimeTypesTest` class:
```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-of-elements.md)
3. [Exceptions](Exceptions.md)
4. [Static methods](Static-methods.md)
5. [Value Objects](Value-Objects.md)
[&lsaquo; Back to `Readme`](../README.md)

View File

@@ -0,0 +1,51 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# Collection of elements
Located here: `Meritoo\Common\Collection\Collection`. It's a set of some elements, 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
Examples of usage below.
### An empty collection
```php
use Meritoo\Common\Collection\Collection;
$emptyCollection = new Collection();
var_dump($emptyCollection->isEmpty()); // bool(true)
```
### Simple collection
```php
use Meritoo\Common\Collection\Collection;
$elements = [
'lorem',
'ipsum',
123 => 'dolor',
345 => 'sit',
];
$simpleCollection = new Collection($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**](Collection-of-elements.md)
3. [Exceptions](Exceptions.md)
4. [Static methods](Static-methods.md)
5. [Value Objects](Value-Objects.md)
[&lsaquo; Back to `Readme`](../README.md)

119
docs/Development.md Normal file
View File

@@ -0,0 +1,119 @@
# 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. Install packages by running command:
```bash
docker-compose run composer install
```
> [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 composer <command>
```
Examples below.
##### Install packages
```bash
docker-compose run composer install
```
##### Update packages
```bash
docker-compose run composer update
```
##### Add package
```bash
docker-compose run composer require <vendor>/<package>
```
##### Remove package
```bash
docker-compose run composer remove <vendor>/<package>
```
# Coding Standards Fixer
Fix coding standard by running command:
```bash
docker-compose exec php php-cs-fixer fix
```
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 composer install`.
### Running tests
#### Simply & quick, without code coverage
Tests are running using Docker and `php` service defined in `docker-compose.yml`. Example:
```bash
docker-compose exec php phpunit --no-coverage
```
You can also run them in container. In this case you have to run 2 commands:
1. Enter container:
```bash
docker-compose exec php bash
```
2. Run tests:
```bash
phpunit --no-coverage
```
#### With code coverage
```bash
docker-compose exec php phpunit
```
# Other
Rebuild project and run tests by running command:
```bash
docker-compose exec php phing
```
[&lsaquo; Back to `Readme`](../README.md)

62
docs/Exceptions.md Normal file
View File

@@ -0,0 +1,62 @@
# 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-of-elements.md)
3. [**Exceptions**](Exceptions.md)
4. [Static methods](Static-methods.md)
5. [Value Objects](Value-Objects.md)
[&lsaquo; Back to `Readme`](../README.md)

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

@@ -0,0 +1,24 @@
# 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-of-elements.md)
3. [Exceptions](Exceptions.md)
4. [**Static methods**](Static-methods.md)
5. [Value Objects](Value-Objects.md)
[&lsaquo; 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)
[&lsaquo; Back to `Readme`](../README.md)

View File

@@ -2,12 +2,12 @@
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.14.0"> <project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.14.0">
<!-- Properties --> <!-- Properties -->
<if> <if>
<available file=".phing/properties" property="custom.properties.available"/> <available file="phing/properties" property="custom.properties.available"/>
<then> <then>
<property file=".phing/properties" /> <property file="phing/properties"/>
</then> </then>
<else> <else>
<property file=".phing/properties.dist" /> <property file="phing/properties.dist"/>
</else> </else>
</if> </if>
@@ -21,9 +21,9 @@
depends="app:composer, app:vendors, app:checkout" depends="app:composer, app:vendors, app:checkout"
description="Prepares app to build." /> description="Prepares app to build." />
<!-- Check / update composer --> <!-- Updates Composer and validates composer.* files -->
<target name="app:composer" description="Checks / updates composer"> <target name="app:composer" description="Updates Composer and validates composer.* files">
<echo msg="Checking / updating composer..." /> <echo msg="Updating Composer and validating composer.* files..." />
<if> <if>
<available file="composer.phar" /> <available file="composer.phar" />
@@ -42,7 +42,14 @@
</if> </if>
</else> </else>
</if> </if>
<!-- Update Composer -->
<composer command="selfupdate" /> <composer command="selfupdate" />
<!-- Validate Composer -->
<composer command="validate">
<arg line="--no-check-all --strict" />
</composer>
</target> </target>
<!-- Project Install/update vendors --> <!-- Project Install/update vendors -->
@@ -68,6 +75,8 @@
<then> <then>
<composer php="${composer.php}" composer="${composer.path}" command="install"> <composer php="${composer.php}" composer="${composer.path}" command="install">
<arg value="--optimize-autoloader" /> <arg value="--optimize-autoloader" />
<arg value="--prefer-dist" />
<arg value="--classmap-authoritative" />
</composer> </composer>
</then> </then>
<else> <else>

View File

@@ -31,7 +31,7 @@ assets.installWithSymlink = true
# The cache:clear command should always be called with the --no-warmup option. Warmup should be done via the cache:warmup command. # 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 # https://github.com/symfony/symfony/blob/master/UPGRADE-3.3.md#frameworkbundle
# #
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl> # Meritoo <github@meritoo.pl>
# 2017-06-06 # 2017-06-06
# #
cache.clearWithWarmup = false cache.clearWithWarmup = false
@@ -65,7 +65,7 @@ composer.validate = false
# System directories # System directories
# #
dir.data = ${project.basedir}/.data dir.data = ${project.basedir}/data
dir.src = ${project.basedir}/src dir.src = ${project.basedir}/src
dir.tests = ${project.basedir}/tests dir.tests = ${project.basedir}/tests
@@ -73,7 +73,7 @@ dir.tests = ${project.basedir}/tests
# Build directories # Build directories
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
dir.build = ${project.basedir}/.build dir.build = ${project.basedir}/build
dir.reports = ${dir.build}/logs dir.reports = ${dir.build}/logs
dir.reports.pdepend = ${dir.reports}/pdepend dir.reports.pdepend = ${dir.reports}/pdepend
dir.reports.coverage = ${dir.reports}/phpunit_coverage dir.reports.coverage = ${dir.reports}/phpunit_coverage
@@ -81,7 +81,7 @@ dir.reports.coverage = ${dir.reports}/phpunit_coverage
# Disabled, because unnecessary right now # Disabled, because unnecessary right now
# phpdocumentor/phpdocumentor cannot be installed via Composer # phpdocumentor/phpdocumentor cannot be installed via Composer
# #
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl> # Meritoo <github@meritoo.pl>
# 2017-02-22 # 2017-02-22
# #
#dir.docs = ${dir.build}/docs #dir.docs = ${dir.build}/docs
@@ -91,40 +91,15 @@ dir.reports.coverage = ${dir.reports}/phpunit_coverage
# Data directories # Data directories
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
dir.data.tests = ${dir.data}/tests
dir.data.temporary = ${dir.data}/tmp dir.data.temporary = ${dir.data}/tmp
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# Testing # Testing
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# Test database path # Path of the framework used to run unit tests
# #
tests.database = ${dir.data.temporary}/database.sqlite tests.framework.path = ./vendor/bin/phpunit --verbose --no-coverage --testdox
#
# 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) # Path of the PHP Coding Standards Fixer (http://cs.sensiolabs.org)
# #

View File

@@ -4,19 +4,19 @@
The AutoloaderTask is required to load binaries installed by Composer. 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. The "autoloaderpath" attribute of this task is not required, because it's default value is: vendor/autoload.php.
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-23 2017-02-23
--> -->
<autoloader /> <autoloader />
<!-- Properties --> <!-- Properties -->
<if> <if>
<available file=".phing/properties" property="custom.properties.available"/> <available file="phing/properties" property="custom.properties.available"/>
<then> <then>
<property file=".phing/properties" /> <property file="phing/properties"/>
</then> </then>
<else> <else>
<property file=".phing/properties.dist" /> <property file="phing/properties.dist"/>
</else> </else>
</if> </if>
@@ -48,7 +48,7 @@
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2 a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.* b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
--> -->
@@ -73,7 +73,7 @@
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2 a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.* b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
--> -->
<!--<target name="build:doc"--> <!--<target name="build:doc"-->
@@ -87,7 +87,7 @@
<!-- Test target --> <!-- Test target -->
<target name="build:test" <target name="build:test"
depends="test:phpunit" depends="test:unit"
description="Executes all tests" /> description="Executes all tests" />
<!-- Project build clean --> <!-- Project build clean -->
@@ -103,8 +103,8 @@
<!--<mkdir dir="${dir.docs}" />--> <!--<mkdir dir="${dir.docs}" />-->
<!--<mkdir dir="${dir.docs.phpdoc2}" />--> <!--<mkdir dir="${dir.docs.phpdoc2}" />-->
<mkdir dir="${dir.reports}" /> <mkdir dir="${dir.reports}" />
<mkdir dir="${dir.reports.coverage}" />
<mkdir dir="${dir.reports.pdepend}" /> <mkdir dir="${dir.reports.pdepend}" />
<mkdir dir="${dir.reports.coverage}"/>
</target> </target>
<!-- PHPDocumentor2 API documentation target --> <!-- PHPDocumentor2 API documentation target -->
@@ -113,7 +113,7 @@
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2 a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.* b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
<target name="doc:phpdoc2" description="Generates API documentations"> <target name="doc:phpdoc2" description="Generates API documentations">
@@ -142,7 +142,7 @@
via Composer the Symfony2 standard is not included / available in this package. In this case the PHP Coding 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. Standards Fixer (http://cs.sensiolabs.org) is used.
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
--> -->
<target name="check:cs" description="Checks coding standard"> <target name="check:cs" description="Checks coding standard">
@@ -166,7 +166,7 @@
<!-- <!--
Previous / old version Previous / old version
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
<exec command="phpcpd \-\-log-pmd=${dir.reports}/pmd-cpd.xml ${dir.src}" /> <exec command="phpcpd \-\-log-pmd=${dir.reports}/pmd-cpd.xml ${dir.src}" />
@@ -204,7 +204,7 @@
<!-- <!--
Previous / old version Previous / old version
Krzysztof Niziol <krzysztof.niziol@meritoo.pl> Meritoo <github@meritoo.pl>
2017-02-22 2017-02-22
<exec command="phploc \-\-log-csv=${dir.reports}/phploc.csv ${dir.src}" /> <exec command="phploc \-\-log-csv=${dir.reports}/phploc.csv ${dir.src}" />
@@ -212,94 +212,9 @@
</target> </target>
<!-- Unit tests --> <!-- Unit tests -->
<target name="test:phpunit" description="Executes PHPUnit tests"> <target name="test:unit" description="Executes unit tests">
<!-- Check test database -->
<if>
<not>
<available file="${dir.data.tests}" type="dir" property="dir.data.tests.available" />
</not>
<then>
<mkdir dir="${dir.data.tests}" />
</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..." /> <echo msg="Running unit tests..." />
<coverage-setup database="${dir.reports.coverage}/coverage.db"> <exec command="${tests.framework.path}" passthru="true"/>
<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
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>
-->
</target> </target>
<!-- Checkout and finalization --> <!-- Checkout and finalization -->

View File

@@ -1,16 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false" <phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/4.8/phpunit.xsd"
backupGlobals="true"
backupStaticAttributes="false" backupStaticAttributes="false"
bootstrap="./vendor/autoload.php"
cacheTokens="false"
colors="true" colors="true"
convertErrorsToExceptions="true" convertErrorsToExceptions="true"
convertNoticesToExceptions="true" convertNoticesToExceptions="true"
convertWarningsToExceptions="true" convertWarningsToExceptions="true"
forceCoversAnnotation="false"
mapTestClassNameToCoveredClassName="false"
processIsolation="false" processIsolation="false"
stopOnError="false"
stopOnFailure="false" stopOnFailure="false"
syntaxCheck="true" stopOnIncomplete="false"
bootstrap="./vendor/autoload.php" stopOnSkipped="false"
stopOnRisky="false"
testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
timeoutForSmallTests="1"
timeoutForMediumTests="10"
timeoutForLargeTests="60"
verbose="true"
> >
<php>
<ini name="error_reporting" value="-1"/>
</php>
<testsuites> <testsuites>
<testsuite name="Meritoo Package - Main Test Suite"> <testsuite name="Meritoo Package - Main Test Suite">
<directory>./tests/</directory> <directory>./tests/</directory>
@@ -30,6 +48,6 @@
</groups> </groups>
<logging> <logging>
<log type="coverage-html" target="./.build/logs/phpunit_coverage/html" /> <log type="coverage-html" target="./build/logs/phpunit_coverage/html"/>
</logging> </logging>
</phpunit> </phpunit>

View File

@@ -18,8 +18,8 @@ use Meritoo\Common\Utilities\Arrays;
* Collection of elements. * Collection of elements.
* It's a set of some elements, e.g. objects. * It's a set of some elements, e.g. objects.
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class Collection implements Countable, ArrayAccess, IteratorAggregate class Collection implements Countable, ArrayAccess, IteratorAggregate
{ {
@@ -109,7 +109,7 @@ class Collection implements Countable, ArrayAccess, IteratorAggregate
*/ */
public function add($element, $index = null) public function add($element, $index = null)
{ {
if (null === $index) { if (null === $index || '' === $index) {
$this->elements[] = $element; $this->elements[] = $element;
} else { } else {
$this->elements[$index] = $element; $this->elements[$index] = $element;

View File

@@ -15,27 +15,28 @@ use Meritoo\Common\Utilities\Arrays;
/** /**
* An exception used while type of something is unknown * An exception used while type of something is unknown
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
abstract class UnknownTypeException extends Exception abstract class UnknownTypeException extends Exception
{ {
/** /**
* Class constructor * Creates exception
* *
* @param string|int $unknownType The unknown type of something (value of constant) * @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 BaseType $typeInstance An instance of class that contains type of the something
* @param string $typeName Name of the something * @param string $typeName Name of the something
* @return UnknownTypeException
*/ */
public function __construct($unknownType, BaseType $typeInstance, $typeName) public static function create($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' $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.'; . ' of these types: %s.';
$allTypes = $typeInstance->getAll();
$types = Arrays::values2string($allTypes, '', ', ');
$message = sprintf(sprintf($template, $unknownType, $typeName, $types)); $message = sprintf(sprintf($template, $unknownType, $typeName, $types));
parent::__construct($message);
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

@@ -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 Meritoo\Common\Exception\Base\UnknownTypeException;
use Meritoo\Common\Type\DatePartType;
/**
* An exception used while type of date part, e.g. "year", is unknown
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class UnknownDatePartTypeException extends UnknownTypeException
{
/**
* Class constructor
*
* @param string $unknownDatePart Type of date part, e.g. "year". One of DatePartType class constants.
* @param string $value Incorrect value
*/
public function __construct($unknownDatePart, $value)
{
parent::__construct($unknownDatePart, new DatePartType(), sprintf('date part (with value %s)', $value));
}
}

View File

@@ -11,21 +11,22 @@ namespace Meritoo\Common\Exception\File;
/** /**
* An exception used while file with given path is empty (has no content) * An exception used while file with given path is empty (has no content)
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class EmptyFileException extends \Exception class EmptyFileException extends \Exception
{ {
/** /**
* Class constructor * Creates exception
* *
* @param string $emptyFilePath Path of the empty file * @param string $emptyFilePath Path of the empty file
* @return EmptyFileException
*/ */
public function __construct($emptyFilePath) public static function create($emptyFilePath)
{ {
$template = 'File with path \'%s\' is empty (has no content). Did you provide path of proper file?'; $template = 'File with path \'%s\' is empty (has no content). Did you provide path of proper file?';
$message = sprintf($template, $emptyFilePath); $message = sprintf($template, $emptyFilePath);
parent::__construct($message); return new static($message);
} }
} }

View File

@@ -11,16 +11,16 @@ namespace Meritoo\Common\Exception\File;
/** /**
* An exception used while path of given file is empty * An exception used while path of given file is empty
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class EmptyFilePathException extends \Exception class EmptyFilePathException extends \Exception
{ {
/** /**
* Class constructor * Creates exception
*/ */
public function __construct() public static function create()
{ {
parent::__construct('Path of the file is empty. Did you provide path of proper file?'); return new static('Path of the file is empty. Did you provide path of proper file?');
} }
} }

View File

@@ -11,21 +11,22 @@ namespace Meritoo\Common\Exception\File;
/** /**
* An exception used while file with given path does not exist * An exception used while file with given path does not exist
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class NotExistingFileException extends \Exception class NotExistingFileException extends \Exception
{ {
/** /**
* Class constructor * Creates exception
* *
* @param string $notExistingFilePath Path of not existing (or not readable) file * @param string $notExistingFilePath Path of not existing (or not readable) file
* @return NotExistingFileException
*/ */
public function __construct($notExistingFilePath) public static function create($notExistingFilePath)
{ {
$template = 'File with path \'%s\' does not exist (or is not readable). Did you provide path of proper file?'; $template = 'File with path \'%s\' does not exist (or is not readable). Did you provide path of proper file?';
$message = sprintf($template, $notExistingFilePath); $message = sprintf($template, $notExistingFilePath);
parent::__construct($message); return new static($message);
} }
} }

View File

@@ -13,18 +13,19 @@ use Exception;
/** /**
* An exception used while method cannot be called, because is disabled * An exception used while method cannot be called, because is disabled
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class DisabledMethodException extends Exception class DisabledMethodException extends Exception
{ {
/** /**
* Class constructor * Creates exception
* *
* @param string $disabledMethod Name of the disabled method * @param string $disabledMethod Name of the disabled method
* @param string $alternativeMethod (optional) Name of the alternative method * @param string $alternativeMethod (optional) Name of the alternative method
* @return DisabledMethodException
*/ */
public function __construct($disabledMethod, $alternativeMethod = '') public static function create($disabledMethod, $alternativeMethod = '')
{ {
$template = 'Method %s() cannot be called, because is disabled.'; $template = 'Method %s() cannot be called, because is disabled.';
@@ -33,6 +34,7 @@ class DisabledMethodException extends Exception
} }
$message = sprintf($template, $disabledMethod, $alternativeMethod); $message = sprintf($template, $disabledMethod, $alternativeMethod);
parent::__construct($message);
return new static($message);
} }
} }

View File

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

View File

@@ -14,18 +14,19 @@ use Meritoo\Common\Utilities\Reflection;
/** /**
* An exception used while given class has no child classes * An exception used while given class has no child classes
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class MissingChildClassesException extends Exception 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, * @param array|object|string $parentClass Class that hasn't child classes, but it should. An array of objects,
* strings, object or string. * strings, object or string.
* @return MissingChildClassesException
*/ */
public function __construct($parentClass) public static function create($parentClass)
{ {
$template = 'The \'%s\' class requires one child class at least who will extend her (maybe is an abstract' $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?';
@@ -33,6 +34,6 @@ class MissingChildClassesException extends Exception
$parentClassName = Reflection::getClassName($parentClass); $parentClassName = Reflection::getClassName($parentClass);
$message = sprintf($template, $parentClassName); $message = sprintf($template, $parentClassName);
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\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

@@ -14,19 +14,20 @@ use Meritoo\Common\Utilities\Reflection;
/** /**
* An exception used while given class has more than one child class * An exception used while given class has more than one child class
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class TooManyChildClassesException extends Exception 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 * @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. * of objects, strings, object or string.
* @param array $childClasses Child classes * @param array $childClasses Child classes
* @return TooManyChildClassesException
*/ */
public function __construct($parentClass, array $childClasses) public static function create($parentClass, array $childClasses)
{ {
$template = "The '%s' class requires one child class at most who will extend her, but more than one child" $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?";
@@ -34,6 +35,6 @@ class TooManyChildClassesException extends Exception
$parentClassName = Reflection::getClassName($parentClass); $parentClassName = Reflection::getClassName($parentClass);
$message = sprintf($template, $parentClassName, implode("\n- ", $childClasses), $parentClassName); $message = sprintf($template, $parentClassName, implode("\n- ", $childClasses), $parentClassName);
parent::__construct($message); return new static($message);
} }
} }

View File

@@ -11,22 +11,24 @@ namespace Meritoo\Common\Exception\Regex;
/** /**
* An exception used while length of given hexadecimal value of color is incorrect * An exception used while length of given hexadecimal value of color is incorrect
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright 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 * @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.' $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)); $message = sprintf($template, $color, strlen($color));
parent::__construct($message);
return new static($message);
} }
} }

View File

@@ -11,19 +11,21 @@ namespace Meritoo\Common\Exception\Regex;
/** /**
* An exception used while given hexadecimal value of color is invalid * An exception used while given hexadecimal value of color is invalid
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class InvalidColorHexValueException extends \Exception class InvalidColorHexValueException extends \Exception
{ {
/** /**
* Class constructor * Creates exception
* *
* @param string $color Invalid hexadecimal value of color * @param string $color Invalid hexadecimal value of color
* @return InvalidColorHexValueException
*/ */
public function __construct($color) public static function create($color)
{ {
$message = sprintf('Hexadecimal value of color \'%s\' is invalid. Is there everything ok?', $color); $message = sprintf('Hexadecimal value of color \'%s\' is invalid. Is there everything ok?', $color);
parent::__construct($message);
return new static($message);
} }
} }

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.
*/
namespace Meritoo\Common\Exception\Regex;
/**
* 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

@@ -1,23 +1,31 @@
<?php <?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; namespace Meritoo\Common\Exception\Regex;
/** /**
* An exception used while url is invalid * An exception used while url is invalid
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class InvalidUrlException extends \Exception class InvalidUrlException extends \Exception
{ {
/** /**
* Class constructor * Creates exception
* *
* @param string $url Invalid url * @param string $url Invalid url
* @return InvalidUrlException
*/ */
public function __construct($url) public static function create($url)
{ {
$message = sprintf('Url \'%s\' is invalid. Is there everything ok?', $url); $message = sprintf('Url \'%s\' is invalid. Is there everything ok?', $url);
parent::__construct($message);
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\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($unknownDatePart, $value)
{
/* @var UnknownDatePartTypeException $exception */
$exception = parent::create($unknownDatePart, new DatePartType(), sprintf('date part (with value %s)', $value));
return $exception;
}
}

View File

@@ -1,5 +1,11 @@
<?php <?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; namespace Meritoo\Common\Exception\Type;
use Meritoo\Common\Exception\Base\UnknownTypeException; use Meritoo\Common\Exception\Base\UnknownTypeException;
@@ -8,16 +14,22 @@ 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 * An exception used while the visibility of a property, a method or (as of PHP 7.1.0) a constant is unknown
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class UnknownOopVisibilityTypeException extends UnknownTypeException class UnknownOopVisibilityTypeException extends UnknownTypeException
{ {
/** /**
* {@inheritdoc} * Creates exception
*
* @param string $unknownType Unknown visibility of a property, a method or (as of PHP 7.1.0) a constant
* @return UnknownOopVisibilityTypeException
*/ */
public function __construct($unknownType) public static function createException($unknownType)
{ {
parent::__construct($unknownType, new OopVisibilityType(), 'OOP-related visibility'); /* @var UnknownOopVisibilityTypeException $exception */
$exception = parent::create($unknownType, new OopVisibilityType(), 'OOP-related visibility');
return $exception;
} }
} }

View File

@@ -14,8 +14,8 @@ use PHPUnit\Framework\TestCase;
/** /**
* Base test case with common methods and data providers * Base test case with common methods and data providers
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
abstract class BaseTestCase extends TestCase abstract class BaseTestCase extends TestCase
{ {

View File

@@ -13,8 +13,8 @@ use Meritoo\Common\Traits\Test\Base\BaseTypeTestCaseTrait;
/** /**
* Base test case for the type of something * Base test case for the type of something
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
abstract class BaseTypeTestCase extends BaseTestCase abstract class BaseTypeTestCase extends BaseTestCase
{ {

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

@@ -14,14 +14,16 @@ use Meritoo\Common\Exception\Type\UnknownOopVisibilityTypeException;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\Common\Utilities\Miscellaneous; use Meritoo\Common\Utilities\Miscellaneous;
use ReflectionClass; use ReflectionClass;
use ReflectionException;
use ReflectionMethod; use ReflectionMethod;
use stdClass;
/** /**
* BaseTestCaseTrait * BaseTestCaseTrait
* Created on 2017-11-02 * Created on 2017-11-02
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
trait BaseTestCaseTrait trait BaseTestCaseTrait
{ {
@@ -30,7 +32,7 @@ trait BaseTestCaseTrait
* *
* @var string * @var string
*/ */
private static $testsDataDirPath = '.data/tests'; private static $testsDataDirPath = 'data/tests';
/** /**
* Provides an empty value * Provides an empty value
@@ -47,6 +49,20 @@ trait BaseTestCaseTrait
yield[[]]; yield[[]];
} }
/**
* Provides an empty scalar value
*
* @return Generator
*/
public function provideEmptyScalarValue()
{
yield[''];
yield[' '];
yield[null];
yield[0];
yield[false];
}
/** /**
* Provides boolean value * Provides boolean value
* *
@@ -103,9 +119,29 @@ trait BaseTestCaseTrait
yield['surprise/me/one/more/time.txt']; yield['surprise/me/one/more/time.txt'];
} }
/**
* Provides non scalar value, e.g. [] or null
*
* @return Generator
*/
public function provideNonScalarValue()
{
yield[
[],
];
yield[
null,
];
yield[
new stdClass(),
];
}
/** /**
* Returns path of file used by tests. * Returns path of file used by tests.
* It should be placed in /.data/tests directory of this project. * It should be placed in /data/tests directory of this project.
* *
* @param string $fileName Name of file * @param string $fileName Name of file
* @param string $directoryPath (optional) Path of directory containing the file * @param string $directoryPath (optional) Path of directory containing the file
@@ -137,6 +173,7 @@ trait BaseTestCaseTrait
* @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments * @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments
* of the verified method * of the verified method
* @throws UnknownOopVisibilityTypeException * @throws UnknownOopVisibilityTypeException
* @throws ReflectionException
* *
* Attention. 2nd argument, the $method, may be: * Attention. 2nd argument, the $method, may be:
* - string - name of the method * - string - name of the method
@@ -193,6 +230,7 @@ trait BaseTestCaseTrait
* @param int $argumentsCount (optional) Expected count/amount of arguments of the verified method * @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 * @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments of the verified
* method * method
* @throws ReflectionException
* @throws UnknownOopVisibilityTypeException * @throws UnknownOopVisibilityTypeException
*/ */
protected static function assertConstructorVisibilityAndArguments( protected static function assertConstructorVisibilityAndArguments(
@@ -214,6 +252,7 @@ trait BaseTestCaseTrait
* Asserts that class with given namespace has no constructor * Asserts that class with given namespace has no constructor
* *
* @param string $classNamespace Namespace of class that contains constructor to verify * @param string $classNamespace Namespace of class that contains constructor to verify
* @throws ReflectionException
*/ */
protected static function assertHasNoConstructor($classNamespace) protected static function assertHasNoConstructor($classNamespace)
{ {

View File

@@ -14,8 +14,8 @@ use Meritoo\Common\Type\Base\BaseType;
/** /**
* Trait for the base test case for the type of something * Trait for the base test case for the type of something
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
trait BaseTypeTestCaseTrait trait BaseTypeTestCaseTrait
{ {

View File

@@ -14,8 +14,8 @@ use Meritoo\Common\Utilities\Reflection;
* Base / abstract type of something, e.g. type of button, order, date etc. * Base / abstract type of something, e.g. type of button, order, date etc.
* Child class should contain constants - each of them represent one type. * Child class should contain constants - each of them represent one type.
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
abstract class BaseType abstract class BaseType
{ {

View File

@@ -13,8 +13,8 @@ use Meritoo\Common\Type\Base\BaseType;
/** /**
* Type of date part, e.g. "year" * Type of date part, e.g. "year"
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class DatePartType extends BaseType class DatePartType extends BaseType
{ {

View File

@@ -6,18 +6,20 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Meritoo\Common\Utilities; namespace Meritoo\Common\Type;
use DateTime; use DateTime;
use Meritoo\Common\Type\Base\BaseType;
use Meritoo\Common\Utilities\Date;
/** /**
* A date's period. * A date's period.
* Contains start and end date of the period. * Contains start and end date of the period.
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class DatePeriod class DatePeriod extends BaseType
{ {
/** /**
* The period constant: last month * The period constant: last month
@@ -108,17 +110,6 @@ class DatePeriod
$this->endDate = $endDate; $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 * Returns formatted one of the period's date: start date or end date
* *

View File

@@ -7,8 +7,8 @@ use Meritoo\Common\Type\Base\BaseType;
/** /**
* The visibility of a property, a method or (as of PHP 7.1.0) a constant * The visibility of a property, a method or (as of PHP 7.1.0) a constant
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
* *
* @see http://php.net/manual/en/language.oop5.visibility.php * @see http://php.net/manual/en/language.oop5.visibility.php
*/ */

View File

@@ -11,8 +11,8 @@ namespace Meritoo\Common\Utilities;
/** /**
* Useful arrays methods * Useful arrays methods
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class Arrays class Arrays
{ {
@@ -48,23 +48,6 @@ class Arrays
if (is_array($value)) { if (is_array($value)) {
$effect .= self::values2string($value, $arrayColumnKey, $separator); $effect .= self::values2string($value, $arrayColumnKey, $separator);
/*
* Previous version. Doesn't work with array containing arrays, e.g.:
* array(
* 1 => array(
* 'item1',
* 'item2'
* ),
* 2 => array(
* 'item3',
* 'item4'
* )
* )
*
if(isset($value[$arrayColumnKey])){
$effect .= $value[$arrayColumnKey];
}
*/
} else { } else {
if (empty($arrayColumnKey)) { if (empty($arrayColumnKey)) {
$effect .= $value; $effect .= $value;
@@ -530,6 +513,10 @@ class Arrays
*/ */
public static function removeElement(array $array, $item) public static function removeElement(array $array, $item)
{ {
/*
* No elements or the element does not exist?
* Nothing to do
*/
if (empty($array) || !in_array($item, $array)) { if (empty($array) || !in_array($item, $array)) {
return false; return false;
} }
@@ -626,6 +613,10 @@ class Arrays
*/ */
public static function setKeysAsValues(array $array, $ignoreDuplicatedValues = true) public static function setKeysAsValues(array $array, $ignoreDuplicatedValues = true)
{ {
/*
* No elements?
* Nothing to do
*/
if (empty($array)) { if (empty($array)) {
return []; return [];
} }
@@ -682,7 +673,7 @@ class Arrays
return null; return null;
} }
$effect = $array; $effect = &$array;
ksort($effect, $sortFlags); ksort($effect, $sortFlags);
foreach ($effect as &$value) { foreach ($effect as &$value) {
@@ -831,13 +822,20 @@ class Arrays
*/ */
public static function getLastElementsPaths(array $array, $separator = '.', $parentPath = '', $stopIfMatchedBy = '') public static function getLastElementsPaths(array $array, $separator = '.', $parentPath = '', $stopIfMatchedBy = '')
{ {
$paths = []; /*
* No elements?
* Nothing to do
*/
if (empty($array)) {
return [];
}
if (!empty($array)) {
if (!empty($stopIfMatchedBy)) { if (!empty($stopIfMatchedBy)) {
$stopIfMatchedBy = self::makeArray($stopIfMatchedBy); $stopIfMatchedBy = self::makeArray($stopIfMatchedBy);
} }
$paths = [];
foreach ($array as $key => $value) { foreach ($array as $key => $value) {
$path = $key; $path = $key;
$stopRecursion = false; $stopRecursion = false;
@@ -886,7 +884,6 @@ class Arrays
$paths += $recursivePaths; $paths += $recursivePaths;
} }
} }
}
return $paths; return $paths;
} }
@@ -1083,6 +1080,10 @@ class Arrays
*/ */
public static function getAllValuesOfKey(array $array, $key) public static function getAllValuesOfKey(array $array, $key)
{ {
/*
* No elements?
* Nothing to do
*/
if (empty($array)) { if (empty($array)) {
return null; return null;
} }

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

@@ -8,20 +8,23 @@
namespace Meritoo\Common\Utilities; namespace Meritoo\Common\Utilities;
use Meritoo\Common\Exception\Bundle\IncorrectBundleNameException;
/** /**
* Useful methods for bundle * Useful methods for bundle
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class Bundle class Bundle
{ {
/** /**
* Returns path to view / template of given 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" * @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 $bundleName Full name of the bundle, e.g. "MyExtraBundle"
* @param string $extension (optional) Extension of the view / template * @param string $extension (optional) Extension of the view / template (default: "html.twig")
* @throws IncorrectBundleNameException
* @return string|null * @return string|null
*/ */
public static function getBundleViewPath($viewPath, $bundleName, $extension = 'html.twig') public static function getBundleViewPath($viewPath, $bundleName, $extension = 'html.twig')
@@ -34,6 +37,13 @@ class Bundle
return null; return null;
} }
/*
* Given name of bundle is invalid?
*/
if (!Regex::isValidBundleName($bundleName)) {
throw IncorrectBundleNameException::create($bundleName);
}
/* /*
* Path of the view / template doesn't end with given extension? * Path of the view / template doesn't end with given extension?
*/ */
@@ -41,6 +51,39 @@ class Bundle
$viewPath = sprintf('%s.%s', $viewPath, $extension); $viewPath = sprintf('%s.%s', $viewPath, $extension);
} }
return sprintf('%s:%s', $bundleName, $viewPath); /*
* Prepare short name of bundle and path of view / template with "/" (instead of ":")
*/
$shortBundleName = static::getShortBundleName($bundleName);
$viewPath = str_replace(':', '/', $viewPath);
return sprintf('@%s/%s', $shortBundleName, $viewPath);
}
/**
* Returns short name of bundle (without "Bundle")
*
* @param string $fullBundleName Full name of the bundle, e.g. "MyExtraBundle"
* @throws IncorrectBundleNameException
* @return string|null
*/
public static function getShortBundleName($fullBundleName)
{
/*
* Given name of bundle is invalid?
*/
if (!Regex::isValidBundleName($fullBundleName)) {
if (!is_string($fullBundleName)) {
$fullBundleName = gettype($fullBundleName);
}
throw new IncorrectBundleNameException($fullBundleName);
}
$matches = [];
$pattern = Regex::getBundleNamePattern();
preg_match($pattern, $fullBundleName, $matches);
return $matches[1];
} }
} }

View File

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

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 DateInterval;
use DateTime; use DateTime;
use Meritoo\Common\Exception\Date\UnknownDatePartTypeException; use Exception;
use Meritoo\Common\Exception\Type\UnknownDatePartTypeException;
use Meritoo\Common\Type\DatePartType; use Meritoo\Common\Type\DatePartType;
use Meritoo\Common\Type\DatePeriod;
/** /**
* Useful date methods * Useful date methods
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class Date class Date
{ {
@@ -66,13 +68,19 @@ class Date
* The dates are returned in an array with indexes 'start' and 'end'. * 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. * @param int $period The period, type of period. One of DatePeriod class constants, e.g. DatePeriod::LAST_WEEK.
* @return DatePeriod * @throws Exception
* @return null|DatePeriod
*/ */
public static function getDatesForPeriod($period) public static function getDatesForPeriod($period)
{ {
$datePeriod = null; /*
* Type of period is incorrect?
* Nothing to do
*/
if (!(new DatePeriod())->isCorrectType($period)) {
return null;
}
if (DatePeriod::isCorrectPeriod($period)) {
$dateStart = null; $dateStart = null;
$dateEnd = null; $dateEnd = null;
@@ -111,11 +119,15 @@ class Date
$lastMonth = self::getDatesForPeriod(DatePeriod::LAST_MONTH); $lastMonth = self::getDatesForPeriod(DatePeriod::LAST_MONTH);
$nextMonth = self::getDatesForPeriod(DatePeriod::NEXT_MONTH); $nextMonth = self::getDatesForPeriod(DatePeriod::NEXT_MONTH);
if (null !== $lastMonth) {
$dateStart = $lastMonth->getEndDate(); $dateStart = $lastMonth->getEndDate();
$dateStart->add(new DateInterval('P1D')); $dateStart->add(new DateInterval('P1D'));
}
if (null !== $nextMonth) {
$dateEnd = $nextMonth->getStartDate(); $dateEnd = $nextMonth->getStartDate();
$dateEnd->sub(new DateInterval('P1D')); $dateEnd->sub(new DateInterval('P1D'));
}
break; break;
case DatePeriod::NEXT_MONTH: case DatePeriod::NEXT_MONTH:
@@ -129,10 +141,10 @@ class Date
$dateStart = new DateTime(); $dateStart = new DateTime();
$dateEnd = 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; $yearDifference = 1;
if (DatePeriod::LAST_YEAR == $period) { if (DatePeriod::LAST_YEAR === $period) {
$yearDifference *= -1; $yearDifference *= -1;
} }
@@ -148,15 +160,18 @@ class Date
break; break;
} }
if (null !== $dateStart && null !== $dateEnd) { /*
* Start or end date is unknown?
* Nothing to do
*/
if (null === $dateStart || null === $dateEnd) {
return null;
}
$dateStart->setTime(0, 0, 0); $dateStart->setTime(0, 0, 0);
$dateEnd->setTime(23, 59, 59); $dateEnd->setTime(23, 59, 59);
$datePeriod = new DatePeriod($dateStart, $dateEnd); return new DatePeriod($dateStart, $dateEnd);
}
}
return $datePeriod;
} }
/** /**
@@ -230,8 +245,8 @@ class Date
* @param int $month The month value * @param int $month The month value
* @param int $day The day value * @param int $day The day value
* *
* @return int
* @throws UnknownDatePartTypeException * @throws UnknownDatePartTypeException
* @return int
*/ */
public static function getDayOfWeek($year, $month, $day) public static function getDayOfWeek($year, $month, $day)
{ {
@@ -243,21 +258,21 @@ class Date
* Oops, incorrect year * Oops, incorrect year
*/ */
if ($year <= 0) { if ($year <= 0) {
throw new UnknownDatePartTypeException(DatePartType::YEAR, $year); throw UnknownDatePartTypeException::createException(DatePartType::YEAR, $year);
} }
/* /*
* Oops, incorrect month * Oops, incorrect month
*/ */
if ($month < 1 || $month > 12) { if ($month < 1 || $month > 12) {
throw new UnknownDatePartTypeException(DatePartType::MONTH, $month); throw UnknownDatePartTypeException::createException(DatePartType::MONTH, $month);
} }
/* /*
* Oops, incorrect day * Oops, incorrect day
*/ */
if ($day < 1 || $day > 31) { if ($day < 1 || $day > 31) {
throw new UnknownDatePartTypeException(DatePartType::DAY, $day); throw UnknownDatePartTypeException::createException(DatePartType::DAY, $day);
} }
if ($month < 3) { if ($month < 3) {
@@ -356,11 +371,11 @@ class Date
return null; return null;
} }
$dateStart = self::getDateTime($dateStart, true); $start = self::getDateTime($dateStart, true);
$dateEnd = self::getDateTime($dateEnd, true); $end = self::getDateTime($dateEnd, true);
$difference = []; $difference = [];
$dateDiff = $dateEnd->getTimestamp() - $dateStart->getTimestamp(); $dateDiff = $end->getTimestamp() - $start->getTimestamp();
$daysInSeconds = 0; $daysInSeconds = 0;
$hoursInSeconds = 0; $hoursInSeconds = 0;
@@ -378,39 +393,39 @@ class Date
self::DATE_DIFFERENCE_UNIT_MINUTES, self::DATE_DIFFERENCE_UNIT_MINUTES,
]; ];
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_YEARS == $differenceUnit) { if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_YEARS === $differenceUnit) {
$diff = $dateEnd->diff($dateStart); $diff = $end->diff($start);
/* /*
* Difference between dates in years should be returned only? * 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; return $diff->y;
} }
$difference[self::DATE_DIFFERENCE_UNIT_YEARS] = $diff->y; $difference[self::DATE_DIFFERENCE_UNIT_YEARS] = $diff->y;
} }
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MONTHS == $differenceUnit) { if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MONTHS === $differenceUnit) {
$diff = $dateEnd->diff($dateStart); $diff = $end->diff($start);
/* /*
* Difference between dates in months should be returned only? * 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; return $diff->m;
} }
$difference[self::DATE_DIFFERENCE_UNIT_MONTHS] = $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); $days = (int)floor($dateDiff / $daySeconds);
/* /*
* Difference between dates in days should be returned only? * 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; return $days;
} }
@@ -427,13 +442,13 @@ class Date
$daysInSeconds = $days * $daySeconds; $daysInSeconds = $days * $daySeconds;
} }
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits)) { if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
$hours = (int)floor(($dateDiff - $daysInSeconds) / $hourSeconds); $hours = (int)floor(($dateDiff - $daysInSeconds) / $hourSeconds);
/* /*
* Difference between dates in hours should be returned only? * 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; return $hours;
} }
@@ -450,13 +465,13 @@ class Date
$hoursInSeconds = $hours * $hourSeconds; $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); $minutes = (int)floor(($dateDiff - $daysInSeconds - $hoursInSeconds) / 60);
/* /*
* Difference between dates in minutes should be returned only? * 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; return $minutes;
} }
@@ -475,6 +490,7 @@ class Date
* @param string $intervalTemplate (optional) Template used to build date interval. It should contain "%d" as the * @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. * placeholder which is replaced with a number that represents each iteration.
* Default: interval for days. * Default: interval for days.
* @throws Exception
* @return array * @return array
*/ */
public static function getDatesCollection(DateTime $startDate, $datesCount, $intervalTemplate = 'P%dD') public static function getDatesCollection(DateTime $startDate, $datesCount, $intervalTemplate = 'P%dD')
@@ -520,6 +536,7 @@ class Date
* @param int $end (optional) End 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 * @param string $intervalTemplate (optional) Template used to build date interval. The placeholder is replaced
* with next, iterated value. * with next, iterated value.
* @throws Exception
* @return DateTime * @return DateTime
*/ */
public static function getRandomDate(DateTime $startDate = null, $start = 1, $end = 100, $intervalTemplate = 'P%sD') public static function getRandomDate(DateTime $startDate = null, $start = 1, $end = 100, $intervalTemplate = 'P%sD')
@@ -540,7 +557,7 @@ class Date
} }
$randomDate = clone $startDate; $randomDate = clone $startDate;
$randomInterval = new DateInterval(sprintf($intervalTemplate, rand($start, $end))); $randomInterval = new DateInterval(sprintf($intervalTemplate, mt_rand($start, $end)));
return $randomDate->add($randomInterval); return $randomDate->add($randomInterval);
} }
@@ -623,7 +640,7 @@ class Date
* So, I have to refuse those special compound formats if they are not explicitly declared as * 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) * compound (2nd argument of this method, set to false by default)
*/ */
if (in_array($value, $specialFormats)) { if (in_array($value, $specialFormats, true)) {
return false; return false;
} }
} }
@@ -648,7 +665,7 @@ class Date
*/ */
$dateString = (new DateTime())->format($value); $dateString = (new DateTime())->format($value);
if ($dateString != $value) { if ($dateString !== (string)$value) {
return new DateTime($dateString); return new DateTime($dateString);
} }
} catch (\Exception $exception) { } catch (\Exception $exception) {
@@ -692,7 +709,7 @@ class Date
* Formatted date it's the format who is validated? * Formatted date it's the format who is validated?
* The format is invalid * The format is invalid
*/ */
if ($formatted == $format) { if ($formatted === $format) {
return false; return false;
} }

View File

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

View File

@@ -11,8 +11,8 @@ namespace Meritoo\Common\Utilities;
/** /**
* Useful locale methods * Useful locale methods
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class Locale class Locale
{ {
@@ -23,7 +23,7 @@ class Locale
* setting. It's the same constant as required by setlocale() function. * setting. It's the same constant as required by setlocale() function.
* @param string $languageCode Language code, in ISO 639-1 format. Short form of the locale, e.g. "fr". * @param string $languageCode Language code, in ISO 639-1 format. Short form of the locale, e.g. "fr".
* @param string $countryCode (optional) Country code, in ISO 3166-1 alpha-2 format, e.g. "FR" * @param string $countryCode (optional) Country code, in ISO 3166-1 alpha-2 format, e.g. "FR"
* @return bool * @return false|string
* *
* Available categories (values of $category argument): * Available categories (values of $category argument):
* - LC_ALL for all of the below * - LC_ALL for all of the below
@@ -57,9 +57,29 @@ class Locale
} }
$localeLongForm = self::getLongForm($languageCode, $countryCode); $localeLongForm = self::getLongForm($languageCode, $countryCode);
setlocale($category, $localeLongForm);
return true; return setlocale($category, $localeLongForm);
}
/**
* Returns locale for given category
*
* @param int $category Named constant specifying the category of the functions affected by the locale setting.
* It's the same constant as required by setlocale() function.
* @return string
*
* Available categories (values of $category argument):
* - LC_ALL for all of the below
* - LC_COLLATE for string comparison, see strcoll()
* - LC_CTYPE for character classification and conversion, for example strtoupper()
* - LC_MONETARY for localeconv()
* - LC_NUMERIC for decimal separator (See also localeconv())
* - LC_TIME for date and time formatting with strftime()
* - LC_MESSAGES for system responses (available if PHP was compiled with libintl)
*/
public static function getLocale($category)
{
return setlocale($category, '0');
} }
/** /**

View File

@@ -11,8 +11,8 @@ namespace Meritoo\Common\Utilities;
/** /**
* Useful methods for mime types of files * Useful methods for mime types of files
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class MimeTypes class MimeTypes
{ {
@@ -759,9 +759,8 @@ class MimeTypes
* Returns mime type of given file * Returns mime type of given file
* *
* @param string $filePath Path of the file to check * @param string $filePath Path of the file to check
* @return string
*
* @throws \RuntimeException * @throws \RuntimeException
* @return string
*/ */
public static function getMimeType($filePath) public static function getMimeType($filePath)
{ {

View File

@@ -9,14 +9,13 @@
namespace Meritoo\Common\Utilities; namespace Meritoo\Common\Utilities;
use Gedmo\Sluggable\Util\Urlizer; use Gedmo\Sluggable\Util\Urlizer;
use Symfony\Component\HttpFoundation\Cookie;
use Transliterator; use Transliterator;
/** /**
* Miscellaneous methods (only static functions) * Miscellaneous methods (only static functions)
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class Miscellaneous class Miscellaneous
{ {
@@ -61,15 +60,15 @@ class Miscellaneous
$startFileName = mb_substr($startFileName, 1); $startFileName = mb_substr($startFileName, 1);
} }
$directoryContent = scandir($directoryPath); $directoryContent = scandir($directoryPath, SCANDIR_SORT_ASCENDING);
if (!empty($directoryContent)) { if (!empty($directoryContent)) {
foreach ($directoryContent as $fileName) { foreach ($directoryContent as $fileName) {
if ('.' != $fileName && '..' != $fileName) { if ('.' !== $fileName && '..' !== $fileName) {
$content = null; $content = null;
if (!empty($startFileName) && !$startFileFound) { if (!empty($startFileName) && !$startFileFound) {
if ($fileName == $startFileName) { if ($fileName === $startFileName) {
$startFileFound = true; $startFileFound = true;
} }
@@ -83,18 +82,18 @@ class Miscellaneous
if (null !== $content) { if (null !== $content) {
$files[$fileName] = $content; $files[$fileName] = $content;
if (!empty($maxFilesCount)) { if (null !== $maxFilesCount) {
$count += Arrays::getNonArrayElementsCount($content); $count += Arrays::getNonArrayElementsCount($content);
} }
} else { } else {
$files[] = $fileName; $files[] = $fileName;
if (!empty($maxFilesCount)) { if (null !== $maxFilesCount) {
++$count; ++$count;
} }
} }
if (!empty($maxFilesCount) && $count >= $maxFilesCount) { if (null !== $maxFilesCount && $count >= $maxFilesCount) {
break; break;
} }
} }
@@ -159,11 +158,17 @@ class Miscellaneous
*/ */
public static function includeFileExtension($fileName, $extension) public static function includeFileExtension($fileName, $extension)
{ {
if (self::getFileExtension($fileName, true) != strtolower($extension)) { $fileExtension = self::getFileExtension($fileName, true);
return sprintf('%s.%s', $fileName, $extension);
/*
* File has given extension?
* Nothing to do
*/
if ($fileExtension === strtolower($extension)) {
return $fileName;
} }
return $fileName; return sprintf('%s.%s', $fileName, $extension);
} }
/** /**
@@ -228,31 +233,28 @@ class Miscellaneous
/* /*
* Let's clear name of file * Let's clear name of file
* *
* Attention. The name without extension may be cleared / urlized only * Attention.
* to avoid incorrect name by replacing "." with "-". * The name without extension may be cleared / urlized only to avoid incorrect name by replacing "." with "-".
*/ */
$withoutExtension = Urlizer::urlize($withoutExtension); $withoutExtension = Urlizer::urlize($withoutExtension);
/* /*
* Now I have to complete the template used to build / generate unique name * Now I have to complete the template used to build / generate unique name
*/ */
$template = '%s-%s'; // file's name and unique key $template = '%s-%s.%s'; // [file's name]-[unique key].[file's extension]
if ($objectId > 0) {
$template .= '-%s'; // object ID
}
$template .= '.%s'; // file's extension
/* /*
* Add some uniqueness * Add some uniqueness
*/ */
$unique = uniqid(mt_rand(), true); $unique = self::getUniqueString(mt_rand());
/* /*
* Finally build and return the unique name * Finally build and return the unique name
*/ */
if ($objectId > 0) { 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); return sprintf($template, $withoutExtension, $unique, $objectId, $extension);
} }
@@ -332,7 +334,7 @@ class Miscellaneous
{ {
$phpModulesArray = get_loaded_extensions(); $phpModulesArray = get_loaded_extensions();
return in_array($phpModuleName, $phpModulesArray); return in_array($phpModuleName, $phpModulesArray, false);
} }
/** /**
@@ -460,7 +462,7 @@ class Miscellaneous
* Value to find is neither a string nor an array OR it's an empty string? * Value to find is neither a string nor an array OR it's an empty string?
* Nothing to do * Nothing to do
*/ */
if ((!$searchIsString && !$searchIsArray) || ($searchIsString && 0 == strlen($search))) { if ((!$searchIsString && !$searchIsArray) || ($searchIsString && '' === $search)) {
return $effect; return $effect;
} }
@@ -485,7 +487,7 @@ class Miscellaneous
* Second step: replace with regular expressions. * Second step: replace with regular expressions.
* Attention. Searched and replacement value should be the same type: strings or arrays. * 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) { if ($quoteStrings && $replacementIsString) {
$replacement = '\'' . $replacement . '\''; $replacement = '\'' . $replacement . '\'';
} }
@@ -503,7 +505,7 @@ class Miscellaneous
* Third step: complex replace of the replacement defined as an array. * 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. * 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); $subjectIsArray = is_array($subject);
$effect = ''; $effect = '';
@@ -588,7 +590,12 @@ class Miscellaneous
*/ */
public static function getOperatingSystemNameServer() public static function getOperatingSystemNameServer()
{ {
return php_uname('s'); return PHP_OS;
/*
* Previous version:
* return php_uname('s');
*/
} }
/** /**
@@ -626,10 +633,10 @@ class Miscellaneous
* Breaks long text * Breaks long text
* *
* @param string $text The text to check and break * @param string $text The text to check and break
* @param int $perLine (optional) Characters count per line * @param int $perLine (optional) Characters count per line. Default: 100.
* @param string $separator (optional) Separator that is placed beetwen lines * @param string $separator (optional) Separator that is placed between lines. Default: "<br>".
* @param string $encoding (optional) Character encoding. Used by mb_substr(). * @param string $encoding (optional) Character encoding. Used by mb_substr(). Default: "UTF-8".
* @param int $proportionalAberration (optional) Proportional aberration for chars (percent value) * @param int $proportionalAberration (optional) Proportional aberration for chars (percent value). Default: 20.
* @return string * @return string
*/ */
public static function breakLongText( public static function breakLongText(
@@ -680,7 +687,8 @@ class Miscellaneous
$spacePosition = mb_strrpos($lineWithAberration, ' ', 0, $encoding); $spacePosition = mb_strrpos($lineWithAberration, ' ', 0, $encoding);
if ($spacePosition > 0) { if (false !== $spacePosition && 0 < $spacePosition) {
/* @var int $spacePosition */
$perLine = $spacePosition; $perLine = $spacePosition;
$insertSeparator = true; $insertSeparator = true;
} }
@@ -716,21 +724,29 @@ class Miscellaneous
* *
* @param string $directoryPath Directory path * @param string $directoryPath Directory path
* @param bool $contentOnly (optional) If is set to true, only content of the directory is removed, not * @param bool $contentOnly (optional) If is set to true, only content of the directory is removed, not
* directory. Otherwise - directory is removed too. * directory itself. Otherwise - directory is removed too (default behaviour).
* @return bool * @return bool|null
*/ */
public static function removeDirectory($directoryPath, $contentOnly = false) public static function removeDirectory($directoryPath, $contentOnly = false)
{ {
/*
* Directory does not exist?
* Nothing to do
*/
if (!file_exists($directoryPath)) { if (!file_exists($directoryPath)) {
return true; return null;
} }
/*
* It's not a directory?
* Let's treat it like file
*/
if (!is_dir($directoryPath)) { if (!is_dir($directoryPath)) {
return unlink($directoryPath); return unlink($directoryPath);
} }
foreach (scandir($directoryPath) as $item) { foreach (scandir($directoryPath, SCANDIR_SORT_ASCENDING) as $item) {
if ('.' == $item || '..' == $item) { if ('.' === $item || '..' === $item) {
continue; continue;
} }
@@ -739,6 +755,9 @@ class Miscellaneous
} }
} }
/*
* Directory should be removed too?
*/
if (!$contentOnly) { if (!$contentOnly) {
return rmdir($directoryPath); return rmdir($directoryPath);
} }
@@ -776,7 +795,7 @@ class Miscellaneous
foreach ($members as $key => $value) { foreach ($members as $key => $value) {
$value = mb_strtolower($value); $value = mb_strtolower($value);
if (0 == $key) { if (0 === $key) {
$effect .= self::lowercaseFirst($value); $effect .= self::lowercaseFirst($value);
} else { } else {
$effect .= self::uppercaseFirst($value); $effect .= self::uppercaseFirst($value);
@@ -797,10 +816,6 @@ class Miscellaneous
* - null (default): nothing is done with the string * - null (default): nothing is done with the string
* - true: the rest of string is lowercased * - true: the rest of string is lowercased
* - false: the rest of string is uppercased * - 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) public static function lowercaseFirst($text, $restLowercase = null)
{ {
@@ -816,16 +831,7 @@ class Miscellaneous
$effect = mb_strtoupper($effect); $effect = mb_strtoupper($effect);
} }
if (function_exists('lcfirst')) { return lcfirst($effect);
$effect = lcfirst($effect);
} else {
$first = mb_strtolower($effect[0]);
$rest = mb_substr($effect, 1);
$effect = $first . $rest;
}
return $effect;
} }
/** /**
@@ -854,16 +860,7 @@ class Miscellaneous
$effect = mb_strtoupper($effect); $effect = mb_strtoupper($effect);
} }
if (function_exists('ucfirst')) { return ucfirst($effect);
$effect = ucfirst($effect);
} else {
$first = mb_strtoupper($effect[0]);
$rest = mb_substr($effect, 1);
$effect = $first . $rest;
}
return $effect;
} }
/** /**
@@ -904,9 +901,9 @@ class Miscellaneous
'TB', 'TB',
'PB', '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]; $unit = $units[(int)$index];
return sprintf('%s %s', $size, $unit); return sprintf('%s %s', $size, $unit);
@@ -1182,148 +1179,12 @@ class Miscellaneous
if (null !== $globalSource && isset($globalSource[$variableName])) { if (null !== $globalSource && isset($globalSource[$variableName])) {
$value = $globalSource[$variableName]; $value = $globalSource[$variableName];
if (!ini_get('magic_quotes_gpc')) {
$value = addslashes($value);
}
} }
} }
return $value; return $value;
} }
/**
* Returns a CURL response with parsed HTTP headers as array with "headers", "cookies" and "content" keys
*
* The headers and cookies are parsed and returned as an array, and an array of Cookie objects. Returned array looks
* like this example:
* <code>
* [
* 'headers' => [
* 'Content-Type' => 'text/html; charset=UTF-8',
* ...
* ],
* 'cookies' => [
* new Symfony\Component\HttpFoundation\Cookie(),
* new Symfony\Component\HttpFoundation\Cookie(),
* ...
* ],
* 'content' => '<html>...</html>'
* ]
* </code>
*
* If you want to attach HTTP headers into response content by CURL you need to set "CURLOPT_HEADER" option
* to "true". To read exact length of HTTP headers from CURL you can use "curl_getinfo()" function
* and read "CURLINFO_HEADER_SIZE" option.
*
* @param string $response the full content of response, including HTTP headers
* @param int $headerSize The length of HTTP headers in content
* @return array
*/
public static function getCurlResponseWithHeaders($response, $headerSize)
{
$headerContent = mb_substr($response, 0, $headerSize);
$content = mb_substr($response, $headerSize);
$headers = [];
$cookies = [];
/*
* Let's transform headers content into two arrays: headers and cookies
*/
foreach (explode("\r\n", $headerContent) as $i => $line) {
/*
* First line is only HTTP status and is unneeded so skip it
*/
if (0 === $i) {
continue;
}
if (Regex::contains($line, ':')) {
list($key, $value) = explode(': ', $line);
/*
* If the header is a "set-cookie" let's save it to "cookies" array
*/
if ('Set-Cookie' === $key) {
$cookieParameters = explode(';', $value);
$name = '';
$value = '';
$expire = 0;
$path = '/';
$domain = null;
$secure = false;
$httpOnly = true;
foreach ($cookieParameters as $j => $parameter) {
$param = explode('=', $parameter);
/*
* First parameter will be always a cookie name and it's value. It is not needed to run
* further actions for them, so save the values and move to next parameter.
*/
if (0 === $j) {
$name = trim($param[0]);
$value = trim($param[1]);
continue;
}
/*
* Now there would be the rest of cookie parameters, names of params are sent different way so
* I need to lowercase the names and remove unneeded spaces.
*/
$paramName = mb_strtolower(trim($param[0]));
$paramValue = true;
/*
* Some parameters don't have value e.g. "secure", but the value for them if they're specified
* is "true". Otherwise - just read a value for parameter if exists.
*/
if (array_key_exists(1, $param)) {
$paramValue = trim($param[1]);
}
switch ($paramName) {
case 'expires':
$expire = $paramValue;
break;
case 'path':
$path = $paramValue;
break;
case 'domain':
$domain = $paramValue;
break;
case 'secure':
$secure = $paramValue;
break;
case 'httponly':
$httpOnly = $paramValue;
break;
}
}
/*
* Create new Cookie object and add it to "cookies" array.
* I must skip to next header as cookies shouldn't be saved in "headers" array.
*/
$cookies[] = new Cookie($name, $value, $expire, $path, $domain, $secure, $httpOnly);
continue;
}
/*
* Save response header which is not a cookie
*/
$headers[$key] = $value;
}
}
return [
'headers' => $headers,
'cookies' => $cookies,
'content' => $content,
];
}
/** /**
* Adds missing the "0" characters to given number until given length is reached * Adds missing the "0" characters to given number until given length is reached
* *
@@ -1363,7 +1224,7 @@ class Miscellaneous
continue; continue;
} }
$text = $text . '0'; $text .= '0';
} }
return $text; return $text;
@@ -1418,8 +1279,8 @@ class Miscellaneous
if ($asHexadecimal) { if ($asHexadecimal) {
$hexadecimal = dechex($colorComponent); $hexadecimal = dechex($colorComponent);
if (1 == strlen($hexadecimal)) { if (1 === strlen($hexadecimal)) {
return sprintf('0%s', $hexadecimal, $hexadecimal); return sprintf('0%s', $hexadecimal);
} }
return $hexadecimal; return $hexadecimal;
@@ -1446,14 +1307,14 @@ class Miscellaneous
* Verify and get valid value of color. * Verify and get valid value of color.
* An exception will be thrown if the value is not a 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 * Grab color's components
*/ */
$red = hexdec(substr($color, 0, 2)); $red = hexdec(substr($validColor, 0, 2));
$green = hexdec(substr($color, 2, 2)); $green = hexdec(substr($validColor, 2, 2));
$blue = hexdec(substr($color, 4, 2)); $blue = hexdec(substr($validColor, 4, 2));
/* /*
* Calculate inverted color's components * Calculate inverted color's components

View File

@@ -10,6 +10,7 @@ namespace Meritoo\Common\Utilities;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\Query\Parameter; use Doctrine\ORM\Query\Parameter;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
@@ -17,8 +18,8 @@ use Doctrine\ORM\QueryBuilder;
/** /**
* Useful methods for query builder (the Doctrine's QueryBuilder class) * Useful methods for query builder (the Doctrine's QueryBuilder class)
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class QueryBuilderUtility class QueryBuilderUtility
{ {
@@ -33,6 +34,10 @@ class QueryBuilderUtility
{ {
$aliases = $queryBuilder->getRootAliases(); $aliases = $queryBuilder->getRootAliases();
/*
* No aliases?
* Nothing to do
*/
if (empty($aliases)) { if (empty($aliases)) {
return null; return null;
} }
@@ -42,7 +47,8 @@ class QueryBuilderUtility
/** /**
* Returns alias of given property joined in given query builder * Returns alias of given property joined in given query builder
* If the join does not exist, null is returned. *
* If there are no joins or the join does not exist, null is returned.
* It's also information if given property is already joined in given query builder. * It's also information if given property is already joined in given query builder.
* *
* @param QueryBuilder $queryBuilder The query builder to verify * @param QueryBuilder $queryBuilder The query builder to verify
@@ -53,6 +59,10 @@ class QueryBuilderUtility
{ {
$joins = $queryBuilder->getDQLPart('join'); $joins = $queryBuilder->getDQLPart('join');
/*
* No joins?
* Nothing to do
*/
if (empty($joins)) { if (empty($joins)) {
return null; return null;
} }
@@ -99,7 +109,18 @@ class QueryBuilderUtility
*/ */
public static function setCriteria(QueryBuilder $queryBuilder, array $criteria = [], $alias = '') public static function setCriteria(QueryBuilder $queryBuilder, array $criteria = [], $alias = '')
{ {
if (!empty($criteria)) { /*
* No criteria used in WHERE clause?
* Nothing to do
*/
if (empty($criteria)) {
return $queryBuilder;
}
/*
* No alias provided?
* Let's use root alias
*/
if (empty($alias)) { if (empty($alias)) {
$alias = self::getRootAlias($queryBuilder); $alias = self::getRootAlias($queryBuilder);
} }
@@ -126,7 +147,6 @@ class QueryBuilderUtility
$queryBuilder = $queryBuilder->andWhere($predicate); $queryBuilder = $queryBuilder->andWhere($predicate);
} }
}
return $queryBuilder; return $queryBuilder;
} }
@@ -136,14 +156,15 @@ class QueryBuilderUtility
* *
* @param EntityManager $entityManager The entity manager * @param EntityManager $entityManager The entity manager
* @param array|ArrayCollection $entities The entities to delete * @param array|ArrayCollection $entities The entities to delete
* @param bool $flushDeleted (optional) If is set to true, flushes the deleted objects. * @param bool $flushDeleted (optional) If is set to true, flushes the deleted objects (default
* Otherwise - not. * behaviour). Otherwise - not.
* @throws OptimisticLockException
* @return bool * @return bool
*/ */
public static function deleteEntities(EntityManager $entityManager, $entities, $flushDeleted = true) public static function deleteEntities(EntityManager $entityManager, $entities, $flushDeleted = true)
{ {
/* /*
* No entities found? * No entities provided?
* Nothing to do * Nothing to do
*/ */
if (empty($entities)) { if (empty($entities)) {
@@ -169,13 +190,20 @@ class QueryBuilderUtility
* Attention. Existing parameters will be overridden. * Attention. Existing parameters will be overridden.
* *
* @param QueryBuilder $queryBuilder The query builder * @param QueryBuilder $queryBuilder The query builder
* @param array|ArrayCollection $parameters Parameters to add. Collection of instances of * @param array|ArrayCollection $parameters Parameters to add. Collection of Doctrine\ORM\Query\Parameter
* Doctrine\ORM\Query\Parameter class or an array with key-value pairs. * instances or an array with key-value pairs.
* @return QueryBuilder * @return QueryBuilder
*/ */
public static function addParameters(QueryBuilder $queryBuilder, $parameters) public static function addParameters(QueryBuilder $queryBuilder, $parameters)
{ {
if (!empty($parameters)) { /*
* No parameters?
* Nothing to do
*/
if (empty($parameters)) {
return $queryBuilder;
}
foreach ($parameters as $key => $parameter) { foreach ($parameters as $key => $parameter) {
$name = $key; $name = $key;
$value = $parameter; $value = $parameter;
@@ -187,7 +215,6 @@ class QueryBuilderUtility
$queryBuilder->setParameter($name, $value); $queryBuilder->setParameter($name, $value);
} }
}
return $queryBuilder; return $queryBuilder;
} }

View File

@@ -13,18 +13,14 @@ use Doctrine\Common\Util\Inflector;
use Meritoo\Common\Collection\Collection; use Meritoo\Common\Collection\Collection;
use Meritoo\Common\Exception\Reflection\CannotResolveClassNameException; use Meritoo\Common\Exception\Reflection\CannotResolveClassNameException;
use Meritoo\Common\Exception\Reflection\MissingChildClassesException; use Meritoo\Common\Exception\Reflection\MissingChildClassesException;
use Meritoo\Common\Exception\Reflection\NotExistingPropertyException;
use Meritoo\Common\Exception\Reflection\TooManyChildClassesException; use Meritoo\Common\Exception\Reflection\TooManyChildClassesException;
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
use ReflectionObject;
use ReflectionProperty;
/** /**
* Useful reflection methods * Useful reflection methods
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class Reflection class Reflection
{ {
@@ -40,14 +36,14 @@ class Reflection
{ {
$effect = []; $effect = [];
$reflection = new ReflectionClass($class); $reflection = new \ReflectionClass($class);
$methods = $reflection->getMethods(); $methods = $reflection->getMethods();
if (!empty($methods)) { if (!empty($methods)) {
$className = self::getClassName($class); $className = self::getClassName($class);
foreach ($methods as $method) { foreach ($methods as $method) {
if ($method instanceof ReflectionMethod) { if ($method instanceof \ReflectionMethod) {
if ($withoutInheritance && $className !== $method->class) { if ($withoutInheritance && $className !== $method->class) {
continue; continue;
} }
@@ -68,14 +64,14 @@ class Reflection
*/ */
public static function getConstants($class) public static function getConstants($class)
{ {
$reflection = new ReflectionClass($class); $reflection = new \ReflectionClass($class);
return $reflection->getConstants(); return $reflection->getConstants();
} }
/** /**
* Returns maximum constant from all constants of given class / object. * Returns maximum integer value of constant of given class / object.
* Values of constants should be integers. * Constants whose values are integers are considered only.
* *
* @param object|string $class The object or name of object's class * @param object|string $class The object or name of object's class
* @return int|null * @return int|null
@@ -108,7 +104,7 @@ class Reflection
*/ */
public static function hasMethod($class, $method) public static function hasMethod($class, $method)
{ {
$reflection = new ReflectionClass($class); $reflection = new \ReflectionClass($class);
return $reflection->hasMethod($method); return $reflection->hasMethod($method);
} }
@@ -122,7 +118,7 @@ class Reflection
*/ */
public static function hasProperty($class, $property) public static function hasProperty($class, $property)
{ {
$reflection = new ReflectionClass($class); $reflection = new \ReflectionClass($class);
return $reflection->hasProperty($property); return $reflection->hasProperty($property);
} }
@@ -136,7 +132,7 @@ class Reflection
*/ */
public static function hasConstant($class, $constant) public static function hasConstant($class, $constant)
{ {
$reflection = new ReflectionClass($class); $reflection = new \ReflectionClass($class);
return $reflection->hasConstant($constant); return $reflection->hasConstant($constant);
} }
@@ -150,7 +146,7 @@ class Reflection
*/ */
public static function getConstantValue($class, $constant) public static function getConstantValue($class, $constant)
{ {
$reflection = new ReflectionClass($class); $reflection = new \ReflectionClass($class);
if (self::hasConstant($class, $constant)) { if (self::hasConstant($class, $constant)) {
return $reflection->getConstant($constant); return $reflection->getConstant($constant);
@@ -189,16 +185,16 @@ class Reflection
* Let's dig more and get proper value * Let's dig more and get proper value
* *
* Required to avoid bug: * 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) * 5. at Reflection ::getPropertyValue (null, 'name', true)
* 6. at ListService->getItemValue (object(Deal), 'project.name', '0') * 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) * while using "project.name" as property - $project has $name property ($project exists in the Deal class)
* and the $project equals null * and the $project equals null
* *
* Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * Meritoo <github@meritoo.pl>
* 2016-11-07 * 2016-11-07
*/ */
if (null !== $object) { if (null !== $object) {
@@ -216,17 +212,17 @@ class Reflection
* Use \ReflectionObject class * Use \ReflectionObject class
*/ */
try { try {
$reflectionProperty = new ReflectionProperty($className, $property); $reflectionProperty = new \ReflectionProperty($className, $property);
$value = $reflectionProperty->getValue($object); $value = $reflectionProperty->getValue($object);
} catch (ReflectionException $exception) { } catch (\ReflectionException $exception) {
/* /*
* 2nd try: * 2nd try:
* Look for the get / has / is methods * Look for the get / has / is methods
*/ */
$class = new ReflectionObject($object); $class = new \ReflectionObject($object);
$valueFound = false; $valueFound = false;
if ($class->hasProperty($property) || $force) { if ($force || $class->hasProperty($property)) {
$property = Inflector::classify($property); $property = Inflector::classify($property);
$getterPrefixes = [ $getterPrefixes = [
@@ -239,7 +235,7 @@ class Reflection
$getterName = sprintf('%s%s', $prefix, $property); $getterName = sprintf('%s%s', $prefix, $property);
if ($class->hasMethod($getterName)) { if ($class->hasMethod($getterName)) {
$method = new ReflectionMethod($object, $getterName); $method = new \ReflectionMethod($object, $getterName);
/* /*
* Getter is not accessible publicly? * Getter is not accessible publicly?
@@ -386,13 +382,13 @@ class Reflection
{ {
$fullClassName = self::getClassName($source); $fullClassName = self::getClassName($source);
if (empty($fullClassName)) { if (null === $fullClassName || '' === $fullClassName) {
return ''; return '';
} }
$className = self::getClassName($source, true); $className = self::getClassName($source, true);
if ($className == $fullClassName) { if ($className === $fullClassName) {
return $className; return $className;
} }
@@ -411,7 +407,7 @@ class Reflection
$className = self::getClassName($source); $className = self::getClassName($source);
$interfaces = class_implements($className); $interfaces = class_implements($className);
return in_array($interface, $interfaces); return in_array($interface, $interfaces, true);
} }
/** /**
@@ -428,8 +424,8 @@ class Reflection
$parents = class_parents($childClassName); $parents = class_parents($childClassName);
if (is_array($parents)) { if (is_array($parents) && 0 < count($parents)) {
return in_array($parentClassName, $parents); return in_array($parentClassName, $parents, true);
} }
return false; return false;
@@ -439,22 +435,22 @@ class Reflection
* Returns given object properties * Returns given object properties
* *
* @param array|object|string $source An array of objects, namespaces, object or namespace * @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. * constants. By default all properties are returned.
* @param bool $includeParents (optional) If is set to true, properties of parent classes are * @param bool $includeParents (optional) If is set to true, properties of parent classes are
* included (recursively). Otherwise - not. * included (recursively). Otherwise - not.
* @return array|ReflectionProperty * @return array|\ReflectionProperty
*/ */
public static function getProperties($source, $filter = null, $includeParents = false) public static function getProperties($source, $filter = null, $includeParents = false)
{ {
$className = self::getClassName($source); $className = self::getClassName($source);
$reflection = new ReflectionClass($className); $reflection = new \ReflectionClass($className);
if (null === $filter) { if (null === $filter) {
$filter = ReflectionProperty::IS_PRIVATE $filter = \ReflectionProperty::IS_PRIVATE
+ ReflectionProperty::IS_PROTECTED + \ReflectionProperty::IS_PROTECTED
+ ReflectionProperty::IS_PUBLIC + \ReflectionProperty::IS_PUBLIC
+ ReflectionProperty::IS_STATIC; + \ReflectionProperty::IS_STATIC;
} }
$properties = $reflection->getProperties($filter); $properties = $reflection->getProperties($filter);
@@ -476,12 +472,12 @@ class Reflection
* Returns a parent class or false if there is no parent class * 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 * @param array|object|string $source An array of objects, namespaces, object or namespace
* @return ReflectionClass|bool * @return \ReflectionClass|bool
*/ */
public static function getParentClass($source) public static function getParentClass($source)
{ {
$className = self::getClassName($source); $className = self::getClassName($source);
$reflection = new ReflectionClass($className); $reflection = new \ReflectionClass($className);
return $reflection->getParentClass(); return $reflection->getParentClass();
} }
@@ -492,8 +488,8 @@ class Reflection
* *
* @param array|object|string $class Class who child classes should be returned. An array of objects, strings, * @param array|object|string $class Class who child classes should be returned. An array of objects, strings,
* object or string. * object or string.
* @return array|null
* @throws CannotResolveClassNameException * @throws CannotResolveClassNameException
* @return array|null
*/ */
public static function getChildClasses($class) public static function getChildClasses($class)
{ {
@@ -513,7 +509,7 @@ class Reflection
* Oops, cannot resolve class * Oops, cannot resolve class
*/ */
if (null === $className) { if (null === $className) {
throw new CannotResolveClassNameException($class); throw CannotResolveClassNameException::create($class);
} }
$childClasses = []; $childClasses = [];
@@ -530,7 +526,7 @@ class Reflection
*/ */
$realClass = ClassUtils::getRealClass($oneClass); $realClass = ClassUtils::getRealClass($oneClass);
if (in_array($realClass, $childClasses)) { if (in_array($realClass, $childClasses, true)) {
continue; continue;
} }
@@ -547,10 +543,9 @@ class Reflection
* *
* @param array|object|string $parentClass Class who child class should be returned. An array of objects, * @param array|object|string $parentClass Class who child class should be returned. An array of objects,
* namespaces, object or namespace. * namespaces, object or namespace.
* @return mixed
*
* @throws MissingChildClassesException * @throws MissingChildClassesException
* @throws TooManyChildClassesException * @throws TooManyChildClassesException
* @return mixed
*/ */
public static function getOneChildClass($parentClass) public static function getOneChildClass($parentClass)
{ {
@@ -561,7 +556,7 @@ class Reflection
* Oops, the base / parent class hasn't child class * Oops, the base / parent class hasn't child class
*/ */
if (empty($childClasses)) { if (empty($childClasses)) {
throw new MissingChildClassesException($parentClass); throw MissingChildClassesException::create($parentClass);
} }
/* /*
@@ -569,20 +564,20 @@ class Reflection
* Oops, the base / parent class has too many child classes * Oops, the base / parent class has too many child classes
*/ */
if (count($childClasses) > 1) { if (count($childClasses) > 1) {
throw new TooManyChildClassesException($parentClass, $childClasses); throw TooManyChildClassesException::create($parentClass, $childClasses);
} }
return trim($childClasses[0]); return trim($childClasses[0]);
} }
/** /**
* 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 array|object|string $class An array of objects, namespaces, object or namespace
* @param string $property Name of the property * @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. * By default all properties are allowed / processed.
* @return null|ReflectionProperty * @return null|\ReflectionProperty
*/ */
public static function getProperty($class, $property, $filter = null) public static function getProperty($class, $property, $filter = null)
{ {
@@ -590,9 +585,9 @@ class Reflection
$properties = self::getProperties($className, $filter); $properties = self::getProperties($className, $filter);
if (!empty($properties)) { if (!empty($properties)) {
/* @var $reflectionProperty ReflectionProperty */ /* @var $reflectionProperty \ReflectionProperty */
foreach ($properties as $reflectionProperty) { foreach ($properties as $reflectionProperty) {
if ($reflectionProperty->getName() == $property) { if ($reflectionProperty->getName() === $property) {
return $reflectionProperty; return $reflectionProperty;
} }
} }
@@ -608,8 +603,8 @@ class Reflection
* @param array|string $trait An array of strings or string * @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 * @param bool $verifyParents If is set to true, parent classes are verified if they use given
* trait. Otherwise - not. * trait. Otherwise - not.
* @return bool|null
* @throws CannotResolveClassNameException * @throws CannotResolveClassNameException
* @return bool|null
*/ */
public static function usesTrait($class, $trait, $verifyParents = false) public static function usesTrait($class, $trait, $verifyParents = false)
{ {
@@ -619,21 +614,21 @@ class Reflection
/* /*
* Oops, cannot resolve class * Oops, cannot resolve class
*/ */
if (empty($className)) { if (null === $className || '' === $className) {
throw new CannotResolveClassNameException($class); throw CannotResolveClassNameException::create($class);
} }
/* /*
* Oops, cannot resolve trait * Oops, cannot resolve trait
*/ */
if (empty($traitName)) { if (null === $traitName || '' === $traitName) {
throw new CannotResolveClassNameException($class, false); throw new CannotResolveClassNameException($class, false);
} }
$reflection = new ReflectionClass($className); $reflection = new \ReflectionClass($className);
$traitsNames = $reflection->getTraitNames(); $traitsNames = $reflection->getTraitNames();
$uses = in_array($traitName, $traitsNames); $uses = in_array($traitName, $traitsNames, true);
if (!$uses && $verifyParents) { if (!$uses && $verifyParents) {
$parentClassName = self::getParentClassName($className); $parentClassName = self::getParentClassName($className);
@@ -656,7 +651,7 @@ class Reflection
public static function getParentClassName($class) public static function getParentClassName($class)
{ {
$className = self::getClassName($class); $className = self::getClassName($class);
$reflection = new ReflectionClass($className); $reflection = new \ReflectionClass($className);
$parentClass = $reflection->getParentClass(); $parentClass = $reflection->getParentClass();
if (null === $parentClass || false === $parentClass) { if (null === $parentClass || false === $parentClass) {
@@ -665,4 +660,36 @@ class Reflection
return $parentClass->getName(); 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

@@ -14,8 +14,8 @@ use Meritoo\Common\Exception\Regex\InvalidColorHexValueException;
/** /**
* Useful regular expressions methods * Useful regular expressions methods
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class Regex class Regex
{ {
@@ -25,18 +25,21 @@ class Regex
* @var array * @var array
*/ */
private static $patterns = [ private static $patterns = [
'email' => '/[\w-]{2,}@[\w-]+\.[\w]{2,}+/', 'email' => '/^[\w-.]{2,}@[\w-]+\.[\w]{2,}+$/',
'phone' => '/^\+?[0-9 ]+$/', 'phone' => '/^\+?[0-9 ]+$/',
'camelCasePart' => '/([a-z]|[A-Z]){1}[a-z]*/', 'camelCasePart' => '/([a-z]|[A-Z]){1}[a-z]*/',
'urlProtocol' => '/^([a-z]+:\/\/)', 'urlProtocol' => '/^([a-z]+:\/\/)',
'urlDomain' => '([\da-z\.-]+)\.([a-z\.]{2,6})(\/)?([\w\.\-]*)?(\?)?([\w \.\-\/=&]*)\/?$/i', 'urlDomain' => '([\da-z\.-]+)\.([a-z\.]{2,6})(\/)?([\w\.\-]*)?(\?)?([\w \.\-\/=&]*)\/?$/i',
'letterOrDigit' => '/[a-zA-Z0-9]+/', 'letterOrDigit' => '/[a-zA-Z0-9]+/',
'htmlEntity' => '/&[a-z0-9]+;/', 'htmlEntity' => '/&[a-z0-9]+;/',
'htmlAttribute' => '/([\w-]+)="([\w -]+)"/',
'fileName' => '/.+\.\w+$/', 'fileName' => '/.+\.\w+$/',
'isQuoted' => '/^[\'"]{1}.+[\'"]{1}$/', 'isQuoted' => '/^[\'"]{1}.+[\'"]{1}$/',
'windowsBasedPath' => '/^[A-Z]{1}:\\\.*$/', 'windowsBasedPath' => '/^[A-Z]{1}:\\\.*$/',
'money' => '/^[-+]?\d+([\.,]{1}\d*)?$/', 'money' => '/^[-+]?\d+([\.,]{1}\d*)?$/',
'color' => '/^[a-f0-9]{6}$/i', 'color' => '/^[a-f0-9]{6}$/i',
'bundleName' => '/^(([A-Z]{1}[a-z0-9]+)((?2))*)(Bundle)$/',
'binaryValue' => '/[^\x20-\x7E\t\r\n]/',
]; ];
/** /**
@@ -56,20 +59,53 @@ class Regex
*/ */
public static function isValidEmail($email) public static function isValidEmail($email)
{ {
/*
* Not a string?
* Nothing to do
*/
if (!is_string($email)) {
return false;
}
$pattern = self::getEmailPattern(); $pattern = self::getEmailPattern();
return (bool)preg_match($pattern, $email); return (bool)preg_match($pattern, $email);
} }
/** /**
* Returns information if given tax ID (in polish: NIP) is valid * Returns information if given tax ID is valid (in Poland it's named "NIP")
* *
* @param string $taxidString Tax ID (NIP) string * @param string $taxIdString Tax ID (NIP) string
* @return bool * @return bool
*/ */
public static function isValidTaxid($taxidString) public static function isValidTaxId($taxIdString)
{ {
if (!empty($taxidString)) { /*
* Not a string?
* Nothing to do
*/
if (!is_string($taxIdString)) {
return false;
}
/*
* Empty/Unknown value?
* Nothing to do
*/
if (empty($taxIdString)) {
return false;
}
$taxId = preg_replace('/[\s-]/', '', $taxIdString);
/*
* Tax ID is not 10 characters length OR is not numeric?
* Nothing to do
*/
if (10 !== strlen($taxId) || !is_numeric($taxId)) {
return false;
}
$weights = [ $weights = [
6, 6,
5, 5,
@@ -81,19 +117,20 @@ class Regex
6, 6,
7, 7,
]; ];
$taxid = preg_replace('/[\s-]/', '', $taxidString);
$sum = 0; $sum = 0;
if (10 == strlen($taxid) && is_numeric($taxid)) {
for ($x = 0; $x <= 8; ++$x) { for ($x = 0; $x <= 8; ++$x) {
$sum += $taxid[$x] * $weights[$x]; $sum += $taxId[$x] * $weights[$x];
} }
if ((($sum % 11) % 10) == $taxid[9]) { /*
* Last number it's not a remainder from dividing per 11?
* Nothing to do
*/
if ($sum % 11 == $taxId[9]) {
return true; return true;
} }
}
}
return false; return false;
} }
@@ -108,6 +145,14 @@ class Regex
*/ */
public static function isValidUrl($url, $requireProtocol = false) public static function isValidUrl($url, $requireProtocol = false)
{ {
/*
* Not a string?
* Nothing to do
*/
if (!is_string($url)) {
return false;
}
$pattern = self::getUrlPattern($requireProtocol); $pattern = self::getUrlPattern($requireProtocol);
return (bool)preg_match($pattern, $url); return (bool)preg_match($pattern, $url);
@@ -121,117 +166,143 @@ class Regex
*/ */
public static function isValidPhoneNumber($phoneNumber) public static function isValidPhoneNumber($phoneNumber)
{ {
/*
* Not a string?
* Nothing to do
*/
if (!is_string($phoneNumber)) {
return false;
}
$pattern = self::getPhoneNumberPattern(); $pattern = self::getPhoneNumberPattern();
return (bool)preg_match($pattern, $phoneNumber); return (bool)preg_match($pattern, trim($phoneNumber));
} }
/** /**
* Returns array values that matches given pattern (or values that keys matches) * Returns array values that match given pattern (or values that keys match the pattern)
* *
* @param string $pattern Pattern to match * @param string $pattern Pattern to match
* @param array $dataArray The array * @param array $array The array (scalar values only)
* @param bool $itsKeyPattern (optional) If is set to true, keys are checks if they match pattern. Otherwise - * @param bool $itsKeyPattern (optional) If is set to true, keys will be checked if they match pattern.
* values are checks. * Otherwise - values will be checked (default behaviour).
* @return array * @return array
*/ */
public static function getArrayValuesByPattern($pattern, $dataArray, $itsKeyPattern = false) public static function getArrayValuesByPattern($pattern, array $array, $itsKeyPattern = false)
{ {
/*
* No elements?
* Nothing to do
*/
if (empty($array)) {
return [];
}
if ($itsKeyPattern) { if ($itsKeyPattern) {
$effect = []; $effect = [];
if (!empty($dataArray)) { foreach ($array as $key => $value) {
$matches = []; if ((bool)preg_match($pattern, $key)) {
foreach ($dataArray as $key => $value) {
if (preg_match($pattern, $key, $matches)) {
$effect[$key] = $value; $effect[$key] = $value;
} }
} }
}
return $effect; return $effect;
} }
return preg_grep($pattern, $dataArray); return preg_grep($pattern, $array);
} }
/** /**
* Filters array by given expression and column * Filters array by given expression and column
* *
* Expression can be simple compare expression, like ' == 2', or regular expression. * Expression can be simple compare expression, like " == 2", or regular expression.
* Returns filtered array. * Returns filtered array.
* *
* @param array $array The array that should be filtered * @param array $array The 2-dimensional array that should be filtered
* @param string $arrayColumnKey Column name * @param string $arrayColumnKey Column name
* @param string $filterExpression Filter expression, e.g. '== 2' or '!= \'home\'' * @param string $filterExpression Simple filter expression (e.g. "== 2" or "!= \'home\'") or regular
* @param bool $itsRegularExpression (optional) If is set to true, means that filter expression is a * expression (e.g. "/\d+/" or "/[a-z]+[,;]{2,}/")
* regular expression * @param bool $itsRegularExpression (optional) If is set to true, means that filter expression is a regular
* expression. Otherwise - not (default behaviour).
* @return array * @return array
*/ */
public static function arrayFilter($array, $arrayColumnKey, $filterExpression, $itsRegularExpression = false) public static function arrayFilter($array, $arrayColumnKey, $filterExpression, $itsRegularExpression = false)
{ {
$effect = []; /*
* No elements?
* Nothing to do
*/
if (empty($array)) {
return [];
}
if (!empty($array)) {
$effect = $array; $effect = $array;
foreach ($effect as $key => &$item) { foreach ($effect as $key => &$item) {
if (isset($item[$arrayColumnKey])) { if (!isset($item[$arrayColumnKey])) {
continue;
}
$value = $item[$arrayColumnKey]; $value = $item[$arrayColumnKey];
if ($itsRegularExpression) { if ($itsRegularExpression) {
$matches = []; $matchesCount = preg_match($filterExpression, $value);
$pattern = '|' . $filterExpression . '|';
$matchesCount = preg_match($pattern, $value, $matches);
$remove = 0 == $matchesCount; $remove = 0 == $matchesCount;
} else { } else {
if ('' == $value) { if (is_string($value)) {
$value = '\'\''; $value = sprintf('\'%s\'', $value);
} elseif (is_string($value)) { } elseif (is_bool($value)) {
$value = '\'' . $value . '\''; if (true === $value) {
$value = 'true';
} else {
$value = 'false';
}
} }
eval('$isTrue = ' . $value . $filterExpression . ';'); eval(sprintf('$isEqual = %s%s;', $value, $filterExpression));
/* @var bool $isTrue */ /* @var bool $isEqual */
$remove = !$isTrue; $remove = !$isEqual;
} }
if ($remove) { if ($remove) {
unset($effect[$key]); unset($effect[$key]);
} }
} }
}
}
return $effect; return $effect;
} }
/** /**
* Perform regular expression match with many given patterns. * Performs regular expression match with many given patterns.
* Returns information if given $subject matches one or all given $patterns. * Returns information if given $subject matches one or all given $patterns.
* *
* @param array|string $patterns The patterns to match * @param array|string $patterns The patterns to match
* @param string $subject The string to check * @param string $subject The string to check
* @param bool $mustAllMatch (optional) If is set to true, $subject must match all $patterns. Otherwise - * @param bool $mustAllMatch (optional) If is set to true, $subject must match all $patterns. Otherwise -
* not. * not (default behaviour).
* @return bool * @return bool
*/ */
public static function pregMultiMatch($patterns, $subject, $mustAllMatch = false) public static function pregMultiMatch($patterns, $subject, $mustAllMatch = false)
{ {
/*
* No patterns?
* Nothing to do
*/
if (empty($patterns)) {
return false;
}
$effect = false; $effect = false;
$patterns = Arrays::makeArray($patterns); $patterns = Arrays::makeArray($patterns);
if (!empty($patterns)) {
if ($mustAllMatch) { if ($mustAllMatch) {
$effect = true; $effect = true;
} }
foreach ($patterns as $pattern) { foreach ($patterns as $pattern) {
$matches = []; $matched = (bool)preg_match_all($pattern, $subject);
$matched = (bool)preg_match_all($pattern, $subject, $matches);
if ($mustAllMatch) { if ($mustAllMatch) {
$effect = $effect && $matched; $effect = $effect && $matched;
@@ -242,7 +313,6 @@ class Regex
} }
} }
} }
}
return $effect; return $effect;
} }
@@ -676,6 +746,14 @@ class Regex
*/ */
public static function isValidMoneyValue($value) public static function isValidMoneyValue($value)
{ {
/*
* Not a scalar value?
* Nothing to do
*/
if (!is_scalar($value)) {
return false;
}
$pattern = self::getMoneyPattern(); $pattern = self::getMoneyPattern();
return (bool)preg_match($pattern, $value); return (bool)preg_match($pattern, $value);
@@ -688,32 +766,54 @@ class Regex
* @param string $color Color to verify * @param string $color Color to verify
* @param bool $throwException (optional) If is set to true, throws an exception if given color is invalid * @param bool $throwException (optional) If is set to true, throws an exception if given color is invalid
* (default behaviour). Otherwise - not. * (default behaviour). Otherwise - not.
* @return string|bool
*
* @throws IncorrectColorHexLengthException * @throws IncorrectColorHexLengthException
* @throws InvalidColorHexValueException * @throws InvalidColorHexValueException
* @return string|bool
*/ */
public static function getValidColorHexValue($color, $throwException = true) public static function getValidColorHexValue($color, $throwException = true)
{ {
/*
* Not a scalar value?
* Nothing to do
*/
if (!is_scalar($color)) {
return false;
}
$color = Miscellaneous::replace($color, '/#/', ''); $color = Miscellaneous::replace($color, '/#/', '');
$length = strlen($color); $length = strlen($color);
if (3 === $length) { /*
$color = Miscellaneous::replace($color, '/(.)(.)(.)/', '$1$1$2$2$3$3'); * Color is not 3 or 6 characters long?
} else { * Nothing to do
if (6 !== $length) { */
if (3 !== $length && 6 !== $length) {
if ($throwException) { if ($throwException) {
throw new IncorrectColorHexLengthException($color); throw new IncorrectColorHexLengthException($color);
} }
return false; return false;
} }
/*
* Color is 3 characters long?
* Let's make it 6 characters long
*/
if (3 === $length) {
$color = Miscellaneous::replace($color, '/(.)(.)(.)/', '$1$1$2$2$3$3');
} }
$pattern = self::$patterns['color']; $pattern = self::$patterns['color'];
$match = (bool)preg_match($pattern, $color); $match = (bool)preg_match($pattern, $color);
if (!$match) { /*
* It's valid color
* Nothing to do more
*/
if ($match) {
return strtolower($color);
}
if ($throwException) { if ($throwException) {
throw new InvalidColorHexValueException($color); throw new InvalidColorHexValueException($color);
} }
@@ -721,6 +821,107 @@ class Regex
return false; return false;
} }
return strtolower($color); /**
* Returns information if given name of bundle is valid
*
* @param string $bundleName Full name of bundle to verify, e.g. "MyExtraBundle"
* @return bool
*/
public static function isValidBundleName($bundleName)
{
/*
* Not a string?
* Nothing to do
*/
if (!is_string($bundleName)) {
return false;
}
$pattern = self::getBundleNamePattern();
return (bool)preg_match($pattern, $bundleName);
}
/**
* Returns pattern used to validate / verify name of bundle
*
* @return string
*/
public static function getBundleNamePattern()
{
return self::$patterns['bundleName'];
}
/**
* Returns pattern used to validate / verify html attribute
*
* @return string
*/
public static function getHtmlAttributePattern()
{
return self::$patterns['htmlAttribute'];
}
/**
* Returns information if given html attribute is valid
*
* @param string $htmlAttribute The html attribute to verify
* @return bool
*/
public static function isValidHtmlAttribute($htmlAttribute)
{
/*
* Not a string?
* Nothing to do
*/
if (!is_string($htmlAttribute)) {
return false;
}
$pattern = self::getHtmlAttributePattern();
return (bool)preg_match($pattern, $htmlAttribute);
}
/**
* Returns information if given html attributes are valid
*
* @param string $htmlAttributes The html attributes to verify
* @return bool
*/
public static function areValidHtmlAttributes($htmlAttributes)
{
/*
* Not a string?
* Nothing to do
*/
if (!is_string($htmlAttributes)) {
return false;
}
$pattern = self::getHtmlAttributePattern();
return (bool)preg_match_all($pattern, $htmlAttributes);
}
/**
* Returns information if given value is a binary value
*
* @param string $value Value to verify
* @return bool
*/
public static function isBinaryValue($value)
{
/*
* Not a string?
* Nothing to do
*/
if (!is_string($value)) {
return false;
}
$pattern = self::$patterns['binaryValue'];
return (bool)preg_match($pattern, $value);
} }
} }

View File

@@ -14,74 +14,150 @@ use Doctrine\ORM\QueryBuilder;
/** /**
* Useful methods for repository * Useful methods for repository
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class Repository class Repository
{ {
/**
* Name of key responsible for sorting/position of an item in array
*
* @var string
*/
const POSITION_KEY = 'position';
/** /**
* Replenishes positions of given items * Replenishes positions of given items
* *
* @param array $items The items * @param array $items Objects who have "getPosition()" and "setPosition()" methods or arrays
* @param bool $asLast (optional) If is set to true, items are placed at the end. Otherwise - at the top. * @param bool $asLast (optional) If is set to true, items are placed at the end (default behaviour). Otherwise -
* at top.
* @param bool $force (optional) If is set to true, positions are set even there is no extreme position. * @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. * Otherwise - if extreme position is unknown (is null) replenishment is stopped / skipped
* (default behaviour).
*/ */
public static function replenishPositions($items, $asLast = true, $force = false) public static function replenishPositions(array &$items, $asLast = true, $force = false)
{ {
$position = self::getExtremePosition($items, $asLast); $position = self::getExtremePosition($items, $asLast);
/*
* Extreme position is unknown, but it's required?
* Use 0 as default/start value
*/
if (null === $position && $force) { if (null === $position && $force) {
$position = 0; $position = 0;
} }
if (null !== $position && !empty($items)) { /*
foreach ($items as $item) { * Extreme position is unknown or there are no items to sort?
if (method_exists($item, 'getPosition')) { * Nothing to do
if (null === $item->getPosition()) { */
if (null === $position || empty($items)) {
return;
}
foreach ($items as &$item) {
/*
* The item is not sortable?
*/
if (!self::isSortable($item)) {
continue;
}
/*
* Position has been set?
* Nothing to do
*/
if (self::isSorted($item)) {
continue;
}
/*
* Calculate position
*/
if ($asLast) { if ($asLast) {
++$position; ++$position;
} else { } else {
--$position; --$position;
} }
if (method_exists($item, 'setPosition')) { /*
* It's an object?
* Use proper method to set position
*/
if (is_object($item)) {
$item->setPosition($position); $item->setPosition($position);
continue;
} }
}
} /*
} * It's an array
* Use proper key to set position
*/
$item[static::POSITION_KEY] = $position;
} }
} }
/** /**
* Returns extreme position (max or min) of given items * Returns extreme position (max or min) of given items
* *
* @param array $items The items * @param array $items Objects who have "getPosition()" and "setPosition()" methods or arrays
* @param bool $max (optional) If is set to true, maximum value is returned. Otherwise - minimum. * @param bool $max (optional) If is set to true, maximum value is returned. Otherwise - minimum.
* @return int * @return int
*/ */
public static function getExtremePosition($items, $max = true) public static function getExtremePosition(array $items, $max = true)
{ {
/*
* No items?
* Nothing to do
*/
if (empty($items)) {
return null;
}
$extreme = null; $extreme = null;
if (!empty($items)) {
foreach ($items as $item) { foreach ($items as $item) {
if (Reflection::hasMethod($item, 'getPosition')) { /*
$position = $item->getPosition(); * The item is not sortable?
*/
if (!self::isSortable($item)) {
continue;
}
$position = null;
/*
* Let's grab the position
*/
if (is_object($item)) {
$position = $item->getPosition();
} elseif (array_key_exists(static::POSITION_KEY, $item)) {
$position = $item[static::POSITION_KEY];
}
/*
* Maximum value is expected?
*/
if ($max) { if ($max) {
if ($position > $extreme) { /*
* Position was found and it's larger than previously found position (the extreme position)?
*/
if (null === $extreme || (null !== $position && $position > $extreme)) {
$extreme = $position; $extreme = $position;
} }
} else {
if ($position < $extreme) { continue;
}
/*
* Minimum value is expected here.
* Position was found and it's smaller than previously found position (the extreme position)?
*/
if (null === $extreme || (null !== $position && $position < $extreme)) {
$extreme = $position; $extreme = $position;
} }
} }
}
}
}
return $extreme; return $extreme;
} }
@@ -106,4 +182,54 @@ class Repository
->createQueryBuilder($alias) ->createQueryBuilder($alias)
->orderBy(sprintf('%s.%s', $alias, $property), $direction); ->orderBy(sprintf('%s.%s', $alias, $property), $direction);
} }
/**
* Returns information if given item is sortable
*
* Sortable means it's an:
* - array
* or
* - object and has getPosition() and setPosition()
*
* @param mixed $item An item to verify (object who has "getPosition()" and "setPosition()" methods or an array)
* @return bool
*/
private static function isSortable($item)
{
return is_array($item)
||
(
is_object($item)
&&
Reflection::hasMethod($item, 'getPosition')
&&
Reflection::hasMethod($item, 'setPosition')
);
}
/**
* Returns information if given item is sorted (position has been set)
*
* @param mixed $item An item to verify (object who has "getPosition()" and "setPosition()" methods or an array)
* @return bool
*/
private static function isSorted($item)
{
/*
* Given item is not sortable?
*/
if (!self::isSortable($item)) {
return false;
}
/*
* It's an object or it's an array
* and position has been set?
*/
return
(is_object($item) && null !== $item->getPosition())
||
(is_array($item) && isset($item[static::POSITION_KEY]));
}
} }

View File

@@ -11,8 +11,8 @@ namespace Meritoo\Common\Utilities;
/** /**
* Useful uri methods (only static functions) * Useful uri methods (only static functions)
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class Uri class Uri
{ {
@@ -24,13 +24,25 @@ class Uri
*/ */
public static function getFullUri($withoutHost = false) public static function getFullUri($withoutHost = false)
{ {
$effect = Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'REQUEST_URI'); $requestedUrl = Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'REQUEST_URI');
if ($withoutHost) { /*
return $effect; * Unknown requested url?
* Nothing to do
*/
if (empty($requestedUrl)) {
return '';
} }
return self::getServerNameOrIp(true) . $effect; /*
* Without host / server name?
* All is done
*/
if ($withoutHost) {
return $requestedUrl;
}
return self::getServerNameOrIp(true) . $requestedUrl;
} }
/** /**
@@ -41,13 +53,25 @@ class Uri
*/ */
public static function getServerNameOrIp($withProtocol = false) public static function getServerNameOrIp($withProtocol = false)
{ {
$protocol = ''; $host = Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'HTTP_HOST');
if ($withProtocol) { /*
$protocol .= self::getProtocolName() . '://'; * Unknown host / server?
* Nothing to do
*/
if (empty($host)) {
return '';
} }
return $protocol . Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'HTTP_HOST'); /*
* With protocol?
* Let's include the protocol
*/
if ($withProtocol) {
return sprintf('%s://%s', self::getProtocolName(), $host);
}
return $host;
} }
/** /**
@@ -57,8 +81,6 @@ class Uri
*/ */
public static function getProtocolName() public static function getProtocolName()
{ {
$effect = '';
$matches = []; $matches = [];
$protocolData = Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'SERVER_PROTOCOL'); // e.g. HTTP/1.1 $protocolData = Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'SERVER_PROTOCOL'); // e.g. HTTP/1.1
$matchCount = preg_match('|(.+)\/(.+)|', $protocolData, $matches); $matchCount = preg_match('|(.+)\/(.+)|', $protocolData, $matches);
@@ -68,11 +90,14 @@ class Uri
* $matches[2] - protocol version, e.g. 1.1 * $matches[2] - protocol version, e.g. 1.1
*/ */
if ($matchCount > 0) { /*
$effect = strtolower($matches[1]); * Oops, cannot match protocol
*/
if (0 == $matchCount) {
return '';
} }
return $effect; return strtolower($matches[1]);
} }
/** /**
@@ -82,13 +107,7 @@ class Uri
*/ */
public static function getRefererUri() public static function getRefererUri()
{ {
$effect = ''; return Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'HTTP_REFERER');
if (filter_has_var(INPUT_SERVER, 'HTTP_REFERER')) {
$effect = Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'HTTP_REFERER');
}
return $effect;
} }
/** /**
@@ -214,10 +233,35 @@ class Uri
*/ */
public static function isExternalUrl($url) public static function isExternalUrl($url)
{ {
/*
* Unknown url or it's just slash?
* Nothing to do
*/
if (empty($url) || '/' === $url) {
return false;
}
$currentUrl = self::getServerNameOrIp(true); $currentUrl = self::getServerNameOrIp(true);
$url = self::replenishProtocol($url); $url = self::replenishProtocol($url);
return !Regex::contains($currentUrl, $url); /*
* Let's prepare pattern of current url
*/
$search = [
':',
'/',
'.',
];
$replace = [
'\:',
'\/',
'\.',
];
$currentUrlPattern = str_replace($search, $replace, $currentUrl);
return !Regex::contains($url, $currentUrlPattern);
} }
/** /**
@@ -273,6 +317,14 @@ class Uri
*/ */
public static function getSecuredUrl($url, $user = '', $password = '') public static function getSecuredUrl($url, $user = '', $password = '')
{ {
/*
* Url is not provided?
* Nothing to do
*/
if (empty($url)) {
return '';
}
$protocol = self::getProtocolName(); $protocol = self::getProtocolName();
$host = self::getServerNameOrIp(); $host = self::getServerNameOrIp();

View File

@@ -15,8 +15,8 @@ use SimpleXMLElement;
/** /**
* Useful XML-related methods (only static functions) * Useful XML-related methods (only static functions)
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class Xml class Xml
{ {

179
src/ValueObject/Version.php Normal file
View File

@@ -0,0 +1,179 @@
<?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\ValueObject;
/**
* Version of software
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class Version
{
/**
* The "major" part.
* Incremented when you make incompatible API changes.
*
* @var int
*/
private $majorPart;
/**
* The "minor" part.
* Incremented when you add functionality in a backwards-compatible manner.
*
* @var int
*/
private $minorPart;
/**
* The "patch" part.
* Incremented when you make backwards-compatible bug fixes.
*
* @var int
*/
private $patchPart;
/**
* Class constructor
*
* @param int $majorPart The "major" part. Incremented when you make incompatible API changes.
* @param int $minorPart The "minor" part. Incremented when you add functionality in a backwards-compatible manner.
* @param int $patchPart The "patch" part. Incremented when you make backwards-compatible bug fixes.
*/
public function __construct($majorPart, $minorPart, $patchPart)
{
$this->majorPart = $majorPart;
$this->minorPart = $minorPart;
$this->patchPart = $patchPart;
}
/**
* Returns the "major" part.
* Incremented when you make incompatible API changes.
*
* @return int
*/
public function getMajorPart()
{
return $this->majorPart;
}
/**
* Returns the "minor" part.
* Incremented when you add functionality in a backwards-compatible manner.
*
* @return int
*/
public function getMinorPart()
{
return $this->minorPart;
}
/**
* Returns the "patch" part.
* Incremented when you make backwards-compatible bug fixes.
*
* @return int
*/
public function getPatchPart()
{
return $this->patchPart;
}
/**
* Returns string representation of instance of this class
*
* @return string
*/
public function __toString()
{
return sprintf('%d.%d.%d', $this->getMajorPart(), $this->getMinorPart(), $this->getPatchPart());
}
/**
* Returns new instance based on given version as string.
* Given version should contain 3 dot-separated integers, 1 per each part ("major", "minor" and "patch").
*
* Examples:
* "1.0.2";
* "10.4.0";
*
* @param string $version The version
* @return Version|null
*/
public static function fromString($version)
{
$version = trim($version);
/*
* No version provided?
* Nothing to do
*/
if (empty($version)) {
return null;
}
$matches = [];
$pattern = '/^(\d+)\.(\d+)\.(\d+)$/'; // e.g. "1.0.2"
$matched = preg_match($pattern, $version, $matches);
/*
* Incorrect version?
* Nothing to do
*/
if (0 === $matched || false === $matched) {
return null;
}
$majorPart = (int)$matches[1];
$minorPart = (int)$matches[2];
$patchPart = (int)$matches[3];
return new static($majorPart, $minorPart, $patchPart);
}
/**
* Returns new instance based on given version as array.
* Given version should contain 3 integers, 1 per each part ("major", "minor" and "patch").
*
* Examples:
* [1, 0, 2];
* [10, 4, 0];
*
* @param array $version The version
* @return Version|null
*/
public static function fromArray(array $version)
{
/*
* No version provided?
* Nothing to do
*/
if (empty($version)) {
return null;
}
$count = count($version);
/*
* Incorrect version?
* Nothing to do
*/
if (3 !== $count) {
return null;
}
$majorPart = (int)$version[0];
$minorPart = (int)$version[1];
$patchPart = (int)$version[2];
return new static($majorPart, $minorPart, $patchPart);
}
}

View File

@@ -9,6 +9,7 @@
namespace Meritoo\Common\Test\Collection; namespace Meritoo\Common\Test\Collection;
use ArrayIterator; use ArrayIterator;
use Generator;
use Meritoo\Common\Collection\Collection; use Meritoo\Common\Collection\Collection;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
@@ -16,8 +17,8 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of the collection of elements * Test case of the collection of elements
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class CollectionTest extends BaseTestCase class CollectionTest extends BaseTestCase
{ {
@@ -129,22 +130,39 @@ class CollectionTest extends BaseTestCase
static::assertInstanceOf(ArrayIterator::class, $this->simpleCollection->getIterator()); static::assertInstanceOf(ArrayIterator::class, $this->simpleCollection->getIterator());
} }
public function testAdd() /**
* @param mixed $element The element to add
* @param int $expectedCount Expected count of elements in collection
* @param int $expectedIndex Expected index of added element in collection
* @param Collection $collection The collection
*
* @dataProvider provideElementToAdd
*/
public function testAddWithoutIndex($element, $expectedCount, $expectedIndex, Collection $collection)
{ {
$this->emptyCollection->add('test1'); $collection->add($element);
static::assertTrue($this->emptyCollection->has('test1')); static::assertTrue($collection->has($element));
static::assertEquals(1, $this->emptyCollection->count()); static::assertEquals($expectedCount, $collection->count());
static::assertEquals('test1', $this->emptyCollection[0]); static::assertEquals($element, $collection[$expectedIndex]);
} }
public function testAddWithIndex() /**
* @param mixed $element The element to add
* @param mixed $index Index of element to add
* @param int $expectedCount Expected count of elements in collection
* @param int $expectedIndex Expected index of added element in collection
* @param Collection $collection The collection
*
* @dataProvider provideElementToAddWithIndex
*/
public function testAddWithIndex($element, $index, $expectedCount, $expectedIndex, Collection $collection)
{ {
$this->emptyCollection->add('test2', 1234); $collection->add($element, $index);
static::assertTrue($this->emptyCollection->has('test2')); static::assertTrue($collection->has($element));
static::assertEquals(1, $this->emptyCollection->count()); static::assertEquals($expectedCount, $collection->count());
static::assertEquals('test2', $this->emptyCollection[1234]); static::assertEquals($element, $collection[$expectedIndex]);
} }
public function testAddMultipleUsingEmptyArray() public function testAddMultipleUsingEmptyArray()
@@ -309,6 +327,87 @@ class CollectionTest extends BaseTestCase
static::assertMethodVisibilityAndArguments(Collection::class, 'exists', OopVisibilityType::IS_PRIVATE, 1, 1); static::assertMethodVisibilityAndArguments(Collection::class, 'exists', OopVisibilityType::IS_PRIVATE, 1, 1);
} }
/**
* Provides element to add to collection
*
* @return Generator
*/
public function provideElementToAdd()
{
$collection = new Collection();
yield[
'test1',
1,
0,
$collection,
];
yield[
'test2',
2,
1,
$collection,
];
yield[
'test3',
3,
2,
$collection,
];
}
/**
* Provides element with index to add to collection
*
* @return Generator
*/
public function provideElementToAddWithIndex()
{
$collection = new Collection();
yield[
'test1',
'aa',
1,
'aa',
$collection,
];
yield[
'test2',
'oo',
2,
'oo',
$collection,
];
yield[
'test3',
null,
3,
0,
$collection,
];
yield[
'test4',
'',
4,
1,
$collection,
];
yield[
'test5',
'vv',
5,
'vv',
$collection,
];
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@@ -16,14 +16,14 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of the exception used while type of something is unknown * Test case of the exception used while type of something is unknown
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class UnknownTypeExceptionTest extends BaseTestCase class UnknownTypeExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(UnknownTestTypeException::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(UnknownTestTypeException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
public function testWithoutException() public function testWithoutException()
@@ -41,8 +41,8 @@ class UnknownTypeExceptionTest extends BaseTestCase
/** /**
* Type of something (for testing purposes) * Type of something (for testing purposes)
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class TestType extends BaseType class TestType extends BaseType
{ {
@@ -54,27 +54,31 @@ class TestType extends BaseType
/** /**
* An exception used while type of something is unknown (for testing purposes) * An exception used while type of something is unknown (for testing purposes)
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class UnknownTestTypeException extends UnknownTypeException class UnknownTestTypeException extends UnknownTypeException
{ {
/** /**
* Class constructor * Creates exception
* *
* @param int|string $unknownType The unknown type of something (for testing purposes) * @param string $unknownType The unknown type of something (for testing purposes)
* @return UnknownTestTypeException
*/ */
public function __construct($unknownType) public static function createException($unknownType)
{ {
parent::__construct($unknownType, new TestType(), 'type of something used for testing'); /* @var UnknownTestTypeException $exception */
$exception = parent::create($unknownType, new TestType(), 'type of something used for testing');
return $exception;
} }
} }
/** /**
* Service used together with type of something (for testing purposes) * Service used together with type of something (for testing purposes)
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class TestService class TestService
{ {
@@ -82,9 +86,8 @@ class TestService
* Returns translated type (for testing purposes) * Returns translated type (for testing purposes)
* *
* @param string $type Type of something (for testing purposes) * @param string $type Type of something (for testing purposes)
* @return string
*
* @throws UnknownTestTypeException * @throws UnknownTestTypeException
* @return string
*/ */
public function getTranslatedType($type) public function getTranslatedType($type)
{ {

View File

@@ -9,7 +9,7 @@
namespace Meritoo\Common\Test\Exception\Date; namespace Meritoo\Common\Test\Exception\Date;
use Generator; use Generator;
use Meritoo\Common\Exception\Date\UnknownDatePartTypeException; use Meritoo\Common\Exception\Type\UnknownDatePartTypeException;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\DatePartType; use Meritoo\Common\Type\DatePartType;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
@@ -17,14 +17,14 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of an exception used while type of date part, e.g. "year", is unknown * Test case of an exception used while type of date part, e.g. "year", is unknown
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class UnknownDatePartTypeExceptionTest extends BaseTestCase class UnknownDatePartTypeExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(UnknownDatePartTypeException::class, OopVisibilityType::IS_PUBLIC, 2, 2); static::assertConstructorVisibilityAndArguments(UnknownDatePartTypeException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
/** /**
@@ -34,9 +34,9 @@ class UnknownDatePartTypeExceptionTest extends BaseTestCase
* *
* @dataProvider provideDatePartAndValue * @dataProvider provideDatePartAndValue
*/ */
public function testConstructorMessage($unknownDatePart, $value, $expectedMessage) public function testMessage($unknownDatePart, $value, $expectedMessage)
{ {
$exception = new UnknownDatePartTypeException($unknownDatePart, $value); $exception = UnknownDatePartTypeException::createException($unknownDatePart, $value);
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }

View File

@@ -16,14 +16,14 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of an exception used while file with given path is empty (has no content) * Test case of an exception used while file with given path is empty (has no content)
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class EmptyFileExceptionTest extends BaseTestCase class EmptyFileExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(EmptyFileException::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(EmptyFileException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
/** /**
@@ -32,9 +32,9 @@ class EmptyFileExceptionTest extends BaseTestCase
* *
* @dataProvider providePathOfFile * @dataProvider providePathOfFile
*/ */
public function testConstructorMessage($emptyFilePath, $expectedMessage) public function testMessage($emptyFilePath, $expectedMessage)
{ {
$exception = new EmptyFileException($emptyFilePath); $exception = EmptyFileException::create($emptyFilePath);
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }

View File

@@ -15,19 +15,19 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of an exception used while path of given file is empty * Test case of an exception used while path of given file is empty
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class EmptyFilePathExceptionTest extends BaseTestCase class EmptyFilePathExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(EmptyFilePathException::class, OopVisibilityType::IS_PUBLIC); static::assertConstructorVisibilityAndArguments(EmptyFilePathException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
public function testConstructorMessage() public function testConstructorMessage()
{ {
$exception = new EmptyFilePathException(); $exception = EmptyFilePathException::create();
static::assertEquals('Path of the file is empty. Did you provide path of proper file?', $exception->getMessage()); static::assertEquals('Path of the file is empty. Did you provide path of proper file?', $exception->getMessage());
} }
} }

View File

@@ -16,14 +16,14 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of an exception used while file with given path does not exist * Test case of an exception used while file with given path does not exist
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class NotExistingFileExceptionTest extends BaseTestCase class NotExistingFileExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(NotExistingFileException::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(NotExistingFileException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
/** /**
@@ -34,7 +34,7 @@ class NotExistingFileExceptionTest extends BaseTestCase
*/ */
public function testConstructorMessage($notExistingFilePath, $expectedMessage) public function testConstructorMessage($notExistingFilePath, $expectedMessage)
{ {
$exception = new NotExistingFileException($notExistingFilePath); $exception = NotExistingFileException::create($notExistingFilePath);
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }

View File

@@ -16,14 +16,14 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of an exception used while method cannot be called, because is disabled * Test case of an exception used while method cannot be called, because is disabled
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class DisabledMethodExceptionTest extends BaseTestCase class DisabledMethodExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(DisabledMethodException::class, OopVisibilityType::IS_PUBLIC, 2, 1); static::assertConstructorVisibilityAndArguments(DisabledMethodException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
/** /**
@@ -36,7 +36,7 @@ class DisabledMethodExceptionTest extends BaseTestCase
*/ */
public function testConstructorMessage($disabledMethod, $alternativeMethod, $expectedMessage) public function testConstructorMessage($disabledMethod, $alternativeMethod, $expectedMessage)
{ {
$exception = new DisabledMethodException($disabledMethod, $alternativeMethod); $exception = DisabledMethodException::create($disabledMethod, $alternativeMethod);
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }

View File

@@ -16,14 +16,14 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of an exception used while name of class or trait cannot be resolved * Test case of an exception used while name of class or trait cannot be resolved
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class CannotResolveClassNameExceptionTest extends BaseTestCase class CannotResolveClassNameExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(CannotResolveClassNameException::class, OopVisibilityType::IS_PUBLIC, 2, 1); static::assertConstructorVisibilityAndArguments(CannotResolveClassNameException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
/** /**
@@ -37,7 +37,7 @@ class CannotResolveClassNameExceptionTest extends BaseTestCase
*/ */
public function testConstructorMessage($source, $forClass, $expectedMessage) public function testConstructorMessage($source, $forClass, $expectedMessage)
{ {
$exception = new CannotResolveClassNameException($source, $forClass); $exception = CannotResolveClassNameException::create($source, $forClass);
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }

View File

@@ -16,14 +16,14 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of an exception used while given class has no child classes * Test case of an exception used while given class has no child classes
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class MissingChildClassesExceptionTest extends BaseTestCase class MissingChildClassesExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(MissingChildClassesException::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(MissingChildClassesException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
/** /**
@@ -35,7 +35,7 @@ class MissingChildClassesExceptionTest extends BaseTestCase
*/ */
public function testConstructorMessage($parentClass, $expectedMessage) public function testConstructorMessage($parentClass, $expectedMessage)
{ {
$exception = new MissingChildClassesException($parentClass); $exception = MissingChildClassesException::create($parentClass);
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }

View File

@@ -16,14 +16,14 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of an exception used while given class has more than one child class * Test case of an exception used while given class has more than one child class
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class TooManyChildClassesExceptionTest extends BaseTestCase class TooManyChildClassesExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(TooManyChildClassesException::class, OopVisibilityType::IS_PUBLIC, 2, 2); static::assertConstructorVisibilityAndArguments(TooManyChildClassesException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
/** /**
@@ -36,7 +36,7 @@ class TooManyChildClassesExceptionTest extends BaseTestCase
*/ */
public function testConstructorMessage($parentClass, array $childClasses, $expectedMessage) public function testConstructorMessage($parentClass, array $childClasses, $expectedMessage)
{ {
$exception = new TooManyChildClassesException($parentClass, $childClasses); $exception = TooManyChildClassesException::create($parentClass, $childClasses);
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }

View File

@@ -16,14 +16,14 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of an exception used while length of given hexadecimal value of color is incorrect * Test case of an exception used while length of given hexadecimal value of color is incorrect
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class IncorrectColorHexLengthExceptionTest extends BaseTestCase class IncorrectColorHexLengthExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(IncorrectColorHexLengthException::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(IncorrectColorHexLengthException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
/** /**
@@ -34,7 +34,7 @@ class IncorrectColorHexLengthExceptionTest extends BaseTestCase
*/ */
public function testConstructorMessage($color, $expectedMessage) public function testConstructorMessage($color, $expectedMessage)
{ {
$exception = new IncorrectColorHexLengthException($color); $exception = IncorrectColorHexLengthException::create($color);
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }

View File

@@ -16,14 +16,14 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of an exception used while given hexadecimal value of color is invalid * Test case of an exception used while given hexadecimal value of color is invalid
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class InvalidColorHexValueExceptionTest extends BaseTestCase class InvalidColorHexValueExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(InvalidColorHexValueException::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(InvalidColorHexValueException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
/** /**
@@ -34,7 +34,7 @@ class InvalidColorHexValueExceptionTest extends BaseTestCase
*/ */
public function testConstructorMessage($color, $expectedMessage) public function testConstructorMessage($color, $expectedMessage)
{ {
$exception = new InvalidColorHexValueException($color); $exception = InvalidColorHexValueException::create($color);
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }

View File

@@ -0,0 +1,65 @@
<?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\Exception\Regex;
use Generator;
use Meritoo\Common\Exception\Regex\InvalidHtmlAttributesException;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType;
/**
* Test case of an exception used while html attributes are invalid
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class InvalidHtmlAttributesExceptionTest extends BaseTestCase
{
public function testConstructorVisibilityAndArguments()
{
static::assertConstructorVisibilityAndArguments(InvalidHtmlAttributesException::class, OopVisibilityType::IS_PUBLIC, 3);
}
/**
* @param string $htmlAttributes Invalid html attributes
* @param string $expectedMessage Expected exception's message
*
* @dataProvider provideHtmlAttributes
*/
public function testConstructorMessage($htmlAttributes, $expectedMessage)
{
$exception = InvalidHtmlAttributesException::create($htmlAttributes);
static::assertEquals($expectedMessage, $exception->getMessage());
}
/**
* Provides html attributes
*
* @return Generator
*/
public function provideHtmlAttributes()
{
$template = 'HTML attributes \'%s\' are invalid. Is there everything ok?';
yield[
'abc = def',
sprintf($template, 'abc = def'),
];
yield[
'abc = def ghi = jkl',
sprintf($template, 'abc = def ghi = jkl'),
];
yield[
'abc=def ghi=jkl',
sprintf($template, 'abc=def ghi=jkl'),
];
}
}

View File

@@ -16,14 +16,14 @@ use Meritoo\Common\Type\OopVisibilityType;
/** /**
* Test case of an exception used while url is invalid * Test case of an exception used while url is invalid
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class InvalidUrlExceptionTest extends BaseTestCase class InvalidUrlExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(InvalidUrlException::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(InvalidUrlException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
/** /**
@@ -34,7 +34,7 @@ class InvalidUrlExceptionTest extends BaseTestCase
*/ */
public function testConstructorMessage($url, $expectedMessage) public function testConstructorMessage($url, $expectedMessage)
{ {
$exception = new InvalidUrlException($url); $exception = InvalidUrlException::create($url);
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }

View File

@@ -17,14 +17,14 @@ use Meritoo\Common\Type\OopVisibilityType;
* Test case of an exception used while the visibility of a property, a method or (as of PHP 7.1.0) a constant is * Test case of an exception used while the visibility of a property, a method or (as of PHP 7.1.0) a constant is
* unknown * unknown
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class UnknownOopVisibilityTypeExceptionTest extends BaseTestCase class UnknownOopVisibilityTypeExceptionTest extends BaseTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
static::assertConstructorVisibilityAndArguments(UnknownOopVisibilityTypeException::class, OopVisibilityType::IS_PUBLIC, 1, 1); static::assertConstructorVisibilityAndArguments(UnknownOopVisibilityTypeException::class, OopVisibilityType::IS_PUBLIC, 3);
} }
/** /**
@@ -35,7 +35,7 @@ class UnknownOopVisibilityTypeExceptionTest extends BaseTestCase
*/ */
public function testConstructorMessage($unknownType, $expectedMessage) public function testConstructorMessage($unknownType, $expectedMessage)
{ {
$exception = new UnknownOopVisibilityTypeException($unknownType); $exception = UnknownOopVisibilityTypeException::createException($unknownType);
static::assertEquals($expectedMessage, $exception->getMessage()); static::assertEquals($expectedMessage, $exception->getMessage());
} }

View File

@@ -17,8 +17,8 @@ use Meritoo\Common\Utilities\GeneratorUtility;
/** /**
* Test case of the base test case with common methods and data providers * Test case of the base test case with common methods and data providers
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class BaseTestCaseTest extends BaseTestCase class BaseTestCaseTest extends BaseTestCase
{ {
@@ -132,7 +132,7 @@ class BaseTestCaseTest extends BaseTestCase
$directoryPath .= '/'; $directoryPath .= '/';
} }
$expectedContains = sprintf('/.data/tests/%s%s', $directoryPath, $fileName); $expectedContains = sprintf('/data/tests/%s%s', $directoryPath, $fileName);
static::assertContains($expectedContains, $path); static::assertContains($expectedContains, $path);
} }
@@ -168,8 +168,8 @@ class BaseTestCaseTest extends BaseTestCase
/** /**
* Simple test case * Simple test case
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class SimpleTestCase extends BaseTestCase class SimpleTestCase extends BaseTestCase
{ {

View File

@@ -15,8 +15,8 @@ use Meritoo\Common\Type\Base\BaseType;
/** /**
* Test case of the base / abstract type of something * Test case of the base / abstract type of something
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class BaseTypeTest extends BaseTestCase class BaseTypeTest extends BaseTestCase
{ {
@@ -184,8 +184,8 @@ class BaseTypeTest extends BaseTestCase
/** /**
* Empty type of something used for testing * Empty type of something used for testing
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class TestEmptyType extends BaseType class TestEmptyType extends BaseType
{ {
@@ -194,8 +194,8 @@ class TestEmptyType extends BaseType
/** /**
* Type of something used for testing * Type of something used for testing
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class TestType extends BaseType class TestType extends BaseType
{ {

View File

@@ -14,8 +14,8 @@ use Meritoo\Common\Type\DatePartType;
/** /**
* Test case of the type of date part, e.g. "year" * Test case of the type of date part, e.g. "year"
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class DatePartTypeTest extends BaseTypeTestCase class DatePartTypeTest extends BaseTypeTestCase
{ {

View File

@@ -6,21 +6,21 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Meritoo\Common\Test\Utilities; namespace Meritoo\Common\Test\Type;
use DateTime; use DateTime;
use Generator; use Generator;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTypeTestCase;
use Meritoo\Common\Type\DatePeriod;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\Common\Utilities\DatePeriod;
/** /**
* Test case of date's period * Test case of date's period
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class DatePeriodTest extends BaseTestCase class DatePeriodTest extends BaseTypeTestCase
{ {
public function testConstructorVisibilityAndArguments() public function testConstructorVisibilityAndArguments()
{ {
@@ -58,33 +58,6 @@ class DatePeriodTest extends BaseTestCase
self::assertEquals($endDate, $period->getEndDate()); self::assertEquals($endDate, $period->getEndDate());
} }
/**
* @param mixed $period Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testIsCorrectPeriodEmptyPeriod($period)
{
self::assertFalse(DatePeriod::isCorrectPeriod($period));
}
/**
* @param int $period Incorrect period to verify
* @dataProvider provideIncorrectPeriod
*/
public function testIsCorrectPeriodIncorrectPeriod($period)
{
self::assertFalse(DatePeriod::isCorrectPeriod($period));
}
/**
* @param int $period The period to verify
* @dataProvider providePeriod
*/
public function testIsCorrectPeriod($period)
{
self::assertTrue(DatePeriod::isCorrectPeriod($period));
}
/** /**
* @param DatePeriod $period The date period to verify * @param DatePeriod $period The date period to verify
* @param string $format Format used to format the date * @param string $format Format used to format the date
@@ -142,36 +115,6 @@ class DatePeriodTest extends BaseTestCase
]; ];
} }
/**
* Provides incorrect period
*
* @return Generator
*/
public function provideIncorrectPeriod()
{
yield[-1];
yield[0];
yield[10];
}
/**
* Provides period to verify
*
* @return Generator
*/
public function providePeriod()
{
yield[DatePeriod::LAST_WEEK];
yield[DatePeriod::THIS_WEEK];
yield[DatePeriod::NEXT_WEEK];
yield[DatePeriod::LAST_MONTH];
yield[DatePeriod::THIS_MONTH];
yield[DatePeriod::NEXT_MONTH];
yield[DatePeriod::LAST_YEAR];
yield[DatePeriod::THIS_YEAR];
yield[DatePeriod::NEXT_YEAR];
}
/** /**
* Provides period and incorrect format of date to verify * Provides period and incorrect format of date to verify
* *
@@ -270,4 +213,68 @@ class DatePeriodTest extends BaseTestCase
'2002-02-02 00:00', '2002-02-02 00:00',
]; ];
} }
/**
* Returns all expected types of the tested type
*
* @return array
*/
protected function getAllExpectedTypes()
{
return [
'LAST_MONTH' => DatePeriod::LAST_MONTH,
'LAST_WEEK' => DatePeriod::LAST_WEEK,
'LAST_YEAR' => DatePeriod::LAST_YEAR,
'NEXT_MONTH' => DatePeriod::NEXT_MONTH,
'NEXT_WEEK' => DatePeriod::NEXT_WEEK,
'NEXT_YEAR' => DatePeriod::NEXT_YEAR,
'THIS_MONTH' => DatePeriod::THIS_MONTH,
'THIS_WEEK' => DatePeriod::THIS_WEEK,
'THIS_YEAR' => DatePeriod::THIS_YEAR,
];
}
/**
* {@inheritdoc}
*/
protected function getTestedTypeInstance()
{
return new DatePeriod();
}
/**
* {@inheritdoc}
*/
public function provideTypeToVerify()
{
yield[
'',
false,
];
yield[
-1,
false,
];
yield[
true,
false,
];
yield[
DatePeriod::LAST_MONTH,
true,
];
yield[
DatePeriod::NEXT_WEEK,
true,
];
yield[
DatePeriod::THIS_YEAR,
true,
];
}
} }

View File

@@ -14,8 +14,8 @@ use Meritoo\Common\Utilities\Arrays;
/** /**
* Test case of the useful arrays methods * Test case of the useful arrays methods
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class ArraysTest extends BaseTestCase class ArraysTest extends BaseTestCase
{ {
@@ -517,7 +517,12 @@ letsTest[2] = value_2;';
self::assertTrue(Arrays::areKeysInArray($keys17, $this->complexArray, false)); 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 * Using default separator and other default arguments
@@ -536,7 +541,10 @@ letsTest[2] = value_2;';
]; ];
self::assertEquals($expected, Arrays::getLastElementsPaths($this->complexArray)); self::assertEquals($expected, Arrays::getLastElementsPaths($this->complexArray));
}
public function testGetLastElementsPathsUsingCustomSeparator()
{
/* /*
* Using custom separator * Using custom separator
*/ */
@@ -555,204 +563,20 @@ letsTest[2] = value_2;';
]; ];
self::assertEquals($expected, Arrays::getLastElementsPaths($this->complexArray, $separator)); self::assertEquals($expected, Arrays::getLastElementsPaths($this->complexArray, $separator));
}
/* /**
* Special exception: do not use, stop recursive on the "diam" key * @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
*/ */
$expected = [ public function testGetLastElementsPathsUsingStopIfMatchedBy($stopIfMatchedBy, $separator, array $expected)
'lorem.ipsum.dolor' => 'sit', {
'consectetur' => 'adipiscing', self::assertEquals($expected, Arrays::getLastElementsPaths($this->superComplexArray, $separator, '', $stopIfMatchedBy));
'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));
} }
public function testAreAllKeysMatchedByPattern() 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} * {@inheritdoc}
*/ */
@@ -1877,10 +1924,12 @@ letsTest[2] = value_2;';
{ {
parent::tearDown(); parent::tearDown();
unset($this->simpleArray); unset(
unset($this->simpleArrayWithKeys); $this->simpleArray,
unset($this->twoDimensionsArray); $this->simpleArrayWithKeys,
unset($this->complexArray); $this->twoDimensionsArray,
unset($this->superComplexArray); $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

@@ -8,14 +8,16 @@
namespace Meritoo\Common\Test\Utilities; namespace Meritoo\Common\Test\Utilities;
use Generator;
use Meritoo\Common\Exception\Bundle\IncorrectBundleNameException;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Utilities\Bundle; use Meritoo\Common\Utilities\Bundle;
/** /**
* Test case of the useful methods for bundle * Test case of the useful methods for bundle
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class BundleTest extends BaseTestCase class BundleTest extends BaseTestCase
{ {
@@ -24,22 +26,227 @@ class BundleTest extends BaseTestCase
static::assertHasNoConstructor(Bundle::class); static::assertHasNoConstructor(Bundle::class);
} }
public function testGetBundleViewPathEmptyPathAndBundle() /**
* @param string $viewPath Path of the view / template, e.g. "MyDirectory/my-template"
* @param string $bundleName Full name of the bundle, e.g. "MyExtraBundle"
*
* @throws IncorrectBundleNameException
* @dataProvider provideEmptyViewPathAndBundle
*/
public function testGetBundleViewPathUsingEmptyPathAndBundle($viewPath, $bundleName)
{ {
self::assertNull(Bundle::getBundleViewPath('', '')); self::assertNull(Bundle::getBundleViewPath($viewPath, $bundleName));
self::assertNull(Bundle::getBundleViewPath('test', ''));
self::assertNull(Bundle::getBundleViewPath('', 'test'));
} }
public function testGetBundleViewPathWithDefaultExtension() /**
* @param string $viewPath Path of the view / template, e.g. "MyDirectory/my-template"
* @param string $bundleName Full name of the bundle, e.g. "MyExtraBundle"
*
* @dataProvider provideViewPathAndIncorrectBundleName
*/
public function testGetBundleViewPathUsingIncorrectBundleName($viewPath, $bundleName)
{ {
self::assertEquals('Lorem:Ipsum.html.twig', Bundle::getBundleViewPath('Ipsum', 'Lorem')); $template = 'Name of bundle \'%s\' is incorrect. It should start with big letter and end with "Bundle". Is'
self::assertEquals('LobortisTincidunt:FusceElementum.html.twig', Bundle::getBundleViewPath('FusceElementum', 'LobortisTincidunt')); . ' there everything ok?';
$message = sprintf($template, $bundleName);
$this->setExpectedException(IncorrectBundleNameException::class, $message);
Bundle::getBundleViewPath($viewPath, $bundleName);
} }
public function testGetBundleViewPathWithCustomExtension() /**
* @param string $viewPath Path of the view / template, e.g. "MyDirectory/my-template"
* @param string $bundleName Full name of the bundle, e.g. "MyExtraBundle"
* @param string $expected Expected path to view / template
*
* @throws IncorrectBundleNameException
* @dataProvider provideViewPathAndBundle
*/
public function testGetBundleViewPathUsingDefaultExtension($viewPath, $bundleName, $expected)
{ {
self::assertNull(Bundle::getBundleViewPath('Ipsum', 'Lorem', '')); self::assertEquals($expected, Bundle::getBundleViewPath($viewPath, $bundleName));
self::assertEquals('Lorem:Ipsum.js.twig', Bundle::getBundleViewPath('Ipsum', 'Lorem', 'js.twig')); }
/**
* @param string $viewPath Path of the view / template, e.g. "MyDirectory/my-template"
* @param string $bundleName Full name of the bundle, e.g. "MyExtraBundle"
* @param string $extension (optional) Extension of the view / template
* @param string $expected Expected path to view / template
*
* @throws IncorrectBundleNameException
* @dataProvider provideViewPathAndBundleAndExtension
*/
public function testGetBundleViewPathUsingCustomExtension($viewPath, $bundleName, $extension, $expected)
{
self::assertEquals($expected, Bundle::getBundleViewPath($viewPath, $bundleName, $extension));
}
/**
* @param mixed $emptyValue Empty value, e.g. ""
*
* @throws IncorrectBundleNameException
* @dataProvider provideEmptyValue
*/
public function testGetShortBundleNameUsingEmptyValue($emptyValue)
{
$this->setExpectedException(IncorrectBundleNameException::class);
Bundle::getShortBundleName($emptyValue);
}
/**
* @param string $bundleName Full name of the bundle, e.g. "MyExtraBundle"
*
* @throws IncorrectBundleNameException
* @dataProvider provideIncorrectBundleName
*/
public function testGetShortBundleNameUsingIncorrectBundleName($bundleName)
{
$this->setExpectedException(IncorrectBundleNameException::class);
Bundle::getShortBundleName($bundleName);
}
/**
* @param string $fullBundleName Full name of the bundle, e.g. "MyExtraBundle"
* @param string $shortBundleName Short name of bundle (without "Bundle")
*
* @throws IncorrectBundleNameException
* @dataProvider provideFullAndShortBundleName
*/
public function testGetShortBundleName($fullBundleName, $shortBundleName)
{
self::assertEquals($shortBundleName, Bundle::getShortBundleName($fullBundleName));
}
/**
* Provides empty path of the view / template and/or name of bundle
*
* @return Generator
*/
public function provideEmptyViewPathAndBundle()
{
yield[
'',
'',
];
yield[
'test',
'',
];
yield[
'',
'test',
];
}
/**
* Provides path of the view / template and incorrect name of bundle
*
* @return Generator
*/
public function provideViewPathAndIncorrectBundleName()
{
yield[
'User:Active',
'myExtra',
];
yield[
'User:Active',
'MyExtra',
];
yield[
'User:Active',
'MySuperExtraGorgeous',
];
}
/**
* Provides path of the view / template and name of bundle
*
* @return Generator
*/
public function provideViewPathAndBundle()
{
yield[
'User',
'MyExtraBundle',
'@MyExtra/User.html.twig',
];
yield[
'User:Active',
'MyExtraBundle',
'@MyExtra/User/Active.html.twig',
];
yield[
'User:Active',
'MySuperExtraGorgeousBundle',
'@MySuperExtraGorgeous/User/Active.html.twig',
];
}
/**
* Provides path of the view / template, name of bundle and extension of the view / template
*
* @return Generator
*/
public function provideViewPathAndBundleAndExtension()
{
yield[
'User:Active',
'MyExtraBundle',
'',
null,
];
yield[
'User:Active',
'MyExtraBundle',
'js.twig',
'@MyExtra/User/Active.js.twig',
];
}
/**
* Provides incorrect name of bundle
*
* @return Generator
*/
public function provideIncorrectBundleName()
{
yield[
'myExtra',
];
yield[
'MyExtra',
];
yield[
'MySuperExtraGorgeous',
];
}
/**
* Provides full and short name of bundle
*
* @return Generator
*/
public function provideFullAndShortBundleName()
{
yield[
'MyExtraBundle',
'MyExtra',
];
yield[
'MySuperExtraGorgeousBundle',
'MySuperExtraGorgeous',
];
} }
} }

View File

@@ -15,8 +15,8 @@ use Meritoo\Common\Utilities\Composer;
/** /**
* Test case of the useful Composer-related methods * Test case of the useful Composer-related methods
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class ComposerTest extends BaseTestCase class ComposerTest extends BaseTestCase
{ {

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

@@ -11,15 +11,16 @@ namespace Meritoo\Common\Test\Utilities;
use DateInterval; use DateInterval;
use DateTime; use DateTime;
use Generator; use Generator;
use Meritoo\Common\Exception\Date\UnknownDatePartTypeException; use Meritoo\Common\Exception\Type\UnknownDatePartTypeException;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\DatePeriod;
use Meritoo\Common\Utilities\Date; use Meritoo\Common\Utilities\Date;
/** /**
* Test case of the Date methods (only static functions) * Test case of the Date methods (only static functions)
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class DateTest extends BaseTestCase class DateTest extends BaseTestCase
{ {
@@ -506,6 +507,35 @@ class DateTest extends BaseTestCase
self::assertTrue($randomDate >= $intervalMinDate && $randomDate <= $intervalMaxDate); self::assertTrue($randomDate >= $intervalMinDate && $randomDate <= $intervalMaxDate);
} }
/**
* @param mixed $period Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetDatesForPeriodUsingEmptyPeriod($period)
{
self::assertNull(Date::getDatesForPeriod($period));
}
/**
* @param int $period Incorrect period to verify
* @dataProvider provideIncorrectPeriod
*/
public function testGetDatesForPeriodUsingIncorrectPeriod($period)
{
self::assertNull(Date::getDatesForPeriod($period));
}
/**
* @param int $period The period, type of period. One of DatePeriod class constants, e.g. DatePeriod::LAST_WEEK.
* @param DatePeriod $expected Expected start and end date for given period
*
* @dataProvider provideCorrectPeriod
*/
public function testGetDatesForPeriod($period, DatePeriod $expected)
{
self::assertEquals($expected, Date::getDatesForPeriod($period));
}
/** /**
* Provides incorrect invalidCount of DateTime * Provides incorrect invalidCount of DateTime
* *
@@ -758,4 +788,112 @@ class DateTest extends BaseTestCase
50, 50,
]; ];
} }
/**
* Provides incorrect period
*
* @return Generator
*/
public function provideIncorrectPeriod()
{
yield[-1];
yield[0];
yield[10];
}
/**
* Provides correct period
*
* @return Generator
*/
public function provideCorrectPeriod()
{
yield[
DatePeriod::LAST_WEEK,
new DatePeriod(
(new DateTime('this week'))->sub(new DateInterval('P7D'))->setTime(0, 0, 0),
(new DateTime('this week'))->sub(new DateInterval('P1D'))->setTime(23, 59, 59)
),
];
yield[
DatePeriod::THIS_WEEK,
new DatePeriod(
(new DateTime('this week'))->setTime(0, 0, 0),
(new DateTime('this week'))->add(new DateInterval('P6D'))->setTime(23, 59, 59)
),
];
yield[
DatePeriod::NEXT_WEEK,
new DatePeriod(
(new DateTime('this week'))->add(new DateInterval('P7D'))->setTime(0, 0, 0),
(new DateTime('this week'))->add(new DateInterval('P7D'))->add(new DateInterval('P6D'))->setTime(23, 59, 59)
),
];
yield[
DatePeriod::LAST_MONTH,
new DatePeriod(
(new DateTime('first day of last month'))->setTime(0, 0, 0),
(new DateTime('last day of last month'))->setTime(23, 59, 59)
),
];
yield[
DatePeriod::THIS_MONTH,
new DatePeriod(
Date::getDatesForPeriod(DatePeriod::LAST_MONTH)
->getEndDate()
->add(new DateInterval('P1D'))
->setTime(0, 0, 0),
Date::getDatesForPeriod(DatePeriod::NEXT_MONTH)
->getStartDate()
->sub(new DateInterval('P1D'))
->setTime(23, 59, 59)
),
];
yield[
DatePeriod::NEXT_MONTH,
new DatePeriod(
(new DateTime('first day of next month'))->setTime(0, 0, 0),
(new DateTime('last day of next month'))->setTime(23, 59, 59)
),
];
$lastYearStart = (new DateTime())->modify('-1 year');
$lastYearEnd = (new DateTime())->modify('-1 year');
$year = $lastYearStart->format('Y');
yield[
DatePeriod::LAST_YEAR,
new DatePeriod(
$lastYearStart->setDate($year, 1, 1)->setTime(0, 0, 0),
$lastYearEnd->setDate($year, 12, 31)->setTime(23, 59, 59)
),
];
$year = (new DateTime())->format('Y');
yield[
DatePeriod::THIS_YEAR,
new DatePeriod(
(new DateTime())->setDate($year, 1, 1)->setTime(0, 0, 0),
(new DateTime())->setDate($year, 12, 31)->setTime(23, 59, 59)
),
];
$nextYearStart = (new DateTime())->modify('1 year');
$nextYearEnd = (new DateTime())->modify('1 year');
$year = $nextYearStart->format('Y');
yield[
DatePeriod::NEXT_YEAR,
new DatePeriod(
$nextYearStart->setDate($year, 1, 1)->setTime(0, 0, 0),
$nextYearEnd->setDate($year, 12, 31)->setTime(23, 59, 59)
),
];
}
} }

View File

@@ -14,8 +14,8 @@ use Meritoo\Common\Utilities\GeneratorUtility;
/** /**
* Test case of the useful methods for the Generator class * Test case of the useful methods for the Generator class
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class GeneratorUtilityTest extends BaseTestCase class GeneratorUtilityTest extends BaseTestCase
{ {

View File

@@ -11,15 +11,19 @@ namespace Meritoo\Common\Test\Utilities;
use Generator; use Generator;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Utilities\Locale; use Meritoo\Common\Utilities\Locale;
use ReflectionException;
/** /**
* Test case of the useful locale methods * Test case of the useful locale methods
* *
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo.pl * @copyright Meritoo <http://www.meritoo.pl>
*/ */
class LocaleTest extends BaseTestCase class LocaleTest extends BaseTestCase
{ {
/**
* @throws ReflectionException
*/
public function testConstructor() public function testConstructor()
{ {
static::assertHasNoConstructor(Locale::class); static::assertHasNoConstructor(Locale::class);
@@ -40,7 +44,7 @@ class LocaleTest extends BaseTestCase
* @param string $encoding Encoding of the final locale * @param string $encoding Encoding of the final locale
* @param string $expected Expected long form of the locale * @param string $expected Expected long form of the locale
* *
* @dataProvider provideLanguageAndCountryCode * @dataProvider provideLanguageEncodingAndCountryCode
*/ */
public function testGetLongForm($languageCode, $countryCode, $encoding, $expected) public function testGetLongForm($languageCode, $countryCode, $encoding, $expected)
{ {
@@ -56,24 +60,46 @@ class LocaleTest extends BaseTestCase
self::assertFalse(Locale::setLocale($emptyValue, $emptyValue)); self::assertFalse(Locale::setLocale($emptyValue, $emptyValue));
} }
public function testSetLocaleIncorrectCategory()
{
self::assertFalse(Locale::setLocale(-1, 'en'));
}
/** /**
* @param int $category Named constant specifying the category of the functions affected by the locale * @param int $category Named constant specifying the category of the functions affected by the locale
* setting. It's the same constant as required by setlocale() function. * setting. It's the same constant as required by setlocale() function.
* @param string $languageCode Language code, in ISO 639-1 format. Short form of the locale, e.g. "fr". * @param string $languageCode Language code, in ISO 639-1 format. Short form of the locale, e.g. "fr".
* @param string $countryCode Country code, in ISO 3166-1 alpha-2 format, e.g. "FR"
* @param string $expectedLocale Expected locale
* *
* @dataProvider provideCategoryAndLanguageCode * @dataProvider provideCategoryLanguageCodeAndExpectedLocale
*/ */
public function testSetLocale($category, $languageCode) public function testSetLocale($category, $languageCode, $countryCode, $expectedLocale)
{ {
self::assertTrue(Locale::setLocale($category, $languageCode)); self::assertEquals($expectedLocale, Locale::setLocale($category, $languageCode, $countryCode));
} }
/** /**
* Provides language and country code * @param int $category Named constant specifying the category of the functions affected by the locale setting.
* It's the same constant as required by setlocale() function.
* @param string $languageCode Language code, in ISO 639-1 format. Short form of the locale, e.g. "fr".
* @param string $countryCode Country code, in ISO 3166-1 alpha-2 format, e.g. "FR"
* @param string $expectedLocale Expected locale
*
* @dataProvider provideCategoryLanguageCodeAndExpectedLocale
*/
public function testGetLocale($category, $languageCode, $countryCode, $expectedLocale)
{
Locale::setLocale($category, $languageCode, $countryCode);
self::assertEquals($expectedLocale, Locale::getLocale($category));
}
/**
* Provides language, encoding and country code
* *
* @return Generator * @return Generator
*/ */
public function provideLanguageAndCountryCode() public function provideLanguageEncodingAndCountryCode()
{ {
yield[ yield[
'fr', 'fr',
@@ -102,33 +128,97 @@ class LocaleTest extends BaseTestCase
'UTF-8', 'UTF-8',
'fr_FR.UTF-8', 'fr_FR.UTF-8',
]; ];
yield[
'en',
'US',
'',
'en_US',
];
yield[
'en',
'US',
'UTF-8',
'en_US.UTF-8',
];
yield[
'en',
'US',
'ISO-8859-1',
'en_US.ISO-8859-1',
];
} }
/** /**
* Provides category and language * Provides category
* *
* @return Generator * @return Generator
*/ */
public function provideCategoryAndLanguageCode() public function provideCategoryLanguageCodeAndExpectedLocale()
{ {
yield[ yield[
LC_ALL, LC_ALL,
'fr', 'fr',
'',
'fr_FR.UTF-8',
]; ];
yield[ yield[
LC_COLLATE, LC_COLLATE,
'fr', 'fr',
'FR',
'fr_FR.UTF-8',
]; ];
yield[ yield[
LC_CTYPE, LC_CTYPE,
'en', 'en',
'US',
'en_US.UTF-8',
]; ];
yield[ yield[
LC_NUMERIC, LC_NUMERIC,
'en', 'en',
'GB',
'en_GB.UTF-8',
];
yield[
LC_MONETARY,
'es',
'',
'es_ES.UTF-8',
];
yield[
LC_MONETARY,
'es',
'ES',
'es_ES.UTF-8',
];
yield[
LC_TIME,
'it',
'',
'it_IT.UTF-8',
];
yield[
LC_TIME,
'it',
'IT',
'it_IT.UTF-8',
];
yield[
LC_TIME,
'it',
'it',
'it_IT.UTF-8',
]; ];
} }
} }

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