mirror of
https://github.com/wiosna-dev/common-library.git
synced 2026-03-12 01:31:45 +01:00
Compare commits
310 Commits
0.0.15
...
feature/UW
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e6055a48e | ||
|
|
d392b20570 | ||
|
|
cddafc3604 | ||
|
|
08a2d0878f | ||
|
|
d4cb732096 | ||
|
|
5ebf624b7b | ||
|
|
bbc5f6a43d | ||
|
|
41ef088ffe | ||
|
|
a3adae50b8 | ||
|
|
a3af138f0c | ||
|
|
31a7ca6d1a | ||
|
|
ba24e2de23 | ||
|
|
ae72d582e6 | ||
|
|
067be1ab1d | ||
|
|
151ce39226 | ||
|
|
feb8fc293b | ||
|
|
fcaae95810 | ||
|
|
a459bfe1ce | ||
|
|
1eb86cf102 | ||
|
|
0d3265d7b6 | ||
|
|
598f1731be | ||
|
|
95b0cf6cab | ||
|
|
118fa64772 | ||
|
|
d5542b60e3 | ||
|
|
a4d24a788b | ||
|
|
4f8c355d1b | ||
|
|
e47eaae8b2 | ||
|
|
1116034fe6 | ||
|
|
64f474fcf1 | ||
|
|
47d07150d3 | ||
|
|
c6efc30872 | ||
|
|
ab0c0e6e89 | ||
|
|
351224f1f9 | ||
|
|
416f0cd8af | ||
|
|
e38dda200a | ||
|
|
8fec0db05f | ||
|
|
5cd58aec25 | ||
|
|
ddb3f0a544 | ||
|
|
872259e63d | ||
|
|
d8e3d5e7cb | ||
|
|
2fdb18312d | ||
|
|
a7c39b26ba | ||
|
|
b91606ada9 | ||
|
|
1f45d38ab8 | ||
|
|
b0e404aeb9 | ||
|
|
9903c82496 | ||
|
|
678cdfdf01 | ||
|
|
ded1a04900 | ||
|
|
16cdd1cd60 | ||
|
|
f7a8da0550 | ||
|
|
891411e231 | ||
|
|
10992570ad | ||
|
|
e704dacabd | ||
|
|
0afcf9843e | ||
|
|
cc06cdde6f | ||
|
|
030e33064d | ||
|
|
bc20645cba | ||
|
|
ec1e95a086 | ||
|
|
21bfadf5d6 | ||
|
|
ce7ec254b1 | ||
|
|
fe6ec278e3 | ||
|
|
462625caff | ||
|
|
a86a10c51e | ||
|
|
a5148de31c | ||
|
|
dabb1e90c3 | ||
|
|
79708f4e61 | ||
|
|
b251bcec0e | ||
|
|
a2c875556e | ||
|
|
c5a68b54af | ||
|
|
4ddc299e5b | ||
|
|
c0998ac5b9 | ||
|
|
a1c3ba8543 | ||
|
|
6efbf940a3 | ||
|
|
1ac1a221ec | ||
|
|
5678b5b22a | ||
|
|
3b81d0d932 | ||
|
|
c4e09f77a3 | ||
|
|
11e5ce3d56 | ||
|
|
a9b985385e | ||
|
|
15824d3f77 | ||
|
|
e002adc162 | ||
|
|
538aa1fa79 | ||
|
|
b482d814e4 | ||
|
|
2091adc8d0 | ||
|
|
e75854feee | ||
|
|
9a1f49d373 | ||
|
|
98d0fed61d | ||
|
|
a6b2704c66 | ||
|
|
dd5ac0f7e6 | ||
|
|
421d19ff10 | ||
|
|
8b5cbd6f2e | ||
|
|
0f2c6bb099 | ||
|
|
f5e8c8c740 | ||
|
|
c7c96daaaf | ||
|
|
4c6fb569bc | ||
|
|
b166b8b805 | ||
|
|
414ce0fd06 | ||
|
|
fa370be08a | ||
|
|
a56b325307 | ||
|
|
eb8fa110ad | ||
|
|
6f90f5a249 | ||
|
|
2bbd0a4ef3 | ||
|
|
e66cbd54e2 | ||
|
|
39b0172a85 | ||
|
|
e05bc2302d | ||
|
|
a13a629408 | ||
|
|
0f64705132 | ||
|
|
4f55f33385 | ||
|
|
134a5a0108 | ||
|
|
d1c1d48473 | ||
|
|
685addc7c4 | ||
|
|
602855d2a7 | ||
|
|
da9ae20a33 | ||
|
|
92e607a3f0 | ||
|
|
9f2a5294a8 | ||
|
|
87422af5c7 | ||
|
|
1db4a55e31 | ||
|
|
ca4bf05b38 | ||
|
|
cecaa65ef6 | ||
|
|
a90eeed583 | ||
|
|
312e721dc3 | ||
|
|
a93355f2c8 | ||
|
|
a4d6a1c785 | ||
|
|
ed1c9358aa | ||
|
|
faf1da6134 | ||
|
|
0b74f8da6f | ||
|
|
8a94241eb8 | ||
|
|
87249aa30b | ||
|
|
1b4577cc8a | ||
|
|
7ddfcf6946 | ||
|
|
10bf198df5 | ||
|
|
95a81ab322 | ||
|
|
8a27cd94ef | ||
|
|
ce37db5f33 | ||
|
|
b68dd78b06 | ||
|
|
c89b6da0db | ||
|
|
8b5a530bbc | ||
|
|
e623c87268 | ||
|
|
90bc438cae | ||
|
|
28a11d611c | ||
|
|
5022efb9a3 | ||
|
|
56b058ca1d | ||
|
|
eade6a25ad | ||
|
|
9f6af6b6a4 | ||
|
|
df36e050e7 | ||
|
|
a021870ebd | ||
|
|
d88ead92fe | ||
|
|
5ebde80646 | ||
|
|
fe40d9caee | ||
|
|
ba6c185ed9 | ||
|
|
c175fcd126 | ||
|
|
2247000a8a | ||
|
|
924e492e11 | ||
|
|
ddd558a7d4 | ||
|
|
ede9a182b4 | ||
|
|
fad0aa607a | ||
|
|
3a38c09ce2 | ||
|
|
07a04d86f0 | ||
|
|
0c7e27b884 | ||
|
|
421d336498 | ||
|
|
292c5e6d4f | ||
|
|
79c09a26a6 | ||
|
|
d46548d102 | ||
|
|
651c4f2259 | ||
|
|
8c3c85608a | ||
|
|
22c96f0a18 | ||
|
|
aa93cd8e25 | ||
|
|
4391baed3d | ||
|
|
b879dbd803 | ||
|
|
7233fdac52 | ||
|
|
ec5129ad6b | ||
|
|
39ede292d6 | ||
|
|
8e9dcb3206 | ||
|
|
06fbf63e09 | ||
|
|
4e600ec599 | ||
|
|
b4ccbbac11 | ||
|
|
c82f53219e | ||
|
|
c8fc0b14ff | ||
|
|
3c3d1b997e | ||
|
|
61209e3f67 | ||
|
|
822dbf6830 | ||
|
|
870bfe48a2 | ||
|
|
ff416fda69 | ||
|
|
61676a445e | ||
|
|
1f5106bcf0 | ||
|
|
971224b2e6 | ||
|
|
7e4b14a92f | ||
|
|
38c68b0952 | ||
|
|
ca9c3bd8f1 | ||
|
|
97c6112919 | ||
|
|
26b136d676 | ||
|
|
4db631223f | ||
|
|
5d6b559108 | ||
|
|
e31af27c01 | ||
|
|
575bb344cd | ||
|
|
35b70f53e7 | ||
|
|
51ff110101 | ||
|
|
2f9138d093 | ||
|
|
75707a3f76 | ||
|
|
8ecbefbba6 | ||
|
|
e850375c19 | ||
|
|
0bd1e1e158 | ||
|
|
535ae65e5e | ||
|
|
60d7b03cd7 | ||
|
|
c20fa5941f | ||
|
|
a448d592d2 | ||
|
|
e53273fb32 | ||
|
|
cc30ad8d9e | ||
|
|
9f08a2aaaf | ||
|
|
b49605a26c | ||
|
|
8441c82356 | ||
|
|
55dde2e898 | ||
|
|
a32e0c4cca | ||
|
|
834b24f348 | ||
|
|
9342f0e87e | ||
|
|
72fd87e165 | ||
|
|
64499b49d3 | ||
|
|
848adef015 | ||
|
|
1431fd9935 | ||
|
|
3bb7a182c2 | ||
|
|
5c9436e4e2 | ||
|
|
1a649d35e1 | ||
|
|
107480d01b | ||
|
|
f4c12661b4 | ||
|
|
fc7df571e2 | ||
|
|
0f37edfc9b | ||
|
|
ae3e82e233 | ||
|
|
c99a099c31 | ||
|
|
c443ef22d7 | ||
|
|
be8b4a3498 | ||
|
|
b1ddc6d561 | ||
|
|
ffe34eb9cf | ||
|
|
155c091a3e | ||
|
|
0a3955026b | ||
|
|
f9fa5f5915 | ||
|
|
43945a8721 | ||
|
|
e9da0cf351 | ||
|
|
4c534394d9 | ||
|
|
3726a26e47 | ||
|
|
fb24bc2ff1 | ||
|
|
57a78d1299 | ||
|
|
696cff023c | ||
|
|
9197682cd2 | ||
|
|
49638ff1c3 | ||
|
|
abf0ebf7ec | ||
|
|
2e60176d95 | ||
|
|
c351ce887a | ||
|
|
8a6262a8c3 | ||
|
|
3c83a8800e | ||
|
|
233473d915 | ||
|
|
7382bce842 | ||
|
|
c5b42017d2 | ||
|
|
bc54f734e2 | ||
|
|
0eb5343df0 | ||
|
|
52e74c8b48 | ||
|
|
96bdb6eb60 | ||
|
|
5be449a83d | ||
|
|
132a0a00e7 | ||
|
|
6fd18111b4 | ||
|
|
26c63ecb5c | ||
|
|
bedb6333b9 | ||
|
|
ec2b5742ec | ||
|
|
ec2f3c6ead | ||
|
|
834c12f280 | ||
|
|
122ff41dad | ||
|
|
180a8b8b5d | ||
|
|
499c603d54 | ||
|
|
1cbc87222f | ||
|
|
129b75ea93 | ||
|
|
aae7609c8c | ||
|
|
5578b051a7 | ||
|
|
f111174ed2 | ||
|
|
ddbff1b557 | ||
|
|
8d1df9ced8 | ||
|
|
b7d0b61094 | ||
|
|
ad64d2e02a | ||
|
|
470b8244ec | ||
|
|
af38c35a1b | ||
|
|
1e3e1d454e | ||
|
|
57b411b59f | ||
|
|
8a4860088f | ||
|
|
e9b8fb8852 | ||
|
|
780d4df17e | ||
|
|
d801e675fc | ||
|
|
6753076937 | ||
|
|
7f713e0c6e | ||
|
|
ebbed4825c | ||
|
|
7d23ff59d1 | ||
|
|
0e4c33241e | ||
|
|
66aefa2446 | ||
|
|
5aaf7cde72 | ||
|
|
8bb529b88d | ||
|
|
3588c00009 | ||
|
|
78480ac853 | ||
|
|
3bcda8e906 | ||
|
|
1641c50d1d | ||
|
|
afbbdfe437 | ||
|
|
8bcf006e02 | ||
|
|
edc51aeee1 | ||
|
|
6d4e422165 | ||
|
|
6f441bb9ea | ||
|
|
73030d703b | ||
|
|
36ddb326b9 | ||
|
|
452a4ec458 | ||
|
|
325fe6b141 | ||
|
|
a1c26b3812 | ||
|
|
67d93036cf | ||
|
|
9368616dfe | ||
|
|
5ab68d3667 | ||
|
|
4613a63f02 |
2
.coveralls.yml
Normal file
2
.coveralls.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
coverage_clover: build/reports/coveralls/clover.xml
|
||||
json_path: build/reports/coveralls/upload.json
|
||||
@@ -1,54 +0,0 @@
|
||||
FROM php:5.6-cli
|
||||
|
||||
#
|
||||
# Tools & libraries
|
||||
#
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
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:
|
||||
# - timezone
|
||||
#
|
||||
ARG TIMEZONE
|
||||
RUN echo "date.timezone = $TIMEZONE" >> /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/*
|
||||
@@ -1,7 +0,0 @@
|
||||
[xdebug]
|
||||
zend_extension='xdebug.so'
|
||||
|
||||
xdebug.remote_enable=1
|
||||
xdebug.remote_connect_back=1
|
||||
xdebug.idekey='PHPSTORM'
|
||||
xdebug.remote_port=9001
|
||||
16
.env
16
.env
@@ -1 +1,15 @@
|
||||
TIMEZONE=Europe/Warsaw
|
||||
# ------------------------------------------------------------------------------
|
||||
### Docker
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# All containers
|
||||
#
|
||||
DOCKER_CONTAINER_OWNER=meritoo
|
||||
DOCKER_CONTAINER_PROJECT=common-library
|
||||
|
||||
#
|
||||
# PHP configuration:
|
||||
# - timezone
|
||||
#
|
||||
PHP_DATE_TIMEZONE=Europe/London
|
||||
|
||||
259
.gitignore
vendored
259
.gitignore
vendored
@@ -1,86 +1,25 @@
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### Vendors
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/vendor/
|
||||
# ------------------------------------------------------------------------------
|
||||
### Linux template
|
||||
# ------------------------------------------------------------------------------
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### Composer
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/composer.lock
|
||||
/composer.phar
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### Phing
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/.phing/properties
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### PHPUnit
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/phpunit.xml
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### PHP Coding Standards Fixer generated files
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/.php_cs.cache
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### Build files
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/.build/
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### Generated databases
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/.data/tmp
|
||||
*.sql
|
||||
*.sqlite
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### Compiled source
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### Shell scripts
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/*.sh
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### JetBrains
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/.idea
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### NetBeans template
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
nbactions.xml
|
||||
.nb-gradle/
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### OSX template
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
# ------------------------------------------------------------------------------
|
||||
### macOS template
|
||||
# ------------------------------------------------------------------------------
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
@@ -98,6 +37,7 @@ Icon
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
@@ -107,30 +47,20 @@ Temporary Items
|
||||
.apdisk
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### Linux template
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
# ------------------------------------------------------------------------------
|
||||
### Windows template
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
# Windows image file caches
|
||||
# ------------------------------------------------------------------------------
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
@@ -138,8 +68,137 @@ $RECYCLE.BIN/
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
### JetBrains template
|
||||
# ------------------------------------------------------------------------------
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
### Build files
|
||||
# ------------------------------------------------------------------------------
|
||||
/build/
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
### Phing
|
||||
# ------------------------------------------------------------------------------
|
||||
/phing/properties
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
### Infection
|
||||
# ------------------------------------------------------------------------------
|
||||
/infection.json
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
### Temporary data & databases
|
||||
# ------------------------------------------------------------------------------
|
||||
/data/tmp
|
||||
*.sqlite
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
### Composer & vendors
|
||||
# ------------------------------------------------------------------------------
|
||||
/composer.lock
|
||||
/composer.phar
|
||||
/vendor/
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
### PHPUnit
|
||||
# ------------------------------------------------------------------------------
|
||||
/phpunit.xml
|
||||
/.phpunit.result.cache
|
||||
/tests/Resources/var
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
### PHP Coding Standards Fixer
|
||||
# ------------------------------------------------------------------------------
|
||||
/.php_cs
|
||||
/.php_cs.cache
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
### PHP_CodeSniffer
|
||||
# ------------------------------------------------------------------------------
|
||||
/.phpcs-cache
|
||||
/phpcs.xml
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.14.0">
|
||||
<!-- Properties -->
|
||||
<if>
|
||||
<available file=".phing/properties" property="custom.properties.available"/>
|
||||
<then>
|
||||
<property file=".phing/properties" />
|
||||
</then>
|
||||
<else>
|
||||
<property file=".phing/properties.dist" />
|
||||
</else>
|
||||
</if>
|
||||
|
||||
<!-- Default / main target -->
|
||||
<target name="build:main"
|
||||
depends="build:app"
|
||||
description="Builds the application" />
|
||||
|
||||
<!-- App target -->
|
||||
<target name="build:app"
|
||||
depends="app:composer, app:vendors, app:checkout"
|
||||
description="Prepares app to build." />
|
||||
|
||||
<!-- Check / update composer -->
|
||||
<target name="app:composer" description="Checks / updates composer">
|
||||
<echo msg="Checking / updating composer..." />
|
||||
|
||||
<if>
|
||||
<available file="composer.phar" />
|
||||
<then>
|
||||
<echo msg="[Skipped] Downloading of Composer skipped, because exist in the project..." />
|
||||
</then>
|
||||
<else>
|
||||
<if>
|
||||
<os family="windows" />
|
||||
<then>
|
||||
<fail message="Composer not found! Go to http://getcomposer.org/download and download the Composer." />
|
||||
</then>
|
||||
<else>
|
||||
<exec command="${composer.download_command}" checkreturn="true" />
|
||||
</else>
|
||||
</if>
|
||||
</else>
|
||||
</if>
|
||||
<composer command="selfupdate" />
|
||||
</target>
|
||||
|
||||
<!-- Project Install/update vendors -->
|
||||
<target name="app:vendors" description="Installs / updates vendors">
|
||||
<echo msg="Installing / updating vendors..." />
|
||||
|
||||
<if>
|
||||
<istrue value="${composer.self-update}"/>
|
||||
<then>
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="self-update"/>
|
||||
</then>
|
||||
</if>
|
||||
|
||||
<if>
|
||||
<istrue value="${composer.validate}"/>
|
||||
<then>
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="validate"/>
|
||||
</then>
|
||||
</if>
|
||||
|
||||
<if>
|
||||
<equals arg1="${env}" arg2="prod" />
|
||||
<then>
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="install">
|
||||
<arg value="--optimize-autoloader" />
|
||||
</composer>
|
||||
</then>
|
||||
<else>
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="install" />
|
||||
</else>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<!-- Checkout and finalization -->
|
||||
<target name="app:checkout">
|
||||
<tstamp>
|
||||
<format property="date_end" pattern="%Y-%m-%d %H:%M" />
|
||||
</tstamp>
|
||||
|
||||
<echo msg="------------------------------------" />
|
||||
<echo msg="Build finished at: ${date_end}" />
|
||||
<echo msg="------------------------------------" />
|
||||
</target>
|
||||
</project>
|
||||
@@ -1,125 +0,0 @@
|
||||
# --------------------------------------------------------------------------------
|
||||
# Information
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# Property files contain key/value pairs
|
||||
# key = value
|
||||
#
|
||||
# Property keys may contain alphanumeric chars and colons, but
|
||||
# not special chars. This way you can create pseudo-namespaces
|
||||
#
|
||||
# You can refer to values of other properties by enclosing their keys in "${}".
|
||||
# Example: dir.js = ${dir.web}/js
|
||||
#
|
||||
# Everything behind the equal sign is the value, you do
|
||||
# not have to enclose strings: text=This is some text, Your OS is ${php.os}
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Common, e.g. default environment
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# Default environment
|
||||
#
|
||||
env = dev
|
||||
|
||||
# Install assets using symlinks
|
||||
#
|
||||
assets.installWithSymlink = true
|
||||
|
||||
# Clear cache with the "warmup" option
|
||||
#
|
||||
cache.clearWithWarmup = true
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Composer
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
composer.download_command = php -r "eval('?>'.file_get_contents('https://getcomposer.org/installer'));"
|
||||
|
||||
# Path to composer executable or composer.phar file
|
||||
#
|
||||
composer.path = composer.phar
|
||||
#composer.path = /usr/local/bin/composer
|
||||
|
||||
# Path to php executable used by composer
|
||||
#
|
||||
composer.php = php
|
||||
|
||||
# Self update of the composer
|
||||
#
|
||||
composer.self-update = false
|
||||
|
||||
# Validate the composer.json file
|
||||
#
|
||||
composer.validate = false
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Directories
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# System directories
|
||||
#
|
||||
dir.data = ${project.basedir}/.data
|
||||
dir.src = ${project.basedir}/src
|
||||
dir.tests = ${project.basedir}/tests
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Build directories
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
dir.build = ${project.basedir}/.build
|
||||
dir.reports = ${dir.build}/logs
|
||||
dir.reports.pdepend = ${dir.reports}/pdepend
|
||||
dir.reports.coverage = ${dir.reports}/phpunit_coverage
|
||||
#
|
||||
# Disabled, because unnecessary right now
|
||||
# phpdocumentor/phpdocumentor cannot be installed via Composer
|
||||
#
|
||||
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
# 2017-02-22
|
||||
#
|
||||
#dir.docs = ${dir.build}/docs
|
||||
#dir.docs.phpdoc2 = ${dir.docs}/phpdoc2
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Data directories
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
dir.data.tests = ${dir.data}/tests
|
||||
dir.data.temporary = ${dir.data}/tmp
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Testing
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# Test database path
|
||||
#
|
||||
tests.database = ${dir.data.temporary}/database.sqlite
|
||||
|
||||
#
|
||||
# Disabled, because unnecessary right now
|
||||
# PHPUnit is installed and loaded by Composer
|
||||
#
|
||||
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
# 2017-02-22
|
||||
#
|
||||
# Run PHPUnit using exec task instead of phpunitTask
|
||||
#phpunit.useExec = false
|
||||
|
||||
#
|
||||
# Disabled, because unnecessary right now
|
||||
# We want generate code coverage always
|
||||
#
|
||||
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
# 2017-02-22
|
||||
#
|
||||
# Collect coverage data during tests
|
||||
#phpunit.withCoverage = true
|
||||
|
||||
# Path of the PHPUnit (https://phpunit.de)
|
||||
#
|
||||
phpUnit.path = ./vendor/bin/phpunit
|
||||
|
||||
# Path of the PHP Coding Standards Fixer (http://cs.sensiolabs.org)
|
||||
#
|
||||
phpCsFixer.path = ./vendor/bin/php-cs-fixer
|
||||
315
.phing/tests.xml
315
.phing/tests.xml
@@ -1,315 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.14.0">
|
||||
<!--
|
||||
The AutoloaderTask is required to load binaries installed by Composer.
|
||||
The "autoloaderpath" attribute of this task is not required, because it's default value is: vendor/autoload.php.
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-23
|
||||
-->
|
||||
<autoloader />
|
||||
|
||||
<!-- Properties -->
|
||||
<if>
|
||||
<available file=".phing/properties" property="custom.properties.available"/>
|
||||
<then>
|
||||
<property file=".phing/properties" />
|
||||
</then>
|
||||
<else>
|
||||
<property file=".phing/properties.dist" />
|
||||
</else>
|
||||
</if>
|
||||
|
||||
<!-- Filesets -->
|
||||
<fileset id="sourcecode" dir="${dir.src}">
|
||||
<include name="**/*.php" />
|
||||
<exclude name="*Test.php" />
|
||||
<exclude name="**/*Test.php" />
|
||||
<exclude name="**/Resources/**" />
|
||||
<exclude name="**/DataFixtures/**" />
|
||||
<exclude name="**/Tests/**" />
|
||||
</fileset>
|
||||
<fileset id="tests" dir="${dir.tests}">
|
||||
<include name="**/*Test*.php" />
|
||||
</fileset>
|
||||
|
||||
<!-- Default / main target -->
|
||||
<target name="build:main"
|
||||
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, app:checkout"
|
||||
description="Runs all tests and builds everything" />
|
||||
<!--
|
||||
Before:
|
||||
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, build:doc, app:checkout"
|
||||
|
||||
After:
|
||||
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, app:checkout"
|
||||
|
||||
The "build:doc" task is disabled, because it cannot be installed via Composer:
|
||||
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
|
||||
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
-->
|
||||
|
||||
<!-- Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org) -->
|
||||
<target name="build:fix-coding-standards" description="Fixes coding standards using the PHP Coding Standards Fixer">
|
||||
<echo msg="Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org)..." />
|
||||
|
||||
<!--
|
||||
Attention.
|
||||
Rules for formatting are defined in /.php_cs.dist file.
|
||||
-->
|
||||
|
||||
<exec
|
||||
passthru="true"
|
||||
command="${phpCsFixer.path} fix --verbose"
|
||||
/>
|
||||
</target>
|
||||
|
||||
<!-- Doc target -->
|
||||
<!--
|
||||
Disabled, because it cannot be installed via Composer:
|
||||
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
|
||||
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
-->
|
||||
<!--<target name="build:doc"-->
|
||||
<!--depends="build:prepare, doc:phpdoc2"-->
|
||||
<!--description="Generates API documentation" />-->
|
||||
|
||||
<!-- Check target -->
|
||||
<target name="build:check"
|
||||
depends="check:cs, check:md, check:cpd, check:depend, check:loc"
|
||||
description="Analyzes code" />
|
||||
|
||||
<!-- Test target -->
|
||||
<target name="build:test"
|
||||
depends="test:phpunit"
|
||||
description="Executes all tests" />
|
||||
|
||||
<!-- Project build clean -->
|
||||
<target name="build:clean" description="Cleans up build directories">
|
||||
<echo msg="Cleaning docs and reports directories..." />
|
||||
<!--<delete dir="${dir.docs}" />-->
|
||||
<delete dir="${dir.reports}" />
|
||||
</target>
|
||||
|
||||
<!-- Project build prepare -->
|
||||
<target name="build:prepare" description="Create build directories">
|
||||
<echo msg="Creating build directories..." />
|
||||
<!--<mkdir dir="${dir.docs}" />-->
|
||||
<!--<mkdir dir="${dir.docs.phpdoc2}" />-->
|
||||
<mkdir dir="${dir.reports}" />
|
||||
<mkdir dir="${dir.reports.coverage}" />
|
||||
<mkdir dir="${dir.reports.pdepend}" />
|
||||
</target>
|
||||
|
||||
<!-- PHPDocumentor2 API documentation target -->
|
||||
<!--
|
||||
Disabled, because it cannot be installed via Composer:
|
||||
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
|
||||
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
|
||||
<target name="doc:phpdoc2" description="Generates API documentations">
|
||||
<echo msg="Generating API Documentation with phpDocumentor 2..." />
|
||||
<phpdoc2 title="${phing.project.name}"
|
||||
destdir="${dir.docs.phpdoc2}"
|
||||
template="responsive">
|
||||
<fileset refid="sourcecode" />
|
||||
</phpdoc2>
|
||||
</target>
|
||||
-->
|
||||
|
||||
<!-- Symfony2 code sniffer -->
|
||||
<!--
|
||||
Attention 1.
|
||||
To use Symfony2 standards to check coding you have to:
|
||||
copy, symlink or check out repo to a folder called Symfony2 inside the phpcs Standards directory.
|
||||
|
||||
Example:
|
||||
$ pear config-show | grep php_dir
|
||||
$ cd /path/to/pear/PHP/CodeSniffer/Standards
|
||||
$ git clone git://github.com/opensky/Symfony2-coding-standard.git Symfony2
|
||||
|
||||
Attention 2.
|
||||
PSR2 standard is used instead of Symfony2 standard, because after installation squizlabs/php_codesniffer package
|
||||
via Composer the Symfony2 standard is not included / available in this package. In this case the PHP Coding
|
||||
Standards Fixer (http://cs.sensiolabs.org) is used.
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
-->
|
||||
<target name="check:cs" description="Checks coding standard">
|
||||
<echo msg="Checking coding standard..." />
|
||||
<phpcodesniffer standard="PSR2" showWarnings="true">
|
||||
<fileset refid="sourcecode" />
|
||||
<formatter type="checkstyle" outfile="${dir.reports}/checkstyle.xml" />
|
||||
<formatter type="csv" outfile="${dir.reports}/checkstyle.csv" />
|
||||
<formatter type="summary" outfile="${dir.reports}/checkstyle_summary.txt" />
|
||||
</phpcodesniffer>
|
||||
</target>
|
||||
|
||||
<!-- copy/paste detector -->
|
||||
<target name="check:cpd" description="Checks similar code blocks.">
|
||||
<echo msg="Checking similar code blocks..." />
|
||||
<phpcpd>
|
||||
<fileset refid="sourcecode" />
|
||||
<formatter type="pmd" outfile="${dir.reports}/pmd-cpd.xml" />
|
||||
</phpcpd>
|
||||
|
||||
<!--
|
||||
Previous / old version
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
|
||||
<exec command="phpcpd \-\-log-pmd=${dir.reports}/pmd-cpd.xml ${dir.src}" />
|
||||
-->
|
||||
</target>
|
||||
|
||||
<!-- Mess detector -->
|
||||
<target name="check:md" description="Generate code metrics">
|
||||
<echo msg="Generating code metrics..." />
|
||||
<phpmd rulesets="codesize,controversial,design,naming,unusedcode">
|
||||
<fileset refid="sourcecode" />
|
||||
<formatter type="html" outfile="${dir.reports}/phpmd.html" />
|
||||
<formatter type="text" outfile="${dir.reports}/phpmd.txt" />
|
||||
</phpmd>
|
||||
</target>
|
||||
|
||||
<!-- Code dependency -->
|
||||
<target name="check:depend" description="Checks coupling and dependency">
|
||||
<echo msg="Checking coupling and dependency..." />
|
||||
<phpdepend>
|
||||
<fileset refid="sourcecode" />
|
||||
<logger type="jdepend-xml" outfile="${dir.reports.pdepend}/jdepend.xml" />
|
||||
<logger type="jdepend-chart" outfile="${dir.reports.pdepend}/dependencies.svg" />
|
||||
<logger type="overview-pyramid" outfile="${dir.reports.pdepend}/overview-pyramid.svg" />
|
||||
</phpdepend>
|
||||
</target>
|
||||
|
||||
<!-- Measure the size and analyzing the structure of a project -->
|
||||
<target name="check:loc" description="Measures the size and analyzes the structure of a project">
|
||||
<echo msg="Measuring the size and analyzing the structure of a project..." />
|
||||
<phploc reportType="txt" reportName="phploc" reportDirectory="${dir.reports}">
|
||||
<fileset refid="sourcecode" />
|
||||
</phploc>
|
||||
|
||||
<!--
|
||||
Previous / old version
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
|
||||
<exec command="phploc \-\-log-csv=${dir.reports}/phploc.csv ${dir.src}" />
|
||||
-->
|
||||
</target>
|
||||
|
||||
<!-- Unit tests -->
|
||||
<target name="test:phpunit" description="Executes PHPUnit 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..." />
|
||||
<coverage-setup database="${dir.reports.coverage}/coverage.db">
|
||||
<fileset refid="sourcecode" />
|
||||
</coverage-setup>
|
||||
<exec command="${phpUnit.path} --verbose --configuration ${project.basedir}/phpunit.xml.dist" passthru="true" />
|
||||
<!--
|
||||
I have to use ExecTask to run PHPUnit instead of PHPUnitTask, because tests are not running if PHPUnitTask is
|
||||
used (don't know why):
|
||||
Total tests run: 0, Failures: 0, Errors: 0, Incomplete: 0, Skipped: 0
|
||||
|
||||
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>
|
||||
|
||||
<!-- Checkout and finalization -->
|
||||
<target name="app:checkout">
|
||||
<tstamp>
|
||||
<format property="date_end" pattern="%Y-%m-%d %H:%M" />
|
||||
</tstamp>
|
||||
|
||||
<echo msg="--------------------------------------------" />
|
||||
<echo msg="Build tests finished at: ${date_end}" />
|
||||
<echo msg="--------------------------------------------" />
|
||||
</target>
|
||||
</project>
|
||||
56
.php_cs.dist
56
.php_cs.dist
@@ -1,30 +1,52 @@
|
||||
<?php
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
/*
|
||||
* Do not verify:
|
||||
* - all DependencyInjection/Configuration classes: the Configuration.php files
|
||||
* - autoloader from /app directory: autoload.php
|
||||
*/
|
||||
->notPath('/DependencyInjection\/Configuration\.php/')
|
||||
->notPath('/autoload\.php/')
|
||||
->in([
|
||||
__DIR__ . '/src',
|
||||
__DIR__ . '/tests',
|
||||
->in(__DIR__)
|
||||
->exclude([
|
||||
'build',
|
||||
'vendor',
|
||||
])
|
||||
->notPath([
|
||||
'tests/Resources/var/',
|
||||
]);
|
||||
|
||||
return PhpCsFixer\Config::create()
|
||||
->setRules([
|
||||
'@Symfony' => true,
|
||||
'phpdoc_summary' => false,
|
||||
'phpdoc_separation' => false,
|
||||
'phpdoc_align' => false,
|
||||
'cast_spaces' => false,
|
||||
'@Symfony' => true,
|
||||
'@PhpCsFixer' => true,
|
||||
'@PHP71Migration' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'binary_operator_spaces' => [
|
||||
'align_double_arrow' => true,
|
||||
],
|
||||
'concat_space' => [
|
||||
'blank_line_before_return' => false,
|
||||
'cast_spaces' => false,
|
||||
'concat_space' => [
|
||||
'spacing' => 'one',
|
||||
],
|
||||
'ordered_class_elements' => [
|
||||
'order' => [
|
||||
'use_trait',
|
||||
'constant_public',
|
||||
'constant_protected',
|
||||
'constant_private',
|
||||
'property_public',
|
||||
'property_protected',
|
||||
'property_private',
|
||||
'construct',
|
||||
'destruct',
|
||||
'magic',
|
||||
'method_public',
|
||||
'method_protected',
|
||||
'method_private',
|
||||
],
|
||||
],
|
||||
'phpdoc_add_missing_param_annotation' => true,
|
||||
'phpdoc_align' => false,
|
||||
'phpdoc_order' => true,
|
||||
'phpdoc_separation' => false,
|
||||
'phpdoc_summary' => false,
|
||||
'trim_array_spaces' => false,
|
||||
])
|
||||
->setFinder($finder);
|
||||
->setFinder($finder)
|
||||
;
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
preset: symfony
|
||||
|
||||
disabled:
|
||||
- phpdoc_annotation_without_dot
|
||||
- cast_spaces
|
||||
- concat_without_spaces
|
||||
- blank_line_before_return
|
||||
- trim_array_spaces
|
||||
2
.travis-php-config.ini
Normal file
2
.travis-php-config.ini
Normal file
@@ -0,0 +1,2 @@
|
||||
date.timezone = Europe/London
|
||||
memory_limit = 2G
|
||||
21
.travis.yml
21
.travis.yml
@@ -1,12 +1,23 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
- 7.4
|
||||
|
||||
before_install:
|
||||
- sudo locale-gen de_DE.UTF-8 es_ES.UTF-8 en_GB.UTF-8 en_US.UTF-8 fr_FR.UTF-8 it_IT.UTF-8 pl_PL.UTF-8 ru_RU.UTF-8
|
||||
- pear channel-discover pear.phing.info
|
||||
|
||||
install:
|
||||
- composer install
|
||||
- pear install phing/phing
|
||||
- phpenv rehash
|
||||
|
||||
before_script:
|
||||
- phpenv config-add .travis-php-config.ini
|
||||
|
||||
script:
|
||||
- php ./vendor/bin/phpunit
|
||||
- phing
|
||||
|
||||
after_success:
|
||||
- travis_retry php vendor/bin/php-coveralls -v
|
||||
|
||||
185
CHANGELOG.md
Normal file
185
CHANGELOG.md
Normal file
@@ -0,0 +1,185 @@
|
||||
# Meritoo Common Library
|
||||
|
||||
Common and useful classes, methods, exceptions etc.
|
||||
|
||||
# 1.1.8
|
||||
|
||||
1. [Composer] Upgrade all dev packages (to the latest, stable versions for PHP `7.4`)
|
||||
2. [BaseCollection] Interfaces of different types of collections. May be used to build specific collections.
|
||||
|
||||
# 1.1.7
|
||||
|
||||
1. [Arrays] Allow to define a key of next level elements in a function that returns elements from given level
|
||||
|
||||
# 1.1.6
|
||||
|
||||
1. [Arrays] Function that returns elements from given level
|
||||
|
||||
# 1.1.5
|
||||
|
||||
1. [BaseCollection] Prepare elements while adding them by `addMultiple()` method in the same way as passing them in
|
||||
constructor.
|
||||
|
||||
# 1.1.4
|
||||
|
||||
1. [BaseCollection] Fix incorrectly working limit() method
|
||||
|
||||
# 1.1.3
|
||||
|
||||
1. Move `Renderable` class: `Meritoo\Common` -> `Meritoo\Common\Contract`
|
||||
2. Create and implement `CollectionInterface` as contract of all collections (e.g. based on the `BaseCollection` class)
|
||||
|
||||
# 1.1.2
|
||||
|
||||
1. Change mode of `Xdebug` to `coverage` in Docker's configuration to make it possible to generate code coverage by
|
||||
`PHPUnit`
|
||||
2. Mark PHPUnit test as risky when it does not have a `@covers` annotation
|
||||
|
||||
# 1.1.1
|
||||
|
||||
1. [BaseCollection] Treat the `null` index as "no index" only while adding new element, iow. do not treat empty string
|
||||
as "no index" behaviour.
|
||||
2. [Miscellaneous] [Regex] Use simpler & stronger pattern to match name of file
|
||||
3. Do not install `hirak/prestissimo` package while running Travis CI (incompatible with your PHP version, PHP
|
||||
extensions and Composer version)
|
||||
4. Use PHP `7.4` while running build in Travis CI
|
||||
|
||||
# 1.1.0
|
||||
|
||||
1. Rename Meritoo\Common\Collection\Collection class to Meritoo\Common\Collection\BaseCollection. Add BaseCollection::
|
||||
isValidType() method to validate type of element before add it to collection. Add BaseCollection ::prepareElements()
|
||||
method to allow preparation of elements in custom way.
|
||||
|
||||
# 1.0.6
|
||||
|
||||
1. Use `.env` instead of `.env.dist`
|
||||
2. Docker > use images (instead of Dockerfiles)
|
||||
3. composer > squizlabs/php_codesniffer package > use ^3.4 (instead of ^2.9)
|
||||
4. Do not require name of class by BaseTestCaseTrait::assertMethodVisibilityAndArguments() method
|
||||
5. PHP CS Fixer > configuration > make more readable & remove unnecessary code
|
||||
6. Update .gitignore, docker-compose.yml, phpunit.xml.dist
|
||||
|
||||
# 1.0.5
|
||||
|
||||
1. Collection > trait > return "void" where "self" causes type hinting problem and is not required
|
||||
|
||||
# 1.0.4
|
||||
|
||||
1. PHP Coding Standards Fixer > update configuration
|
||||
2. Phing > tests > add task for Psalm (https://psalm.dev)
|
||||
3. Collection > trait > split into smaller traits (to make it more flexible)
|
||||
|
||||
# 1.0.3
|
||||
|
||||
1. Travis CI > run many tasks using Phing > update configuration
|
||||
2. Template with placeholders > verification of placeholders without values > make stronger and point out which are
|
||||
missing
|
||||
3. Reflection > getPropertyValue() method > look for the property in parent classes
|
||||
|
||||
# 1.0.2
|
||||
|
||||
1. Phing > remove old and unused tools
|
||||
2. Phing > configuration > minor updates
|
||||
3. Implement Mutation Testing Framework (infection/infection package)
|
||||
4. Travis CI > run many tasks using Phing (instead of PHPUnit only)
|
||||
5. Fix integration with [Coveralls](https://www.coveralls.io) (available as the badge in [README.md](README.md))
|
||||
6. Implement [PHPStan](https://github.com/phpstan/phpstan)
|
||||
7. PHPUnit > execute tests in random order
|
||||
8. Implement [Psalm](https://github.com/vimeo/psalm)
|
||||
9. Infection (Mutation Testing Framework) > fix bugs while running (generate proper code coverage, bugs while running
|
||||
tests randomly)
|
||||
10. Phing > php-coveralls > add task
|
||||
|
||||
# 1.0.1
|
||||
|
||||
1. Regex > make compatible with PHP 7.3 Tests > Regex > fix "preg_match(): Compilation failed: invalid range in
|
||||
character class at offset 4" bug
|
||||
2. Collection/storage of templates
|
||||
3. Template with placeholders that may be filled by real data
|
||||
4. RenderableInterface > something that may be rendered
|
||||
|
||||
# 1.0.0
|
||||
|
||||
1. Composer > support/require PHP 7.2+ (instead of 5.6+)
|
||||
|
||||
# 0.1.8
|
||||
|
||||
1. Size, e.g. of image
|
||||
|
||||
# 0.1.7
|
||||
|
||||
1. Collection > create trait (to make it more flexible)
|
||||
|
||||
# 0.1.6
|
||||
|
||||
1. Arrays > refactoring & more tests
|
||||
2. ValueObject > Human > represents a human
|
||||
3. Tests > use `Meritoo\Test\Common` namespace (instead of `Meritoo\Common\Test`)
|
||||
4. Tests > use @dataProvider
|
||||
|
||||
# 0.1.5
|
||||
|
||||
1. Tests > Date > one more test case
|
||||
2. Phing > update configuration
|
||||
3. Miscellaneous > variableDump() method > remove, because unnecessary
|
||||
4. Regex > createSlug() method > returns slug for given value
|
||||
5. Arrays > getNonEmptyValues() method > returns non-empty values, e.g. without "" (empty string), null or []
|
||||
6. Arrays > getNonEmptyValuesAsString() method > returns non-empty values concatenated by given separator
|
||||
7. ValueObject > Company > represents a company
|
||||
8. ValueObject > BankAccount > represents bank account
|
||||
9. ValueObject > Address > represents address of company, institution, user etc.
|
||||
|
||||
# 0.1.4
|
||||
|
||||
1. Phing > update configuration
|
||||
2. Utilities > Date > update descriptions of methods
|
||||
3. Docker > docker-compose.yml > add "phpunit" service > used to run PHPUnit's tests
|
||||
4. Reflection > setPropertiesValues() method > sets values of properties in given object
|
||||
|
||||
# 0.1.3
|
||||
|
||||
1. Tests > refactoring & minor improvements
|
||||
2. Utilities > CssSelector > useful methods related to CSS selectors
|
||||
3. Utilities > Bootstrap4CssSelector > useful methods related to CSS selectors and the Bootstrap4 (front-end component
|
||||
library)
|
||||
|
||||
# 0.1.2
|
||||
|
||||
1. Documentation > Value Objects
|
||||
2. Docker > improve performance
|
||||
3. Utilities > Reflection > setPropertyValue() method > sets value of given property
|
||||
|
||||
# 0.1.1
|
||||
|
||||
1. TravisCI > run using PHP 7.2 too
|
||||
2. ValueObject > class Version > represents version of software
|
||||
3. Move version of this package to `VERSION` file (from `composer.json` file)
|
||||
|
||||
# 0.1.0
|
||||
|
||||
1. Composer > support/require PHP 5.6+ (instead of 5.5.9+)
|
||||
2. Docker > rename `php-cli` service to `php`
|
||||
3. Exceptions > create instance of exception using static `create()` method (instead of constructor)
|
||||
4. Documentation > Exceptions
|
||||
|
||||
# 0.0.21
|
||||
|
||||
1. Composer > require ext-pcre
|
||||
2. Arrays > minor refactoring
|
||||
3. Update @author and @copyright in classes' descriptions
|
||||
|
||||
# 0.0.20
|
||||
|
||||
1. Collection > add() method > treat empty string as not provided index (same as null)
|
||||
|
||||
# 0.0.19
|
||||
|
||||
1. Add this changelog
|
||||
2. Reorganize documentation & update [Readme](README.md)
|
||||
3. Docker: use project-related binaries globally
|
||||
4. StyleCI & PHP Coding Standards Fixer: update configuration
|
||||
5. Documentation > Docker > add paragraph for PHP Coding Standards Fixer
|
||||
6. Coding standard > fix automatically
|
||||
7. StyleCI configuration > fix bug "The provided fixer 'binary_operator_spaces' cannot be enabled again because it was
|
||||
already enabled"
|
||||
8. StyleCI > disable & remove
|
||||
131
README.md
131
README.md
@@ -1,114 +1,49 @@
|
||||
# Meritoo Common Library
|
||||
|
||||
Common and useful classes, methods, exceptions etc.
|
||||
|
||||
[](https://travis-ci.org/meritoo/common-library) [](https://packagist.org/packages/meritoo/common-library) [](https://styleci.io/repos/101790028) [](https://github.com/meritoo/common-library) [](https://github.com/meritoo/common-library) [](https://coveralls.io/github/meritoo/common-library?branch=master)
|
||||

|
||||
[](https://travis-ci.com/meritoo/common-library)
|
||||
[](https://packagist.org/packages/meritoo/common-library)
|
||||
[](https://github.com/meritoo/common-library)
|
||||
[](https://github.com/meritoo/common-library)
|
||||
[](https://coveralls.io/github/meritoo/common-library)
|
||||
|
||||
## Installation
|
||||
# Installation
|
||||
|
||||
In your `composer.json` add address of repository into `repositories` section:
|
||||
|
||||
```json
|
||||
"repositories": [
|
||||
(...)
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/wiosna-dev/common-library"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Run [Composer](https://getcomposer.org) to install this package in your project:
|
||||
|
||||
```bash
|
||||
$ composer require meritoo/common-library
|
||||
composer require wiosna-dev/common-library
|
||||
```
|
||||
|
||||
> How to install Composer: https://getcomposer.org/download
|
||||
> [How to install Composer?](https://getcomposer.org/download)
|
||||
|
||||
## Rebuilding project and tests running
|
||||
# Usage
|
||||
|
||||
```bash
|
||||
$ docker-compose up -d
|
||||
$ docker-compose exec php-cli phing
|
||||
```
|
||||
1. [Base test case (with common methods and data providers)](docs/Base-test-case.md)
|
||||
2. [Collection of elements](docs/Collection/BaseCollection.md)
|
||||
3. [Exceptions](docs/Static-methods.md)
|
||||
4. [Static methods](docs/Static-methods.md)
|
||||
1. [Arrays](docs/Static-methods/Arrays.md)
|
||||
2. [Regex](docs/Static-methods/Regex.md)
|
||||
3. [Uri](docs/Static-methods/Uri.md)
|
||||
5. [Value Objects](docs/Value-Objects.md)
|
||||
|
||||
> What is Docker? https://www.docker.com/what-docker
|
||||
# Development
|
||||
|
||||
## 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"
|
||||
```
|
||||
|
||||
## 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)
|
||||
```
|
||||
More information [you can find here](docs/Development.md)
|
||||
|
||||
Enjoy!
|
||||
|
||||
38
build.xml
38
build.xml
@@ -1,46 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.14.0">
|
||||
<!-- Properties -->
|
||||
<if>
|
||||
<available file=".phing/properties" property="custom.properties.available"/>
|
||||
<available file="${project.basedir}/phing/properties" property="custom.properties.available" />
|
||||
<then>
|
||||
<property file=".phing/properties" />
|
||||
<property file="${project.basedir}/phing/properties" />
|
||||
</then>
|
||||
<else>
|
||||
<property file=".phing/properties.dist" />
|
||||
<property file="${project.basedir}/phing/properties.dist" />
|
||||
</else>
|
||||
</if>
|
||||
|
||||
<!-- Default / main target -->
|
||||
<target name="build:main"
|
||||
depends="build:app, build:tests"
|
||||
description="Builds everything and runs all tests" />
|
||||
depends="build:app,
|
||||
build:tests"
|
||||
/>
|
||||
|
||||
<!-- Build app -->
|
||||
<target name="build:app" description="Prepares app to build and tests">
|
||||
<phing phingfile=".phing/app.xml" haltonfailure="true" />
|
||||
<target name="build:app">
|
||||
<phing phingfile="${project.basedir}/phing/app.xml" haltonfailure="true" />
|
||||
</target>
|
||||
|
||||
<!-- Build tests -->
|
||||
<target name="build:tests" description="Runs all tests, checks and creates docs">
|
||||
<phing phingfile=".phing/tests.xml" haltonfailure="true" />
|
||||
|
||||
<!--
|
||||
Conditional running of tests.
|
||||
Disabled, because not required.
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
|
||||
<if>
|
||||
<equals arg1="${env}" arg2="test" />
|
||||
<then>
|
||||
<phing phingfile=".phing/tests.xml" haltonfailure="true" />
|
||||
</then>
|
||||
<else>
|
||||
<echo message="[Skipped] Running tests, checks and creating docs, because it's a not 'test' environment..." />
|
||||
</else>
|
||||
</if>
|
||||
-->
|
||||
<target name="build:tests">
|
||||
<phing phingfile="${project.basedir}/phing/tests.xml" haltonfailure="true" />
|
||||
</target>
|
||||
</project>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"name": "meritoo/common-library",
|
||||
"name": "wiosna-dev/common-library",
|
||||
"description": "Useful classes, methods, extensions etc.",
|
||||
"license": "MIT",
|
||||
"version": "0.0.15",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Meritoo.pl",
|
||||
@@ -11,19 +10,25 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.6.0",
|
||||
"doctrine/orm": "^2.5",
|
||||
"gedmo/doctrine-extensions": "^2.4",
|
||||
"symfony/http-foundation": "^3.3"
|
||||
"php": "^7.4 || ^8.0",
|
||||
"ext-dom": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-simplexml": "*",
|
||||
"doctrine/orm": "^2.6",
|
||||
"gedmo/doctrine-extensions": "^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.6",
|
||||
"pdepend/pdepend": "^2.5",
|
||||
"phploc/phploc": "^4.0",
|
||||
"phpmd/phpmd": "^2.6",
|
||||
"phpunit/phpunit": "^5.7",
|
||||
"sebastian/phpcpd": "^3.0",
|
||||
"squizlabs/php_codesniffer": "^2.9"
|
||||
"friendsofphp/php-cs-fixer": "^3.11",
|
||||
"infection/infection": "^0.26",
|
||||
"php-coveralls/php-coveralls": "^2.5",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpunit/phpunit": "^9",
|
||||
"sebastian/phpcpd": "^6.0",
|
||||
"squizlabs/php_codesniffer": "^3.7",
|
||||
"vimeo/psalm": "^4.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -32,7 +37,10 @@
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Meritoo\\Common\\Test\\": "tests/"
|
||||
"Meritoo\\Test\\Common\\": "tests/"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
@@ -1,15 +1,33 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
php-cli:
|
||||
image: meritoo/common-library
|
||||
container_name: meritoo-common-library
|
||||
working_dir: /project
|
||||
#
|
||||
# Required to run project
|
||||
#
|
||||
php:
|
||||
image: meritoo/php:7.4
|
||||
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-php
|
||||
entrypoint: php
|
||||
command: -S 0.0.0.0:9999
|
||||
build:
|
||||
context: ./.docker/config
|
||||
args:
|
||||
- TIMEZONE=$TIMEZONE
|
||||
environment:
|
||||
PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE}
|
||||
volumes:
|
||||
- .:/project
|
||||
- .:/var/www/application:cached
|
||||
composer:
|
||||
image: meritoo/php:7.4
|
||||
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-composer
|
||||
entrypoint: php -d memory_limit=-1 /usr/local/bin/composer
|
||||
volumes:
|
||||
- .:/var/www/application:cached
|
||||
#
|
||||
# Required to run PHPUnit's tests
|
||||
#
|
||||
phpunit:
|
||||
image: meritoo/php:7.4
|
||||
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-phpunit
|
||||
entrypoint: ./vendor/bin/phpunit
|
||||
command: --version
|
||||
volumes:
|
||||
- .:/var/www/application:cached
|
||||
environment:
|
||||
XDEBUG_MODE: coverage
|
||||
|
||||
63
docs/Base-test-case.md
Normal file
63
docs/Base-test-case.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Meritoo Common Library
|
||||
|
||||
Common and useful classes, methods, exceptions etc.
|
||||
|
||||
# Base test case (with common methods and data providers)
|
||||
|
||||
Located here: `Meritoo\Common\Test\Base\BaseTestCase`.
|
||||
|
||||
##### Usage
|
||||
|
||||
1. Just extend the `BaseTestCase` class or implement `Meritoo\Common\Traits\Test\Base\BaseTestCaseTrait` trait.
|
||||
2. Use one of available data providers, e.g. `@dataProvider provideEmptyValue`, or asserts,
|
||||
e.g. `static::assertMethodVisibility($method, $visibilityType);`
|
||||
|
||||
##### Examples
|
||||
|
||||
```php
|
||||
class DateTest extends BaseTestCase
|
||||
{
|
||||
/**
|
||||
* @param mixed $value Empty value, e.g. ""
|
||||
* @dataProvider provideEmptyValue
|
||||
*/
|
||||
public function testGetDateTimeEmptyValue($value)
|
||||
{
|
||||
self::assertFalse(Date::getDateTime($value));
|
||||
}
|
||||
|
||||
(...)
|
||||
}
|
||||
```
|
||||
|
||||
```php
|
||||
class MimeTypesTest extends BaseTestCase
|
||||
{
|
||||
(...)
|
||||
|
||||
/**
|
||||
* @param bool $mimeType The mime type, e.g. "video/mpeg"
|
||||
* @dataProvider provideBooleanValue
|
||||
*/
|
||||
public function testGetExtensionBooleanMimeType($mimeType)
|
||||
{
|
||||
self::assertEquals('', MimeTypes::getExtension($mimeType));
|
||||
}
|
||||
|
||||
(...)
|
||||
}
|
||||
```
|
||||
|
||||
# More
|
||||
|
||||
1. [**Base test case (with common methods and data providers)**](Base-test-case.md)
|
||||
2. [Collection of elements](Collection/BaseCollection.md)
|
||||
3. [Templates](Collection/Templates.md)
|
||||
4. [Exceptions](Exceptions.md)
|
||||
5. [Static methods](Static-methods.md)
|
||||
1. [Arrays](Static-methods/Arrays.md)
|
||||
2. [Regex](Static-methods/Regex.md)
|
||||
3. [Uri](Static-methods/Uri.md)
|
||||
6. [Value Objects](Value-Objects.md)
|
||||
|
||||
[‹ Back to `Readme`](../README.md)
|
||||
90
docs/Collection/BaseCollection.md
Normal file
90
docs/Collection/BaseCollection.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Meritoo Common Library
|
||||
|
||||
Common and useful classes, methods, exceptions etc.
|
||||
|
||||
# BaseCollection
|
||||
|
||||
### Namespace
|
||||
|
||||
`Meritoo\Common\Collection\BaseCollection`
|
||||
|
||||
### Info
|
||||
|
||||
It's a set of some elements with the same type, e.g. objects. It's iterable and countable. Provides very useful methods.
|
||||
Some of them:
|
||||
|
||||
- `getFirst()` - returns the first element in the collection
|
||||
- `getLast()` - returns the last element in the collection
|
||||
- `isEmpty()` - returns information if collection is empty
|
||||
- `add($element, $index = null)` - adds given element (at the end of collection)
|
||||
- `addMultiple($elements, $useIndexes = false)` - adds given elements (at the end of collection)
|
||||
- `prepend($element)` - prepends given element (adds given element at the beginning of collection)
|
||||
- `remove($element)` - removes given element
|
||||
|
||||
### Implementation
|
||||
|
||||
You have to implement:
|
||||
|
||||
```php
|
||||
abstract protected function isValidType($element): bool;
|
||||
```
|
||||
|
||||
This method verifies 1 element before it will be added to collection. Returns information if the element has valid,
|
||||
expected type.
|
||||
|
||||
Example (from `Meritoo\Common\Collection\Templates` class):
|
||||
|
||||
```php
|
||||
protected function isValidType($element): bool
|
||||
{
|
||||
return $element instanceof Template;
|
||||
}
|
||||
```
|
||||
|
||||
### Methods to overwrite
|
||||
|
||||
You can, if you wish, overwrite these methods:
|
||||
|
||||
1. To prepare elements used to initialize the collection in your own way:
|
||||
|
||||
```php
|
||||
protected function prepareElements(array $elements): array
|
||||
```
|
||||
|
||||
2. To validate type of elements in your own way:
|
||||
|
||||
```php
|
||||
protected function getElementsWithValidType(array $elements): array
|
||||
```
|
||||
|
||||
### Examples of usage
|
||||
|
||||
```php
|
||||
use Meritoo\Common\Collection\StringCollection;
|
||||
|
||||
$emptyCollection = new StringCollection();
|
||||
var_dump($emptyCollection->isEmpty()); // bool(true)
|
||||
|
||||
$elements = [
|
||||
'lorem',
|
||||
'ipsum',
|
||||
123 => 'dolor',
|
||||
345 => 'sit',
|
||||
];
|
||||
|
||||
$simpleCollection = new StringCollection($elements);
|
||||
var_dump($simpleCollection->has('dolor')); // bool(true)
|
||||
```
|
||||
|
||||
# More
|
||||
|
||||
1. [Base test case (with common methods and data providers)](../Base-test-case.md)
|
||||
2. [**Collection of elements**](BaseCollection.md)
|
||||
3. [Templates](Templates.md)
|
||||
4. [Exceptions](../Exceptions.md)
|
||||
5. [Static methods](../Static-methods.md)
|
||||
1. [Arrays](../Static-methods/Arrays.md)
|
||||
2. [Regex](../Static-methods/Regex.md)
|
||||
6. [Value Objects](../Value-Objects.md)
|
||||
|
||||
[‹ Back to `Readme`](../../README.md)
|
||||
67
docs/Collection/Templates.md
Normal file
67
docs/Collection/Templates.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Meritoo Common Library
|
||||
|
||||
Common and useful classes, methods, exceptions etc.
|
||||
|
||||
# Templates
|
||||
|
||||
### Namespace
|
||||
|
||||
`Meritoo\Common\Collection\Templates`
|
||||
|
||||
### Info
|
||||
|
||||
Collection/storage of templates, instance of `Meritoo\Common\ValueObject\Template` class.
|
||||
|
||||
##### New instance
|
||||
|
||||
New instance can be created using:
|
||||
|
||||
1. Constructor:
|
||||
|
||||
```php
|
||||
new Templates([
|
||||
'first' => new Template('First name: %first_name%'),
|
||||
'last' => new Template('Last name: %last_name%'),
|
||||
]);
|
||||
```
|
||||
|
||||
2. Static method `fromArray(array $templates)` - creates and returns the collection from given array
|
||||
|
||||
```php
|
||||
Templates::fromArray([
|
||||
'first' => 'First name: %first_name%',
|
||||
'last' => 'Last name: %last_name%',
|
||||
]);
|
||||
```
|
||||
|
||||
##### Methods
|
||||
|
||||
Has all methods of parent class `Meritoo\Common\Collection\Collection` + `findTemplate(string $index)` method that finds
|
||||
and returns template with given index.
|
||||
|
||||
Example of usage:
|
||||
|
||||
```php
|
||||
$templates = new Templates([
|
||||
'first' => new Template('First name: %first_name%'),
|
||||
'last' => new Template('Last name: %last_name%'),
|
||||
]);
|
||||
|
||||
$template = $templates->findTemplate('first'); // new Template('First name: %first_name%')
|
||||
```
|
||||
|
||||
Throws an `Meritoo\Common\Exception\ValueObject\Template\TemplateNotFoundException` exception if template with given
|
||||
index was not found.
|
||||
|
||||
# More
|
||||
|
||||
1. [Base test case (with common methods and data providers)](../Base-test-case.md)
|
||||
2. [Collection of elements](BaseCollection.md)
|
||||
3. [**Templates**](Templates.md)
|
||||
4. [Exceptions](../Exceptions.md)
|
||||
5. [Static methods](../Static-methods.md)
|
||||
1. [Arrays](../Static-methods/Arrays.md)
|
||||
2. [Regex](../Static-methods/Regex.md)
|
||||
6. [Value Objects](../Value-Objects.md)
|
||||
|
||||
[‹ Back to `Readme`](../../README.md)
|
||||
159
docs/Development.md
Normal file
159
docs/Development.md
Normal file
@@ -0,0 +1,159 @@
|
||||
# Meritoo Common Library
|
||||
|
||||
Development-related information
|
||||
|
||||
# Requirements
|
||||
|
||||
* [Docker](https://www.docker.com)
|
||||
* Your favourite IDE :)
|
||||
|
||||
# Getting started
|
||||
|
||||
1. Build, create and start Docker's containers by running command:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
2. Rebuild project by running command (installs packages, prepares required directories and runs tests):
|
||||
|
||||
```bash
|
||||
docker-compose exec php phing
|
||||
```
|
||||
|
||||
> [What is Docker?](https://www.docker.com/what-docker)
|
||||
|
||||
# Composer
|
||||
|
||||
Available as `composer` service. You can run any Composer's command using the `composer` service:
|
||||
|
||||
```bash
|
||||
docker-compose run --rm composer [command]
|
||||
```
|
||||
|
||||
Examples below.
|
||||
|
||||
##### Install packages
|
||||
|
||||
```bash
|
||||
docker-compose run --rm composer install
|
||||
```
|
||||
|
||||
##### Update packages
|
||||
|
||||
```bash
|
||||
docker-compose run --rm composer update
|
||||
```
|
||||
|
||||
##### Add package
|
||||
|
||||
```bash
|
||||
docker-compose run --rm composer require [vendor]/[package]
|
||||
```
|
||||
|
||||
##### Remove package
|
||||
|
||||
```bash
|
||||
docker-compose run --rm composer remove [vendor]/[package]
|
||||
```
|
||||
|
||||
# Coding Standards Fixer
|
||||
|
||||
Fix coding standard by running command:
|
||||
|
||||
```bash
|
||||
docker-compose exec php php-cs-fixer fix
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
docker-compose exec php phing -f phing/tests.xml build:fix-coding-standards
|
||||
```
|
||||
|
||||
Omit cache and run the Fixer from scratch by running command:
|
||||
|
||||
```bash
|
||||
docker-compose exec php rm .php_cs.cache && docker-compose exec php php-cs-fixer fix
|
||||
```
|
||||
|
||||
> [Want more?](https://cs.sensiolabs.org)
|
||||
|
||||
# Tests
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Install required packages by running command: `docker-compose run --rm composer install`.
|
||||
|
||||
### Running [PHPUnit](https://phpunit.de) tests
|
||||
|
||||
##### Easy (with code coverage)
|
||||
|
||||
```bash
|
||||
docker-compose run --rm phpunit --verbose
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
docker-compose exec php phing -f phing/tests.xml test:phpunit
|
||||
```
|
||||
|
||||
##### Quick (without code coverage)
|
||||
|
||||
```bash
|
||||
docker-compose run --rm phpunit --verbose --no-coverage
|
||||
```
|
||||
|
||||
# Infection - Mutation Testing
|
||||
|
||||
Served by [Infection — Mutation Testing Framework](https://infection.github.io).
|
||||
|
||||
### Running tests
|
||||
|
||||
```bash
|
||||
$ docker-compose exec php bash
|
||||
root@18f2f0cfaa5d:/var/www/application# XDEBUG_MODE=coverage ./vendor/bin/infection --threads=$(nproc)
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
$ docker-compose exec php bash
|
||||
root@18f2f0cfaa5d:/var/www/application# XDEBUG_MODE=coverage phing -f phing/tests.xml test:infection
|
||||
```
|
||||
|
||||
### Result of testing
|
||||
|
||||
##### Terminal
|
||||
|
||||
Example of output:
|
||||
|
||||
```bash
|
||||
125 mutations were generated:
|
||||
105 mutants were killed
|
||||
3 mutants were not covered by tests
|
||||
5 covered mutants were not detected
|
||||
0 errors were encountered
|
||||
12 time outs were encountered
|
||||
|
||||
Metrics:
|
||||
Mutation Score Indicator (MSI): 93%
|
||||
Mutation Code Coverage: 97%
|
||||
Covered Code MSI: 95%
|
||||
```
|
||||
|
||||
##### Stored in `build/reports/infection` directory
|
||||
|
||||
* `build/reports/infection/infection-log.txt`
|
||||
* `build/reports/infection/summary-log.txt`
|
||||
|
||||
# Other
|
||||
|
||||
Rebuild project and run tests by running command:
|
||||
|
||||
```bash
|
||||
docker-compose exec php phing
|
||||
```
|
||||
|
||||
[‹ Back to `Readme`](../README.md)
|
||||
70
docs/Exceptions.md
Normal file
70
docs/Exceptions.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Meritoo Common Library
|
||||
|
||||
Common and useful classes, methods, exceptions etc.
|
||||
|
||||
# Exceptions
|
||||
|
||||
### Create instance of exception
|
||||
|
||||
This package contains a lot of exceptions. Each of them contains static method `create()` with proper arguments that is
|
||||
used to create instance of the exception. Example:
|
||||
|
||||
```php
|
||||
use Meritoo\Common\Exception\Bundle\IncorrectBundleNameException;
|
||||
throw IncorrectBundleNameException::create('RisusIpsum');
|
||||
```
|
||||
|
||||
### Base exception for unknown type of something
|
||||
|
||||
##### Short description
|
||||
|
||||
It's a `Meritoo\Common\Exception\Base\UnknownTypeException` class. Related to `Meritoo\Common\Type\Base\BaseType` class
|
||||
that represents type of something, e.g. type of button, order.
|
||||
|
||||
##### Usage
|
||||
|
||||
You can extend `Meritoo\Common\Exception\Base\UnknownTypeException` class and create your own static method,
|
||||
e.g. `createException()`, which will be used create instance of the exception. Inside the `createException()` method you
|
||||
can call `parent::create()` method.
|
||||
|
||||
##### Example
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Your\Package\Exception\Type;
|
||||
|
||||
use Meritoo\Common\Exception\Base\UnknownTypeException;
|
||||
use Your\Package\Type\SimpleType;
|
||||
|
||||
class UnknownSimpleTypeException extends UnknownTypeException
|
||||
{
|
||||
/**
|
||||
* Creates exception
|
||||
*
|
||||
* @param string $unknownType Unknown and simple type
|
||||
* @return UnknownSimpleTypeException
|
||||
*/
|
||||
public static function createException($unknownType)
|
||||
{
|
||||
/* @var UnknownSimpleTypeException $exception */
|
||||
$exception = parent::create($unknownType, new SimpleType(), 'my simple type of something');
|
||||
|
||||
return $exception;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# More
|
||||
|
||||
1. [Base test case (with common methods and data providers)](Base-test-case.md)
|
||||
2. [Collection of elements](Collection/BaseCollection.md)
|
||||
3. [Templates](Collection/Templates.md)
|
||||
4. [**Exceptions**](Exceptions.md)
|
||||
5. [Static methods](Static-methods.md)
|
||||
1. [Arrays](Static-methods/Arrays.md)
|
||||
2. [Regex](Static-methods/Regex.md)
|
||||
3. [Uri](Static-methods/Uri.md)
|
||||
6. [Value Objects](Value-Objects.md)
|
||||
|
||||
[‹ Back to `Readme`](../README.md)
|
||||
29
docs/Static-methods.md
Normal file
29
docs/Static-methods.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Meritoo Common Library
|
||||
|
||||
Common and useful classes, methods, exceptions etc.
|
||||
|
||||
# Static methods
|
||||
|
||||
This package contains a lot of class with static methods, so usage is not so complicated. Just run the static method who
|
||||
would you like to use. Example:
|
||||
|
||||
```php
|
||||
use Meritoo\Common\Utilities\Arrays;
|
||||
|
||||
$firstElement = Arrays::getFirstElement(['lorem', 'ipsum']);
|
||||
var_dump($firstElement); // string(5) "lorem"
|
||||
```
|
||||
|
||||
# More
|
||||
|
||||
1. [Base test case (with common methods and data providers)](Base-test-case.md)
|
||||
2. [Collection of elements](Collection/BaseCollection.md)
|
||||
3. [Templates](Collection/Templates.md)
|
||||
4. [Exceptions](Exceptions.md)
|
||||
5. [**Static methods**](Static-methods.md)
|
||||
1. [Arrays](Static-methods/Arrays.md)
|
||||
2. [Regex](Static-methods/Regex.md)
|
||||
3. [Uri](Static-methods/Uri.md)
|
||||
6. [Value Objects](Value-Objects.md)
|
||||
|
||||
[‹ Back to `Readme`](../README.md)
|
||||
109
docs/Static-methods/Arrays.md
Normal file
109
docs/Static-methods/Arrays.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Meritoo Common Library
|
||||
|
||||
Common and useful classes, methods, exceptions etc.
|
||||
|
||||
# Arrays
|
||||
|
||||
> Useful methods related to arrays
|
||||
|
||||
Class: `Meritoo\Common\Utilities\Arrays`
|
||||
File: `src/Utilities/Arrays.php`
|
||||
|
||||
### containsEmptyStringsOnly(array): bool
|
||||
|
||||
> Returns information if given array contains an empty strings only
|
||||
|
||||
##### Arguments
|
||||
|
||||
- `array $array` - The array to verify
|
||||
|
||||
##### Examples
|
||||
|
||||
1)
|
||||
|
||||
- array: `[]` (an empty array)
|
||||
- result: `false`
|
||||
|
||||
2)
|
||||
|
||||
- array: `["", -1]`
|
||||
- result: `false`
|
||||
|
||||
3)
|
||||
|
||||
- array: `["", null, ""]`
|
||||
- result: `true`
|
||||
|
||||
### getNonEmptyValues(array $values)
|
||||
|
||||
> Returns non-empty values, e.g. without "" (empty string), null or []
|
||||
|
||||
##### Arguments
|
||||
|
||||
- `array $values` - The values to filter
|
||||
|
||||
##### Examples
|
||||
|
||||
1)
|
||||
|
||||
- values: `[]` (no values)
|
||||
- result: `[]` (an empty array)
|
||||
|
||||
2)
|
||||
|
||||
- values: `[null, ""]` (all empty values)
|
||||
- result: `[]` (an empty array)
|
||||
|
||||
3)
|
||||
|
||||
- values: `["test 1", "", 123, null, 0]`
|
||||
- result: `["test 1", 123, 0]`
|
||||
|
||||
### getNonEmptyValuesAsString(array $values, $separator = ', ')
|
||||
|
||||
> Returns non-empty values concatenated by given separator
|
||||
|
||||
##### Arguments
|
||||
|
||||
- `array $values` - The values to filter
|
||||
- `[string $separator]` - (optional) Separator used to implode the values. Default: ", ".
|
||||
|
||||
##### Examples
|
||||
|
||||
1)
|
||||
|
||||
- values: `[]` (no values)
|
||||
- separator: default or any other string
|
||||
- result: `""` (an empty string)
|
||||
|
||||
2)
|
||||
|
||||
- values: `[null, ""]` (all empty values)
|
||||
- separator: default or any other string
|
||||
- result: `""` (an empty string)
|
||||
|
||||
3)
|
||||
|
||||
- values: `["test 1", "", 123, null, 0]`
|
||||
- separator: `", "` (default)
|
||||
- result: `"test 1, 123, 0"`
|
||||
|
||||
4)
|
||||
|
||||
- values: `["test 1", "", 123, null, 0]`
|
||||
- separator: `" | "`
|
||||
- result: `"test 1 | 123 | 0"`
|
||||
|
||||
# More
|
||||
|
||||
1. [Base test case (with common methods and data providers)](../Base-test-case.md)
|
||||
2. [Collection of elements](../Collection/BaseCollection.md)
|
||||
3. [Templates](../Collection/Templates.md)
|
||||
4. [Exceptions](../Exceptions.md)
|
||||
5. [Static methods](../Static-methods.md)
|
||||
1. [**Arrays**](Arrays.md)
|
||||
2. [Regex](Regex.md)
|
||||
3. [Uri](Uri.md)
|
||||
6. [Value Objects](../Value-Objects.md)
|
||||
|
||||
[‹ Back to `Readme`](../../README.md)
|
||||
99
docs/Static-methods/Regex.md
Normal file
99
docs/Static-methods/Regex.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Meritoo Common Library
|
||||
|
||||
Common and useful classes, methods, exceptions etc.
|
||||
|
||||
# Regex
|
||||
|
||||
> Useful methods related to regular expressions
|
||||
|
||||
Class: `Meritoo\Common\Utilities\Regex`
|
||||
File: `src/Utilities/Regex.php`
|
||||
|
||||
### createSlug($value)
|
||||
|
||||
> Returns slug for given value
|
||||
|
||||
##### Arguments
|
||||
|
||||
- `string $value` - Value that should be transformed to slug
|
||||
|
||||
##### Examples
|
||||
|
||||
1)
|
||||
|
||||
- value: non-scalar or `null`
|
||||
- result: `false`
|
||||
|
||||
2)
|
||||
|
||||
- value: `""` (an empty string)
|
||||
- result: `""` (an empty string)
|
||||
|
||||
3)
|
||||
|
||||
- value: `"Lorem ipsum. Dolor sit 12.34 amet."`
|
||||
- result: `"lorem-ipsum-dolor-sit-1234-amet"`
|
||||
|
||||
### clearBeginningSlash(string): string
|
||||
|
||||
> Clears, removes slash from the beginning of given string
|
||||
|
||||
##### Arguments
|
||||
|
||||
- `string $string` - String that may contains slash as the 1st character
|
||||
|
||||
##### Examples
|
||||
|
||||
1)
|
||||
|
||||
- string: `"lorem ipsum"`
|
||||
- result: `"lorem ipsum"`
|
||||
|
||||
2)
|
||||
|
||||
- string: `"/lorem ipsum"`
|
||||
- result: `"lorem ipsum"`
|
||||
|
||||
3)
|
||||
|
||||
- string: `"/ lorem 123 ipsum"`
|
||||
- result: `" lorem 123 ipsum"`
|
||||
|
||||
### clearEndingSlash(string): string
|
||||
|
||||
> Clears, removes slash from the end of given string
|
||||
|
||||
##### Arguments
|
||||
|
||||
- `string $string` - String that may contains slash as the last character
|
||||
|
||||
##### Examples
|
||||
|
||||
1)
|
||||
|
||||
- string: `"lorem ipsum"`
|
||||
- result: `"lorem ipsum"`
|
||||
|
||||
2)
|
||||
|
||||
- string: `"lorem ipsum/"`
|
||||
- result: `"lorem ipsum"`
|
||||
|
||||
3)
|
||||
|
||||
- string: `"lorem 123 ipsum /"`
|
||||
- result: `"lorem 123 ipsum "`
|
||||
|
||||
# More
|
||||
|
||||
1. [Base test case (with common methods and data providers)](../Base-test-case.md)
|
||||
2. [Collection of elements](../Collection/BaseCollection.md)
|
||||
3. [Templates](../Collection/Templates.md)
|
||||
4. [Exceptions](../Exceptions.md)
|
||||
5. [Static methods](../Static-methods.md)
|
||||
1. [Arrays](../Static-methods/Arrays.md)
|
||||
2. [**Regex**](Regex.md)
|
||||
3. [Uri](Uri.md)
|
||||
6. [Value Objects](../Value-Objects.md)
|
||||
|
||||
[‹ Back to `Readme`](../../README.md)
|
||||
47
docs/Static-methods/Uri.md
Normal file
47
docs/Static-methods/Uri.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Meritoo Common Library
|
||||
|
||||
Common and useful classes, methods, exceptions etc.
|
||||
|
||||
# Uri
|
||||
|
||||
> Useful methods related to uri
|
||||
|
||||
Class: `Meritoo\Common\Utilities\Uri`
|
||||
File: `src/Utilities/Uri.php`
|
||||
|
||||
### buildUrl(string, string ...): string
|
||||
|
||||
> Builds url with given root url and parts of url (concatenates them using "/")
|
||||
|
||||
##### Arguments
|
||||
|
||||
- `string $rootUrl` - Protocol and domain (or domain only)
|
||||
- `string ...$urlParts` - Parts of url that will be concatenated with the rool url by "/"
|
||||
|
||||
##### Examples
|
||||
|
||||
1)
|
||||
|
||||
- rootUrl: `"http://my.example"`
|
||||
- urlParts: `""` (an empty string)
|
||||
- result: `"http://my.example"`
|
||||
|
||||
2)
|
||||
|
||||
- rootUrl: `"http://my.example"`
|
||||
- urlParts: `"/test", "/123"`
|
||||
- result: `"http://my.example/test/123"`
|
||||
|
||||
# More
|
||||
|
||||
1. [Base test case (with common methods and data providers)](../Base-test-case.md)
|
||||
2. [Collection of elements](../Collection/BaseCollection.md)
|
||||
3. [Templates](../Collection/Templates.md)
|
||||
4. [Exceptions](../Exceptions.md)
|
||||
5. [Static methods](../Static-methods.md)
|
||||
1. [Arrays](Arrays.md)
|
||||
2. [Regex](Regex.md)
|
||||
3. [**Uri**](Uri.md)
|
||||
6. [Value Objects](../Value-Objects.md)
|
||||
|
||||
[‹ Back to `Readme`](../../README.md)
|
||||
365
docs/Value-Objects.md
Normal file
365
docs/Value-Objects.md
Normal file
@@ -0,0 +1,365 @@
|
||||
# Meritoo Common Library
|
||||
|
||||
Common and useful classes, methods, exceptions etc.
|
||||
|
||||
# Value Objects
|
||||
|
||||
Located in `Meritoo\Common\ValueObject` namespace and in `src/ValueObject/` directory.
|
||||
|
||||
### Address
|
||||
|
||||
##### Namespace
|
||||
|
||||
`Meritoo\Common\ValueObject\Address`
|
||||
|
||||
##### Info
|
||||
|
||||
Represents address of company, institution, user etc. Contains properties:
|
||||
|
||||
1. `$street` - the street
|
||||
2. `$buildingNumber` - the number of building
|
||||
3. `$flatNumber` - the number of flat
|
||||
4. `$zipCode` - the zip code
|
||||
5. `$city` - the city, location
|
||||
|
||||
##### New instance
|
||||
|
||||
New instance can be created using constructor
|
||||
|
||||
```php
|
||||
new Address('New York', '00123', '4th Avenue', '10', '200');
|
||||
```
|
||||
|
||||
##### Methods
|
||||
|
||||
Has getters for each property, e.g. `getFlatNumber()` or `getZipCode()`, and 1 extra method:
|
||||
|
||||
```php
|
||||
getFullStreet()
|
||||
```
|
||||
|
||||
that returns name of street with related numbers (building & flat number).
|
||||
|
||||
Example:
|
||||
|
||||
```php
|
||||
$address = new Address('New York', '00123', '4th Avenue', '10', '200');
|
||||
$fullStreet = $address->getFullStreet(); // "4th Avenue 10/200"
|
||||
```
|
||||
|
||||
##### Conversion to string (the `__toString()` method)
|
||||
|
||||
Instance of `Address` may be represented as string that contains all non-empty properties separated by `, `.
|
||||
|
||||
Example:
|
||||
|
||||
```php
|
||||
$address = new Address('New York', '00123', '4th Avenue', '10', '200');
|
||||
$asString = (string)$address; // "4th Avenue 10/200, 00123, New York"
|
||||
```
|
||||
|
||||
### BankAccount
|
||||
|
||||
##### Namespace
|
||||
|
||||
`Meritoo\Common\ValueObject\BankAccount`
|
||||
|
||||
##### Info
|
||||
|
||||
Represents bank account. Contains properties:
|
||||
|
||||
1. `$bankName` - name of bank
|
||||
2. `$accountNumber` - number of bank's account
|
||||
|
||||
##### New instance
|
||||
|
||||
New instance can be created using constructor
|
||||
|
||||
```php
|
||||
new BankAccount('Bank of America', '1234567890')
|
||||
```
|
||||
|
||||
##### Methods
|
||||
|
||||
Has getters for each property `getBankName()` and `getAccountNumber()`.
|
||||
|
||||
##### Conversion to string (the `__toString()` method)
|
||||
|
||||
Instance of `BankAccount` may be represented as string that contains all non-empty properties separated by `, `.
|
||||
|
||||
Example:
|
||||
|
||||
```php
|
||||
$bank = new BankAccount('Bank of America', '1234567890');
|
||||
$asString = (string)$bank; // "Bank of America, 1234567890"
|
||||
```
|
||||
|
||||
### Company
|
||||
|
||||
##### Namespace
|
||||
|
||||
`Meritoo\Common\ValueObject\Company`
|
||||
|
||||
##### Info
|
||||
|
||||
Represents a company. Contains properties:
|
||||
|
||||
1. `$name` - name of company
|
||||
2. `$address` - address of company
|
||||
3. `$bankAccount` - bank account of company
|
||||
|
||||
##### New instance
|
||||
|
||||
New instance can be created using constructor:
|
||||
|
||||
```php
|
||||
new Company(
|
||||
'Test 1',
|
||||
new Address('New York', '00123', '4th Avenue', '10', '200'),
|
||||
new BankAccount('Bank 1', '12345')
|
||||
);
|
||||
```
|
||||
|
||||
##### Methods
|
||||
|
||||
Has getters for each property `getName()`, `getAddress()` and `getBankAccount()`.
|
||||
|
||||
##### Conversion to string (the `__toString()` method)
|
||||
|
||||
Instance of `Company` may be represented as string that contains all non-empty properties separated by `, `.
|
||||
|
||||
Example:
|
||||
|
||||
```php
|
||||
$company = new Company(
|
||||
'Test 1',
|
||||
new Address('New York', '00123', '4th Avenue', '10', '200'),
|
||||
new BankAccount('Bank 1', '12345')
|
||||
);
|
||||
|
||||
$asString = (string)$company; // "Test 1, 4th Avenue 10/200, 00123, New York, Bank 1, 12345"
|
||||
```
|
||||
|
||||
### Human
|
||||
|
||||
##### Namespace
|
||||
|
||||
`Meritoo\Common\ValueObject\Human`
|
||||
|
||||
##### Info
|
||||
|
||||
Represents human. Based on `\Meritoo\Common\Traits\ValueObject\HumanTrait` trait. Contains properties same
|
||||
as `HumanTrait` trait:
|
||||
|
||||
1. `$firstName` - first name
|
||||
2. `$lastName` - last name
|
||||
3. `$email` - email address
|
||||
4. `$birthDate` - birth date
|
||||
|
||||
##### New instance
|
||||
|
||||
New instance can be created using constructor:
|
||||
|
||||
```php
|
||||
new Human('John', 'Scott', 'john@scott.com', new \DateTime('2001-01-01'));
|
||||
```
|
||||
|
||||
##### Methods
|
||||
|
||||
Has getters for each property, e.g. `getFirstName()`, `getEmail()` etc.
|
||||
|
||||
##### Conversion to string (the `__toString()` method)
|
||||
|
||||
Instance of `Human` may be represented as string that contains first name, last name and email address (if provided).
|
||||
|
||||
Example:
|
||||
|
||||
```php
|
||||
$human1 = new Human('John', 'Scott');
|
||||
$asString1 = (string)$human1; // "John Scott"
|
||||
|
||||
$human2 = new Human('John', 'Scott', 'john@scott.com', new \DateTime('2001-01-01'));
|
||||
$asString2 = (string)$human2; // "John Scott <john@scott.com>"
|
||||
```
|
||||
|
||||
### Size
|
||||
|
||||
##### Namespace
|
||||
|
||||
`Meritoo\Common\ValueObject\Size`
|
||||
|
||||
##### Info
|
||||
|
||||
Size, e.g. of image. Contains properties:
|
||||
|
||||
1. `width` - the width
|
||||
2. `height` - the height
|
||||
3. `unit` - unit used when width or height should be returned with unit, default: `"px"`
|
||||
4. `separator` - separator used when converting to string, default: `" x "`
|
||||
|
||||
##### New instance
|
||||
|
||||
New instance can be created using static methods:
|
||||
|
||||
1. `fromArray()` - creates new instance from given array
|
||||
|
||||
```php
|
||||
// Using default "px" unit
|
||||
Size::fromArray([200, 100]);
|
||||
|
||||
// With custom "mm" unit
|
||||
Size::fromArray([200, 100], 'mm');
|
||||
```
|
||||
|
||||
2. `fromString()` - creates new instance from given string
|
||||
|
||||
```php
|
||||
// Using default "px" unit and default " x " separator
|
||||
Size::fromString('200 x 100');
|
||||
|
||||
// With custom "mm" unit and " X " separator
|
||||
Size::fromString('200 X 100', 'mm', ' X ');
|
||||
```
|
||||
|
||||
##### Methods
|
||||
|
||||
Has:
|
||||
|
||||
- getters and setters for `width` and `height` properties.
|
||||
- setter for `separator` property
|
||||
- `toString()` and `toArray()` methods that returns size represented as string and array
|
||||
|
||||
##### Conversion to string (using `__toString()` method)
|
||||
|
||||
Instance of `Size` may be represented as string that contains width and height separated by separator (default: `" x "`)
|
||||
.
|
||||
|
||||
Example:
|
||||
|
||||
```php
|
||||
$size = Size::fromArray([200, 100]);
|
||||
|
||||
// With default separator
|
||||
$asString1 = (string)$size; // "200 x 100"
|
||||
|
||||
// With custom separator
|
||||
$size->setSeparator('X');
|
||||
$asString2 = (string)$size; // "200X100"
|
||||
```
|
||||
|
||||
### Template
|
||||
|
||||
##### Namespace
|
||||
|
||||
`Meritoo\Common\ValueObject\Template`
|
||||
|
||||
##### Info
|
||||
|
||||
Template with placeholders that may be filled by real data. Contains properties:
|
||||
|
||||
1. `$content` - raw string with placeholders (content of the template)
|
||||
|
||||
##### New instance
|
||||
|
||||
New instance can be created using constructor:
|
||||
|
||||
```php
|
||||
new Template('First name: %first_name%');
|
||||
```
|
||||
|
||||
Each placeholder should be wrapped by `%` character, e.g. `%first_name%`. If content of template is an empty string or
|
||||
does not contain 1 placeholder at least, an `Meritoo\Common\Exception\ValueObject\Template\InvalidContentException`
|
||||
exception will be thrown.
|
||||
|
||||
Examples of invalid content of template:
|
||||
|
||||
```php
|
||||
new Template(''); // An empty string
|
||||
new Template('test'); // Without placeholders
|
||||
new Template('This is %test'); // With starting tag only (invalid placeholder)
|
||||
```
|
||||
|
||||
##### Methods
|
||||
|
||||
Has 1 public method: `fill(array $values)`. Returns content of the template filled with given values (by replacing
|
||||
placeholders with their proper values).
|
||||
|
||||
Example of usage:
|
||||
|
||||
```php
|
||||
$template = new Template('My name is %name% and I am %profession%');
|
||||
$result = $template->fill([
|
||||
'name' => 'Jane',
|
||||
'profession' => 'photographer',
|
||||
]); // "My name is Jane and I am photographer"
|
||||
```
|
||||
|
||||
Throws an `Meritoo\Common\Exception\ValueObject\Template\NotEnoughValuesException` exception if there is not enough
|
||||
values (iow. more placeholders than values).
|
||||
|
||||
### Version
|
||||
|
||||
##### Namespace
|
||||
|
||||
`Meritoo\Common\ValueObject\Version`
|
||||
|
||||
##### Info
|
||||
|
||||
Represents version of software. Contains properties:
|
||||
|
||||
1. `$majorPart` - the "major" part of version
|
||||
2. `$minorPart` - the "minor" part of version
|
||||
3. `$patchPart` - the "patch" part of version
|
||||
|
||||
##### New instance
|
||||
|
||||
New instance can be created using:
|
||||
|
||||
1. Constructor:
|
||||
|
||||
```php
|
||||
new Version(1, 0, 2);
|
||||
```
|
||||
|
||||
2. Static methods:
|
||||
1. `fromArray(array $version)` - creates new instance using given version as array
|
||||
|
||||
```php
|
||||
Version::fromArray([1, 0, 2]);
|
||||
```
|
||||
|
||||
2. `fromString(string $version)` - creates new instance using given version as string:
|
||||
|
||||
```php
|
||||
Version::fromString('1.0.2');
|
||||
```
|
||||
|
||||
##### Methods
|
||||
|
||||
Has getters for each property: `getMajorPart()`, `getMinorPart()`, `getPatchPart()`.
|
||||
|
||||
##### Conversion to string (using `__toString()` method)
|
||||
|
||||
Instance of `Version` may be represented as string that contains all properties separated by `.` (`$majorPart`
|
||||
.`$minorPart`.`$patchPart`).
|
||||
|
||||
Example:
|
||||
|
||||
```php
|
||||
$version = new Version(1, 0, 2);
|
||||
$asString = (string)$version; // "1.0.2"
|
||||
```
|
||||
|
||||
# More
|
||||
|
||||
1. [Base test case (with common methods and data providers)](Base-test-case.md)
|
||||
2. [Collection of elements](Collection/BaseCollection.md)
|
||||
3. [Templates](Collection/Templates.md)
|
||||
4. [Exceptions](Exceptions.md)
|
||||
5. [Static methods](Static-methods.md)
|
||||
1. [Arrays](Static-methods/Arrays.md)
|
||||
2. [Regex](Static-methods/Regex.md)
|
||||
3. [Uri](Static-methods/Uri.md)
|
||||
6. [**Value Objects**](Value-Objects.md)
|
||||
|
||||
[‹ Back to `Readme`](../README.md)
|
||||
13
infection.json.dist
Normal file
13
infection.json.dist
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"timeout": 10,
|
||||
"source": {
|
||||
"directories": [
|
||||
"src"
|
||||
]
|
||||
},
|
||||
"logs": {
|
||||
"text": "build/reports/infection/infection-log.txt",
|
||||
"summary": "build/reports/infection/summary-log.txt",
|
||||
"debug": "build/reports/infection/debug-log.txt"
|
||||
}
|
||||
}
|
||||
179
phing/app.xml
Normal file
179
phing/app.xml
Normal file
@@ -0,0 +1,179 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
|
||||
<!-- Properties -->
|
||||
<if>
|
||||
<available file="${project.basedir}/phing/properties" property="custom.properties.available" />
|
||||
<then>
|
||||
<property file="${project.basedir}/phing/properties" />
|
||||
</then>
|
||||
<else>
|
||||
<property file="${project.basedir}/phing/properties.dist" />
|
||||
</else>
|
||||
</if>
|
||||
|
||||
<!-- Filesets -->
|
||||
<import file="${project.basedir}/phing/filesets.xml" />
|
||||
|
||||
<!-- Default / main target -->
|
||||
<target name="build:main"
|
||||
depends="build:app"
|
||||
/>
|
||||
|
||||
<!-- App target -->
|
||||
<target name="build:app"
|
||||
depends="app:clean,
|
||||
app:composer:self-update,
|
||||
app:composer:install,
|
||||
app:composer:validate,
|
||||
app:checkout"
|
||||
/>
|
||||
|
||||
<!-- Updates Composer -->
|
||||
<target name="app:composer:self-update">
|
||||
<if>
|
||||
<not>
|
||||
<available file="${composer.path}" property="composer.local.unavailable" />
|
||||
</not>
|
||||
<then>
|
||||
<if>
|
||||
<os family="windows" />
|
||||
<then>
|
||||
<fail message="Composer not found! Go to http://getcomposer.org/download and download the Composer." />
|
||||
</then>
|
||||
<else>
|
||||
<exec command="${composer.download_command}" checkreturn="true" passthru="true" />
|
||||
</else>
|
||||
</if>
|
||||
</then>
|
||||
</if>
|
||||
|
||||
<!-- Update Composer -->
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="selfupdate">
|
||||
<arg value="--ansi" />
|
||||
</composer>
|
||||
</target>
|
||||
|
||||
<!-- Validates composer.* files -->
|
||||
<target name="app:composer:validate" depends="app:composer:install">
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="validate">
|
||||
<arg value="--no-check-all" />
|
||||
<arg value="--strict" />
|
||||
<arg value="--ansi" />
|
||||
</composer>
|
||||
</target>
|
||||
|
||||
<!-- Project clean -->
|
||||
<target name="app:clean">
|
||||
<if>
|
||||
<equals arg1="${env}" arg2="prod" />
|
||||
<then>
|
||||
<echo message="[Skipped] Cleaning project (and directories cleanup) -> 'prod' environment" />
|
||||
</then>
|
||||
<else>
|
||||
<foreach list="${directoriesToEmpty}" param="directory" target="app:clean:empty" />
|
||||
</else>
|
||||
</if>
|
||||
|
||||
<foreach list="${directoriesToCheck}" param="directory" target="app:clean:check" />
|
||||
<foreach list="${directoriesToEmpty}" param="directory" target="app:permissions" />
|
||||
</target>
|
||||
|
||||
<!-- Cleaning directory (making empty) directory -->
|
||||
<target name="app:clean:empty">
|
||||
<if>
|
||||
<available file="${directory}" type="dir" property="dir_is_available" />
|
||||
<then>
|
||||
<delete includeemptydirs="true" dir="${directory}" />
|
||||
</then>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<!-- Checking if directory exists -->
|
||||
<target name="app:clean:check">
|
||||
<if>
|
||||
<not>
|
||||
<available file="${directory}" type="dir" property="dir_is_available" />
|
||||
</not>
|
||||
<then>
|
||||
<if>
|
||||
<or>
|
||||
<contains string="${directory}" substring="cache" />
|
||||
<contains string="${directory}" substring="logs" />
|
||||
<contains string="${directory}" substring="sessions" />
|
||||
</or>
|
||||
<then>
|
||||
<mkdir dir="${directory}" mode="0777" />
|
||||
</then>
|
||||
<else>
|
||||
<mkdir dir="${directory}" mode="0775" />
|
||||
</else>
|
||||
</if>
|
||||
</then>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<!-- Installs vendors -->
|
||||
<target name="app:composer:install" depends="app:composer:self-update">
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="install">
|
||||
<arg value="--optimize-autoloader" />
|
||||
<arg value="--ansi" />
|
||||
</composer>
|
||||
</target>
|
||||
|
||||
<!-- Clearing cache -->
|
||||
<target name="app:cache">
|
||||
<if>
|
||||
<istrue value="${cache.clearWithWarmup}" />
|
||||
<then>
|
||||
<SymfonyConsole console="bin/console" command="cache:clear">
|
||||
<arg name="env" value="${env}" />
|
||||
</SymfonyConsole>
|
||||
</then>
|
||||
<else>
|
||||
<SymfonyConsole console="bin/console" command="cache:clear">
|
||||
<arg name="env" value="${env}" />
|
||||
<arg name="no-warmup" />
|
||||
</SymfonyConsole>
|
||||
</else>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<!-- Clearing cache (faster) -->
|
||||
<target name="app:cache:faster">
|
||||
<SymfonyConsole console="bin/console" command="cache:clear">
|
||||
<arg name="env" value="${env}" />
|
||||
<arg name="no-optional-warmers" />
|
||||
</SymfonyConsole>
|
||||
</target>
|
||||
|
||||
<!-- Warming up cache -->
|
||||
<target name="app:cache:warmup">
|
||||
<SymfonyConsole console="bin/console" command="cache:warmup">
|
||||
<arg name="env" value="${env}" />
|
||||
</SymfonyConsole>
|
||||
</target>
|
||||
|
||||
<!-- Setting permissions of given directory -->
|
||||
<target name="app:permissions">
|
||||
<if>
|
||||
<not>
|
||||
<os family="windows" />
|
||||
</not>
|
||||
<then>
|
||||
<exec command="chmod -R 777 ${directory}/*" />
|
||||
</then>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<!-- Checkout and finalization -->
|
||||
<target name="app:checkout">
|
||||
<tstamp>
|
||||
<format property="date_end" pattern="%Y-%m-%d %H:%M" />
|
||||
</tstamp>
|
||||
|
||||
<echo msg="------------------------------------" />
|
||||
<echo msg="Build finished at: ${date_end}" />
|
||||
<echo msg="------------------------------------" />
|
||||
</target>
|
||||
</project>
|
||||
20
phing/composer-install.sh
Normal file
20
phing/composer-install.sh
Normal file
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
|
||||
EXPECTED_SIGNATURE="$(curl -L https://composer.github.io/installer.sig)"
|
||||
# Original line (with wget):
|
||||
# EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"
|
||||
|
||||
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
ACTUAL_SIGNATURE="$(php -r "echo hash_file('SHA384', 'composer-setup.php');")"
|
||||
|
||||
if [[ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]]
|
||||
then
|
||||
>&2 echo 'ERROR: Invalid installer signature'
|
||||
rm composer-setup.php
|
||||
exit 1
|
||||
fi
|
||||
|
||||
php composer-setup.php --quiet
|
||||
RESULT=$?
|
||||
rm composer-setup.php
|
||||
exit ${RESULT}
|
||||
14
phing/filesets.xml
Normal file
14
phing/filesets.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
|
||||
<!-- Directories to check -->
|
||||
<property name="directoriesToCheck" value="
|
||||
${dir.data.tests},
|
||||
${dir.data.temporary}"
|
||||
/>
|
||||
|
||||
<!-- Directories to empty -->
|
||||
<property name="directoriesToEmpty" value="
|
||||
${dir.data.temporary}"
|
||||
/>
|
||||
</project>
|
||||
89
phing/properties.dist
Normal file
89
phing/properties.dist
Normal file
@@ -0,0 +1,89 @@
|
||||
# --------------------------------------------------------------------------------
|
||||
# Common, e.g. default environment
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# Default environment
|
||||
#
|
||||
env = dev
|
||||
|
||||
# Clear cache with the "warmup" option
|
||||
#
|
||||
# The cache:clear command should always be called with the --no-warmup option. Warmup should be done via the cache:warmup command.
|
||||
# https://github.com/symfony/symfony/blob/master/UPGRADE-3.3.md#frameworkbundle
|
||||
#
|
||||
# Meritoo <github@meritoo.pl>
|
||||
# 2017-06-06
|
||||
#
|
||||
cache.clearWithWarmup = false
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Composer
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# Command used to download Composer
|
||||
#
|
||||
composer.download_command = bash ${project.basedir}/phing/composer-install.sh
|
||||
|
||||
# Path to Composer executable or downloaded composer.phar file
|
||||
#
|
||||
composer.path = ${project.basedir}/composer.phar
|
||||
|
||||
# Path to PHP executable used by Composer
|
||||
#
|
||||
composer.php = php
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Directories
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# System directories
|
||||
#
|
||||
dir.src = ${project.basedir}/src
|
||||
dir.data = ${project.basedir}/data
|
||||
dir.tests = ${project.basedir}/tests
|
||||
|
||||
# Build directories
|
||||
#
|
||||
dir.build = ${project.basedir}/build
|
||||
dir.reports = ${dir.build}/reports
|
||||
dir.reports.coverage = ${dir.reports}/phpunit-coverage
|
||||
dir.reports.code_sniffer = ${dir.reports}/code_sniffer
|
||||
|
||||
# Data directories
|
||||
#
|
||||
dir.data.tests = ${dir.data}/tests
|
||||
dir.data.temporary = ${dir.data}/tmp
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Static Analysis
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# Paths of frameworks used to run analysis:
|
||||
# - PHPStan
|
||||
#
|
||||
check.phpstan.command = ./vendor/bin/phpstan analyse
|
||||
check.psalm.command = ./vendor/bin/psalm --report=build/reports/psalm.json
|
||||
check.php_coveralls.command = ./vendor/bin/php-coveralls --ansi -v
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Testing
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# Path of the PHP Coding Standards Fixer (http://cs.sensiolabs.org)
|
||||
#
|
||||
tests.cs_fixer.command = ./vendor/bin/php-cs-fixer fix --verbose
|
||||
|
||||
# Path of the PHP_CodeSniffer (https://github.com/squizlabs/PHP_CodeSniffer)
|
||||
#
|
||||
tests.code_sniffer.command = ./vendor/bin/phpcs --report-full=${dir.reports.code_sniffer}/full.txt --report-summary=${dir.reports.code_sniffer}/summary.txt --report-checkstyle=${dir.reports.code_sniffer}/checkstyle.xml
|
||||
|
||||
# Test database path
|
||||
#
|
||||
tests.database = ${dir.data.temporary}/database.sqlite
|
||||
|
||||
# Paths of frameworks used to run tests:
|
||||
# - PHPUnit (unit tests)
|
||||
# - Infection (mutation tests)
|
||||
#
|
||||
tests.phpunit.command = ./vendor/bin/phpunit --verbose
|
||||
tests.mutation.command = ./vendor/bin/infection --ansi --threads=$(nproc) --coverage=build/reports/infection
|
||||
123
phing/tests.xml
Normal file
123
phing/tests.xml
Normal file
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
|
||||
<autoloader />
|
||||
|
||||
<!-- Properties -->
|
||||
<if>
|
||||
<available file="${project.basedir}/phing/properties" property="custom.properties.available" />
|
||||
<then>
|
||||
<property file="${project.basedir}/phing/properties" />
|
||||
</then>
|
||||
<else>
|
||||
<property file="${project.basedir}/phing/properties.dist" />
|
||||
</else>
|
||||
</if>
|
||||
|
||||
<!-- Filesets -->
|
||||
<fileset id="sourcecode" dir="${dir.src}">
|
||||
<include name="**/*.php" />
|
||||
<exclude name="*Test.php" />
|
||||
<exclude name="**/*Test.php" />
|
||||
<exclude name="**/Resources/**" />
|
||||
<exclude name="**/DataFixtures/**" />
|
||||
<exclude name="**/Tests/**" />
|
||||
</fileset>
|
||||
<fileset id="tests" dir="${dir.tests}">
|
||||
<include name="**/*Test*.php" />
|
||||
</fileset>
|
||||
|
||||
<!-- Default / main target -->
|
||||
<target name="build:main"
|
||||
depends="build:fix-coding-standards,
|
||||
build:check,
|
||||
build:test,
|
||||
app:checkout"
|
||||
/>
|
||||
|
||||
<!-- Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org) -->
|
||||
<target name="build:fix-coding-standards">
|
||||
<exec command="${tests.cs_fixer.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- Check target -->
|
||||
<target name="build:check"
|
||||
depends="check:cs,
|
||||
check:cpd,
|
||||
check:phpstan,
|
||||
check:psalm,
|
||||
check:coveralls"
|
||||
/>
|
||||
|
||||
<!-- Test target -->
|
||||
<target name="build:test"
|
||||
depends="test:phpunit,
|
||||
test:infection"
|
||||
/>
|
||||
|
||||
<!-- PHP_CodeSniffer -->
|
||||
<target name="check:cs" depends="build:prepare">
|
||||
<exec command="${tests.code_sniffer.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- copy/paste detector -->
|
||||
<target name="check:cpd" depends="build:prepare">
|
||||
<phpcpd>
|
||||
<fileset refid="sourcecode" />
|
||||
<formatter type="pmd" outfile="${dir.reports}/copy-paste-detector.xml" />
|
||||
</phpcpd>
|
||||
</target>
|
||||
|
||||
<!-- Run static analysis -->
|
||||
<target name="check:phpstan" depends="build:prepare">
|
||||
<exec command="${check.phpstan.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- Run static analysis -->
|
||||
<target name="check:psalm" depends="build:prepare">
|
||||
<exec command="${check.psalm.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- Run analysis of code coverage -->
|
||||
<target name="check:coveralls" depends="test:phpunit">
|
||||
<exec command="${check.php_coveralls.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- PHPUnit tests -->
|
||||
<target name="test:phpunit" depends="build:prepare">
|
||||
<exec command="${tests.phpunit.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- Run mutation testing -->
|
||||
<target name="test:infection" depends="test:phpunit">
|
||||
<exec command="${tests.mutation.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- Project build clean -->
|
||||
<target name="build:clean">
|
||||
<if>
|
||||
<available file="${dir.reports}" type="dir" property="dir_is_available" />
|
||||
<then>
|
||||
<delete dir="${dir.reports}" />
|
||||
</then>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<!-- Project build prepare -->
|
||||
<target name="build:prepare" depends="build:clean">
|
||||
<mkdir dir="${dir.reports}" />
|
||||
<mkdir dir="${dir.reports.coverage}" />
|
||||
<mkdir dir="${dir.reports.code_sniffer}" />
|
||||
</target>
|
||||
|
||||
<!-- Checkout and finalization -->
|
||||
<target name="app:checkout">
|
||||
<tstamp>
|
||||
<format property="date_end" pattern="%Y-%m-%d %H:%M" />
|
||||
</tstamp>
|
||||
|
||||
<echo msg="--------------------------------------------" />
|
||||
<echo msg="Build tests finished at: ${date_end}" />
|
||||
<echo msg="--------------------------------------------" />
|
||||
</target>
|
||||
</project>
|
||||
16
phpcs.xml.dist
Normal file
16
phpcs.xml.dist
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
|
||||
|
||||
<arg name="basepath" value="."/>
|
||||
<arg name="cache" value=".phpcs-cache"/>
|
||||
<arg name="colors"/>
|
||||
<arg name="extensions" value="php"/>
|
||||
|
||||
<rule ref="PSR2"/>
|
||||
|
||||
<file>src/</file>
|
||||
<file>tests/</file>
|
||||
|
||||
</ruleset>
|
||||
5
phpstan.neon.dist
Normal file
5
phpstan.neon.dist
Normal file
@@ -0,0 +1,5 @@
|
||||
parameters:
|
||||
level: 1
|
||||
paths:
|
||||
- src
|
||||
- tests
|
||||
@@ -1,35 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
<!-- https://phpunit.readthedocs.io/en/8.2/configuration.html -->
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="true"
|
||||
bootstrap="./vendor/autoload.php"
|
||||
executionOrder="random"
|
||||
forceCoversAnnotation="true"
|
||||
verbose="true"
|
||||
>
|
||||
<coverage>
|
||||
<include>
|
||||
<directory>src</directory>
|
||||
</include>
|
||||
<report>
|
||||
<clover outputFile="build/reports/coveralls/clover.xml" />
|
||||
<html outputDirectory="build/reports/phpunit-coverage/html" />
|
||||
<xml outputDirectory="build/reports/infection/coverage-xml" />
|
||||
</report>
|
||||
</coverage>
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1" />
|
||||
</php>
|
||||
<testsuites>
|
||||
<testsuite name="Meritoo Package - Main Test Suite">
|
||||
<directory>./tests/</directory>
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
<testsuite name="Collection">
|
||||
<directory>tests/Collection</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./src/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<groups>
|
||||
<exclude>
|
||||
<group>performance</group>
|
||||
</exclude>
|
||||
</groups>
|
||||
|
||||
<logging>
|
||||
<log type="coverage-html" target="./.build/logs/phpunit_coverage/html" />
|
||||
<junit outputFile="build/reports/infection/phpunit.junit.xml" />
|
||||
</logging>
|
||||
</phpunit>
|
||||
|
||||
53
psalm.xml
Normal file
53
psalm.xml
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
totallyTyped="false"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config file:///project/vendor/vimeo/psalm/config.xsd"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
<ignoreFiles>
|
||||
<directory name="vendor" />
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
|
||||
<issueHandlers>
|
||||
<LessSpecificReturnType errorLevel="info" />
|
||||
|
||||
<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
|
||||
|
||||
<DeprecatedMethod errorLevel="info" />
|
||||
<DeprecatedProperty errorLevel="info" />
|
||||
<DeprecatedClass errorLevel="info" />
|
||||
<DeprecatedConstant errorLevel="info" />
|
||||
<DeprecatedInterface errorLevel="info" />
|
||||
<DeprecatedTrait errorLevel="info" />
|
||||
|
||||
<InternalMethod errorLevel="info" />
|
||||
<InternalProperty errorLevel="info" />
|
||||
<InternalClass errorLevel="info" />
|
||||
|
||||
<MissingClosureReturnType errorLevel="info" />
|
||||
<MissingReturnType errorLevel="info" />
|
||||
<MissingPropertyType errorLevel="info" />
|
||||
<InvalidDocblock errorLevel="info" />
|
||||
<MisplacedRequiredParam errorLevel="info" />
|
||||
|
||||
<PropertyNotSetInConstructor errorLevel="info" />
|
||||
<MissingConstructor errorLevel="info" />
|
||||
<MissingClosureParamType errorLevel="info" />
|
||||
<MissingParamType errorLevel="info" />
|
||||
|
||||
<RedundantCondition errorLevel="info" />
|
||||
|
||||
<DocblockTypeContradiction errorLevel="info" />
|
||||
<RedundantConditionGivenDocblockType errorLevel="info" />
|
||||
|
||||
<UnresolvableInclude errorLevel="info" />
|
||||
|
||||
<RawObjectIteration errorLevel="info" />
|
||||
|
||||
<InvalidStringClass errorLevel="info" />
|
||||
</issueHandlers>
|
||||
</psalm>
|
||||
349
src/Collection/BaseCollection.php
Normal file
349
src/Collection/BaseCollection.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Collection;
|
||||
|
||||
use ArrayIterator;
|
||||
use Meritoo\Common\Contract\Collection\CollectionInterface;
|
||||
use Meritoo\Common\Utilities\Arrays;
|
||||
|
||||
/**
|
||||
* Collection of elements with the same type
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
abstract class BaseCollection implements CollectionInterface
|
||||
{
|
||||
/**
|
||||
* The elements of collection
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private array $elements;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param array $elements (optional) Elements of collection
|
||||
*/
|
||||
public function __construct(array $elements = [])
|
||||
{
|
||||
$validated = $this->getElementsWithValidType($elements);
|
||||
$this->elements = $this->prepareElements($validated);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add($element, $index = null): void
|
||||
{
|
||||
if (!$this->isValidType($element)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null === $index) {
|
||||
$this->elements[] = $element;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->elements[$index] = $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addMultiple($elements, bool $useIndexes = false): void
|
||||
{
|
||||
if (empty($elements)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$prepared = $this->prepareElements($elements);
|
||||
|
||||
foreach ($prepared as $index => $element) {
|
||||
if ($useIndexes) {
|
||||
$this->add($element, $index);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->add($element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function append($element): void
|
||||
{
|
||||
$this->elements[] = $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear(): void
|
||||
{
|
||||
$this->elements = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
return count($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getByIndex($index)
|
||||
{
|
||||
return $this->elements[$index] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFirst()
|
||||
{
|
||||
return Arrays::getFirstElement($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIterator(): ArrayIterator
|
||||
{
|
||||
return new ArrayIterator($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLast()
|
||||
{
|
||||
return Arrays::getLastElement($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNext($element)
|
||||
{
|
||||
return Arrays::getNextElement($this->elements, $element);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPrevious($element)
|
||||
{
|
||||
return Arrays::getPreviousElement($this->elements, $element);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($element): bool
|
||||
{
|
||||
$index = Arrays::getIndexOf($this->elements, $element);
|
||||
|
||||
return null !== $index && false !== $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isFirst($element): bool
|
||||
{
|
||||
return reset($this->elements) === $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isLast($element): bool
|
||||
{
|
||||
return end($this->elements) === $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function limit(int $max, int $offset = 0): self
|
||||
{
|
||||
$result = clone $this;
|
||||
|
||||
$negativeMax = $max <= 0;
|
||||
$exceededMax = $max >= $this->count();
|
||||
|
||||
if ($negativeMax || $exceededMax) {
|
||||
if ($negativeMax) {
|
||||
$result->clear();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$iteration = -1;
|
||||
|
||||
foreach ($result as $index => $element) {
|
||||
$iteration++;
|
||||
|
||||
if ($iteration >= $offset && $iteration < $offset + $max) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unset($result[$index]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function offsetExists($offset): bool
|
||||
{
|
||||
return $this->exists($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if ($this->exists($offset)) {
|
||||
return $this->elements[$offset];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function offsetSet($offset, $value): void
|
||||
{
|
||||
$this->elements[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function offsetUnset($offset): void
|
||||
{
|
||||
if ($this->exists($offset)) {
|
||||
unset($this->elements[$offset]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepend($element): void
|
||||
{
|
||||
array_unshift($this->elements, $element);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function remove($element): void
|
||||
{
|
||||
if (0 === $this->count()) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->elements as $index => $existing) {
|
||||
if ($element === $existing) {
|
||||
unset($this->elements[$index]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given element has valid type
|
||||
*
|
||||
* @param mixed $element Element of collection
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function isValidType($element): bool;
|
||||
|
||||
/**
|
||||
* Prepares elements to initialize the collection.
|
||||
* Feel free to override and prepare elements in your way.
|
||||
*
|
||||
* @param array $elements The elements of collection to prepare
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareElements(array $elements): array
|
||||
{
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if element with given index/key exists
|
||||
*
|
||||
* @param int|string $index The index/key of element
|
||||
* @return bool
|
||||
*/
|
||||
private function exists($index): bool
|
||||
{
|
||||
return isset($this->elements[$index]) || array_key_exists($index, $this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns elements of collection with valid types
|
||||
*
|
||||
* @param array $elements The elements of collection to verify
|
||||
* @return array
|
||||
*/
|
||||
private function getElementsWithValidType(array $elements): array
|
||||
{
|
||||
if (empty($elements)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($elements as $index => $element) {
|
||||
if (!$this->isValidType($element)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[$index] = $element;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -1,284 +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\Collection;
|
||||
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use Countable;
|
||||
use IteratorAggregate;
|
||||
use Meritoo\Common\Utilities\Arrays;
|
||||
|
||||
/**
|
||||
* Collection of elements.
|
||||
* It's a set of some elements, e.g. objects.
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
*/
|
||||
class Collection implements Countable, ArrayAccess, IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* The elements of collection
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $elements;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param array $elements (optional) The elements of collection
|
||||
*/
|
||||
public function __construct(array $elements = [])
|
||||
{
|
||||
$this->elements = $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Required by interface Countable
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Required by interface ArrayAccess
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->exists($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Required by interface ArrayAccess
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if ($this->exists($offset)) {
|
||||
return $this->elements[$offset];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Required by interface ArrayAccess
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->elements[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Required by interface ArrayAccess
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
if ($this->exists($offset)) {
|
||||
unset($this->elements[$offset]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Required by interface IteratorAggregate
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds given element (at the end of collection)
|
||||
*
|
||||
* @param mixed $element The element to add
|
||||
* @param mixed $index (optional) Index / key of the element
|
||||
* @return $this
|
||||
*/
|
||||
public function add($element, $index = null)
|
||||
{
|
||||
if (null === $index) {
|
||||
$this->elements[] = $element;
|
||||
} else {
|
||||
$this->elements[$index] = $element;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds given elements (at the end of collection)
|
||||
*
|
||||
* @param array|Collection $elements The elements to add
|
||||
* @param bool|false $useIndexes (optional) If is set to true, indexes of given elements will be used in
|
||||
* this collection. Otherwise - not.
|
||||
* @return $this
|
||||
*/
|
||||
public function addMultiple($elements, $useIndexes = false)
|
||||
{
|
||||
if (!empty($elements)) {
|
||||
foreach ($elements as $index => $element) {
|
||||
if (!$useIndexes) {
|
||||
$index = null;
|
||||
}
|
||||
|
||||
$this->add($element, $index);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends given element (adds given element at the beginning of collection)
|
||||
*
|
||||
* @param mixed $element The element to prepend
|
||||
* @return $this
|
||||
*/
|
||||
public function prepend($element)
|
||||
{
|
||||
array_unshift($this->elements, $element);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes given element
|
||||
*
|
||||
* @param mixed $element The element to remove
|
||||
* @return $this
|
||||
*/
|
||||
public function remove($element)
|
||||
{
|
||||
if ($this->count() > 0) {
|
||||
foreach ($this->elements as $index => $existing) {
|
||||
if ($element === $existing) {
|
||||
unset($this->elements[$index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if collection is empty
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return empty($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given element is first in the collection
|
||||
*
|
||||
* @param mixed $element The element to verify
|
||||
* @return bool
|
||||
*/
|
||||
public function isFirst($element)
|
||||
{
|
||||
return reset($this->elements) === $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given element is last in the collection
|
||||
*
|
||||
* @param mixed $element The element to verify
|
||||
* @return bool
|
||||
*/
|
||||
public function isLast($element)
|
||||
{
|
||||
return end($this->elements) === $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if the collection has given element, iow. if given element exists in the collection
|
||||
*
|
||||
* @param mixed $element The element to verify
|
||||
* @return bool
|
||||
*/
|
||||
public function has($element)
|
||||
{
|
||||
$index = Arrays::getIndexOf($this->elements, $element);
|
||||
|
||||
return null !== $index && false !== $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns previous element for given element
|
||||
*
|
||||
* @param mixed $element The element to verify
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getPrevious($element)
|
||||
{
|
||||
return Arrays::getPreviousElement($this->elements, $element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next element for given element
|
||||
*
|
||||
* @param mixed $element The element to verify
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getNext($element)
|
||||
{
|
||||
return Arrays::getNextElement($this->elements, $element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element in the collection
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFirst()
|
||||
{
|
||||
return Arrays::getFirstElement($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element in the collection
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLast()
|
||||
{
|
||||
return Arrays::getLastElement($this->elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the collection
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if element with given index/key exists
|
||||
*
|
||||
* @param string|int $index The index/key of element
|
||||
* @return bool
|
||||
*/
|
||||
private function exists($index)
|
||||
{
|
||||
return isset($this->elements[$index]) || array_key_exists($index, $this->elements);
|
||||
}
|
||||
}
|
||||
27
src/Collection/DateTimeCollection.php
Normal file
27
src/Collection/DateTimeCollection.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Collection;
|
||||
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* Collection of DateTime instances
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class DateTimeCollection extends BaseCollection
|
||||
{
|
||||
protected function isValidType($element): bool
|
||||
{
|
||||
return $element instanceof DateTime;
|
||||
}
|
||||
}
|
||||
25
src/Collection/IntegerCollection.php
Normal file
25
src/Collection/IntegerCollection.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Collection;
|
||||
|
||||
/**
|
||||
* Collection of integers
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class IntegerCollection extends BaseCollection
|
||||
{
|
||||
protected function isValidType($element): bool
|
||||
{
|
||||
return is_int($element);
|
||||
}
|
||||
}
|
||||
25
src/Collection/StringCollection.php
Normal file
25
src/Collection/StringCollection.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Collection;
|
||||
|
||||
/**
|
||||
* Collection of strings
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class StringCollection extends BaseCollection
|
||||
{
|
||||
protected function isValidType($element): bool
|
||||
{
|
||||
return is_string($element);
|
||||
}
|
||||
}
|
||||
72
src/Collection/Templates.php
Normal file
72
src/Collection/Templates.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Collection;
|
||||
|
||||
use Meritoo\Common\Exception\ValueObject\Template\TemplateNotFoundException;
|
||||
use Meritoo\Common\ValueObject\Template;
|
||||
|
||||
/**
|
||||
* Collection/storage of templates
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class Templates extends BaseCollection
|
||||
{
|
||||
/**
|
||||
* Finds and returns template with given index
|
||||
*
|
||||
* @param string $index Index that contains required template
|
||||
* @return Template
|
||||
* @throws TemplateNotFoundException
|
||||
*/
|
||||
public function findTemplate(string $index): Template
|
||||
{
|
||||
$template = $this->getByIndex($index);
|
||||
|
||||
if ($template instanceof Template) {
|
||||
return $template;
|
||||
}
|
||||
|
||||
// Oops, template not found
|
||||
throw TemplateNotFoundException::create($index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns the collection from given array
|
||||
*
|
||||
* @param array $templates Pairs of key-value where: key - template's index, value - template's content
|
||||
* @return Templates
|
||||
*/
|
||||
public static function fromArray(array $templates): Templates
|
||||
{
|
||||
// No templates. Nothing to do.
|
||||
if (empty($templates)) {
|
||||
return new static();
|
||||
}
|
||||
|
||||
$result = new static();
|
||||
|
||||
foreach ($templates as $index => $template) {
|
||||
$result->add(new Template($template), $index);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function isValidType($element): bool
|
||||
{
|
||||
return $element instanceof Template;
|
||||
}
|
||||
}
|
||||
55
src/Contract/Collection/AddableCollectionInterface.php
Normal file
55
src/Contract/Collection/AddableCollectionInterface.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Contract\Collection;
|
||||
|
||||
/**
|
||||
* Contract for collection that may add elements
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
interface AddableCollectionInterface
|
||||
{
|
||||
/**
|
||||
* Adds given element (at the end of collection)
|
||||
*
|
||||
* @param mixed $element The element to add
|
||||
* @param mixed $index (optional) Index / key of the element
|
||||
* @return void
|
||||
*/
|
||||
public function add($element, $index = null): void;
|
||||
|
||||
/**
|
||||
* Adds given elements (at the end of collection)
|
||||
*
|
||||
* @param array|CollectionInterface $elements The elements to add
|
||||
* @param bool $useIndexes (optional) If is set to true, indexes of given elements will be
|
||||
* used in this collection. Otherwise - not.
|
||||
* @return void
|
||||
*/
|
||||
public function addMultiple(array $elements, bool $useIndexes = false): void;
|
||||
|
||||
/**
|
||||
* Appends given element (adds given element at the end of collection)
|
||||
*
|
||||
* @param mixed $element The element to add at the end
|
||||
* @return void
|
||||
*/
|
||||
public function append($element): void;
|
||||
|
||||
/**
|
||||
* Prepends given element (adds given element at the beginning of collection)
|
||||
*
|
||||
* @param mixed $element The element to add at the beginning
|
||||
* @return void
|
||||
*/
|
||||
public function prepend($element): void;
|
||||
}
|
||||
27
src/Contract/Collection/ClearableCollectionInterface.php
Normal file
27
src/Contract/Collection/ClearableCollectionInterface.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Contract\Collection;
|
||||
|
||||
/**
|
||||
* Contract for collection that may be cleared (all its elements may be removed)
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
interface ClearableCollectionInterface
|
||||
{
|
||||
/**
|
||||
* Removes all elements of the collection
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clear(): void;
|
||||
}
|
||||
32
src/Contract/Collection/CollectionInterface.php
Normal file
32
src/Contract/Collection/CollectionInterface.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Contract\Collection;
|
||||
|
||||
use ArrayAccess;
|
||||
use IteratorAggregate;
|
||||
|
||||
/**
|
||||
* Contract for collection of elements with the same type
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
interface CollectionInterface extends ArrayAccess, IteratorAggregate, AddableCollectionInterface,
|
||||
RemovableCollectionInterface, CountableCollectionInterface, ClearableCollectionInterface,
|
||||
GettableCollectionInterface, VerifiableCollectionInterface, ReducibleCollectionInterface
|
||||
{
|
||||
/**
|
||||
* Returns representation of object as array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array;
|
||||
}
|
||||
23
src/Contract/Collection/CountableCollectionInterface.php
Normal file
23
src/Contract/Collection/CountableCollectionInterface.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Contract\Collection;
|
||||
|
||||
use Countable;
|
||||
|
||||
/**
|
||||
* Contract for collection that may count its elements
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
interface CountableCollectionInterface extends Countable
|
||||
{
|
||||
}
|
||||
58
src/Contract/Collection/GettableCollectionInterface.php
Normal file
58
src/Contract/Collection/GettableCollectionInterface.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Contract\Collection;
|
||||
|
||||
/**
|
||||
* Contract for collection that returns first, last element etc.
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
interface GettableCollectionInterface
|
||||
{
|
||||
/**
|
||||
* Returns element with given index
|
||||
*
|
||||
* @param mixed $index Index / key of element to return
|
||||
* @return mixed
|
||||
*/
|
||||
public function getByIndex($index);
|
||||
|
||||
/**
|
||||
* Returns first element
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFirst();
|
||||
|
||||
/**
|
||||
* Returns last element
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLast();
|
||||
|
||||
/**
|
||||
* Returns element next after given element
|
||||
*
|
||||
* @param mixed $element The element whose next element should be returned
|
||||
* @return mixed
|
||||
*/
|
||||
public function getNext($element);
|
||||
|
||||
/**
|
||||
* Returns element preceding given element
|
||||
*
|
||||
* @param mixed $element The element whose previous element should be returned
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPrevious($element);
|
||||
}
|
||||
29
src/Contract/Collection/ReducibleCollectionInterface.php
Normal file
29
src/Contract/Collection/ReducibleCollectionInterface.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Contract\Collection;
|
||||
|
||||
/**
|
||||
* Contract for collection that may reduce its elements
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
interface ReducibleCollectionInterface
|
||||
{
|
||||
/**
|
||||
* Returns new instance of this collection with limited elements
|
||||
*
|
||||
* @param int $max Maximum elements to return
|
||||
* @param int $offset (optional) Position of element from which limitation should start
|
||||
* @return $this
|
||||
*/
|
||||
public function limit(int $max, int $offset = 0): self;
|
||||
}
|
||||
28
src/Contract/Collection/RemovableCollectionInterface.php
Normal file
28
src/Contract/Collection/RemovableCollectionInterface.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Contract\Collection;
|
||||
|
||||
/**
|
||||
* Contract for collection that may remove elements
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
interface RemovableCollectionInterface
|
||||
{
|
||||
/**
|
||||
* Removes given element
|
||||
*
|
||||
* @param mixed $element The element to remove
|
||||
* @return void
|
||||
*/
|
||||
public function remove($element): void;
|
||||
}
|
||||
51
src/Contract/Collection/VerifiableCollectionInterface.php
Normal file
51
src/Contract/Collection/VerifiableCollectionInterface.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Contract\Collection;
|
||||
|
||||
/**
|
||||
* Contract for collection that may verify its elements
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
interface VerifiableCollectionInterface
|
||||
{
|
||||
/**
|
||||
* Returns information if given element exists in collection
|
||||
*
|
||||
* @param mixed $element The element to verify
|
||||
* @return bool
|
||||
*/
|
||||
public function has($element): bool;
|
||||
|
||||
/**
|
||||
* Returns information if collection is empty (has not any element)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty(): bool;
|
||||
|
||||
/**
|
||||
* Returns information if given element is the first element in collection
|
||||
*
|
||||
* @param mixed $element The element to verify
|
||||
* @return bool
|
||||
*/
|
||||
public function isFirst($element): bool;
|
||||
|
||||
/**
|
||||
* Returns information if given element is the last element in collection
|
||||
*
|
||||
* @param mixed $element The element to verify
|
||||
* @return bool
|
||||
*/
|
||||
public function isLast($element): bool;
|
||||
}
|
||||
31
src/Contract/Renderable/RenderableInterface.php
Normal file
31
src/Contract/Renderable/RenderableInterface.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Contract\Renderable;
|
||||
|
||||
use Meritoo\Common\Collection\Templates;
|
||||
|
||||
/**
|
||||
* Interface/Contract of something that may be rendered
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
interface RenderableInterface
|
||||
{
|
||||
/**
|
||||
* Renders this object using given templates
|
||||
*
|
||||
* @param Templates $templates Collection/storage of templates that will be required while rendering this and
|
||||
* related objects, e.g. children of this object
|
||||
* @return string
|
||||
*/
|
||||
public function render(Templates $templates): string;
|
||||
}
|
||||
@@ -15,27 +15,28 @@ use Meritoo\Common\Utilities\Arrays;
|
||||
/**
|
||||
* An exception used while type of something is unknown
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
abstract class UnknownTypeException extends Exception
|
||||
{
|
||||
/**
|
||||
* Class constructor
|
||||
* Creates exception
|
||||
*
|
||||
* @param string|int $unknownType The unknown type of something (value of constant)
|
||||
* @param BaseType $typeInstance An instance of class that contains type of the something
|
||||
* @param string $typeName Name of the something
|
||||
* @param mixed $unknownType The unknown type of something (value of constant)
|
||||
* @param BaseType $typeInstance An instance of class that contains type of the something
|
||||
* @param string $typeName Name of the something
|
||||
* @return UnknownTypeException
|
||||
*/
|
||||
public function __construct($unknownType, BaseType $typeInstance, $typeName)
|
||||
public static function create($unknownType, BaseType $typeInstance, string $typeName): UnknownTypeException
|
||||
{
|
||||
$allTypes = $typeInstance->getAll();
|
||||
$types = Arrays::values2string($allTypes, '', ', ');
|
||||
|
||||
$template = 'The \'%s\' type of %s is unknown. Probably doesn\'t exist or there is a typo. You should use one'
|
||||
. ' of these types: %s.';
|
||||
.' of these types: %s.';
|
||||
|
||||
$message = sprintf(sprintf($template, $unknownType, $typeName, $types));
|
||||
parent::__construct($message);
|
||||
$allTypes = $typeInstance->getAll();
|
||||
$types = Arrays::values2string($allTypes, '', ', ') ?? '[types not found]';
|
||||
$message = sprintf($template, $unknownType, $typeName, $types);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
|
||||
36
src/Exception/Bundle/IncorrectBundleNameException.php
Normal file
36
src/Exception/Bundle/IncorrectBundleNameException.php
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -8,24 +8,27 @@
|
||||
|
||||
namespace Meritoo\Common\Exception\File;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while file with given path is empty (has no content)
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@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
|
||||
* @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?';
|
||||
$message = sprintf($template, $emptyFilePath);
|
||||
|
||||
parent::__construct($message);
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,19 +8,23 @@
|
||||
|
||||
namespace Meritoo\Common\Exception\File;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while path of given file is empty
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class EmptyFilePathException extends \Exception
|
||||
class EmptyFilePathException extends Exception
|
||||
{
|
||||
/**
|
||||
* Class constructor
|
||||
* Creates exception
|
||||
*
|
||||
* @return EmptyFilePathException
|
||||
*/
|
||||
public function __construct()
|
||||
public static function create(): EmptyFilePathException
|
||||
{
|
||||
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?');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,24 +8,27 @@
|
||||
|
||||
namespace Meritoo\Common\Exception\File;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while file with given path does not exist
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@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
|
||||
* @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?';
|
||||
$message = sprintf($template, $notExistingFilePath);
|
||||
|
||||
parent::__construct($message);
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,26 +13,28 @@ use Exception;
|
||||
/**
|
||||
* An exception used while method cannot be called, because is disabled
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class DisabledMethodException extends Exception
|
||||
{
|
||||
/**
|
||||
* Class constructor
|
||||
* Creates exception
|
||||
*
|
||||
* @param string $disabledMethod Name of the disabled 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.';
|
||||
$message = sprintf($template, $disabledMethod);
|
||||
|
||||
if (!empty($alternativeMethod)) {
|
||||
$template .= ' Use %s() instead.';
|
||||
$template = '%s Use %s() instead.';
|
||||
$message = sprintf($template, $message, $alternativeMethod);
|
||||
}
|
||||
|
||||
$message = sprintf($template, $disabledMethod, $alternativeMethod);
|
||||
parent::__construct($message);
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,20 +13,20 @@ use Exception;
|
||||
/**
|
||||
* An exception used while name of class or trait cannot be resolved
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class CannotResolveClassNameException extends Exception
|
||||
{
|
||||
/**
|
||||
* Class constructor
|
||||
* Creates exception
|
||||
*
|
||||
* @param array|object|string $source Source of the class's / trait's name. It can be an array of objects,
|
||||
* namespaces, object or namespace.
|
||||
* @param bool $forClass (optional) If is set to true, message of this exception for class is
|
||||
* prepared. Otherwise - for trait.
|
||||
* @param string $source Source of name of the class or trait
|
||||
* @param bool $forClass (optional) If is set to true, message of this exception for class is prepared. Otherwise
|
||||
* - for trait.
|
||||
* @return CannotResolveClassNameException
|
||||
*/
|
||||
public function __construct($source, $forClass = true)
|
||||
public static function create(string $source, bool $forClass = true): CannotResolveClassNameException
|
||||
{
|
||||
$forWho = 'trait';
|
||||
$value = '';
|
||||
@@ -36,12 +36,12 @@ class CannotResolveClassNameException extends Exception
|
||||
}
|
||||
|
||||
if (is_scalar($source)) {
|
||||
$value = sprintf(' %s', (string)$source);
|
||||
$value = sprintf(' %s', $source);
|
||||
}
|
||||
|
||||
$template = 'Name of %s from given \'%s\'%s cannot be resolved. Is there everything ok?';
|
||||
$message = sprintf($template, $forWho, gettype($source), $value);
|
||||
|
||||
parent::__construct($message);
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\Reflection;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while given class hasn't constructor
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class ClassWithoutConstructorException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates exception
|
||||
*
|
||||
* @param string $className Fully-qualified name of class that hasn't constructor
|
||||
* @return ClassWithoutConstructorException
|
||||
*/
|
||||
public static function create(string $className): ClassWithoutConstructorException
|
||||
{
|
||||
$template = 'Oops, class \'%s\' hasn\'t constructor. Did you use proper class?';
|
||||
$message = sprintf($template, $className);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
@@ -14,25 +14,26 @@ use Meritoo\Common\Utilities\Reflection;
|
||||
/**
|
||||
* An exception used while given class has no child classes
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class MissingChildClassesException extends Exception
|
||||
{
|
||||
/**
|
||||
* Class constructor
|
||||
* Creates exception
|
||||
*
|
||||
* @param array|object|string $parentClass Class that hasn't child classes, but it should. An array of objects,
|
||||
* strings, object or string.
|
||||
* @return MissingChildClassesException
|
||||
*/
|
||||
public function __construct($parentClass)
|
||||
public static function create($parentClass): MissingChildClassesException
|
||||
{
|
||||
$template = 'The \'%s\' class requires one child class at least who will extend her (maybe is an abstract'
|
||||
. ' class), but the child classes are missing. Did you forget to extend this class?';
|
||||
.' class), but the child classes are missing. Did you forget to extend this class?';
|
||||
|
||||
$parentClassName = Reflection::getClassName($parentClass);
|
||||
$parentClassName = Reflection::getClassName($parentClass) ?? '[unknown class]';
|
||||
$message = sprintf($template, $parentClassName);
|
||||
|
||||
parent::__construct($message);
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
|
||||
35
src/Exception/Reflection/NotExistingPropertyException.php
Normal file
35
src/Exception/Reflection/NotExistingPropertyException.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\Reflection;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while property does not exist in instance of class
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class NotExistingPropertyException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates exception
|
||||
*
|
||||
* @param mixed $object Object that should contains given property
|
||||
* @param null|string $property Name of the property
|
||||
* @return NotExistingPropertyException
|
||||
*/
|
||||
public static function create($object, ?string $property): NotExistingPropertyException
|
||||
{
|
||||
$template = 'Property \'%s\' does not exist in instance of class \'%s\'. Did you use proper name of property?';
|
||||
$message = sprintf($template, $property, get_class($object));
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
@@ -14,26 +14,27 @@ use Meritoo\Common\Utilities\Reflection;
|
||||
/**
|
||||
* An exception used while given class has more than one child class
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class TooManyChildClassesException extends Exception
|
||||
{
|
||||
/**
|
||||
* Class constructor
|
||||
* Creates exception
|
||||
*
|
||||
* @param array|object|string $parentClass Class that has more than one child class, but it shouldn't. An array
|
||||
* of objects, strings, object or string.
|
||||
* @param array $childClasses Child classes
|
||||
* @return TooManyChildClassesException
|
||||
*/
|
||||
public function __construct($parentClass, array $childClasses)
|
||||
public static function create($parentClass, array $childClasses): TooManyChildClassesException
|
||||
{
|
||||
$template = "The '%s' class requires one child class at most who will extend her, but more than one child"
|
||||
. " class was found:\n- %s\n\nWhy did you create more than one classes that extend '%s' class?";
|
||||
." class was found:\n- %s\n\nWhy did you create more than one classes that extend '%s' class?";
|
||||
|
||||
$parentClassName = Reflection::getClassName($parentClass);
|
||||
$parentClassName = Reflection::getClassName($parentClass) ?? '[unknown class]';
|
||||
$message = sprintf($template, $parentClassName, implode("\n- ", $childClasses), $parentClassName);
|
||||
|
||||
parent::__construct($message);
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,25 +8,29 @@
|
||||
|
||||
namespace Meritoo\Common\Exception\Regex;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while length of given hexadecimal value of color is incorrect
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class IncorrectColorHexLengthException extends \Exception
|
||||
class IncorrectColorHexLengthException extends Exception
|
||||
{
|
||||
/**
|
||||
* Class constructor
|
||||
* Creates exception
|
||||
*
|
||||
* @param string $color Incorrect hexadecimal value of color
|
||||
* @return IncorrectColorHexLengthException
|
||||
*/
|
||||
public function __construct($color)
|
||||
public static function create($color)
|
||||
{
|
||||
$template = 'Length of hexadecimal value of color \'%s\' is incorrect. It\'s %d, but it should be 3 or 6.'
|
||||
. ' Is there everything ok?';
|
||||
.' Is there everything ok?';
|
||||
|
||||
$message = sprintf($template, $color, strlen($color));
|
||||
parent::__construct($message);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,22 +8,26 @@
|
||||
|
||||
namespace Meritoo\Common\Exception\Regex;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while given hexadecimal value of color is invalid
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@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
|
||||
* @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);
|
||||
parent::__construct($message);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
|
||||
33
src/Exception/Regex/InvalidHtmlAttributesException.php
Normal file
33
src/Exception/Regex/InvalidHtmlAttributesException.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\Regex;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while html attributes are invalid
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class InvalidHtmlAttributesException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates exception
|
||||
*
|
||||
* @param string $htmlAttributes Invalid html attributes
|
||||
* @return InvalidHtmlAttributesException
|
||||
*/
|
||||
public static function create($htmlAttributes)
|
||||
{
|
||||
$message = sprintf('HTML attributes \'%s\' are invalid. Is there everything ok?', $htmlAttributes);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\Regex;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while url is invalid
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@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
|
||||
* @return InvalidUrlException
|
||||
*/
|
||||
public function __construct($url)
|
||||
public static function create($url)
|
||||
{
|
||||
$message = sprintf('Url \'%s\' is invalid. Is there everything ok?', $url);
|
||||
parent::__construct($message);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\Date;
|
||||
namespace Meritoo\Common\Exception\Type;
|
||||
|
||||
use Meritoo\Common\Exception\Base\UnknownTypeException;
|
||||
use Meritoo\Common\Type\DatePartType;
|
||||
@@ -14,19 +14,20 @@ 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
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class UnknownDatePartTypeException extends UnknownTypeException
|
||||
{
|
||||
/**
|
||||
* Class constructor
|
||||
* Creates exception
|
||||
*
|
||||
* @param string $unknownDatePart Type of date part, e.g. "year". One of DatePartType class constants.
|
||||
* @param string $unknownDatePart Unknown type of date part
|
||||
* @param string $value Incorrect value
|
||||
* @return UnknownDatePartTypeException
|
||||
*/
|
||||
public function __construct($unknownDatePart, $value)
|
||||
public static function createException(string $unknownDatePart, string $value): UnknownDatePartTypeException
|
||||
{
|
||||
parent::__construct($unknownDatePart, new DatePartType(), sprintf('date part (with value %s)', $value));
|
||||
return parent::create($unknownDatePart, new DatePartType(), sprintf('date part (with value %s)', $value));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\Type;
|
||||
|
||||
use Meritoo\Common\Exception\Base\UnknownTypeException;
|
||||
@@ -8,16 +14,19 @@ use Meritoo\Common\Type\OopVisibilityType;
|
||||
/**
|
||||
* An exception used while the visibility of a property, a method or (as of PHP 7.1.0) a constant is unknown
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
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(string $unknownType): UnknownOopVisibilityTypeException
|
||||
{
|
||||
parent::__construct($unknownType, new OopVisibilityType(), 'OOP-related visibility');
|
||||
return parent::create($unknownType, new OopVisibilityType(), 'OOP-related visibility');
|
||||
}
|
||||
}
|
||||
|
||||
35
src/Exception/ValueObject/InvalidSizeDimensionsException.php
Normal file
35
src/Exception/ValueObject/InvalidSizeDimensionsException.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\ValueObject;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while dimensions of size, passed to the instance of Size class, are invalid
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class InvalidSizeDimensionsException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates exception
|
||||
*
|
||||
* @param int $width The width
|
||||
* @param int $height The height
|
||||
* @return InvalidSizeDimensionsException
|
||||
*/
|
||||
public static function create($width, $height)
|
||||
{
|
||||
$template = 'Dimensions of size should be positive, but they are not: %d, %d. Is there everything ok?';
|
||||
$message = sprintf($template, $width, $height);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Exception\ValueObject\Template;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while content of template is invalid
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class InvalidContentException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates an exception
|
||||
*
|
||||
* @param string $content Invalid content of template
|
||||
* @return InvalidContentException
|
||||
*/
|
||||
public static function create(string $content): InvalidContentException
|
||||
{
|
||||
$template = 'Content of template \'%s\' is invalid. Did you use string with 1 placeholder at least?';
|
||||
$message = sprintf($template, $content);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\ValueObject\Template;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while there are missing values required to fill all placeholders in template
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class MissingPlaceholdersInValuesException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates an exception
|
||||
*
|
||||
* @param string $content Content of template
|
||||
* @param array $missingPlaceholders Missing placeholders in provided values, iow. placeholders without values
|
||||
* @return MissingPlaceholdersInValuesException
|
||||
*/
|
||||
public static function create(string $content, array $missingPlaceholders): MissingPlaceholdersInValuesException
|
||||
{
|
||||
$template = 'Cannot fill template \'%s\', because of missing values for placeholder(s): %s. Did you provide all'
|
||||
.' required values?';
|
||||
$message = sprintf($template, $content, implode(', ', $missingPlaceholders));
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Exception\ValueObject\Template;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while template with given index was not found
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class TemplateNotFoundException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates the exception
|
||||
*
|
||||
* @param string $index Index that should contain template, but it was not found
|
||||
* @return TemplateNotFoundException
|
||||
*/
|
||||
public static function create(string $index): TemplateNotFoundException
|
||||
{
|
||||
$template = 'Template with \'%s\' index was not found. Did you provide all required templates?';
|
||||
$message = sprintf($template, $index);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
@@ -8,231 +8,16 @@
|
||||
|
||||
namespace Meritoo\Common\Test\Base;
|
||||
|
||||
use DateTime;
|
||||
use Generator;
|
||||
use Meritoo\Common\Exception\Type\UnknownOopVisibilityTypeException;
|
||||
use Meritoo\Common\Type\OopVisibilityType;
|
||||
use Meritoo\Common\Utilities\Miscellaneous;
|
||||
use Meritoo\Common\Traits\Test\Base\BaseTestCaseTrait;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Base test case with common methods and data providers
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
abstract class BaseTestCase extends TestCase
|
||||
{
|
||||
/**
|
||||
* Path of directory with data used by test cases
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $testsDataDirPath = '.data/tests';
|
||||
|
||||
/**
|
||||
* Provides an empty value
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideEmptyValue()
|
||||
{
|
||||
yield[''];
|
||||
yield[' '];
|
||||
yield[null];
|
||||
yield[0];
|
||||
yield[false];
|
||||
yield[[]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides boolean value
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideBooleanValue()
|
||||
{
|
||||
yield[false];
|
||||
yield[true];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides instance of DateTime class
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideDateTimeInstance()
|
||||
{
|
||||
yield[new DateTime()];
|
||||
yield[new DateTime('yesterday')];
|
||||
yield[new DateTime('now')];
|
||||
yield[new DateTime('tomorrow')];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides relative / compound format of DateTime
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideDateTimeRelativeFormat()
|
||||
{
|
||||
yield['now'];
|
||||
yield['yesterday'];
|
||||
yield['tomorrow'];
|
||||
yield['back of 10'];
|
||||
yield['front of 10'];
|
||||
yield['last day of February'];
|
||||
yield['first day of next month'];
|
||||
yield['last day of previous month'];
|
||||
yield['last day of next month'];
|
||||
yield['Y-m-d'];
|
||||
yield['Y-m-d 10:00'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides path of not existing file, e.g. "lorem/ipsum.jpg"
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideNotExistingFilePath()
|
||||
{
|
||||
yield['lets-test.doc'];
|
||||
yield['lorem/ipsum.jpg'];
|
||||
yield['surprise/me/one/more/time.txt'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns path of file used by tests.
|
||||
* It should be placed in /.data/tests directory of this project.
|
||||
*
|
||||
* @param string $fileName Name of file
|
||||
* @param string $directoryPath (optional) Path of directory containing the file
|
||||
* @return string
|
||||
*/
|
||||
public function getFilePathToTests($fileName, $directoryPath = '')
|
||||
{
|
||||
$rootPath = Miscellaneous::getProjectRootPath();
|
||||
|
||||
$paths = [
|
||||
$rootPath,
|
||||
self::$testsDataDirPath,
|
||||
$directoryPath,
|
||||
$fileName,
|
||||
];
|
||||
|
||||
return Miscellaneous::concatenatePaths($paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies visibility and arguments of method
|
||||
*
|
||||
* @param string $classNamespace Namespace of class that contains method to verify
|
||||
* @param string|ReflectionMethod $method Name of method or just the method to verify
|
||||
* @param string $visibilityType Expected visibility of verified method. One of
|
||||
* OopVisibilityType class constants.
|
||||
* @param int $argumentsCount (optional) Expected count/amount of arguments of the
|
||||
* verified method
|
||||
* @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments
|
||||
* of the verified method
|
||||
* @throws UnknownOopVisibilityTypeException
|
||||
*
|
||||
* Attention. 2nd argument, the $method, may be:
|
||||
* - string - name of the method
|
||||
* - instance of ReflectionMethod - just the method (provided by ReflectionClass::getMethod() method)
|
||||
*/
|
||||
protected static function assertMethodVisibilityAndArguments(
|
||||
$classNamespace,
|
||||
$method,
|
||||
$visibilityType,
|
||||
$argumentsCount = 0,
|
||||
$requiredArgumentsCount = 0
|
||||
) {
|
||||
/*
|
||||
* Type of visibility is correct?
|
||||
*/
|
||||
if (!(new OopVisibilityType())->isCorrectType($visibilityType)) {
|
||||
throw new UnknownOopVisibilityTypeException($visibilityType);
|
||||
}
|
||||
|
||||
$reflection = new ReflectionClass($classNamespace);
|
||||
|
||||
/*
|
||||
* Name of method provided only?
|
||||
* Let's find instance of the method (based on reflection)
|
||||
*/
|
||||
if (!$method instanceof ReflectionMethod) {
|
||||
$method = $reflection->getMethod($method);
|
||||
}
|
||||
|
||||
switch ($visibilityType) {
|
||||
case OopVisibilityType::IS_PUBLIC:
|
||||
static::assertTrue($method->isPublic());
|
||||
break;
|
||||
|
||||
case OopVisibilityType::IS_PROTECTED:
|
||||
static::assertTrue($method->isProtected());
|
||||
break;
|
||||
|
||||
case OopVisibilityType::IS_PRIVATE:
|
||||
static::assertTrue($method->isPrivate());
|
||||
break;
|
||||
}
|
||||
|
||||
static::assertEquals($argumentsCount, $method->getNumberOfParameters());
|
||||
static::assertEquals($requiredArgumentsCount, $method->getNumberOfRequiredParameters());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies visibility and arguments of class constructor
|
||||
*
|
||||
* @param string $classNamespace Namespace of class that contains constructor to verify
|
||||
* @param string $visibilityType Expected visibility of verified method. One of OopVisibilityType class
|
||||
* constants.
|
||||
* @param int $argumentsCount (optional) Expected count/amount of arguments of the verified method
|
||||
* @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments of the verified
|
||||
* method
|
||||
* @throws UnknownOopVisibilityTypeException
|
||||
*/
|
||||
protected static function assertConstructorVisibilityAndArguments(
|
||||
$classNamespace,
|
||||
$visibilityType,
|
||||
$argumentsCount = 0,
|
||||
$requiredArgumentsCount = 0
|
||||
) {
|
||||
/*
|
||||
* Let's grab the constructor
|
||||
*/
|
||||
$reflection = new ReflectionClass($classNamespace);
|
||||
$method = $reflection->getConstructor();
|
||||
|
||||
return static::assertMethodVisibilityAndArguments($classNamespace, $method, $visibilityType, $argumentsCount, $requiredArgumentsCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that class with given namespace has no constructor
|
||||
*
|
||||
* @param string $classNamespace Namespace of class that contains constructor to verify
|
||||
*/
|
||||
protected static function assertHasNoConstructor($classNamespace)
|
||||
{
|
||||
/*
|
||||
* Let's grab the constructor
|
||||
*/
|
||||
$reflection = new ReflectionClass($classNamespace);
|
||||
$constructor = $reflection->getConstructor();
|
||||
|
||||
static::assertNull($constructor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets path of directory with data used by test cases
|
||||
*
|
||||
* @param string $testsDataDirPath Path of directory with data used by test cases
|
||||
*/
|
||||
protected static function setTestsDataDirPath($testsDataDirPath)
|
||||
{
|
||||
static::$testsDataDirPath = $testsDataDirPath;
|
||||
}
|
||||
use BaseTestCaseTrait;
|
||||
}
|
||||
|
||||
@@ -1,60 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Test\Base;
|
||||
|
||||
use Generator;
|
||||
use Meritoo\Common\Type\Base\BaseType;
|
||||
use Meritoo\Common\Traits\Test\Base\BaseTypeTestCaseTrait;
|
||||
|
||||
/**
|
||||
* Base test case for the type of something
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
abstract class BaseTypeTestCase extends BaseTestCase
|
||||
{
|
||||
/**
|
||||
* Verifies availability of all types
|
||||
*/
|
||||
public function testAvailabilityOfAllTypes()
|
||||
{
|
||||
$available = $this->getTestedTypeInstance()->getAll();
|
||||
$all = $this->getAllExpectedTypes();
|
||||
|
||||
static::assertEquals($all, $available);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether given type is correct or not
|
||||
*
|
||||
* @param string $type Type to verify
|
||||
* @param bool $expected Information if given type is correct or not
|
||||
*
|
||||
* @dataProvider provideTypeToVerify
|
||||
*/
|
||||
public function testIfGivenTypeIsCorrect($type, $expected)
|
||||
{
|
||||
static::assertEquals($expected, $this->getTestedTypeInstance()->isCorrectType($type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides type to verify and information if it's correct
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
abstract public function provideTypeToVerify();
|
||||
|
||||
/**
|
||||
* Returns instance of the tested type
|
||||
*
|
||||
* @return BaseType
|
||||
*/
|
||||
abstract protected function getTestedTypeInstance();
|
||||
|
||||
/**
|
||||
* Returns all expected types of the tested type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getAllExpectedTypes();
|
||||
use BaseTypeTestCaseTrait;
|
||||
}
|
||||
|
||||
110
src/Traits/CssSelector/FormCssSelector.php
Normal file
110
src/Traits/CssSelector/FormCssSelector.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Traits\CssSelector;
|
||||
|
||||
/**
|
||||
* Useful methods related to CSS selectors of form
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
trait FormCssSelector
|
||||
{
|
||||
/**
|
||||
* Returns selector of field-set using index/position of the field-set
|
||||
*
|
||||
* @param string $formName Name of form (value of the "name" attribute)
|
||||
* @param int $fieldSetIndex Index/Position of the field-set
|
||||
* @return string
|
||||
*/
|
||||
public static function getFieldSetByIndexSelector($formName, $fieldSetIndex)
|
||||
{
|
||||
$formSelector = static::getFormByNameSelector($formName);
|
||||
|
||||
if (empty($formSelector) || 0 > $fieldSetIndex) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return sprintf('%s fieldset:nth-of-type(%d)', $formSelector, $fieldSetIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns selector of form based on its name
|
||||
*
|
||||
* @param string $formName Name of form (value of the "name" attribute)
|
||||
* @return string
|
||||
*/
|
||||
public static function getFormByNameSelector($formName)
|
||||
{
|
||||
$formName = trim($formName);
|
||||
|
||||
if (empty($formName)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return sprintf('form[name="%s"]', $formName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns selector of the input field based on its ID
|
||||
*
|
||||
* @param string $formName Name of form (value of the "name" attribute)
|
||||
* @param string $fieldId ID of field (value of the "id" attribute)
|
||||
* @return string
|
||||
*/
|
||||
public static function getInputByIdSelector($formName, $fieldId)
|
||||
{
|
||||
$formSelector = static::getFormByNameSelector($formName);
|
||||
$fieldId = trim($fieldId);
|
||||
|
||||
if (empty($formSelector) || empty($fieldId)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return sprintf('%s input#%s', $formSelector, $fieldId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns selector of the input field based on its name
|
||||
*
|
||||
* @param string $formName Name of form (value of the "name" attribute)
|
||||
* @param string $fieldName Name of field (value of the "name" attribute)
|
||||
* @return string
|
||||
*/
|
||||
public static function getInputByNameSelector($formName, $fieldName)
|
||||
{
|
||||
$formSelector = static::getFormByNameSelector($formName);
|
||||
$fieldName = trim($fieldName);
|
||||
|
||||
if (empty($formSelector) || empty($fieldName)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return sprintf('%s input[name="%s"]', $formSelector, $fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns selector of label
|
||||
*
|
||||
* @param string $formName Name of form (value of the "name" attribute)
|
||||
* @param string $fieldId ID of field (value of the "id" attribute)
|
||||
* @return string
|
||||
*/
|
||||
public static function getLabelSelector($formName, $fieldId)
|
||||
{
|
||||
$formSelector = static::getFormByNameSelector($formName);
|
||||
$fieldId = trim($fieldId);
|
||||
|
||||
if (empty($formSelector) || empty($fieldId)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return sprintf('%s label[for="%s"]', $formSelector, $fieldId);
|
||||
}
|
||||
}
|
||||
258
src/Traits/Test/Base/BaseTestCaseTrait.php
Normal file
258
src/Traits/Test/Base/BaseTestCaseTrait.php
Normal file
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Traits\Test\Base;
|
||||
|
||||
use DateTime;
|
||||
use Generator;
|
||||
use Meritoo\Common\Exception\Reflection\ClassWithoutConstructorException;
|
||||
use Meritoo\Common\Exception\Type\UnknownOopVisibilityTypeException;
|
||||
use Meritoo\Common\Type\OopVisibilityType;
|
||||
use Meritoo\Common\Utilities\Miscellaneous;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use RuntimeException;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Trait for the base test case
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
trait BaseTestCaseTrait
|
||||
{
|
||||
/**
|
||||
* Path of directory with data used by test cases
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $testsDataDirPath = 'data/tests';
|
||||
|
||||
/**
|
||||
* Provides boolean value
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideBooleanValue(): ?Generator
|
||||
{
|
||||
yield [false];
|
||||
yield [true];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides instance of DateTime class
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideDateTimeInstance(): ?Generator
|
||||
{
|
||||
yield [new DateTime()];
|
||||
yield [new DateTime('yesterday')];
|
||||
yield [new DateTime('now')];
|
||||
yield [new DateTime('tomorrow')];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides relative / compound format of DateTime
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideDateTimeRelativeFormat(): ?Generator
|
||||
{
|
||||
yield ['now'];
|
||||
yield ['yesterday'];
|
||||
yield ['tomorrow'];
|
||||
yield ['back of 10'];
|
||||
yield ['front of 10'];
|
||||
yield ['last day of February'];
|
||||
yield ['first day of next month'];
|
||||
yield ['last day of previous month'];
|
||||
yield ['last day of next month'];
|
||||
yield ['Y-m-d'];
|
||||
yield ['Y-m-d 10:00'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an empty scalar value
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideEmptyScalarValue(): ?Generator
|
||||
{
|
||||
yield [''];
|
||||
yield [' '];
|
||||
yield [null];
|
||||
yield [0];
|
||||
yield [false];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an empty value
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideEmptyValue(): ?Generator
|
||||
{
|
||||
yield [''];
|
||||
yield [' '];
|
||||
yield [null];
|
||||
yield [0];
|
||||
yield [false];
|
||||
yield [[]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides non scalar value, e.g. [] or null
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideNonScalarValue(): ?Generator
|
||||
{
|
||||
yield [[]];
|
||||
yield [null];
|
||||
yield [new stdClass()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides path of not existing file, e.g. "lorem/ipsum.jpg"
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideNotExistingFilePath(): ?Generator
|
||||
{
|
||||
yield ['lets-test.doc'];
|
||||
yield ['lorem/ipsum.jpg'];
|
||||
yield ['surprise/me/one/more/time.txt'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies visibility and arguments of class constructor
|
||||
*
|
||||
* @param string $className Fully-qualified name of class that contains constructor to verify
|
||||
* @param string $visibilityType Expected visibility of verified method. One of OopVisibilityType class
|
||||
* constants.
|
||||
* @param int $argumentsCount (optional) Expected count/amount of arguments of the verified method
|
||||
* @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments of the verified
|
||||
* method
|
||||
* @throws ClassWithoutConstructorException
|
||||
*/
|
||||
protected static function assertConstructorVisibilityAndArguments(
|
||||
string $className,
|
||||
string $visibilityType,
|
||||
int $argumentsCount = 0,
|
||||
int $requiredArgumentsCount = 0
|
||||
): void {
|
||||
$reflection = new ReflectionClass($className);
|
||||
$method = $reflection->getConstructor();
|
||||
|
||||
if (null === $method) {
|
||||
throw ClassWithoutConstructorException::create($className);
|
||||
}
|
||||
|
||||
static::assertMethodVisibility($method, $visibilityType);
|
||||
static::assertMethodArgumentsCount($method, $argumentsCount, $requiredArgumentsCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that class with given namespace has no constructor
|
||||
*
|
||||
* @param string $className Fully-qualified name of class that contains constructor to verify
|
||||
*/
|
||||
protected static function assertHasNoConstructor(string $className): void
|
||||
{
|
||||
$reflection = new ReflectionClass($className);
|
||||
$constructor = $reflection->getConstructor();
|
||||
|
||||
static::assertNull($constructor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies count of method's arguments
|
||||
*
|
||||
* @param ReflectionMethod $method Name of method or just the method to verify
|
||||
* @param int $argumentsCount (optional) Expected count/amount of arguments of the verified method
|
||||
* @param int $requiredCount (optional) Expected count/amount of required arguments of the verified
|
||||
* method
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected static function assertMethodArgumentsCount(
|
||||
ReflectionMethod $method,
|
||||
int $argumentsCount = 0,
|
||||
int $requiredCount = 0
|
||||
): void {
|
||||
static::assertSame($argumentsCount, $method->getNumberOfParameters());
|
||||
static::assertSame($requiredCount, $method->getNumberOfRequiredParameters());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies visibility of method
|
||||
*
|
||||
* @param ReflectionMethod $method Name of method or just the method to verify
|
||||
* @param string $visibilityType Expected visibility of verified method. One of OopVisibilityType
|
||||
* class constants.
|
||||
* @throws UnknownOopVisibilityTypeException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected static function assertMethodVisibility(ReflectionMethod $method, string $visibilityType): void
|
||||
{
|
||||
// Type of visibility is not correct?
|
||||
if (!OopVisibilityType::isCorrectType($visibilityType)) {
|
||||
throw UnknownOopVisibilityTypeException::createException($visibilityType);
|
||||
}
|
||||
|
||||
switch ($visibilityType) {
|
||||
case OopVisibilityType::IS_PUBLIC:
|
||||
static::assertTrue($method->isPublic());
|
||||
|
||||
break;
|
||||
case OopVisibilityType::IS_PROTECTED:
|
||||
static::assertTrue($method->isProtected());
|
||||
|
||||
break;
|
||||
case OopVisibilityType::IS_PRIVATE:
|
||||
static::assertTrue($method->isPrivate());
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns path of file used by tests.
|
||||
* It should be placed in /data/tests directory of this project.
|
||||
*
|
||||
* @param string $fileName Name of file
|
||||
* @param string $directoryPath (optional) Path of directory containing the file
|
||||
* @return string
|
||||
*/
|
||||
protected function getFilePathForTesting(string $fileName, string $directoryPath = ''): string
|
||||
{
|
||||
$rootPath = Miscellaneous::getProjectRootPath();
|
||||
|
||||
$paths = [
|
||||
$rootPath,
|
||||
self::$testsDataDirPath,
|
||||
$directoryPath,
|
||||
$fileName,
|
||||
];
|
||||
|
||||
return Miscellaneous::concatenatePaths($paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets path of directory with data used by test cases
|
||||
*
|
||||
* @param string $testsDataDirPath Path of directory with data used by test cases
|
||||
*/
|
||||
protected static function setTestsDataDirPath(string $testsDataDirPath): void
|
||||
{
|
||||
static::$testsDataDirPath = $testsDataDirPath;
|
||||
}
|
||||
}
|
||||
68
src/Traits/Test/Base/BaseTypeTestCaseTrait.php
Normal file
68
src/Traits/Test/Base/BaseTypeTestCaseTrait.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Traits\Test\Base;
|
||||
|
||||
use Generator;
|
||||
use Meritoo\Common\Type\Base\BaseType;
|
||||
|
||||
/**
|
||||
* Trait for the base test case for the type of something
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
trait BaseTypeTestCaseTrait
|
||||
{
|
||||
/**
|
||||
* Provides type to verify and information if it's correct
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
abstract public function provideTypeToVerify(): Generator;
|
||||
|
||||
/**
|
||||
* Verifies availability of all types
|
||||
*/
|
||||
public function testAvailabilityOfAllTypes(): void
|
||||
{
|
||||
$available = $this->getTestedTypeInstance()->getAll();
|
||||
$all = $this->getAllExpectedTypes();
|
||||
|
||||
static::assertEquals($all, $available);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether given type is correct or not
|
||||
*
|
||||
* @param bool $isCorrect Information if processed type is correct
|
||||
* @param bool $expected Expected information if processed type is correct
|
||||
*
|
||||
* @dataProvider provideTypeToVerify
|
||||
*/
|
||||
public function testIfGivenTypeIsCorrect(bool $isCorrect, bool $expected): void
|
||||
{
|
||||
static::assertEquals($expected, $isCorrect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all expected types of the tested type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function getAllExpectedTypes(): array;
|
||||
|
||||
/**
|
||||
* Returns instance of the tested type
|
||||
*
|
||||
* @return BaseType
|
||||
*/
|
||||
abstract protected function getTestedTypeInstance(): BaseType;
|
||||
}
|
||||
144
src/Traits/ValueObject/HumanTrait.php
Normal file
144
src/Traits/ValueObject/HumanTrait.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Meritoo\Common\Traits\ValueObject;
|
||||
|
||||
use DateTime;
|
||||
|
||||
/**
|
||||
* Methods and properties related to human
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
trait HumanTrait
|
||||
{
|
||||
/**
|
||||
* First name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $firstName;
|
||||
|
||||
/**
|
||||
* Last name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $lastName;
|
||||
|
||||
/**
|
||||
* Email address
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $email;
|
||||
|
||||
/**
|
||||
* Birth date
|
||||
*
|
||||
* @var null|DateTime
|
||||
*/
|
||||
protected $birthDate;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string $firstName First name
|
||||
* @param string $lastName Last name
|
||||
* @param null|string $email (optional) Email address. Default: null.
|
||||
* @param null|DateTime $birthDate (optional) Birth date. Default: null.
|
||||
*/
|
||||
public function __construct(string $firstName, string $lastName, ?string $email = null, ?DateTime $birthDate = null)
|
||||
{
|
||||
$this->firstName = $firstName;
|
||||
$this->lastName = $lastName;
|
||||
$this->email = $email;
|
||||
$this->birthDate = $birthDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns representation of object as string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$template = '%s';
|
||||
$email = '';
|
||||
|
||||
if ('' !== $this->email && null !== $this->email) {
|
||||
$template .= ' <%s>';
|
||||
$email = $this->email;
|
||||
}
|
||||
|
||||
return sprintf($template, $this->getFullName(), $email);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns birth date
|
||||
*
|
||||
* @return null|DateTime
|
||||
*/
|
||||
public function getBirthDate(): ?DateTime
|
||||
{
|
||||
return $this->birthDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns email address
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getEmail(): ?string
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstName(): string
|
||||
{
|
||||
return $this->firstName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full name
|
||||
*
|
||||
* @param bool $firstNameFirst (optional) If is set to true, first name is the first part (default behaviour).
|
||||
* Otherwise - name.
|
||||
* @return string
|
||||
*/
|
||||
public function getFullName(bool $firstNameFirst = true): string
|
||||
{
|
||||
$beginning = $this->lastName;
|
||||
$finish = $this->firstName;
|
||||
|
||||
if ($firstNameFirst) {
|
||||
$beginning = $this->firstName;
|
||||
$finish = $this->lastName;
|
||||
}
|
||||
|
||||
return trim(sprintf('%s %s', $beginning, $finish));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLastName(): string
|
||||
{
|
||||
return $this->lastName;
|
||||
}
|
||||
}
|
||||
@@ -14,15 +14,15 @@ use Meritoo\Common\Utilities\Reflection;
|
||||
* Base / abstract type of something, e.g. type of button, order, date etc.
|
||||
* Child class should contain constants - each of them represent one type.
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
abstract class BaseType
|
||||
{
|
||||
/**
|
||||
* All types
|
||||
*
|
||||
* @var array
|
||||
* @var null|array
|
||||
*/
|
||||
private $all;
|
||||
|
||||
@@ -31,7 +31,7 @@ abstract class BaseType
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll()
|
||||
public function getAll(): array
|
||||
{
|
||||
if (null === $this->all) {
|
||||
$this->all = Reflection::getConstants($this);
|
||||
@@ -43,11 +43,11 @@ abstract class BaseType
|
||||
/**
|
||||
* Returns information if given type is correct
|
||||
*
|
||||
* @param string $type The type to check
|
||||
* @param null|string $type The type to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isCorrectType($type)
|
||||
public static function isCorrectType(?string $type): bool
|
||||
{
|
||||
return in_array($type, $this->getAll(), true);
|
||||
return in_array($type, (new static())->getAll());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ use Meritoo\Common\Type\Base\BaseType;
|
||||
/**
|
||||
* Type of date part, e.g. "year"
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class DatePartType extends BaseType
|
||||
{
|
||||
@@ -23,40 +23,40 @@ class DatePartType extends BaseType
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DAY = 'day';
|
||||
public const DAY = 'day';
|
||||
|
||||
/**
|
||||
* The "hour" date part
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const HOUR = 'hour';
|
||||
public const HOUR = 'hour';
|
||||
|
||||
/**
|
||||
* The "minute" date part
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const MINUTE = 'minute';
|
||||
public const MINUTE = 'minute';
|
||||
|
||||
/**
|
||||
* The "month" date part
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const MONTH = 'month';
|
||||
public const MONTH = 'month';
|
||||
|
||||
/**
|
||||
* The "second" date part
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SECOND = 'second';
|
||||
public const SECOND = 'second';
|
||||
|
||||
/**
|
||||
* The "year" date part
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const YEAR = 'year';
|
||||
public const YEAR = 'year';
|
||||
}
|
||||
|
||||
@@ -6,140 +6,152 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Utilities;
|
||||
namespace Meritoo\Common\Type;
|
||||
|
||||
use DateTime;
|
||||
use Meritoo\Common\Type\Base\BaseType;
|
||||
use Meritoo\Common\Utilities\Date;
|
||||
|
||||
/**
|
||||
* A date's period.
|
||||
* Contains start and end date of the period.
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class DatePeriod
|
||||
class DatePeriod extends BaseType
|
||||
{
|
||||
/**
|
||||
* The period constant: last month
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const LAST_MONTH = 4;
|
||||
public const LAST_MONTH = '4';
|
||||
|
||||
/**
|
||||
* The period constant: last week
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const LAST_WEEK = 1;
|
||||
public const LAST_WEEK = '1';
|
||||
|
||||
/**
|
||||
* The period constant: last year
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const LAST_YEAR = 7;
|
||||
public const LAST_YEAR = '7';
|
||||
|
||||
/**
|
||||
* The period constant: next month
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const NEXT_MONTH = 6;
|
||||
public const NEXT_MONTH = '6';
|
||||
|
||||
/**
|
||||
* The period constant: next week
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const NEXT_WEEK = 3;
|
||||
public const NEXT_WEEK = '3';
|
||||
|
||||
/**
|
||||
* The period constant: next year
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const NEXT_YEAR = 9;
|
||||
public const NEXT_YEAR = '9';
|
||||
|
||||
/**
|
||||
* The period constant: this month
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const THIS_MONTH = 5;
|
||||
public const THIS_MONTH = '5';
|
||||
|
||||
/**
|
||||
* The period constant: this week
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const THIS_WEEK = 2;
|
||||
public const THIS_WEEK = '2';
|
||||
|
||||
/**
|
||||
* The period constant: this year
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const THIS_YEAR = 8;
|
||||
public const THIS_YEAR = '8';
|
||||
|
||||
/**
|
||||
* The start date of period
|
||||
*
|
||||
* @var DateTime
|
||||
* @var null|DateTime
|
||||
*/
|
||||
private $startDate;
|
||||
|
||||
/**
|
||||
* The end date of period
|
||||
*
|
||||
* @var DateTime
|
||||
* @var null|DateTime
|
||||
*/
|
||||
private $endDate;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param DateTime $startDate (optional) The start date of period
|
||||
* @param DateTime $endDate (optional) The end date of period
|
||||
* @param null|DateTime $startDate (optional) The start date of period
|
||||
* @param null|DateTime $endDate (optional) The end date of period
|
||||
*/
|
||||
public function __construct(DateTime $startDate = null, DateTime $endDate = null)
|
||||
public function __construct(?DateTime $startDate = null, ?DateTime $endDate = null)
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
$this->endDate = $endDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given period is correct
|
||||
* Returns the end date of period
|
||||
*
|
||||
* @param int $period The period to verify
|
||||
* @return bool
|
||||
* @return null|DateTime
|
||||
*/
|
||||
public static function isCorrectPeriod($period)
|
||||
public function getEndDate(): ?DateTime
|
||||
{
|
||||
return in_array($period, Reflection::getConstants(__CLASS__));
|
||||
return $this->endDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the end date of period
|
||||
*
|
||||
* @param null|DateTime $endDate (optional) The end date of period. Default: null.
|
||||
* @return $this
|
||||
*/
|
||||
public function setEndDate(?DateTime $endDate = null): self
|
||||
{
|
||||
$this->endDate = $endDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted one of the period's date: start date or end date
|
||||
*
|
||||
* @param string $format Format used to format the date
|
||||
* @param bool $startDate (optional) If is set to true, start date is formatted. Otherwise - end date.
|
||||
* @param bool $startDate (optional) If is set to true, start date will be formatted (default behaviour).
|
||||
* Otherwise - end date.
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedDate($format, $startDate = true)
|
||||
public function getFormattedDate(string $format, bool $startDate = true): string
|
||||
{
|
||||
$date = $this->getEndDate();
|
||||
|
||||
/*
|
||||
* Start date should be formatted?
|
||||
*/
|
||||
// Start date should be formatted?
|
||||
if ($startDate) {
|
||||
$date = $this->getStartDate();
|
||||
}
|
||||
|
||||
/*
|
||||
* Unknown date or format is invalid?
|
||||
*/
|
||||
// Unknown date or format is invalid?
|
||||
// Nothing to do
|
||||
if (null === $date || !Date::isValidDateFormat($format)) {
|
||||
return '';
|
||||
}
|
||||
@@ -147,35 +159,12 @@ class DatePeriod
|
||||
return $date->format($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the end date of period
|
||||
*
|
||||
* @return DateTime
|
||||
*/
|
||||
public function getEndDate()
|
||||
{
|
||||
return $this->endDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the end date of period
|
||||
*
|
||||
* @param DateTime $endDate (optional) The end date of period
|
||||
* @return $this
|
||||
*/
|
||||
public function setEndDate(DateTime $endDate = null)
|
||||
{
|
||||
$this->endDate = $endDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start date of period
|
||||
*
|
||||
* @return DateTime
|
||||
* @return null|DateTime
|
||||
*/
|
||||
public function getStartDate()
|
||||
public function getStartDate(): ?DateTime
|
||||
{
|
||||
return $this->startDate;
|
||||
}
|
||||
@@ -183,10 +172,10 @@ class DatePeriod
|
||||
/**
|
||||
* Sets the start date of period
|
||||
*
|
||||
* @param DateTime $startDate (optional) The start date of period
|
||||
* @param null|DateTime $startDate (optional) The start date of period. Default: null.
|
||||
* @return $this
|
||||
*/
|
||||
public function setStartDate(DateTime $startDate = null)
|
||||
public function setStartDate(?DateTime $startDate = null): self
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
|
||||
@@ -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
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*
|
||||
* @see http://php.net/manual/en/language.oop5.visibility.php
|
||||
*/
|
||||
@@ -17,21 +17,21 @@ class OopVisibilityType extends BaseType
|
||||
/**
|
||||
* The "private" visibility of OOP
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const IS_PRIVATE = 3;
|
||||
public const IS_PRIVATE = '3';
|
||||
|
||||
/**
|
||||
* The "protected" visibility of OOP
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const IS_PROTECTED = 2;
|
||||
public const IS_PROTECTED = '2';
|
||||
|
||||
/**
|
||||
* The "public" visibility of OOP
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const IS_PUBLIC = 1;
|
||||
public const IS_PUBLIC = '1';
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
85
src/Utilities/Bootstrap4CssSelector.php
Normal file
85
src/Utilities/Bootstrap4CssSelector.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Utilities;
|
||||
|
||||
/**
|
||||
* Useful methods related to CSS selectors and the Bootstrap4 (front-end component library)
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class Bootstrap4CssSelector
|
||||
{
|
||||
/**
|
||||
* Returns selector of container with field's validation error
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getFieldErrorContainerSelector()
|
||||
{
|
||||
return '.invalid-feedback .form-error-message';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns selector of field's validation error
|
||||
*
|
||||
* @param string $formName Name of form (value of the "name" attribute)
|
||||
* @param string $fieldId ID of field (value of the "id" attribute)
|
||||
* @return string
|
||||
*/
|
||||
public static function getFieldErrorSelector($formName, $fieldId)
|
||||
{
|
||||
$labelSelector = CssSelector::getLabelSelector($formName, $fieldId);
|
||||
|
||||
if (empty($labelSelector)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$errorContainerSelector = static::getFieldErrorContainerSelector();
|
||||
|
||||
return sprintf('%s %s', $labelSelector, $errorContainerSelector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns selector of field's group
|
||||
*
|
||||
* @param string $formName Name of form (value of the "name" attribute)
|
||||
* @return string
|
||||
*/
|
||||
public static function getFieldGroupSelector($formName)
|
||||
{
|
||||
$formSelector = CssSelector::getFormByNameSelector($formName);
|
||||
|
||||
if (empty($formSelector)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return sprintf('%s .form-group', $formSelector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns selector of radio-button's validation error
|
||||
*
|
||||
* @param string $formName Name of form (value of the "name" attribute)
|
||||
* @param int $fieldSetIndex Index/Position of the field-set
|
||||
* @return string
|
||||
*/
|
||||
public static function getRadioButtonErrorSelector($formName, $fieldSetIndex)
|
||||
{
|
||||
$fieldSetSelector = CssSelector::getFieldSetByIndexSelector($formName, $fieldSetIndex);
|
||||
|
||||
if (empty($fieldSetSelector)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$errorContainerSelector = static::getFieldErrorContainerSelector();
|
||||
|
||||
return sprintf('%s legend.col-form-label %s', $fieldSetSelector, $errorContainerSelector);
|
||||
}
|
||||
}
|
||||
@@ -8,39 +8,70 @@
|
||||
|
||||
namespace Meritoo\Common\Utilities;
|
||||
|
||||
use Meritoo\Common\Exception\Bundle\IncorrectBundleNameException;
|
||||
|
||||
/**
|
||||
* Useful methods for bundle
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
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 $bundleName Name of the bundle, e.g. "MyExtraBundle"
|
||||
* @param string $extension (optional) Extension of the view / template
|
||||
* @return string|null
|
||||
* @param string $viewPath Path of the view / template, e.g. "MyDirectory/my-template". Extension is not required.
|
||||
* @param string $bundleName Full name of the bundle, e.g. "MyExtraBundle"
|
||||
* @param string $extension (optional) Extension of the view / template (default: "html.twig")
|
||||
* @return null|string
|
||||
* @throws IncorrectBundleNameException
|
||||
*/
|
||||
public static function getBundleViewPath($viewPath, $bundleName, $extension = 'html.twig')
|
||||
{
|
||||
/*
|
||||
* Unknown path, extension of the view / template or name of the bundle?
|
||||
* Nothing to do
|
||||
*/
|
||||
public static function getBundleViewPath(
|
||||
string $viewPath,
|
||||
string $bundleName,
|
||||
string $extension = 'html.twig'
|
||||
): ?string {
|
||||
// Nothing to do, because at least one unknown argument provided
|
||||
if (empty($viewPath) || empty($bundleName) || empty($extension)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Path of the view / template doesn't end with given extension?
|
||||
*/
|
||||
// Oops, given name of bundle is invalid
|
||||
if (!Regex::isValidBundleName($bundleName)) {
|
||||
throw IncorrectBundleNameException::create($bundleName);
|
||||
}
|
||||
|
||||
// Make sure that path of the view / template ends with given extension
|
||||
if (!Regex::endsWith($viewPath, $extension)) {
|
||||
$viewPath = sprintf('%s.%s', $viewPath, $extension);
|
||||
}
|
||||
|
||||
return sprintf('%s:%s', $bundleName, $viewPath);
|
||||
// Prepare short name of bundle and path of view / template with "/" (instead of ":")
|
||||
$shortName = static::getShortBundleName($bundleName);
|
||||
$path = str_replace(':', '/', $viewPath);
|
||||
|
||||
return sprintf('@%s/%s', $shortName, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns short name of bundle (without "Bundle")
|
||||
*
|
||||
* @param string $fullBundleName Full name of the bundle, e.g. "MyExtraBundle"
|
||||
* @return null|string
|
||||
* @throws IncorrectBundleNameException
|
||||
*/
|
||||
public static function getShortBundleName(string $fullBundleName): ?string
|
||||
{
|
||||
// Oops, given name of bundle is invalid
|
||||
if (!Regex::isValidBundleName($fullBundleName)) {
|
||||
throw new IncorrectBundleNameException($fullBundleName);
|
||||
}
|
||||
|
||||
$matches = [];
|
||||
$pattern = Regex::getBundleNamePattern();
|
||||
preg_match($pattern, $fullBundleName, $matches);
|
||||
|
||||
return $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,11 @@
|
||||
|
||||
namespace Meritoo\Common\Utilities;
|
||||
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Useful Composer-related methods (only static functions)
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class Composer
|
||||
{
|
||||
@@ -23,23 +21,18 @@ class Composer
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILE_NAME_MAIN = 'composer.json';
|
||||
public const FILE_NAME_MAIN = 'composer.json';
|
||||
|
||||
/**
|
||||
* Returns value from composer.json file
|
||||
*
|
||||
* @param string $composerJsonPath Path of composer.json file
|
||||
* @param string $nodeName Name of node who value should be returned
|
||||
* @return string|null
|
||||
* @return null|string
|
||||
*/
|
||||
public static function getValue($composerJsonPath, $nodeName)
|
||||
public static function getValue(string $composerJsonPath, string $nodeName): ?string
|
||||
{
|
||||
$composerJsonString = is_string($composerJsonPath);
|
||||
$composerJsonReadable = false;
|
||||
|
||||
if ($composerJsonString) {
|
||||
$composerJsonReadable = is_readable($composerJsonPath);
|
||||
}
|
||||
$composerJsonReadable = is_readable($composerJsonPath);
|
||||
|
||||
/*
|
||||
* Provided path or name of node are invalid?
|
||||
@@ -48,12 +41,12 @@ class Composer
|
||||
*
|
||||
* Nothing to do
|
||||
*/
|
||||
if (!$composerJsonString || !is_string($nodeName) || !$composerJsonReadable || empty($nodeName)) {
|
||||
if (!$composerJsonReadable || empty($nodeName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$content = file_get_contents($composerJsonPath);
|
||||
$data = json_decode($content);
|
||||
$data = json_decode($content, false);
|
||||
|
||||
/*
|
||||
* Unknown data from the composer.json file or there is no node with given name?
|
||||
@@ -63,7 +56,6 @@ class Composer
|
||||
return null;
|
||||
}
|
||||
|
||||
/* @var stdClass $data */
|
||||
return $data->{$nodeName};
|
||||
}
|
||||
}
|
||||
|
||||
22
src/Utilities/CssSelector.php
Normal file
22
src/Utilities/CssSelector.php
Normal 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;
|
||||
}
|
||||
@@ -10,14 +10,16 @@ namespace Meritoo\Common\Utilities;
|
||||
|
||||
use DateInterval;
|
||||
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\DatePeriod;
|
||||
|
||||
/**
|
||||
* Useful date methods
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class Date
|
||||
{
|
||||
@@ -27,7 +29,7 @@ class Date
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DATE_DIFFERENCE_UNIT_DAYS = 'days';
|
||||
public const DATE_DIFFERENCE_UNIT_DAYS = 'days';
|
||||
|
||||
/**
|
||||
* The 'hours' unit of date difference.
|
||||
@@ -35,7 +37,7 @@ class Date
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DATE_DIFFERENCE_UNIT_HOURS = 'hours';
|
||||
public const DATE_DIFFERENCE_UNIT_HOURS = 'hours';
|
||||
|
||||
/**
|
||||
* The 'minutes' unit of date difference.
|
||||
@@ -43,7 +45,7 @@ class Date
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DATE_DIFFERENCE_UNIT_MINUTES = 'minutes';
|
||||
public const DATE_DIFFERENCE_UNIT_MINUTES = 'minutes';
|
||||
|
||||
/**
|
||||
* The 'months' unit of date difference.
|
||||
@@ -51,7 +53,7 @@ class Date
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DATE_DIFFERENCE_UNIT_MONTHS = 'months';
|
||||
public const DATE_DIFFERENCE_UNIT_MONTHS = 'months';
|
||||
|
||||
/**
|
||||
* The 'years' unit of date difference.
|
||||
@@ -59,114 +61,16 @@ class Date
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DATE_DIFFERENCE_UNIT_YEARS = 'years';
|
||||
|
||||
/**
|
||||
* Returns start and end date for given period.
|
||||
* The dates are returned in an array with indexes 'start' and 'end'.
|
||||
*
|
||||
* @param int $period The period, type of period. One of DatePeriod class constants, e.g. DatePeriod::LAST_WEEK.
|
||||
* @return DatePeriod
|
||||
*/
|
||||
public static function getDatesForPeriod($period)
|
||||
{
|
||||
$datePeriod = null;
|
||||
|
||||
if (DatePeriod::isCorrectPeriod($period)) {
|
||||
$dateStart = null;
|
||||
$dateEnd = null;
|
||||
|
||||
switch ($period) {
|
||||
case DatePeriod::LAST_WEEK:
|
||||
$thisWeekStart = new DateTime('this week');
|
||||
|
||||
$dateStart = clone $thisWeekStart;
|
||||
$dateEnd = clone $thisWeekStart;
|
||||
|
||||
$dateStart->sub(new DateInterval('P7D'));
|
||||
$dateEnd->sub(new DateInterval('P1D'));
|
||||
|
||||
break;
|
||||
case DatePeriod::THIS_WEEK:
|
||||
$dateStart = new DateTime('this week');
|
||||
|
||||
$dateEnd = clone $dateStart;
|
||||
$dateEnd->add(new DateInterval('P6D'));
|
||||
|
||||
break;
|
||||
case DatePeriod::NEXT_WEEK:
|
||||
$dateStart = new DateTime('this week');
|
||||
$dateStart->add(new DateInterval('P7D'));
|
||||
|
||||
$dateEnd = clone $dateStart;
|
||||
$dateEnd->add(new DateInterval('P6D'));
|
||||
|
||||
break;
|
||||
case DatePeriod::LAST_MONTH:
|
||||
$dateStart = new DateTime('first day of last month');
|
||||
$dateEnd = new DateTime('last day of last month');
|
||||
|
||||
break;
|
||||
case DatePeriod::THIS_MONTH:
|
||||
$lastMonth = self::getDatesForPeriod(DatePeriod::LAST_MONTH);
|
||||
$nextMonth = self::getDatesForPeriod(DatePeriod::NEXT_MONTH);
|
||||
|
||||
$dateStart = $lastMonth->getEndDate();
|
||||
$dateStart->add(new DateInterval('P1D'));
|
||||
|
||||
$dateEnd = $nextMonth->getStartDate();
|
||||
$dateEnd->sub(new DateInterval('P1D'));
|
||||
|
||||
break;
|
||||
case DatePeriod::NEXT_MONTH:
|
||||
$dateStart = new DateTime('first day of next month');
|
||||
$dateEnd = new DateTime('last day of next month');
|
||||
|
||||
break;
|
||||
case DatePeriod::LAST_YEAR:
|
||||
case DatePeriod::THIS_YEAR:
|
||||
case DatePeriod::NEXT_YEAR:
|
||||
$dateStart = new DateTime();
|
||||
$dateEnd = new DateTime();
|
||||
|
||||
if (DatePeriod::LAST_YEAR == $period || DatePeriod::NEXT_YEAR == $period) {
|
||||
$yearDifference = 1;
|
||||
|
||||
if (DatePeriod::LAST_YEAR == $period) {
|
||||
$yearDifference *= -1;
|
||||
}
|
||||
|
||||
$modifyString = sprintf('%s year', $yearDifference);
|
||||
$dateStart->modify($modifyString);
|
||||
$dateEnd->modify($modifyString);
|
||||
}
|
||||
|
||||
$year = $dateStart->format('Y');
|
||||
$dateStart->setDate($year, 1, 1);
|
||||
$dateEnd->setDate($year, 12, 31);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (null !== $dateStart && null !== $dateEnd) {
|
||||
$dateStart->setTime(0, 0, 0);
|
||||
$dateEnd->setTime(23, 59, 59);
|
||||
|
||||
$datePeriod = new DatePeriod($dateStart, $dateEnd);
|
||||
}
|
||||
}
|
||||
|
||||
return $datePeriod;
|
||||
}
|
||||
public const DATE_DIFFERENCE_UNIT_YEARS = 'years';
|
||||
|
||||
/**
|
||||
* Generates and returns random time (the hour, minute and second values)
|
||||
*
|
||||
* @param string $format (optional) Format of returned value. A string acceptable by the DateTime::format()
|
||||
* method.
|
||||
* @return string|null
|
||||
* @return null|string
|
||||
*/
|
||||
public static function generateRandomTime($format = 'H:i:s')
|
||||
public static function generateRandomTime($format = 'H:i:s'): ?string
|
||||
{
|
||||
$dateTime = new DateTime();
|
||||
|
||||
@@ -194,16 +98,15 @@ class Date
|
||||
$seconds[] = $i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare random time (hour, minute and second)
|
||||
*/
|
||||
// Prepare random time (hour, minute and second)
|
||||
$hour = $hours[array_rand($hours)];
|
||||
$minute = $minutes[array_rand($minutes)];
|
||||
$second = $seconds[array_rand($seconds)];
|
||||
|
||||
return $dateTime
|
||||
->setTime($hour, $minute, $second)
|
||||
->format($format);
|
||||
->format($format)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,113 +114,33 @@ class Date
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getCurrentDayOfWeek()
|
||||
public static function getCurrentDayOfWeek(): int
|
||||
{
|
||||
$now = new DateTime();
|
||||
|
||||
$year = $now->format('Y');
|
||||
$month = $now->format('m');
|
||||
$day = $now->format('d');
|
||||
$year = (int) $now->format('Y');
|
||||
$month = (int) $now->format('m');
|
||||
$day = (int) $now->format('d');
|
||||
|
||||
return self::getDayOfWeek($year, $month, $day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns day of week (number 0 to 6, 0 - sunday, 6 - saturday).
|
||||
* Based on the Zeller's algorithm (http://pl.wikipedia.org/wiki/Kalendarz_wieczny).
|
||||
*
|
||||
* @param int $year The year value
|
||||
* @param int $month The month value
|
||||
* @param int $day The day value
|
||||
*
|
||||
* @return int
|
||||
* @throws UnknownDatePartTypeException
|
||||
*/
|
||||
public static function getDayOfWeek($year, $month, $day)
|
||||
{
|
||||
$year = (int)$year;
|
||||
$month = (int)$month;
|
||||
$day = (int)$day;
|
||||
|
||||
/*
|
||||
* Oops, incorrect year
|
||||
*/
|
||||
if ($year <= 0) {
|
||||
throw new UnknownDatePartTypeException(DatePartType::YEAR, $year);
|
||||
}
|
||||
|
||||
/*
|
||||
* Oops, incorrect month
|
||||
*/
|
||||
if ($month < 1 || $month > 12) {
|
||||
throw new UnknownDatePartTypeException(DatePartType::MONTH, $month);
|
||||
}
|
||||
|
||||
/*
|
||||
* Oops, incorrect day
|
||||
*/
|
||||
if ($day < 1 || $day > 31) {
|
||||
throw new UnknownDatePartTypeException(DatePartType::DAY, $day);
|
||||
}
|
||||
|
||||
if ($month < 3) {
|
||||
$count = 0;
|
||||
$yearValue = $year - 1;
|
||||
} else {
|
||||
$count = 2;
|
||||
$yearValue = $year;
|
||||
}
|
||||
|
||||
$firstPart = floor(23 * $month / 9);
|
||||
$secondPart = floor($yearValue / 4);
|
||||
$thirdPart = floor($yearValue / 100);
|
||||
$fourthPart = floor($yearValue / 400);
|
||||
|
||||
return ($firstPart + $day + 4 + $year + $secondPart - $thirdPart + $fourthPart - $count) % 7;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns based on locale name of current weekday
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getCurrentDayOfWeekName()
|
||||
public static function getCurrentDayOfWeekName(): string
|
||||
{
|
||||
$now = new DateTime();
|
||||
|
||||
$year = $now->format('Y');
|
||||
$month = $now->format('m');
|
||||
$day = $now->format('d');
|
||||
$year = (int) $now->format('Y');
|
||||
$month = (int) $now->format('m');
|
||||
$day = (int) $now->format('d');
|
||||
|
||||
return self::getDayOfWeekName($year, $month, $day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns name of weekday based on locale
|
||||
*
|
||||
* @param int $year The year value
|
||||
* @param int $month The month value
|
||||
* @param int $day The day value
|
||||
* @return string
|
||||
*/
|
||||
public static function getDayOfWeekName($year, $month, $day)
|
||||
{
|
||||
$hour = 0;
|
||||
$minute = 0;
|
||||
$second = 0;
|
||||
|
||||
$time = mktime($hour, $minute, $second, $month, $day, $year);
|
||||
$name = strftime('%A', $time);
|
||||
|
||||
$encoding = mb_detect_encoding($name);
|
||||
|
||||
if (false === $encoding) {
|
||||
$name = mb_convert_encoding($name, 'UTF-8', 'ISO-8859-2');
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns difference between given dates.
|
||||
*
|
||||
@@ -333,9 +156,9 @@ class Date
|
||||
* If the unit of date difference is null, all units are returned in array (units are keys of the array).
|
||||
* Otherwise - one, integer value is returned.
|
||||
*
|
||||
* @param string|DateTime $dateStart The start date
|
||||
* @param string|DateTime $dateEnd The end date
|
||||
* @param int $differenceUnit (optional) Unit of date difference. One of this class
|
||||
* @param DateTime|string $dateStart The start date
|
||||
* @param DateTime|string $dateEnd The end date
|
||||
* @param string $differenceUnit (optional) Unit of date difference. One of this class
|
||||
* DATE_DIFFERENCE_UNIT_* constants. If is set to null all units are
|
||||
* returned in the array.
|
||||
* @return array|int
|
||||
@@ -356,11 +179,11 @@ class Date
|
||||
return null;
|
||||
}
|
||||
|
||||
$dateStart = self::getDateTime($dateStart, true);
|
||||
$dateEnd = self::getDateTime($dateEnd, true);
|
||||
$start = self::getDateTime($dateStart, true);
|
||||
$end = self::getDateTime($dateEnd, true);
|
||||
|
||||
$difference = [];
|
||||
$dateDiff = $dateEnd->getTimestamp() - $dateStart->getTimestamp();
|
||||
$dateDiff = $end->getTimestamp() - $start->getTimestamp();
|
||||
|
||||
$daysInSeconds = 0;
|
||||
$hoursInSeconds = 0;
|
||||
@@ -378,85 +201,71 @@ class Date
|
||||
self::DATE_DIFFERENCE_UNIT_MINUTES,
|
||||
];
|
||||
|
||||
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_YEARS == $differenceUnit) {
|
||||
$diff = $dateEnd->diff($dateStart);
|
||||
$differenceYear = self::DATE_DIFFERENCE_UNIT_YEARS === $differenceUnit;
|
||||
$differenceMonth = self::DATE_DIFFERENCE_UNIT_MONTHS === $differenceUnit;
|
||||
$differenceMinutes = self::DATE_DIFFERENCE_UNIT_MINUTES === $differenceUnit;
|
||||
|
||||
/*
|
||||
* Difference between dates in years should be returned only?
|
||||
*/
|
||||
if (self::DATE_DIFFERENCE_UNIT_YEARS == $differenceUnit) {
|
||||
if (null === $differenceUnit || $differenceYear) {
|
||||
$diff = $end->diff($start);
|
||||
|
||||
// Difference between dates in years should be returned only?
|
||||
if ($differenceYear) {
|
||||
return $diff->y;
|
||||
}
|
||||
|
||||
$difference[self::DATE_DIFFERENCE_UNIT_YEARS] = $diff->y;
|
||||
}
|
||||
|
||||
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MONTHS == $differenceUnit) {
|
||||
$diff = $dateEnd->diff($dateStart);
|
||||
if (null === $differenceUnit || $differenceMonth) {
|
||||
$diff = $end->diff($start);
|
||||
|
||||
/*
|
||||
* Difference between dates in months should be returned only?
|
||||
*/
|
||||
if (self::DATE_DIFFERENCE_UNIT_MONTHS == $differenceUnit) {
|
||||
// Difference between dates in months should be returned only?
|
||||
if ($differenceMonth) {
|
||||
return $diff->m;
|
||||
}
|
||||
|
||||
$difference[self::DATE_DIFFERENCE_UNIT_MONTHS] = $diff->m;
|
||||
}
|
||||
|
||||
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits)) {
|
||||
$days = (int)floor($dateDiff / $daySeconds);
|
||||
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
|
||||
$days = (int) floor($dateDiff / $daySeconds);
|
||||
|
||||
/*
|
||||
* Difference between dates in days should be returned only?
|
||||
*/
|
||||
if (self::DATE_DIFFERENCE_UNIT_DAYS == $differenceUnit) {
|
||||
// Difference between dates in days should be returned only?
|
||||
if (self::DATE_DIFFERENCE_UNIT_DAYS === $differenceUnit) {
|
||||
return $days;
|
||||
}
|
||||
|
||||
/*
|
||||
* All units should be returned?
|
||||
*/
|
||||
// All units should be returned?
|
||||
if (null === $differenceUnit) {
|
||||
$difference[self::DATE_DIFFERENCE_UNIT_DAYS] = $days;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculation for later usage
|
||||
*/
|
||||
// Calculation for later usage
|
||||
$daysInSeconds = $days * $daySeconds;
|
||||
}
|
||||
|
||||
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits)) {
|
||||
$hours = (int)floor(($dateDiff - $daysInSeconds) / $hourSeconds);
|
||||
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
|
||||
$hours = (int) floor(($dateDiff - $daysInSeconds) / $hourSeconds);
|
||||
|
||||
/*
|
||||
* Difference between dates in hours should be returned only?
|
||||
*/
|
||||
if (self::DATE_DIFFERENCE_UNIT_HOURS == $differenceUnit) {
|
||||
// Difference between dates in hours should be returned only?
|
||||
if (self::DATE_DIFFERENCE_UNIT_HOURS === $differenceUnit) {
|
||||
return $hours;
|
||||
}
|
||||
|
||||
/*
|
||||
* All units should be returned?
|
||||
*/
|
||||
// All units should be returned?
|
||||
if (null === $differenceUnit) {
|
||||
$difference[self::DATE_DIFFERENCE_UNIT_HOURS] = $hours;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculation for later usage
|
||||
*/
|
||||
// Calculation for later usage
|
||||
$hoursInSeconds = $hours * $hourSeconds;
|
||||
}
|
||||
|
||||
if (null === $differenceUnit || self::DATE_DIFFERENCE_UNIT_MINUTES == $differenceUnit) {
|
||||
$minutes = (int)floor(($dateDiff - $daysInSeconds - $hoursInSeconds) / 60);
|
||||
if (null === $differenceUnit || $differenceMinutes) {
|
||||
$minutes = (int) floor(($dateDiff - $daysInSeconds - $hoursInSeconds) / 60);
|
||||
|
||||
/*
|
||||
* Difference between dates in minutes should be returned only?
|
||||
*/
|
||||
if (self::DATE_DIFFERENCE_UNIT_MINUTES == $differenceUnit) {
|
||||
// Difference between dates in minutes should be returned only?
|
||||
if ($differenceMinutes) {
|
||||
return $minutes;
|
||||
}
|
||||
|
||||
@@ -466,85 +275,6 @@ class Date
|
||||
return $difference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns collection / set of dates for given start date and count of dates.
|
||||
* Start from given date, add next, iterated value to given date interval and returns requested count of dates.
|
||||
*
|
||||
* @param DateTime $startDate The start date. Start of the collection / set.
|
||||
* @param int $datesCount Count of dates in resulting collection / set
|
||||
* @param string $intervalTemplate (optional) Template used to build date interval. It should contain "%d" as the
|
||||
* placeholder which is replaced with a number that represents each iteration.
|
||||
* Default: interval for days.
|
||||
* @return array
|
||||
*/
|
||||
public static function getDatesCollection(DateTime $startDate, $datesCount, $intervalTemplate = 'P%dD')
|
||||
{
|
||||
$dates = [];
|
||||
|
||||
/*
|
||||
* The template used to build date interval have to be string.
|
||||
* Otherwise cannot run preg_match() function and an error occurs.
|
||||
*/
|
||||
if (is_string($intervalTemplate)) {
|
||||
/*
|
||||
* Let's verify the interval template. It should contains the "%d" placeholder and something before and
|
||||
* after it.
|
||||
*
|
||||
* Examples:
|
||||
* - P%dD
|
||||
* - P%dM
|
||||
* - P1Y%dMT1H
|
||||
*/
|
||||
$intervalPattern = '/^(\w*)\%d(\w*)$/';
|
||||
$matches = [];
|
||||
$matchCount = preg_match($intervalPattern, $intervalTemplate, $matches);
|
||||
|
||||
if ($matchCount > 0 && (!empty($matches[1]) || !empty($matches[2]))) {
|
||||
$datesCount = (int)$datesCount;
|
||||
|
||||
for ($index = 1; $index <= $datesCount; ++$index) {
|
||||
$date = clone $startDate;
|
||||
$dates[$index] = $date->add(new DateInterval(sprintf($intervalTemplate, $index)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns random date based on given start date
|
||||
*
|
||||
* @param DateTime $startDate The start date. Start of the random date.
|
||||
* @param int $start (optional) Start of random partition
|
||||
* @param int $end (optional) End of random partition
|
||||
* @param string $intervalTemplate (optional) Template used to build date interval. The placeholder is replaced
|
||||
* with next, iterated value.
|
||||
* @return DateTime
|
||||
*/
|
||||
public static function getRandomDate(DateTime $startDate = null, $start = 1, $end = 100, $intervalTemplate = 'P%sD')
|
||||
{
|
||||
if (null === $startDate) {
|
||||
$startDate = new DateTime();
|
||||
}
|
||||
|
||||
$start = (int)$start;
|
||||
$end = (int)$end;
|
||||
|
||||
/*
|
||||
* Incorrect end of random partition?
|
||||
* Use start as the end of random partition
|
||||
*/
|
||||
if ($end < $start) {
|
||||
$end = $start;
|
||||
}
|
||||
|
||||
$randomDate = clone $startDate;
|
||||
$randomInterval = new DateInterval(sprintf($intervalTemplate, rand($start, $end)));
|
||||
|
||||
return $randomDate->add($randomInterval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DateTime object for given value.
|
||||
* If the DateTime object cannot be created, false is returned.
|
||||
@@ -552,11 +282,12 @@ class Date
|
||||
* @param mixed $value The value which maybe is a date
|
||||
* @param bool $allowCompoundFormats (optional) If is set to true, the compound formats used to create an
|
||||
* instance of DateTime class are allowed (e.g. "now", "last day of next
|
||||
* month", "yyyy"). Otherwise - not and every incorrect value is refused.
|
||||
* month", "yyyy"). Otherwise - not and every incorrect value is refused
|
||||
* (default behaviour).
|
||||
* @param string $dateFormat (optional) Format of date used to verify if given value is actually a date.
|
||||
* It should be format matched to the given value, e.g. "Y-m-d H:i" for
|
||||
* "2015-01-01 10:00" value.
|
||||
* @return DateTime|bool
|
||||
* "2015-01-01 10:00" value. Default: "Y-m-d".
|
||||
* @return bool|DateTime
|
||||
*/
|
||||
public static function getDateTime($value, $allowCompoundFormats = false, $dateFormat = 'Y-m-d')
|
||||
{
|
||||
@@ -623,7 +354,7 @@ class Date
|
||||
* So, I have to refuse those special compound formats if they are not explicitly declared as
|
||||
* compound (2nd argument of this method, set to false by default)
|
||||
*/
|
||||
if (in_array($value, $specialFormats)) {
|
||||
if (in_array($value, $specialFormats, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -631,12 +362,10 @@ class Date
|
||||
* Verify instance of the DateTime created by constructor and by createFromFormat() method.
|
||||
* After formatting, these dates should be the same.
|
||||
*/
|
||||
else {
|
||||
if ($dateFromFormat->format($dateFormat) === $value) {
|
||||
return $date;
|
||||
}
|
||||
elseif ($dateFromFormat->format($dateFormat) === $value) {
|
||||
return $date;
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
} catch (Exception $exception) {
|
||||
if (!$allowCompoundFormats) {
|
||||
return false;
|
||||
}
|
||||
@@ -648,15 +377,284 @@ class Date
|
||||
*/
|
||||
$dateString = (new DateTime())->format($value);
|
||||
|
||||
if ($dateString != $value) {
|
||||
if ($dateString !== (string) $value) {
|
||||
return new DateTime($dateString);
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
} catch (Exception $exception) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns collection / set of dates for given start date and count of dates.
|
||||
* Start from given date, add next, iterated value to given date interval and returns requested count of dates.
|
||||
*
|
||||
* @param DateTime $startDate The start date. Start of the collection / set.
|
||||
* @param int $datesCount Count of dates in resulting collection / set
|
||||
* @param string $intervalTemplate (optional) Template used to build date interval. It should contain "%d" as the
|
||||
* placeholder which is replaced with a number that represents each iteration.
|
||||
* Default: interval for days.
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getDatesCollection(DateTime $startDate, $datesCount, $intervalTemplate = 'P%dD'): array
|
||||
{
|
||||
$dates = [];
|
||||
|
||||
/*
|
||||
* The template used to build date interval have to be string.
|
||||
* Otherwise cannot run preg_match() function and an error occurs.
|
||||
*/
|
||||
if (is_string($intervalTemplate)) {
|
||||
/*
|
||||
* Let's verify the interval template. It should contains the "%d" placeholder and something before and
|
||||
* after it.
|
||||
*
|
||||
* Examples:
|
||||
* - P%dD
|
||||
* - P%dM
|
||||
* - P1Y%dMT1H
|
||||
*/
|
||||
$intervalPattern = '/^(\w*)\%d(\w*)$/';
|
||||
$matches = [];
|
||||
$matchCount = preg_match($intervalPattern, $intervalTemplate, $matches);
|
||||
|
||||
if ($matchCount > 0 && (!empty($matches[1]) || !empty($matches[2]))) {
|
||||
$datesCount = (int) $datesCount;
|
||||
|
||||
for ($index = 1; $index <= $datesCount; ++$index) {
|
||||
$date = clone $startDate;
|
||||
$dates[$index] = $date->add(new DateInterval(sprintf($intervalTemplate, $index)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns date's period (that contains start and end date) for given period
|
||||
*
|
||||
* @param string $period The period, type of period. One of DatePeriod class constants, e.g. DatePeriod::LAST_WEEK.
|
||||
* @return null|DatePeriod
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getDatesForPeriod(string $period): ?DatePeriod
|
||||
{
|
||||
/*
|
||||
* Type of period is incorrect?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (!DatePeriod::isCorrectType($period)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dateStart = null;
|
||||
$dateEnd = null;
|
||||
|
||||
switch ($period) {
|
||||
case DatePeriod::LAST_WEEK:
|
||||
$thisWeekStart = new DateTime('this week');
|
||||
|
||||
$dateStart = clone $thisWeekStart;
|
||||
$dateEnd = clone $thisWeekStart;
|
||||
|
||||
$dateStart->sub(new DateInterval('P7D'));
|
||||
$dateEnd->sub(new DateInterval('P1D'));
|
||||
|
||||
break;
|
||||
case DatePeriod::THIS_WEEK:
|
||||
$dateStart = new DateTime('this week');
|
||||
|
||||
$dateEnd = clone $dateStart;
|
||||
$dateEnd->add(new DateInterval('P6D'));
|
||||
|
||||
break;
|
||||
case DatePeriod::NEXT_WEEK:
|
||||
$dateStart = new DateTime('this week');
|
||||
$dateStart->add(new DateInterval('P7D'));
|
||||
|
||||
$dateEnd = clone $dateStart;
|
||||
$dateEnd->add(new DateInterval('P6D'));
|
||||
|
||||
break;
|
||||
case DatePeriod::LAST_MONTH:
|
||||
$dateStart = new DateTime('first day of last month');
|
||||
$dateEnd = new DateTime('last day of last month');
|
||||
|
||||
break;
|
||||
case DatePeriod::THIS_MONTH:
|
||||
$lastMonth = self::getDatesForPeriod(DatePeriod::LAST_MONTH);
|
||||
$nextMonth = self::getDatesForPeriod(DatePeriod::NEXT_MONTH);
|
||||
|
||||
if (null !== $lastMonth) {
|
||||
$dateStart = $lastMonth->getEndDate();
|
||||
|
||||
if (null !== $dateStart) {
|
||||
$dateStart->add(new DateInterval('P1D'));
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $nextMonth) {
|
||||
$dateEnd = $nextMonth->getStartDate();
|
||||
|
||||
if (null !== $dateEnd) {
|
||||
$dateEnd->sub(new DateInterval('P1D'));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case DatePeriod::NEXT_MONTH:
|
||||
$dateStart = new DateTime('first day of next month');
|
||||
$dateEnd = new DateTime('last day of next month');
|
||||
|
||||
break;
|
||||
case DatePeriod::LAST_YEAR:
|
||||
case DatePeriod::THIS_YEAR:
|
||||
case DatePeriod::NEXT_YEAR:
|
||||
$dateStart = new DateTime();
|
||||
$dateEnd = new DateTime();
|
||||
|
||||
$yearPeriod = [
|
||||
DatePeriod::LAST_YEAR,
|
||||
DatePeriod::NEXT_YEAR,
|
||||
];
|
||||
|
||||
if (in_array($period, $yearPeriod, true)) {
|
||||
$yearDifference = 1;
|
||||
|
||||
if (DatePeriod::LAST_YEAR === $period) {
|
||||
$yearDifference *= -1;
|
||||
}
|
||||
|
||||
$modifyString = sprintf('%s year', $yearDifference);
|
||||
$dateStart->modify($modifyString);
|
||||
$dateEnd->modify($modifyString);
|
||||
}
|
||||
|
||||
$year = (int) $dateStart->format('Y');
|
||||
$dateStart->setDate($year, 1, 1);
|
||||
$dateEnd->setDate($year, 12, 31);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start or end date is unknown?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (null === $dateStart || null === $dateEnd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dateStart->setTime(0, 0);
|
||||
$dateEnd->setTime(23, 59, 59);
|
||||
|
||||
return new DatePeriod($dateStart, $dateEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns day of week (number 0 to 6, 0 - sunday, 6 - saturday).
|
||||
* Based on the Zeller's algorithm (https://en.wikipedia.org/wiki/Perpetual_calendar).
|
||||
*
|
||||
* @param int $year The year value
|
||||
* @param int $month The month value
|
||||
* @param int $day The day value
|
||||
*
|
||||
* @return int
|
||||
* @throws UnknownDatePartTypeException
|
||||
*/
|
||||
public static function getDayOfWeek(int $year, int $month, int $day): int
|
||||
{
|
||||
static::validateYear($year);
|
||||
static::validateMonth($month);
|
||||
static::validateDay($day);
|
||||
|
||||
if ($month < 3) {
|
||||
$count = 0;
|
||||
$yearValue = $year - 1;
|
||||
} else {
|
||||
$count = 2;
|
||||
$yearValue = $year;
|
||||
}
|
||||
|
||||
$firstPart = floor(23 * $month / 9);
|
||||
$secondPart = floor($yearValue / 4);
|
||||
$thirdPart = floor($yearValue / 100);
|
||||
$fourthPart = floor($yearValue / 400);
|
||||
|
||||
return ($firstPart + $day + 4 + $year + $secondPart - $thirdPart + $fourthPart - $count) % 7;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns name of weekday based on locale
|
||||
*
|
||||
* @param int $year The year value
|
||||
* @param int $month The month value
|
||||
* @param int $day The day value
|
||||
* @return string
|
||||
*/
|
||||
public static function getDayOfWeekName($year, $month, $day): string
|
||||
{
|
||||
$hour = 0;
|
||||
$minute = 0;
|
||||
$second = 0;
|
||||
|
||||
$time = mktime($hour, $minute, $second, $month, $day, $year);
|
||||
$name = strftime('%A', $time);
|
||||
|
||||
$encoding = mb_detect_encoding($name);
|
||||
|
||||
if (false === $encoding) {
|
||||
$name = mb_convert_encoding($name, 'UTF-8', 'ISO-8859-2');
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns random date based on given start date
|
||||
*
|
||||
* @param DateTime $startDate (optional) Beginning of the random date. If not provided, current date will
|
||||
* be used (default behaviour).
|
||||
* @param int $start (optional) Start of random partition. If not provided, 1 will be used
|
||||
* (default behaviour).
|
||||
* @param int $end (optional) End of random partition. If not provided, 100 will be used
|
||||
* (default behaviour).
|
||||
* @param string $intervalTemplate (optional) Template used to build date interval. The placeholder is replaced
|
||||
* with next, iterated value. If not provided, "P%sD" will be used (default
|
||||
* behaviour).
|
||||
* @return DateTime
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getRandomDate(
|
||||
DateTime $startDate = null,
|
||||
$start = 1,
|
||||
$end = 100,
|
||||
$intervalTemplate = 'P%sD'
|
||||
): DateTime {
|
||||
if (null === $startDate) {
|
||||
$startDate = new DateTime();
|
||||
}
|
||||
|
||||
$start = (int) $start;
|
||||
$end = (int) $end;
|
||||
|
||||
/*
|
||||
* Incorrect end of random partition?
|
||||
* Use start as the end of random partition
|
||||
*/
|
||||
if ($end < $start) {
|
||||
$end = $start;
|
||||
}
|
||||
|
||||
$randomDate = clone $startDate;
|
||||
$randomInterval = new DateInterval(sprintf($intervalTemplate, random_int($start, $end)));
|
||||
|
||||
return $randomDate->add($randomInterval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given value is valid date
|
||||
*
|
||||
@@ -666,7 +664,7 @@ class Date
|
||||
* month", "yyyy"). Otherwise - not and every incorrect value is refused.
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidDate($value, $allowCompoundFormats = false)
|
||||
public static function isValidDate($value, $allowCompoundFormats = false): bool
|
||||
{
|
||||
return self::getDateTime($value, $allowCompoundFormats) instanceof DateTime;
|
||||
}
|
||||
@@ -677,38 +675,77 @@ class Date
|
||||
* @param string $format The validated format of date
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidDateFormat($format)
|
||||
public static function isValidDateFormat($format): bool
|
||||
{
|
||||
if (empty($format) || !is_string($format)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Datetime to string
|
||||
*/
|
||||
$formatted = (new DateTime())->format($format);
|
||||
|
||||
/*
|
||||
* Formatted date it's the format who is validated?
|
||||
* The format is invalid
|
||||
*/
|
||||
if ($formatted == $format) {
|
||||
// Formatted date it's the format who is validated?
|
||||
// The format is invalid
|
||||
if ($formatted === $format) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the format used to create the datetime
|
||||
*/
|
||||
// Validate the format used to create the datetime
|
||||
$fromFormat = DateTime::createFromFormat($format, $formatted);
|
||||
|
||||
/*
|
||||
* It's instance of DateTime?
|
||||
* The format is valid
|
||||
*/
|
||||
// It's instance of DateTime?
|
||||
// The format is valid
|
||||
if ($fromFormat instanceof DateTime) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $fromFormat instanceof DateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies/validates given day
|
||||
*
|
||||
* @param int $day Day to verify/validate
|
||||
* @throws UnknownDatePartTypeException
|
||||
*/
|
||||
private static function validateDay(int $day): void
|
||||
{
|
||||
// Oops, given day is incorrect
|
||||
if ($day >= 1 && $day <= 31) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw UnknownDatePartTypeException::createException(DatePartType::DAY, $day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies/validates given month
|
||||
*
|
||||
* @param int $month Month to verify/validate
|
||||
* @throws UnknownDatePartTypeException
|
||||
*/
|
||||
private static function validateMonth(int $month): void
|
||||
{
|
||||
// Oops, given month is incorrect
|
||||
if ($month >= 1 && $month <= 12) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw UnknownDatePartTypeException::createException(DatePartType::MONTH, $month);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies/validates given year
|
||||
*
|
||||
* @param int $year Year to verify/validate
|
||||
* @throws UnknownDatePartTypeException
|
||||
*/
|
||||
private static function validateYear(int $year): void
|
||||
{
|
||||
// Oops, given year is incorrect
|
||||
if ($year >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw UnknownDatePartTypeException::createException(DatePartType::YEAR, $year);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ use Generator;
|
||||
/**
|
||||
* Useful methods for the Generator class (only static functions)
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class GeneratorUtility
|
||||
{
|
||||
|
||||
@@ -11,19 +11,17 @@ namespace Meritoo\Common\Utilities;
|
||||
/**
|
||||
* Useful locale methods
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class Locale
|
||||
{
|
||||
/**
|
||||
* Sets locale for given category using given language and country code
|
||||
* 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.
|
||||
* @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"
|
||||
* @return bool
|
||||
* @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
|
||||
@@ -34,32 +32,9 @@ class Locale
|
||||
* - LC_TIME for date and time formatting with strftime()
|
||||
* - LC_MESSAGES for system responses (available if PHP was compiled with libintl)
|
||||
*/
|
||||
public static function setLocale($category, $languageCode, $countryCode = '')
|
||||
public static function getLocale($category)
|
||||
{
|
||||
$category = (int)$category;
|
||||
|
||||
if (is_string($languageCode)) {
|
||||
$languageCode = trim($languageCode);
|
||||
}
|
||||
|
||||
$availableCategories = [
|
||||
LC_ALL,
|
||||
LC_COLLATE,
|
||||
LC_CTYPE,
|
||||
LC_MONETARY,
|
||||
LC_NUMERIC,
|
||||
LC_TIME,
|
||||
LC_MESSAGES,
|
||||
];
|
||||
|
||||
if (empty($languageCode) || !in_array($category, $availableCategories)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$localeLongForm = self::getLongForm($languageCode, $countryCode);
|
||||
setlocale($category, $localeLongForm);
|
||||
|
||||
return true;
|
||||
return setlocale($category, '0');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,4 +78,49 @@ class Locale
|
||||
|
||||
return sprintf('%s_%s%s', $languageCode, strtoupper($countryCode), $encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets locale for given category using given 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 (optional) Country code, in ISO 3166-1 alpha-2 format, e.g. "FR"
|
||||
* @return false|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 setLocale($category, $languageCode, $countryCode = '')
|
||||
{
|
||||
$category = (int) $category;
|
||||
|
||||
if (is_string($languageCode)) {
|
||||
$languageCode = trim($languageCode);
|
||||
}
|
||||
|
||||
$availableCategories = [
|
||||
LC_ALL,
|
||||
LC_COLLATE,
|
||||
LC_CTYPE,
|
||||
LC_MONETARY,
|
||||
LC_NUMERIC,
|
||||
LC_TIME,
|
||||
LC_MESSAGES,
|
||||
];
|
||||
|
||||
if (empty($languageCode) || !in_array($category, $availableCategories, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$localeLongForm = self::getLongForm($languageCode, $countryCode);
|
||||
|
||||
return setlocale($category, $localeLongForm);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -17,32 +17,80 @@ use Doctrine\ORM\QueryBuilder;
|
||||
/**
|
||||
* Useful methods for query builder (the Doctrine's QueryBuilder class)
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class QueryBuilderUtility
|
||||
{
|
||||
/**
|
||||
* Returns root alias of given query builder.
|
||||
* If null is returned, alias was not found.
|
||||
* Adds given parameters to given query builder.
|
||||
* Attention. Existing parameters will be overridden.
|
||||
*
|
||||
* @param QueryBuilder $queryBuilder The query builder to retrieve root alias
|
||||
* @return null|string
|
||||
* @param QueryBuilder $queryBuilder The query builder
|
||||
* @param array|ArrayCollection $parameters Parameters to add. Collection of Doctrine\ORM\Query\Parameter
|
||||
* instances or an array with key-value pairs.
|
||||
* @return QueryBuilder
|
||||
*/
|
||||
public static function getRootAlias(QueryBuilder $queryBuilder)
|
||||
public static function addParameters(QueryBuilder $queryBuilder, $parameters)
|
||||
{
|
||||
$aliases = $queryBuilder->getRootAliases();
|
||||
|
||||
if (empty($aliases)) {
|
||||
return null;
|
||||
/*
|
||||
* No parameters?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($parameters)) {
|
||||
return $queryBuilder;
|
||||
}
|
||||
|
||||
return Arrays::getFirstElement($aliases);
|
||||
foreach ($parameters as $key => $parameter) {
|
||||
$name = $key;
|
||||
$value = $parameter;
|
||||
|
||||
if ($parameter instanceof Parameter) {
|
||||
$name = $parameter->getName();
|
||||
$value = $parameter->getValue();
|
||||
}
|
||||
|
||||
$queryBuilder->setParameter($name, $value);
|
||||
}
|
||||
|
||||
return $queryBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes given entities
|
||||
*
|
||||
* @param EntityManager $entityManager The entity manager
|
||||
* @param array|ArrayCollection $entities The entities to delete
|
||||
* @param bool $flushDeleted (optional) If is set to true, flushes the deleted objects (default
|
||||
* behaviour). Otherwise - not.
|
||||
* @return bool
|
||||
*/
|
||||
public static function deleteEntities(EntityManager $entityManager, $entities, $flushDeleted = true)
|
||||
{
|
||||
/*
|
||||
* No entities provided?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($entities)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($entities as $entity) {
|
||||
$entityManager->remove($entity);
|
||||
}
|
||||
|
||||
// The deleted objects should be flushed?
|
||||
if ($flushDeleted) {
|
||||
$entityManager->flush();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param QueryBuilder $queryBuilder The query builder to verify
|
||||
@@ -53,6 +101,10 @@ class QueryBuilderUtility
|
||||
{
|
||||
$joins = $queryBuilder->getDQLPart('join');
|
||||
|
||||
/*
|
||||
* No joins?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($joins)) {
|
||||
return null;
|
||||
}
|
||||
@@ -61,7 +113,7 @@ class QueryBuilderUtility
|
||||
$pattern = sprintf($patternTemplate, $property);
|
||||
|
||||
foreach ($joins as $joinExpressions) {
|
||||
/* @var $expression Join */
|
||||
/** @var Join $expression */
|
||||
foreach ($joinExpressions as $expression) {
|
||||
$joinedProperty = $expression->getJoin();
|
||||
|
||||
@@ -74,6 +126,28 @@ class QueryBuilderUtility
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns root alias of given query builder.
|
||||
* If null is returned, alias was not found.
|
||||
*
|
||||
* @param QueryBuilder $queryBuilder The query builder to retrieve root alias
|
||||
* @return null|string
|
||||
*/
|
||||
public static function getRootAlias(QueryBuilder $queryBuilder)
|
||||
{
|
||||
$aliases = $queryBuilder->getRootAliases();
|
||||
|
||||
/*
|
||||
* No aliases?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($aliases)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Arrays::getFirstElement($aliases);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the WHERE criteria in given query builder
|
||||
*
|
||||
@@ -81,7 +155,7 @@ class QueryBuilderUtility
|
||||
* @param array $criteria (optional) The criteria used in WHERE clause. It may simple array with pairs
|
||||
* key-value or an array of arrays where second element of sub-array is the
|
||||
* comparison operator. Example below.
|
||||
* @param string $alias (optional) Alias used in the query
|
||||
* @param null|string $alias (optional) Alias used in the query
|
||||
* @return QueryBuilder
|
||||
*
|
||||
* Example of the $criteria argument:
|
||||
@@ -97,96 +171,45 @@ class QueryBuilderUtility
|
||||
* 'position' => 5,
|
||||
* ]
|
||||
*/
|
||||
public static function setCriteria(QueryBuilder $queryBuilder, array $criteria = [], $alias = '')
|
||||
{
|
||||
if (!empty($criteria)) {
|
||||
if (empty($alias)) {
|
||||
$alias = self::getRootAlias($queryBuilder);
|
||||
}
|
||||
|
||||
foreach ($criteria as $column => $value) {
|
||||
$compareOperator = '=';
|
||||
|
||||
if (is_array($value) && !empty($value)) {
|
||||
if (2 == count($value)) {
|
||||
$compareOperator = $value[1];
|
||||
}
|
||||
|
||||
$value = $value[0];
|
||||
}
|
||||
|
||||
$predicate = sprintf('%s.%s %s :%s', $alias, $column, $compareOperator, $column);
|
||||
|
||||
if (null === $value) {
|
||||
$predicate = $queryBuilder->expr()->isNull(sprintf('%s.%s', $alias, $column));
|
||||
unset($criteria[$column]);
|
||||
} else {
|
||||
$queryBuilder->setParameter($column, $value);
|
||||
}
|
||||
|
||||
$queryBuilder = $queryBuilder->andWhere($predicate);
|
||||
}
|
||||
}
|
||||
|
||||
return $queryBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes given entities
|
||||
*
|
||||
* @param EntityManager $entityManager The entity manager
|
||||
* @param array|ArrayCollection $entities The entities to delete
|
||||
* @param bool $flushDeleted (optional) If is set to true, flushes the deleted objects.
|
||||
* Otherwise - not.
|
||||
* @return bool
|
||||
*/
|
||||
public static function deleteEntities(EntityManager $entityManager, $entities, $flushDeleted = true)
|
||||
public static function setCriteria(QueryBuilder $queryBuilder, array $criteria = [], $alias = null)
|
||||
{
|
||||
/*
|
||||
* No entities found?
|
||||
* No criteria used in WHERE clause?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($entities)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($entities as $entity) {
|
||||
$entityManager->remove($entity);
|
||||
if (empty($criteria)) {
|
||||
return $queryBuilder;
|
||||
}
|
||||
|
||||
/*
|
||||
* The deleted objects should be flushed?
|
||||
* No alias provided?
|
||||
* Let's use root alias
|
||||
*/
|
||||
if ($flushDeleted) {
|
||||
$entityManager->flush();
|
||||
if (null === $alias || '' === $alias) {
|
||||
$alias = self::getRootAlias($queryBuilder);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
foreach ($criteria as $column => $value) {
|
||||
$compareOperator = '=';
|
||||
|
||||
/**
|
||||
* Adds given parameters to given query builder.
|
||||
* Attention. Existing parameters will be overridden.
|
||||
*
|
||||
* @param QueryBuilder $queryBuilder The query builder
|
||||
* @param array|ArrayCollection $parameters Parameters to add. Collection of instances of
|
||||
* Doctrine\ORM\Query\Parameter class or an array with key-value pairs.
|
||||
* @return QueryBuilder
|
||||
*/
|
||||
public static function addParameters(QueryBuilder $queryBuilder, $parameters)
|
||||
{
|
||||
if (!empty($parameters)) {
|
||||
foreach ($parameters as $key => $parameter) {
|
||||
$name = $key;
|
||||
$value = $parameter;
|
||||
|
||||
if ($parameter instanceof Parameter) {
|
||||
$name = $parameter->getName();
|
||||
$value = $parameter->getValue();
|
||||
if (is_array($value) && !empty($value)) {
|
||||
if (2 === count($value)) {
|
||||
$compareOperator = $value[1];
|
||||
}
|
||||
|
||||
$queryBuilder->setParameter($name, $value);
|
||||
$value = $value[0];
|
||||
}
|
||||
|
||||
$predicate = sprintf('%s.%s %s :%s', $alias, $column, $compareOperator, $column);
|
||||
|
||||
if (null === $value) {
|
||||
$predicate = $queryBuilder->expr()->isNull(sprintf('%s.%s', $alias, $column));
|
||||
unset($criteria[$column]);
|
||||
} else {
|
||||
$queryBuilder->setParameter($column, $value);
|
||||
}
|
||||
|
||||
$queryBuilder = $queryBuilder->andWhere($predicate);
|
||||
}
|
||||
|
||||
return $queryBuilder;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user