mirror of
https://github.com/wiosna-dev/common-library.git
synced 2026-03-12 01:31:45 +01:00
Compare commits
350 Commits
0.0.5
...
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 | ||
|
|
9dac5bd11c | ||
|
|
12100db058 | ||
|
|
f9ab0a6194 | ||
|
|
b824808cd4 | ||
|
|
71e1eeb81b | ||
|
|
70c273750d | ||
|
|
e5e39651f3 | ||
|
|
4683970c87 | ||
|
|
559466c0ce | ||
|
|
bfd69c1098 | ||
|
|
45493b37b0 | ||
|
|
37e7b14ae2 | ||
|
|
a12aaf4bc0 | ||
|
|
f9c480aa19 | ||
|
|
ffa3fbffe7 | ||
|
|
48aa27fb86 | ||
|
|
86cc5ff79b | ||
|
|
633696ebc0 | ||
|
|
a0d28b326e | ||
|
|
318a635ffd | ||
|
|
6c70fdd673 | ||
|
|
204e8793ac | ||
|
|
3dd37ae202 | ||
|
|
ef017c9d6a | ||
|
|
5030dc2062 | ||
|
|
2c76158093 | ||
|
|
0b560fdf18 | ||
|
|
284d403061 | ||
|
|
7dbb3f9b2e | ||
|
|
fba821b798 | ||
|
|
3985c70076 | ||
|
|
921d4e6106 | ||
|
|
7aa2239dbd | ||
|
|
e1fefcdeae | ||
|
|
94a464cb4d | ||
|
|
463ee751b2 | ||
|
|
89af7145f6 | ||
|
|
09c8569938 | ||
|
|
5ab2cd9de8 | ||
|
|
60eff29e82 |
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
|
||||
15
.env
Normal file
15
.env
Normal file
@@ -0,0 +1,15 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
### Docker
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# All containers
|
||||
#
|
||||
DOCKER_CONTAINER_OWNER=meritoo
|
||||
DOCKER_CONTAINER_PROJECT=common-library
|
||||
|
||||
#
|
||||
# PHP configuration:
|
||||
# - timezone
|
||||
#
|
||||
PHP_DATE_TIMEZONE=Europe/London
|
||||
252
.gitignore
vendored
252
.gitignore
vendored
@@ -1,79 +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.phar
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### Phing
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/phing/properties
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### PHPUnit
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/phpunit.xml
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### PHP Coding Standards Fixer generated files
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/.php_cs.cache
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### Generated databases
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/data/tmp
|
||||
*.sql
|
||||
*.sqlite
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### Compiled source
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### Shell scripts
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/*.sh
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### JetBrains
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
/.idea
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### NetBeans template
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
nbactions.xml
|
||||
.nb-gradle/
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
### OSX template
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
# ------------------------------------------------------------------------------
|
||||
### macOS template
|
||||
# ------------------------------------------------------------------------------
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
@@ -91,6 +37,7 @@ Icon
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
@@ -100,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/
|
||||
@@ -131,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
|
||||
|
||||
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)
|
||||
;
|
||||
|
||||
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
|
||||
23
.travis.yml
Normal file
23
.travis.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 7.2
|
||||
- 7.3
|
||||
- 7.4
|
||||
|
||||
before_install:
|
||||
- sudo locale-gen de_DE.UTF-8 es_ES.UTF-8 en_GB.UTF-8 en_US.UTF-8 fr_FR.UTF-8 it_IT.UTF-8 pl_PL.UTF-8 ru_RU.UTF-8
|
||||
- pear channel-discover pear.phing.info
|
||||
|
||||
install:
|
||||
- pear install phing/phing
|
||||
- phpenv rehash
|
||||
|
||||
before_script:
|
||||
- phpenv config-add .travis-php-config.ini
|
||||
|
||||
script:
|
||||
- phing
|
||||
|
||||
after_success:
|
||||
- travis_retry php vendor/bin/php-coveralls -v
|
||||
185
CHANGELOG.md
Normal file
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
|
||||
56
README.md
56
README.md
@@ -1,25 +1,49 @@
|
||||
# Meritoo Common Library
|
||||
Useful classes, methods, extensions etc.
|
||||
|
||||
## Installation
|
||||
Common and useful classes, methods, exceptions etc.
|
||||
|
||||
Run [Composer](https://getcomposer.org) to install new package:
|
||||

|
||||
[](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)
|
||||
|
||||
```bash
|
||||
$ composer require meritoo/common-library
|
||||
```
|
||||
# Installation
|
||||
|
||||
> How to install Composer: https://getcomposer.org/download
|
||||
In your `composer.json` add address of repository into `repositories` section:
|
||||
|
||||
## Usage
|
||||
|
||||
This package contains a lot of static methods, so usage is not so complicated. Just run the static method who would you like to use. Example:
|
||||
|
||||
```php
|
||||
use Meritoo\Common\Utilities\Arrays;
|
||||
|
||||
$firstElement = Arrays::getFirstElement(['lorem' 'ipsum']);
|
||||
// result: "lorem"
|
||||
```json
|
||||
"repositories": [
|
||||
(...)
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/wiosna-dev/common-library"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Run [Composer](https://getcomposer.org) to install this package in your project:
|
||||
|
||||
```bash
|
||||
composer require wiosna-dev/common-library
|
||||
```
|
||||
|
||||
> [How to install Composer?](https://getcomposer.org/download)
|
||||
|
||||
# Usage
|
||||
|
||||
1. [Base test case (with common methods and data providers)](docs/Base-test-case.md)
|
||||
2. [Collection of elements](docs/Collection/BaseCollection.md)
|
||||
3. [Exceptions](docs/Static-methods.md)
|
||||
4. [Static methods](docs/Static-methods.md)
|
||||
1. [Arrays](docs/Static-methods/Arrays.md)
|
||||
2. [Regex](docs/Static-methods/Regex.md)
|
||||
3. [Uri](docs/Static-methods/Uri.md)
|
||||
5. [Value Objects](docs/Value-Objects.md)
|
||||
|
||||
# Development
|
||||
|
||||
More information [you can find here](docs/Development.md)
|
||||
|
||||
Enjoy!
|
||||
|
||||
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.5",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Meritoo.pl",
|
||||
@@ -11,24 +10,37 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.6.0",
|
||||
"doctrine/orm": "^2.5",
|
||||
"gedmo/doctrine-extensions": "^2.4",
|
||||
"symfony/http-foundation": "^3.3"
|
||||
"php": "^7.4 || ^8.0",
|
||||
"ext-dom": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-simplexml": "*",
|
||||
"doctrine/orm": "^2.6",
|
||||
"gedmo/doctrine-extensions": "^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8 || ^5.0",
|
||||
"squizlabs/php_codesniffer": "^2.8",
|
||||
"phpmd/phpmd": "^2.6",
|
||||
"sebastian/phpcpd": "^3.0",
|
||||
"pdepend/pdepend": "^2.5",
|
||||
"phploc/phploc": "^3.0",
|
||||
"friendsofphp/php-cs-fixer": "^2.1"
|
||||
"friendsofphp/php-cs-fixer": "^3.11",
|
||||
"infection/infection": "^0.26",
|
||||
"php-coveralls/php-coveralls": "^2.5",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpunit/phpunit": "^9",
|
||||
"sebastian/phpcpd": "^6.0",
|
||||
"squizlabs/php_codesniffer": "^3.7",
|
||||
"vimeo/psalm": "^4.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Meritoo\\Common\\": "src/Meritoo/Common/",
|
||||
"Meritoo\\Common\\Test\\": "tests/Meritoo/Common/Test/"
|
||||
"Meritoo\\Common\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Meritoo\\Test\\Common\\": "tests/"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
|
||||
3518
composer.lock
generated
3518
composer.lock
generated
File diff suppressed because it is too large
Load Diff
33
docker-compose.yml
Normal file
33
docker-compose.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
#
|
||||
# Required to run project
|
||||
#
|
||||
php:
|
||||
image: meritoo/php:7.4
|
||||
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-php
|
||||
entrypoint: php
|
||||
command: -S 0.0.0.0:9999
|
||||
environment:
|
||||
PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE}
|
||||
volumes:
|
||||
- .:/var/www/application:cached
|
||||
composer:
|
||||
image: meritoo/php:7.4
|
||||
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-composer
|
||||
entrypoint: php -d memory_limit=-1 /usr/local/bin/composer
|
||||
volumes:
|
||||
- .:/var/www/application:cached
|
||||
#
|
||||
# Required to run PHPUnit's tests
|
||||
#
|
||||
phpunit:
|
||||
image: meritoo/php:7.4
|
||||
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-phpunit
|
||||
entrypoint: ./vendor/bin/phpunit
|
||||
command: --version
|
||||
volumes:
|
||||
- .:/var/www/application:cached
|
||||
environment:
|
||||
XDEBUG_MODE: coverage
|
||||
63
docs/Base-test-case.md
Normal file
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"
|
||||
}
|
||||
}
|
||||
168
phing/app.xml
168
phing/app.xml
@@ -1,79 +1,169 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.14.0">
|
||||
|
||||
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
|
||||
<!-- Properties -->
|
||||
<if>
|
||||
<available file="phing/properties" property="custom.properties.available"/>
|
||||
<available file="${project.basedir}/phing/properties" property="custom.properties.available" />
|
||||
<then>
|
||||
<property file="phing/properties" />
|
||||
<property file="${project.basedir}/phing/properties" />
|
||||
</then>
|
||||
<else>
|
||||
<property file="phing/properties.dist" />
|
||||
<property file="${project.basedir}/phing/properties.dist" />
|
||||
</else>
|
||||
</if>
|
||||
|
||||
<!-- Filesets -->
|
||||
<import file="${project.basedir}/phing/filesets.xml" />
|
||||
|
||||
<!-- Default / main target -->
|
||||
<target name="build:main"
|
||||
depends="build:app"
|
||||
description="Builds the application" />
|
||||
/>
|
||||
|
||||
<!-- App target -->
|
||||
<target name="build:app"
|
||||
depends="app:composer, app:vendors, app:checkout"
|
||||
description="Prepares app to build." />
|
||||
|
||||
<!-- Check / update composer -->
|
||||
<target name="app:composer" description="Checks / updates composer">
|
||||
<echo msg="Checking / updating composer..." />
|
||||
depends="app:clean,
|
||||
app:composer:self-update,
|
||||
app:composer:install,
|
||||
app:composer:validate,
|
||||
app:checkout"
|
||||
/>
|
||||
|
||||
<!-- Updates Composer -->
|
||||
<target name="app:composer:self-update">
|
||||
<if>
|
||||
<available file="composer.phar" />
|
||||
<not>
|
||||
<available file="${composer.path}" property="composer.local.unavailable" />
|
||||
</not>
|
||||
<then>
|
||||
<echo msg="[Skipped] Downloading of Composer skipped, because exist in the project..." />
|
||||
</then>
|
||||
<else>
|
||||
<if>
|
||||
<os family="windows" />
|
||||
<then>
|
||||
<fail message="Composer not found! Go to http://getcomposer.org/download and download the Composer." />
|
||||
</then>
|
||||
<else>
|
||||
<exec command="${composer.download_command}" checkreturn="true" />
|
||||
<exec command="${composer.download_command}" checkreturn="true" passthru="true" />
|
||||
</else>
|
||||
</if>
|
||||
</else>
|
||||
</then>
|
||||
</if>
|
||||
<composer command="selfupdate" />
|
||||
|
||||
<!-- Update Composer -->
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="selfupdate">
|
||||
<arg value="--ansi" />
|
||||
</composer>
|
||||
</target>
|
||||
|
||||
<!-- Project Install/update vendors -->
|
||||
<target name="app:vendors" description="Installs / updates vendors">
|
||||
<echo msg="Installing / updating vendors..." />
|
||||
|
||||
<if>
|
||||
<istrue value="${composer.self-update}"/>
|
||||
<then>
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="self-update"/>
|
||||
</then>
|
||||
</if>
|
||||
|
||||
<if>
|
||||
<istrue value="${composer.validate}"/>
|
||||
<then>
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="validate"/>
|
||||
</then>
|
||||
</if>
|
||||
<!-- Validates composer.* files -->
|
||||
<target name="app:composer:validate" depends="app:composer:install">
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="validate">
|
||||
<arg value="--no-check-all" />
|
||||
<arg value="--strict" />
|
||||
<arg value="--ansi" />
|
||||
</composer>
|
||||
</target>
|
||||
|
||||
<!-- Project clean -->
|
||||
<target name="app:clean">
|
||||
<if>
|
||||
<equals arg1="${env}" arg2="prod" />
|
||||
<then>
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="install">
|
||||
<arg value="--optimize-autoloader" />
|
||||
</composer>
|
||||
<echo message="[Skipped] Cleaning project (and directories cleanup) -> 'prod' environment" />
|
||||
</then>
|
||||
<else>
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="install" />
|
||||
<foreach list="${directoriesToEmpty}" param="directory" target="app:clean:empty" />
|
||||
</else>
|
||||
</if>
|
||||
|
||||
<foreach list="${directoriesToCheck}" param="directory" target="app:clean:check" />
|
||||
<foreach list="${directoriesToEmpty}" param="directory" target="app:permissions" />
|
||||
</target>
|
||||
|
||||
<!-- Cleaning directory (making empty) directory -->
|
||||
<target name="app:clean:empty">
|
||||
<if>
|
||||
<available file="${directory}" type="dir" property="dir_is_available" />
|
||||
<then>
|
||||
<delete includeemptydirs="true" dir="${directory}" />
|
||||
</then>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<!-- Checking if directory exists -->
|
||||
<target name="app:clean:check">
|
||||
<if>
|
||||
<not>
|
||||
<available file="${directory}" type="dir" property="dir_is_available" />
|
||||
</not>
|
||||
<then>
|
||||
<if>
|
||||
<or>
|
||||
<contains string="${directory}" substring="cache" />
|
||||
<contains string="${directory}" substring="logs" />
|
||||
<contains string="${directory}" substring="sessions" />
|
||||
</or>
|
||||
<then>
|
||||
<mkdir dir="${directory}" mode="0777" />
|
||||
</then>
|
||||
<else>
|
||||
<mkdir dir="${directory}" mode="0775" />
|
||||
</else>
|
||||
</if>
|
||||
</then>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<!-- Installs vendors -->
|
||||
<target name="app:composer:install" depends="app:composer:self-update">
|
||||
<composer php="${composer.php}" composer="${composer.path}" command="install">
|
||||
<arg value="--optimize-autoloader" />
|
||||
<arg value="--ansi" />
|
||||
</composer>
|
||||
</target>
|
||||
|
||||
<!-- Clearing cache -->
|
||||
<target name="app:cache">
|
||||
<if>
|
||||
<istrue value="${cache.clearWithWarmup}" />
|
||||
<then>
|
||||
<SymfonyConsole console="bin/console" command="cache:clear">
|
||||
<arg name="env" value="${env}" />
|
||||
</SymfonyConsole>
|
||||
</then>
|
||||
<else>
|
||||
<SymfonyConsole console="bin/console" command="cache:clear">
|
||||
<arg name="env" value="${env}" />
|
||||
<arg name="no-warmup" />
|
||||
</SymfonyConsole>
|
||||
</else>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<!-- Clearing cache (faster) -->
|
||||
<target name="app:cache:faster">
|
||||
<SymfonyConsole console="bin/console" command="cache:clear">
|
||||
<arg name="env" value="${env}" />
|
||||
<arg name="no-optional-warmers" />
|
||||
</SymfonyConsole>
|
||||
</target>
|
||||
|
||||
<!-- Warming up cache -->
|
||||
<target name="app:cache:warmup">
|
||||
<SymfonyConsole console="bin/console" command="cache:warmup">
|
||||
<arg name="env" value="${env}" />
|
||||
</SymfonyConsole>
|
||||
</target>
|
||||
|
||||
<!-- Setting permissions of given directory -->
|
||||
<target name="app:permissions">
|
||||
<if>
|
||||
<not>
|
||||
<os family="windows" />
|
||||
</not>
|
||||
<then>
|
||||
<exec command="chmod -R 777 ${directory}/*" />
|
||||
</then>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<!-- Checkout and finalization -->
|
||||
|
||||
20
phing/composer-install.sh
Normal file
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>
|
||||
@@ -1,19 +1,3 @@
|
||||
# --------------------------------------------------------------------------------
|
||||
# Information
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# Property files contain key/value pairs
|
||||
# key = value
|
||||
#
|
||||
# Property keys may contain alphanumeric chars and colons, but
|
||||
# not special chars. This way you can create pseudo-namespaces
|
||||
#
|
||||
# You can refer to values of other properties by enclosing their keys in "${}".
|
||||
# Example: dir.js = ${dir.web}/js
|
||||
#
|
||||
# Everything behind the equal sign is the value, you do
|
||||
# not have to enclose strings: text=This is some text, Your OS is ${php.os}
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Common, e.g. default environment
|
||||
# --------------------------------------------------------------------------------
|
||||
@@ -22,104 +6,84 @@
|
||||
#
|
||||
env = dev
|
||||
|
||||
# Install assets using symlinks
|
||||
#
|
||||
assets.installWithSymlink = true
|
||||
|
||||
# Clear cache with the "warmup" option
|
||||
#
|
||||
cache.clearWithWarmup = true
|
||||
# The cache:clear command should always be called with the --no-warmup option. Warmup should be done via the cache:warmup command.
|
||||
# https://github.com/symfony/symfony/blob/master/UPGRADE-3.3.md#frameworkbundle
|
||||
#
|
||||
# Meritoo <github@meritoo.pl>
|
||||
# 2017-06-06
|
||||
#
|
||||
cache.clearWithWarmup = false
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Composer
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
composer.download_command = php -r "eval('?>'.file_get_contents('https://getcomposer.org/installer'));"
|
||||
|
||||
# Path to composer executable or composer.phar file
|
||||
# Command used to download Composer
|
||||
#
|
||||
composer.path = composer.phar
|
||||
#composer.path = /usr/local/bin/composer
|
||||
composer.download_command = bash ${project.basedir}/phing/composer-install.sh
|
||||
|
||||
# Path to php executable used by composer
|
||||
# Path to Composer executable or downloaded composer.phar file
|
||||
#
|
||||
composer.path = ${project.basedir}/composer.phar
|
||||
|
||||
# Path to PHP executable used by Composer
|
||||
#
|
||||
composer.php = php
|
||||
|
||||
# Self update of the composer
|
||||
#
|
||||
composer.self-update = false
|
||||
|
||||
# Validate the composer.json file
|
||||
#
|
||||
composer.validate = false
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Directories
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# System directories
|
||||
#
|
||||
dir.data = ${project.basedir}/data
|
||||
dir.src = ${project.basedir}/src
|
||||
dir.data = ${project.basedir}/data
|
||||
dir.tests = ${project.basedir}/tests
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Build directories
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
dir.build = ${project.basedir}/build
|
||||
dir.reports = ${dir.build}/logs
|
||||
dir.reports.pdepend = ${dir.reports}/pdepend
|
||||
dir.reports.coverage = ${dir.reports}/phpunit_coverage
|
||||
#
|
||||
# Disabled, because unnecessary right now
|
||||
# phpdocumentor/phpdocumentor cannot be installed via Composer
|
||||
#
|
||||
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
# 2017-02-22
|
||||
#
|
||||
#dir.docs = ${dir.build}/docs
|
||||
#dir.docs.phpdoc2 = ${dir.docs}/phpdoc2
|
||||
dir.reports = ${dir.build}/reports
|
||||
dir.reports.coverage = ${dir.reports}/phpunit-coverage
|
||||
dir.reports.code_sniffer = ${dir.reports}/code_sniffer
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Data directories
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
dir.data.tests = ${dir.data}/tests
|
||||
dir.data.temporary = ${dir.data}/tmp
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Static Analysis
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# Paths of frameworks used to run analysis:
|
||||
# - PHPStan
|
||||
#
|
||||
check.phpstan.command = ./vendor/bin/phpstan analyse
|
||||
check.psalm.command = ./vendor/bin/psalm --report=build/reports/psalm.json
|
||||
check.php_coveralls.command = ./vendor/bin/php-coveralls --ansi -v
|
||||
|
||||
# --------------------------------------------------------------------------------
|
||||
# Testing
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
# Path of the PHP Coding Standards Fixer (http://cs.sensiolabs.org)
|
||||
#
|
||||
tests.cs_fixer.command = ./vendor/bin/php-cs-fixer fix --verbose
|
||||
|
||||
# Path of the PHP_CodeSniffer (https://github.com/squizlabs/PHP_CodeSniffer)
|
||||
#
|
||||
tests.code_sniffer.command = ./vendor/bin/phpcs --report-full=${dir.reports.code_sniffer}/full.txt --report-summary=${dir.reports.code_sniffer}/summary.txt --report-checkstyle=${dir.reports.code_sniffer}/checkstyle.xml
|
||||
|
||||
# Test database path
|
||||
#
|
||||
tests.database = ${dir.data.temporary}/database.sqlite
|
||||
|
||||
# Paths of frameworks used to run tests:
|
||||
# - PHPUnit (unit tests)
|
||||
# - Infection (mutation tests)
|
||||
#
|
||||
# Disabled, because unnecessary right now
|
||||
# PHPUnit is installed and loaded by Composer
|
||||
#
|
||||
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
# 2017-02-22
|
||||
#
|
||||
# Run PHPUnit using exec task instead of phpunitTask
|
||||
#phpunit.useExec = false
|
||||
|
||||
#
|
||||
# Disabled, because unnecessary right now
|
||||
# We want generate code coverage always
|
||||
#
|
||||
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
# 2017-02-22
|
||||
#
|
||||
# Collect coverage data during tests
|
||||
#phpunit.withCoverage = true
|
||||
|
||||
# Path of the PHPUnit (https://phpunit.de)
|
||||
#
|
||||
phpUnit.path = ./vendor/bin/phpunit
|
||||
|
||||
# Path of the PHP Coding Standards Fixer (http://cs.sensiolabs.org)
|
||||
#
|
||||
phpCsFixer.path = ./vendor/bin/php-cs-fixer
|
||||
tests.phpunit.command = ./vendor/bin/phpunit --verbose
|
||||
tests.mutation.command = ./vendor/bin/infection --ansi --threads=$(nproc) --coverage=build/reports/infection
|
||||
|
||||
300
phing/tests.xml
300
phing/tests.xml
@@ -1,22 +1,16 @@
|
||||
<?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
|
||||
-->
|
||||
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
|
||||
<autoloader />
|
||||
|
||||
<!-- Properties -->
|
||||
<if>
|
||||
<available file="phing/properties" property="custom.properties.available"/>
|
||||
<available file="${project.basedir}/phing/properties" property="custom.properties.available" />
|
||||
<then>
|
||||
<property file="phing/properties" />
|
||||
<property file="${project.basedir}/phing/properties" />
|
||||
</then>
|
||||
<else>
|
||||
<property file="phing/properties.dist" />
|
||||
<property file="${project.basedir}/phing/properties.dist" />
|
||||
</else>
|
||||
</if>
|
||||
|
||||
@@ -35,271 +29,85 @@
|
||||
|
||||
<!-- Default / main target -->
|
||||
<target name="build:main"
|
||||
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, app:checkout"
|
||||
description="Runs all tests and builds everything" />
|
||||
<!--
|
||||
Before:
|
||||
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, build:doc, app:checkout"
|
||||
|
||||
After:
|
||||
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, app:checkout"
|
||||
|
||||
The "build:doc" task is disabled, because it cannot be installed via Composer:
|
||||
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
|
||||
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
-->
|
||||
depends="build:fix-coding-standards,
|
||||
build:check,
|
||||
build:test,
|
||||
app:checkout"
|
||||
/>
|
||||
|
||||
<!-- Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org) -->
|
||||
<target name="build:fix-coding-standards" description="Fixes coding standards using the PHP Coding Standards Fixer">
|
||||
<echo msg="Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org)..." />
|
||||
|
||||
<!--
|
||||
Attention.
|
||||
Rules for formatting are defined in /.php_cs.dist file.
|
||||
-->
|
||||
|
||||
<exec
|
||||
passthru="true"
|
||||
command="${phpCsFixer.path} fix --verbose"
|
||||
/>
|
||||
<target name="build:fix-coding-standards">
|
||||
<exec command="${tests.cs_fixer.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- Doc target -->
|
||||
<!--
|
||||
Disabled, because it cannot be installed via Composer:
|
||||
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
|
||||
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
-->
|
||||
<!--<target name="build:doc"-->
|
||||
<!--depends="build:prepare, doc:phpdoc2"-->
|
||||
<!--description="Generates API documentation" />-->
|
||||
|
||||
<!-- Check target -->
|
||||
<target name="build:check"
|
||||
depends="check:cs, check:md, check:cpd, check:depend, check:loc"
|
||||
description="Analyzes code" />
|
||||
depends="check:cs,
|
||||
check:cpd,
|
||||
check:phpstan,
|
||||
check:psalm,
|
||||
check:coveralls"
|
||||
/>
|
||||
|
||||
<!-- Test target -->
|
||||
<target name="build:test"
|
||||
depends="test:phpunit"
|
||||
description="Executes all tests" />
|
||||
depends="test:phpunit,
|
||||
test:infection"
|
||||
/>
|
||||
|
||||
<!-- Project build clean -->
|
||||
<target name="build:clean" description="Cleans up build directories">
|
||||
<echo msg="Cleaning docs and reports directories..." />
|
||||
<!--<delete dir="${dir.docs}" />-->
|
||||
<delete dir="${dir.reports}" />
|
||||
</target>
|
||||
|
||||
<!-- Project build prepare -->
|
||||
<target name="build:prepare" description="Create build directories">
|
||||
<echo msg="Creating build directories..." />
|
||||
<!--<mkdir dir="${dir.docs}" />-->
|
||||
<!--<mkdir dir="${dir.docs.phpdoc2}" />-->
|
||||
<mkdir dir="${dir.reports}" />
|
||||
<mkdir dir="${dir.reports.coverage}" />
|
||||
<mkdir dir="${dir.reports.pdepend}" />
|
||||
</target>
|
||||
|
||||
<!-- PHPDocumentor2 API documentation target -->
|
||||
<!--
|
||||
Disabled, because it cannot be installed via Composer:
|
||||
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
|
||||
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
|
||||
<target name="doc:phpdoc2" description="Generates API documentations">
|
||||
<echo msg="Generating API Documentation with phpDocumentor 2..." />
|
||||
<phpdoc2 title="${phing.project.name}"
|
||||
destdir="${dir.docs.phpdoc2}"
|
||||
template="responsive">
|
||||
<fileset refid="sourcecode" />
|
||||
</phpdoc2>
|
||||
</target>
|
||||
-->
|
||||
|
||||
<!-- Symfony2 code sniffer -->
|
||||
<!--
|
||||
Attention 1.
|
||||
To use Symfony2 standards to check coding you have to:
|
||||
copy, symlink or check out repo to a folder called Symfony2 inside the phpcs Standards directory.
|
||||
|
||||
Example:
|
||||
$ pear config-show | grep php_dir
|
||||
$ cd /path/to/pear/PHP/CodeSniffer/Standards
|
||||
$ git clone git://github.com/opensky/Symfony2-coding-standard.git Symfony2
|
||||
|
||||
Attention 2.
|
||||
PSR2 standard is used instead of Symfony2 standard, because after installation squizlabs/php_codesniffer package
|
||||
via Composer the Symfony2 standard is not included / available in this package. In this case the PHP Coding
|
||||
Standards Fixer (http://cs.sensiolabs.org) is used.
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
-->
|
||||
<target name="check:cs" description="Checks coding standard">
|
||||
<echo msg="Checking coding standard..." />
|
||||
<phpcodesniffer standard="PSR2" showWarnings="true">
|
||||
<fileset refid="sourcecode" />
|
||||
<formatter type="checkstyle" outfile="${dir.reports}/checkstyle.xml" />
|
||||
<formatter type="csv" outfile="${dir.reports}/checkstyle.csv" />
|
||||
<formatter type="summary" outfile="${dir.reports}/checkstyle_summary.txt" />
|
||||
</phpcodesniffer>
|
||||
<!-- PHP_CodeSniffer -->
|
||||
<target name="check:cs" depends="build:prepare">
|
||||
<exec command="${tests.code_sniffer.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- copy/paste detector -->
|
||||
<target name="check:cpd" description="Checks similar code blocks.">
|
||||
<echo msg="Checking similar code blocks..." />
|
||||
<target name="check:cpd" depends="build:prepare">
|
||||
<phpcpd>
|
||||
<fileset refid="sourcecode" />
|
||||
<formatter type="pmd" outfile="${dir.reports}/pmd-cpd.xml" />
|
||||
<formatter type="pmd" outfile="${dir.reports}/copy-paste-detector.xml" />
|
||||
</phpcpd>
|
||||
|
||||
<!--
|
||||
Previous / old version
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
|
||||
<exec command="phpcpd \-\-log-pmd=${dir.reports}/pmd-cpd.xml ${dir.src}" />
|
||||
-->
|
||||
</target>
|
||||
|
||||
<!-- Mess detector -->
|
||||
<target name="check:md" description="Generate code metrics">
|
||||
<echo msg="Generating code metrics..." />
|
||||
<phpmd rulesets="codesize,controversial,design,naming,unusedcode">
|
||||
<fileset refid="sourcecode" />
|
||||
<formatter type="html" outfile="${dir.reports}/phpmd.html" />
|
||||
<formatter type="text" outfile="${dir.reports}/phpmd.txt" />
|
||||
</phpmd>
|
||||
<!-- Run static analysis -->
|
||||
<target name="check:phpstan" depends="build:prepare">
|
||||
<exec command="${check.phpstan.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- Code dependency -->
|
||||
<target name="check:depend" description="Checks coupling and dependency">
|
||||
<echo msg="Checking coupling and dependency..." />
|
||||
<phpdepend>
|
||||
<fileset refid="sourcecode" />
|
||||
<logger type="jdepend-xml" outfile="${dir.reports.pdepend}/jdepend.xml" />
|
||||
<logger type="jdepend-chart" outfile="${dir.reports.pdepend}/dependencies.svg" />
|
||||
<logger type="overview-pyramid" outfile="${dir.reports.pdepend}/overview-pyramid.svg" />
|
||||
</phpdepend>
|
||||
<!-- Run static analysis -->
|
||||
<target name="check:psalm" depends="build:prepare">
|
||||
<exec command="${check.psalm.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- Measure the size and analyzing the structure of a project -->
|
||||
<target name="check:loc" description="Measures the size and analyzes the structure of a project">
|
||||
<echo msg="Measuring the size and analyzing the structure of a project..." />
|
||||
<phploc reportType="txt" reportName="phploc" reportDirectory="${dir.reports}">
|
||||
<fileset refid="sourcecode" />
|
||||
</phploc>
|
||||
|
||||
<!--
|
||||
Previous / old version
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
|
||||
<exec command="phploc \-\-log-csv=${dir.reports}/phploc.csv ${dir.src}" />
|
||||
-->
|
||||
<!-- Run analysis of code coverage -->
|
||||
<target name="check:coveralls" depends="test:phpunit">
|
||||
<exec command="${check.php_coveralls.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- Unit tests -->
|
||||
<target name="test:phpunit" description="Executes PHPUnit tests">
|
||||
<!-- Check test database -->
|
||||
<!-- PHPUnit tests -->
|
||||
<target name="test:phpunit" depends="build:prepare">
|
||||
<exec command="${tests.phpunit.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- Run mutation testing -->
|
||||
<target name="test:infection" depends="test:phpunit">
|
||||
<exec command="${tests.mutation.command}" passthru="true" />
|
||||
</target>
|
||||
|
||||
<!-- Project build clean -->
|
||||
<target name="build:clean">
|
||||
<if>
|
||||
<not>
|
||||
<available file="${dir.data.tests}" type="dir" property="dir.data.tests.available" />
|
||||
</not>
|
||||
<available file="${dir.reports}" type="dir" property="dir_is_available" />
|
||||
<then>
|
||||
<mkdir dir="${dir.data.tests}" />
|
||||
<delete dir="${dir.reports}" />
|
||||
</then>
|
||||
</if>
|
||||
<if>
|
||||
<not>
|
||||
<available file="${tests.database}" property="tests.database.available" />
|
||||
</not>
|
||||
<then>
|
||||
<touch file="${tests.database}" />
|
||||
</then>
|
||||
</if>
|
||||
<echo msg="Running unit tests..." />
|
||||
<coverage-setup database="${dir.reports.coverage}/coverage.db">
|
||||
<fileset refid="sourcecode" />
|
||||
</coverage-setup>
|
||||
<exec command="${phpUnit.path} --verbose --configuration ${project.basedir}/phpunit.xml.dist" passthru="true" />
|
||||
<!--
|
||||
I have to use ExecTask to run PHPUnit instead of PHPUnitTask, because tests are not running if PHPUnitTask is
|
||||
used (don't know why):
|
||||
Total tests run: 0, Failures: 0, Errors: 0, Incomplete: 0, Skipped: 0
|
||||
</target>
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-23
|
||||
|
||||
<phpunit configuration="${project.basedir}/phpunit.xml.dist" printsummary="true">
|
||||
<formatter type="xml" todir="${dir.reports}" outfile="phpunit.xml" />
|
||||
<formatter type="plain" todir="${dir.reports}" outfile="phpunit.txt" />
|
||||
<formatter type="clover" todir="${dir.reports.coverage}" />
|
||||
<formatter type="summary" todir="${dir.reports}" outfile="phpunit_summary.txt" />
|
||||
</phpunit>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Previous / old version
|
||||
|
||||
Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
2017-02-22
|
||||
|
||||
<if>
|
||||
<istrue value="${phpunit.useExec}" />
|
||||
<then>
|
||||
<if>
|
||||
<istrue value="${phpunit.withCoverage}" />
|
||||
<then>
|
||||
<echo message="Running tests with code coverage..." />
|
||||
<exec command="phpunit \-\-log-junit ${dir.reports}/phpunit.xml \-\-coverage-clover ${dir.reports.coverage}/clover-coverage.xml \-\-coverage-crap4j ${dir.reports.coverage}/crap4j-coverage.xml \-\-coverage-html ${dir.reports.coverage}/ -c ${project.basedir} \-\-colors" passthru="true" checkreturn="true" />
|
||||
</then>
|
||||
<else>
|
||||
<echo message="Running tests without code coverage..." />
|
||||
<exec command="phpunit \-\-log-junit ${dir.reports}/phpunit.xml -c ${project.basedir} \-\-colors" passthru="true" checkreturn="true" />
|
||||
</else>
|
||||
</if>
|
||||
</then>
|
||||
<else>
|
||||
<if>
|
||||
<istrue value="${phpunit.withCoverage}" />
|
||||
<then>
|
||||
<echo message="Running tests with code coverage..." />
|
||||
<coverage-setup database="${dir.reports.coverage}/coverage.db">
|
||||
<fileset refid="sourcecode" />
|
||||
</coverage-setup>
|
||||
<phpunit printsummary="true" codecoverage="true">
|
||||
<formatter type="xml" todir="${dir.reports}" outfile="phpunit.xml" />
|
||||
<formatter type="plain" todir="${dir.reports}" outfile="phpunit.txt" />
|
||||
<formatter type="clover" todir="${dir.reports.coverage}" />
|
||||
<formatter type="summary" todir="${dir.reports}" outfile="phpunit_summary.txt" />
|
||||
</phpunit>
|
||||
</then>
|
||||
<else>
|
||||
<echo message="Running tests without code coverage..." />
|
||||
<phpunit printsummary="true">
|
||||
<formatter todir="${dir.reports}" type="xml" outfile="phpunit.xml" />
|
||||
<batchtest>
|
||||
<fileset refid="tests" />
|
||||
</batchtest>
|
||||
</phpunit>
|
||||
</else>
|
||||
</if>
|
||||
</else>
|
||||
</if>
|
||||
-->
|
||||
<!-- Project build prepare -->
|
||||
<target name="build:prepare" depends="build:clean">
|
||||
<mkdir dir="${dir.reports}" />
|
||||
<mkdir dir="${dir.reports.coverage}" />
|
||||
<mkdir dir="${dir.reports.code_sniffer}" />
|
||||
</target>
|
||||
|
||||
<!-- Checkout and finalization -->
|
||||
|
||||
16
phpcs.xml.dist
Normal file
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
42
src/Exception/Base/UnknownTypeException.php
Normal file
42
src/Exception/Base/UnknownTypeException.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\Base;
|
||||
|
||||
use Exception;
|
||||
use Meritoo\Common\Type\Base\BaseType;
|
||||
use Meritoo\Common\Utilities\Arrays;
|
||||
|
||||
/**
|
||||
* An exception used while type of something is unknown
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
abstract class UnknownTypeException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates exception
|
||||
*
|
||||
* @param mixed $unknownType The unknown type of something (value of constant)
|
||||
* @param BaseType $typeInstance An instance of class that contains type of the something
|
||||
* @param string $typeName Name of the something
|
||||
* @return UnknownTypeException
|
||||
*/
|
||||
public static function create($unknownType, BaseType $typeInstance, string $typeName): UnknownTypeException
|
||||
{
|
||||
$template = 'The \'%s\' type of %s is unknown. Probably doesn\'t exist or there is a typo. You should use one'
|
||||
.' of these types: %s.';
|
||||
|
||||
$allTypes = $typeInstance->getAll();
|
||||
$types = Arrays::values2string($allTypes, '', ', ') ?? '[types not found]';
|
||||
$message = sprintf($template, $unknownType, $typeName, $types);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
34
src/Exception/File/EmptyFileException.php
Normal file
34
src/Exception/File/EmptyFileException.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\File;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while file with given path is empty (has no content)
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class EmptyFileException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates exception
|
||||
*
|
||||
* @param string $emptyFilePath Path of the empty file
|
||||
* @return EmptyFileException
|
||||
*/
|
||||
public static function create($emptyFilePath)
|
||||
{
|
||||
$template = 'File with path \'%s\' is empty (has no content). Did you provide path of proper file?';
|
||||
$message = sprintf($template, $emptyFilePath);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
30
src/Exception/File/EmptyFilePathException.php
Normal file
30
src/Exception/File/EmptyFilePathException.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\File;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while path of given file is empty
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class EmptyFilePathException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates exception
|
||||
*
|
||||
* @return EmptyFilePathException
|
||||
*/
|
||||
public static function create(): EmptyFilePathException
|
||||
{
|
||||
return new static('Path of the file is empty. Did you provide path of proper file?');
|
||||
}
|
||||
}
|
||||
34
src/Exception/File/NotExistingFileException.php
Normal file
34
src/Exception/File/NotExistingFileException.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\File;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while file with given path does not exist
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class NotExistingFileException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates exception
|
||||
*
|
||||
* @param string $notExistingFilePath Path of not existing (or not readable) file
|
||||
* @return NotExistingFileException
|
||||
*/
|
||||
public static function create($notExistingFilePath)
|
||||
{
|
||||
$template = 'File with path \'%s\' does not exist (or is not readable). Did you provide path of proper file?';
|
||||
$message = sprintf($template, $notExistingFilePath);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
40
src/Exception/Method/DisabledMethodException.php
Normal file
40
src/Exception/Method/DisabledMethodException.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\Method;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception used while method cannot be called, because is disabled
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class DisabledMethodException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates exception
|
||||
*
|
||||
* @param string $disabledMethod Name of the disabled method
|
||||
* @param string $alternativeMethod (optional) Name of the alternative method
|
||||
* @return DisabledMethodException
|
||||
*/
|
||||
public static function create($disabledMethod, $alternativeMethod = '')
|
||||
{
|
||||
$template = 'Method %s() cannot be called, because is disabled.';
|
||||
$message = sprintf($template, $disabledMethod);
|
||||
|
||||
if (!empty($alternativeMethod)) {
|
||||
$template = '%s Use %s() instead.';
|
||||
$message = sprintf($template, $message, $alternativeMethod);
|
||||
}
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
@@ -13,20 +13,20 @@ use Exception;
|
||||
/**
|
||||
* An exception used while name of class or trait cannot be resolved
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class CannotResolveClassNameException extends Exception
|
||||
{
|
||||
/**
|
||||
* Class constructor
|
||||
* Creates exception
|
||||
*
|
||||
* @param array|object|string $source Source of the class's / trait's name. It cane be an array of objects,
|
||||
* namespaces, object or namespace.
|
||||
* @param bool $forClass (optional) If is set to true, message of this exception for class is
|
||||
* prepared. Otherwise - for trait.
|
||||
* @param string $source Source of name of the class or trait
|
||||
* @param bool $forClass (optional) If is set to true, message of this exception for class is prepared. Otherwise
|
||||
* - for trait.
|
||||
* @return CannotResolveClassNameException
|
||||
*/
|
||||
public function __construct($source, $forClass = true)
|
||||
public static function create(string $source, bool $forClass = true): CannotResolveClassNameException
|
||||
{
|
||||
$forWho = 'trait';
|
||||
$value = '';
|
||||
@@ -36,12 +36,12 @@ class CannotResolveClassNameException extends Exception
|
||||
}
|
||||
|
||||
if (is_scalar($source)) {
|
||||
$value = sprintf(' %s', (string)$source);
|
||||
$value = sprintf(' %s', $source);
|
||||
}
|
||||
|
||||
$template = 'Name of %s from given \'%s\'%s cannot be resolved. Is there everything ok?';
|
||||
$message = sprintf($template, $forWho, gettype($source), $value);
|
||||
|
||||
parent::__construct($message);
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
33
src/Exception/Regex/InvalidUrlException.php
Normal file
33
src/Exception/Regex/InvalidUrlException.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 url is invalid
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class InvalidUrlException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates exception
|
||||
*
|
||||
* @param string $url Invalid url
|
||||
* @return InvalidUrlException
|
||||
*/
|
||||
public static function create($url)
|
||||
{
|
||||
$message = sprintf('Url \'%s\' is invalid. Is there everything ok?', $url);
|
||||
|
||||
return new static($message);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
32
src/Exception/Type/UnknownOopVisibilityTypeException.php
Normal file
32
src/Exception/Type/UnknownOopVisibilityTypeException.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.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\Type;
|
||||
|
||||
use Meritoo\Common\Exception\Base\UnknownTypeException;
|
||||
use Meritoo\Common\Type\OopVisibilityType;
|
||||
|
||||
/**
|
||||
* An exception used while the visibility of a property, a method or (as of PHP 7.1.0) a constant is unknown
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class UnknownOopVisibilityTypeException extends UnknownTypeException
|
||||
{
|
||||
/**
|
||||
* Creates exception
|
||||
*
|
||||
* @param string $unknownType Unknown visibility of a property, a method or (as of PHP 7.1.0) a constant
|
||||
* @return UnknownOopVisibilityTypeException
|
||||
*/
|
||||
public static function createException(string $unknownType): UnknownOopVisibilityTypeException
|
||||
{
|
||||
return parent::create($unknownType, new OopVisibilityType(), 'OOP-related visibility');
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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 ($index === null) {
|
||||
$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 $index !== null && $index !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Exception\Base;
|
||||
|
||||
use Exception;
|
||||
use Meritoo\Common\Type\Base\BaseType;
|
||||
use Meritoo\Common\Utilities\Arrays;
|
||||
|
||||
/**
|
||||
* An exception used while type of something is unknown
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
*/
|
||||
abstract class UnknownTypeException extends Exception
|
||||
{
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string|int $unknownType The unknown type of something (value of constant)
|
||||
* @param BaseType $typeInstance An instance of class that contains type of the something
|
||||
* @param string $typeName Name of the something
|
||||
*/
|
||||
public function __construct($unknownType, BaseType $typeInstance, $typeName)
|
||||
{
|
||||
$allTypes = $typeInstance->getAll();
|
||||
$types = Arrays::values2string($allTypes, '', ', ');
|
||||
|
||||
$template = 'The \'%s\' type of %s is unknown. Probably doesn\'t exist or there is a typo. You should use one'
|
||||
. ' of these types: %s.';
|
||||
|
||||
$message = sprintf(sprintf($template, $unknownType, $typeName, $types));
|
||||
parent::__construct($message);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Meritoo\Common\Exception\Regex;
|
||||
|
||||
/**
|
||||
* An exception used while url is invalid
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
*/
|
||||
class InvalidUrlException extends \Exception
|
||||
{
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string $url Invalid url
|
||||
*/
|
||||
public function __construct($url)
|
||||
{
|
||||
$message = sprintf('Url \'%s\' is invalid. Is there everything ok?', $url);
|
||||
parent::__construct($message);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Meritoo\Common\Exception\Type;
|
||||
|
||||
use Meritoo\Common\Exception\Base\UnknownTypeException;
|
||||
use Meritoo\Common\Type\OopVisibilityType;
|
||||
|
||||
/**
|
||||
* An exception used while the visibility of a property, a method or (as of PHP 7.1.0) a constant is unknown
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
*/
|
||||
class UnknownOopVisibilityTypeException extends UnknownTypeException
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct($unknownType)
|
||||
{
|
||||
parent::__construct($unknownType, new OopVisibilityType(), 'OOP-related visibility');
|
||||
}
|
||||
}
|
||||
@@ -1,199 +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\Test\Base;
|
||||
|
||||
use DateTime;
|
||||
use Generator;
|
||||
use Meritoo\Common\Exception\Type\UnknownOopVisibilityTypeException;
|
||||
use Meritoo\Common\Type\OopVisibilityType;
|
||||
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
|
||||
*/
|
||||
abstract class BaseTestCase extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Provides an empty value
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideEmptyValue()
|
||||
{
|
||||
yield[''];
|
||||
yield[' '];
|
||||
yield[null];
|
||||
yield[0];
|
||||
yield[false];
|
||||
yield[[]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides boolean value
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideBooleanValue()
|
||||
{
|
||||
yield[false];
|
||||
yield[true];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides instance of DateTime class
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideDateTimeInstance()
|
||||
{
|
||||
yield[new DateTime()];
|
||||
yield[new DateTime('yesterday')];
|
||||
yield[new DateTime('now')];
|
||||
yield[new DateTime('tomorrow')];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides relative / compound format of DateTime
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideDateTimeRelativeFormat()
|
||||
{
|
||||
yield['now'];
|
||||
yield['yesterday'];
|
||||
yield['tomorrow'];
|
||||
yield['back of 10'];
|
||||
yield['front of 10'];
|
||||
yield['last day of February'];
|
||||
yield['first day of next month'];
|
||||
yield['last day of previous month'];
|
||||
yield['last day of next month'];
|
||||
yield['Y-m-d'];
|
||||
yield['Y-m-d 10:00'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides path of not existing file, e.g. "lorem/ipsum.jpg"
|
||||
*
|
||||
* @return Generator
|
||||
*/
|
||||
public function provideNotExistingFilePath()
|
||||
{
|
||||
yield['lets-test.doc'];
|
||||
yield['lorem/ipsum.jpg'];
|
||||
yield['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 = '')
|
||||
{
|
||||
if (!empty($directoryPath)) {
|
||||
$directoryPath = '/' . $directoryPath;
|
||||
}
|
||||
|
||||
return sprintf('%s/../../../../../data/tests/%s%s', __DIR__, $fileName, $directoryPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 function verifyMethodVisibilityAndArguments(
|
||||
$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 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
|
||||
*/
|
||||
protected function verifyConstructorVisibilityAndArguments(
|
||||
$classNamespace,
|
||||
$visibilityType,
|
||||
$argumentsCount = 0,
|
||||
$requiredArgumentsCount = 0
|
||||
) {
|
||||
/*
|
||||
* Let's grab the constructor
|
||||
*/
|
||||
$reflection = new ReflectionClass($classNamespace);
|
||||
$method = $reflection->getConstructor();
|
||||
|
||||
return $this->verifyMethodVisibilityAndArguments($classNamespace, $method, $visibilityType, $argumentsCount, $requiredArgumentsCount);
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Meritoo\Common\Test\Base;
|
||||
|
||||
use Generator;
|
||||
use Meritoo\Common\Type\Base\BaseType;
|
||||
|
||||
/**
|
||||
* Base test case for the type of something
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright 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();
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Utilities;
|
||||
|
||||
/**
|
||||
* Useful methods for bundle
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
*/
|
||||
class Bundle
|
||||
{
|
||||
/**
|
||||
* Returns path to view / template of given bundle
|
||||
*
|
||||
* @param string $viewPath Path of the view / template, e.g. "MyDirectory/my-template"
|
||||
* @param string $bundleName Name of the bundle, e.g. "MyExtraBundle"
|
||||
* @param string $extension (optional) Extension of the view / template
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getBundleViewPath($viewPath, $bundleName, $extension = 'html.twig')
|
||||
{
|
||||
/*
|
||||
* Unknown path, extension of the view / template or name of the bundle?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($viewPath) || empty($bundleName) || empty($extension)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Path of the view / template doesn't end with given extension?
|
||||
*/
|
||||
if (!Regex::endsWith($viewPath, $extension)) {
|
||||
$viewPath = sprintf('%s.%s', $viewPath, $extension);
|
||||
}
|
||||
|
||||
return sprintf('%s:%s', $bundleName, $viewPath);
|
||||
}
|
||||
}
|
||||
@@ -1,816 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Utilities;
|
||||
|
||||
/**
|
||||
* Useful methods for mime types of files
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
*/
|
||||
class MimeTypes
|
||||
{
|
||||
/**
|
||||
* Mime types data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $mimeTypes = [
|
||||
'7z' => 'application/x-7z-compressed',
|
||||
'ez' => 'application/andrew-inset',
|
||||
'atom' => 'application/atom+xml',
|
||||
'atomcat' => 'application/atomcat+xml',
|
||||
'atomsvc' => 'application/atomsvc+xml',
|
||||
'ccxml' => 'application/ccxml+xml',
|
||||
'davmount' => 'application/davmount+xml',
|
||||
'ecma' => 'application/ecmascript',
|
||||
'pfr' => 'application/font-tdpfr',
|
||||
'stk' => 'application/hyperstudio',
|
||||
'js' => 'application/javascript',
|
||||
'json' => 'application/json',
|
||||
'hqx' => 'application/mac-binhex40',
|
||||
'cpt' => 'application/mac-compactpro',
|
||||
'mrc' => 'application/marc',
|
||||
'ma' => 'application/mathematica',
|
||||
'nb' => 'application/mathematica',
|
||||
'mb' => 'application/mathematica',
|
||||
'mathml' => 'application/mathml+xml',
|
||||
'mbox' => 'application/mbox',
|
||||
'mscml' => 'application/mediaservercontrol+xml',
|
||||
'mp4s' => 'application/mp4',
|
||||
'dot' => 'application/msword',
|
||||
'doc' => 'application/msword',
|
||||
/*
|
||||
* MS Office system file format MIME types
|
||||
* http://technet.microsoft.com/en-us/library/ee309278%28office.12%29.aspx
|
||||
*/
|
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'mxf' => 'application/mxf',
|
||||
'bin' => 'application/octet-stream',
|
||||
'dms' => 'application/octet-stream',
|
||||
'lha' => 'application/octet-stream',
|
||||
'lzh' => 'application/octet-stream',
|
||||
'class' => 'application/octet-stream',
|
||||
'so' => 'application/octet-stream',
|
||||
'iso' => 'application/octet-stream',
|
||||
'dmg' => 'application/octet-stream',
|
||||
'dist' => 'application/octet-stream',
|
||||
'distz' => 'application/octet-stream',
|
||||
'pkg' => 'application/octet-stream',
|
||||
'bpk' => 'application/octet-stream',
|
||||
'dump' => 'application/octet-stream',
|
||||
'elc' => 'application/octet-stream',
|
||||
'scpt' => 'application/octet-stream',
|
||||
'oda' => 'application/oda',
|
||||
'ogg' => 'application/ogg',
|
||||
'pdf' => 'application/pdf',
|
||||
'pgp' => 'application/pgp-encrypted',
|
||||
'asc' => 'application/pgp-signature',
|
||||
'sig' => 'application/pgp-signature',
|
||||
'prf' => 'application/pics-rules',
|
||||
'p10' => 'application/pkcs10',
|
||||
'p7m' => 'application/pkcs7-mime',
|
||||
'p7c' => 'application/pkcs7-mime',
|
||||
'p7s' => 'application/pkcs7-signature',
|
||||
'cer' => 'application/pkix-cert',
|
||||
'crl' => 'application/pkix-crl',
|
||||
'pkipath' => 'application/pkix-pkipath',
|
||||
'pki' => 'application/pkixcmp',
|
||||
'pls' => 'application/pls+xml',
|
||||
'ai' => 'application/postscript',
|
||||
'eps' => 'application/postscript',
|
||||
'ps' => 'application/postscript',
|
||||
'cww' => 'application/prs.cww',
|
||||
'rdf' => 'application/rdf+xml',
|
||||
'rif' => 'application/reginfo+xml',
|
||||
'rnc' => 'application/relax-ng-compact-syntax',
|
||||
'rl' => 'application/resource-lists+xml',
|
||||
'rs' => 'application/rls-services+xml',
|
||||
'rsd' => 'application/rsd+xml',
|
||||
'rss' => 'application/rss+xml',
|
||||
'rtf' => 'application/rtf',
|
||||
'sbml' => 'application/sbml+xml',
|
||||
'sdp' => 'application/sdp',
|
||||
'setpay' => 'application/set-payment-initiation',
|
||||
'setreg' => 'application/set-registration-initiation',
|
||||
'shf' => 'application/shf+xml',
|
||||
'smi' => 'application/smil+xml',
|
||||
'smil' => 'application/smil+xml',
|
||||
'gram' => 'application/srgs',
|
||||
'grxml' => 'application/srgs+xml',
|
||||
'ssml' => 'application/ssml+xml',
|
||||
'plb' => 'application/vnd.3gpp.pic-bw-large',
|
||||
'psb' => 'application/vnd.3gpp.pic-bw-small',
|
||||
'pvb' => 'application/vnd.3gpp.pic-bw-var',
|
||||
'pwn' => 'application/vnd.3m.post-it-notes',
|
||||
'aso' => 'application/vnd.accpac.simply.aso',
|
||||
'imp' => 'application/vnd.accpac.simply.imp',
|
||||
'acu' => 'application/vnd.acucobol',
|
||||
'atc' => 'application/vnd.acucorp',
|
||||
'acutc' => 'application/vnd.acucorp',
|
||||
'xdp' => 'application/vnd.adobe.xdp+xml',
|
||||
'xfdf' => 'application/vnd.adobe.xfdf',
|
||||
'ami' => 'application/vnd.amiga.ami',
|
||||
'cii' => 'application/vnd.anser-web-certificate-issue-initiation',
|
||||
'fti' => 'application/vnd.anser-web-funds-transfer-initiation',
|
||||
'atx' => 'application/vnd.antix.game-component',
|
||||
'mpkg' => 'application/vnd.apple.installer+xml',
|
||||
'aep' => 'application/vnd.audiograph',
|
||||
'mpm' => 'application/vnd.blueice.multipass',
|
||||
'bmi' => 'application/vnd.bmi',
|
||||
'rep' => 'application/vnd.businessobjects',
|
||||
'cdxml' => 'application/vnd.chemdraw+xml',
|
||||
'mmd' => 'application/vnd.chipnuts.karaoke-mmd',
|
||||
'cdy' => 'application/vnd.cinderella',
|
||||
'cla' => 'application/vnd.claymore',
|
||||
'c4g' => 'application/vnd.clonk.c4group',
|
||||
'c4d' => 'application/vnd.clonk.c4group',
|
||||
'c4f' => 'application/vnd.clonk.c4group',
|
||||
'c4p' => 'application/vnd.clonk.c4group',
|
||||
'c4u' => 'application/vnd.clonk.c4group',
|
||||
'csp' => 'application/vnd.commonspace',
|
||||
'cst' => 'application/vnd.commonspace',
|
||||
'cdbcmsg' => 'application/vnd.contact.cmsg',
|
||||
'cmc' => 'application/vnd.cosmocaller',
|
||||
'clkx' => 'application/vnd.crick.clicker',
|
||||
'clkk' => 'application/vnd.crick.clicker.keyboard',
|
||||
'clkp' => 'application/vnd.crick.clicker.palette',
|
||||
'clkt' => 'application/vnd.crick.clicker.template',
|
||||
'clkw' => 'application/vnd.crick.clicker.wordbank',
|
||||
'wbs' => 'application/vnd.criticaltools.wbs+xml',
|
||||
'pml' => 'application/vnd.ctc-posml',
|
||||
'ppd' => 'application/vnd.cups-ppd',
|
||||
'curl' => 'application/vnd.curl',
|
||||
'rdz' => 'application/vnd.data-vision.rdz',
|
||||
'dna' => 'application/vnd.dna',
|
||||
'mlp' => 'application/vnd.dolby.mlp',
|
||||
'dpg' => 'application/vnd.dpgraph',
|
||||
'dfac' => 'application/vnd.dreamfactory',
|
||||
'mag' => 'application/vnd.ecowin.chart',
|
||||
'nml' => 'application/vnd.enliven',
|
||||
'esf' => 'application/vnd.epson.esf',
|
||||
'msf' => 'application/vnd.epson.msf',
|
||||
'qam' => 'application/vnd.epson.quickanime',
|
||||
'slt' => 'application/vnd.epson.salt',
|
||||
'ssf' => 'application/vnd.epson.ssf',
|
||||
'es3' => 'application/vnd.eszigno3+xml',
|
||||
'et3' => 'application/vnd.eszigno3+xml',
|
||||
'ez2' => 'application/vnd.ezpix-album',
|
||||
'ez3' => 'application/vnd.ezpix-package',
|
||||
'fdf' => 'application/vnd.fdf',
|
||||
'gph' => 'application/vnd.flographit',
|
||||
'ftc' => 'application/vnd.fluxtime.clip',
|
||||
'fm' => 'application/vnd.framemaker',
|
||||
'frame' => 'application/vnd.framemaker',
|
||||
'maker' => 'application/vnd.framemaker',
|
||||
'fnc' => 'application/vnd.frogans.fnc',
|
||||
'ltf' => 'application/vnd.frogans.ltf',
|
||||
'fsc' => 'application/vnd.fsc.weblaunch',
|
||||
'oas' => 'application/vnd.fujitsu.oasys',
|
||||
'oa2' => 'application/vnd.fujitsu.oasys2',
|
||||
'oa3' => 'application/vnd.fujitsu.oasys3',
|
||||
'fg5' => 'application/vnd.fujitsu.oasysgp',
|
||||
'bh2' => 'application/vnd.fujitsu.oasysprs',
|
||||
'ddd' => 'application/vnd.fujixerox.ddd',
|
||||
'xdw' => 'application/vnd.fujixerox.docuworks',
|
||||
'xbd' => 'application/vnd.fujixerox.docuworks.binder',
|
||||
'fzs' => 'application/vnd.fuzzysheet',
|
||||
'txd' => 'application/vnd.genomatix.tuxedo',
|
||||
'kml' => 'application/vnd.google-earth.kml+xml',
|
||||
'kmz' => 'application/vnd.google-earth.kmz',
|
||||
'gqf' => 'application/vnd.grafeq',
|
||||
'gqs' => 'application/vnd.grafeq',
|
||||
'gac' => 'application/vnd.groove-account',
|
||||
'ghf' => 'application/vnd.groove-help',
|
||||
'gim' => 'application/vnd.groove-identity-message',
|
||||
'grv' => 'application/vnd.groove-injector',
|
||||
'gtm' => 'application/vnd.groove-tool-message',
|
||||
'tpl' => 'application/vnd.groove-tool-template',
|
||||
'vcg' => 'application/vnd.groove-vcard',
|
||||
'zmm' => 'application/vnd.handheld-entertainment+xml',
|
||||
'hbci' => 'application/vnd.hbci',
|
||||
'les' => 'application/vnd.hhe.lesson-player',
|
||||
'hpgl' => 'application/vnd.hp-hpgl',
|
||||
'hpid' => 'application/vnd.hp-hpid',
|
||||
'hps' => 'application/vnd.hp-hps',
|
||||
'jlt' => 'application/vnd.hp-jlyt',
|
||||
'pcl' => 'application/vnd.hp-pcl',
|
||||
'pclxl' => 'application/vnd.hp-pclxl',
|
||||
'x3d' => 'application/vnd.hzn-3d-crossword',
|
||||
'mpy' => 'application/vnd.ibm.minipay',
|
||||
'afp' => 'application/vnd.ibm.modcap',
|
||||
'listafp' => 'application/vnd.ibm.modcap',
|
||||
'list3820' => 'application/vnd.ibm.modcap',
|
||||
'irm' => 'application/vnd.ibm.rights-management',
|
||||
'sc' => 'application/vnd.ibm.secure-container',
|
||||
'igl' => 'application/vnd.igloader',
|
||||
'ivp' => 'application/vnd.immervision-ivp',
|
||||
'ivu' => 'application/vnd.immervision-ivu',
|
||||
'xpw' => 'application/vnd.intercon.formnet',
|
||||
'xpx' => 'application/vnd.intercon.formnet',
|
||||
'qbo' => 'application/vnd.intu.qbo',
|
||||
'qfx' => 'application/vnd.intu.qfx',
|
||||
'rcprofile' => 'application/vnd.ipunplugged.rcprofile',
|
||||
'irp' => 'application/vnd.irepository.package+xml',
|
||||
'xpr' => 'application/vnd.is-xpr',
|
||||
'jam' => 'application/vnd.jam',
|
||||
'rms' => 'application/vnd.jcp.javame.midlet-rms',
|
||||
'jisp' => 'application/vnd.jisp',
|
||||
'ktz' => 'application/vnd.kahootz',
|
||||
'ktr' => 'application/vnd.kahootz',
|
||||
'karbon' => 'application/vnd.kde.karbon',
|
||||
'chrt' => 'application/vnd.kde.kchart',
|
||||
'kfo' => 'application/vnd.kde.kformula',
|
||||
'flw' => 'application/vnd.kde.kivio',
|
||||
'kon' => 'application/vnd.kde.kontour',
|
||||
'kpr' => 'application/vnd.kde.kpresenter',
|
||||
'kpt' => 'application/vnd.kde.kpresenter',
|
||||
'ksp' => 'application/vnd.kde.kspread',
|
||||
'kwd' => 'application/vnd.kde.kword',
|
||||
'kwt' => 'application/vnd.kde.kword',
|
||||
'htke' => 'application/vnd.kenameaapp',
|
||||
'kia' => 'application/vnd.kidspiration',
|
||||
'kne' => 'application/vnd.kinar',
|
||||
'knp' => 'application/vnd.kinar',
|
||||
'skp' => 'application/vnd.koan',
|
||||
'skd' => 'application/vnd.koan',
|
||||
'skt' => 'application/vnd.koan',
|
||||
'skm' => 'application/vnd.koan',
|
||||
'lbd' => 'application/vnd.llamagraphics.life-balance.desktop',
|
||||
'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml',
|
||||
'123' => 'application/vnd.lotus-1-2-3',
|
||||
'apr' => 'application/vnd.lotus-approach',
|
||||
'pre' => 'application/vnd.lotus-freelance',
|
||||
'nsf' => 'application/vnd.lotus-notes',
|
||||
'org' => 'application/vnd.lotus-organizer',
|
||||
'scm' => 'application/vnd.lotus-screencam',
|
||||
'lwp' => 'application/vnd.lotus-wordpro',
|
||||
'portpkg' => 'application/vnd.macports.portpkg',
|
||||
'mcd' => 'application/vnd.mcd',
|
||||
'mc1' => 'application/vnd.medcalcdata',
|
||||
'cdkey' => 'application/vnd.mediastation.cdkey',
|
||||
'mwf' => 'application/vnd.mfer',
|
||||
'mfm' => 'application/vnd.mfmp',
|
||||
'flo' => 'application/vnd.micrografx.flo',
|
||||
'igx' => 'application/vnd.micrografx.igx',
|
||||
'mif' => 'application/vnd.mif',
|
||||
'daf' => 'application/vnd.mobius.daf',
|
||||
'dis' => 'application/vnd.mobius.dis',
|
||||
'mbk' => 'application/vnd.mobius.mbk',
|
||||
'mqy' => 'application/vnd.mobius.mqy',
|
||||
'msl' => 'application/vnd.mobius.msl',
|
||||
'plc' => 'application/vnd.mobius.plc',
|
||||
'txf' => 'application/vnd.mobius.txf',
|
||||
'mpn' => 'application/vnd.mophun.application',
|
||||
'mpc' => 'application/vnd.mophun.certificate',
|
||||
'xul' => 'application/vnd.mozilla.xul+xml',
|
||||
'cil' => 'application/vnd.ms-artgalry',
|
||||
'asf' => 'application/vnd.ms-asf',
|
||||
'cab' => 'application/vnd.ms-cab-compressed',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'xlm' => 'application/vnd.ms-excel',
|
||||
'xla' => 'application/vnd.ms-excel',
|
||||
'xlc' => 'application/vnd.ms-excel',
|
||||
'xlt' => 'application/vnd.ms-excel',
|
||||
'xlw' => 'application/vnd.ms-excel',
|
||||
'eot' => 'application/vnd.ms-fontobject',
|
||||
'chm' => 'application/vnd.ms-htmlhelp',
|
||||
'ims' => 'application/vnd.ms-ims',
|
||||
'lrm' => 'application/vnd.ms-lrm',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'pps' => 'application/vnd.ms-powerpoint',
|
||||
'pot' => 'application/vnd.ms-powerpoint',
|
||||
'mpp' => 'application/vnd.ms-project',
|
||||
'mpt' => 'application/vnd.ms-project',
|
||||
'wps' => 'application/vnd.ms-works',
|
||||
'wks' => 'application/vnd.ms-works',
|
||||
'wcm' => 'application/vnd.ms-works',
|
||||
'wdb' => 'application/vnd.ms-works',
|
||||
'wpl' => 'application/vnd.ms-wpl',
|
||||
'xps' => 'application/vnd.ms-xpsdocument',
|
||||
'mseq' => 'application/vnd.mseq',
|
||||
'mus' => 'application/vnd.musician',
|
||||
'nlu' => 'application/vnd.neurolanguage.nlu',
|
||||
'nnd' => 'application/vnd.noblenet-directory',
|
||||
'nns' => 'application/vnd.noblenet-sealer',
|
||||
'nnw' => 'application/vnd.noblenet-web',
|
||||
'ngdat' => 'application/vnd.nokia.n-gage.data',
|
||||
'n-gage' => 'application/vnd.nokia.n-gage.symbian.install',
|
||||
'rpst' => 'application/vnd.nokia.radio-preset',
|
||||
'rpss' => 'application/vnd.nokia.radio-presets',
|
||||
'edm' => 'application/vnd.novadigm.edm',
|
||||
'edx' => 'application/vnd.novadigm.edx',
|
||||
'ext' => 'application/vnd.novadigm.ext',
|
||||
'odc' => 'application/vnd.oasis.opendocument.chart',
|
||||
'otc' => 'application/vnd.oasis.opendocument.chart-template',
|
||||
'odf' => 'application/vnd.oasis.opendocument.formula',
|
||||
'otf' => 'application/vnd.oasis.opendocument.formula-template',
|
||||
'odg' => 'application/vnd.oasis.opendocument.graphics',
|
||||
'otg' => 'application/vnd.oasis.opendocument.graphics-template',
|
||||
'odi' => 'application/vnd.oasis.opendocument.image',
|
||||
'oti' => 'application/vnd.oasis.opendocument.image-template',
|
||||
'odp' => 'application/vnd.oasis.opendocument.presentation',
|
||||
'otp' => 'application/vnd.oasis.opendocument.presentation-template',
|
||||
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
||||
'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
|
||||
'odt' => 'application/vnd.oasis.opendocument.text',
|
||||
'otm' => 'application/vnd.oasis.opendocument.text-master',
|
||||
'ott' => 'application/vnd.oasis.opendocument.text-template',
|
||||
'oth' => 'application/vnd.oasis.opendocument.text-web',
|
||||
'xo' => 'application/vnd.olpc-sugar',
|
||||
'dd2' => 'application/vnd.oma.dd2+xml',
|
||||
'oxt' => 'application/vnd.openofficeorg.extension',
|
||||
'dp' => 'application/vnd.osgi.dp',
|
||||
'prc' => 'application/vnd.palm',
|
||||
'pdb' => 'application/vnd.palm',
|
||||
'pqa' => 'application/vnd.palm',
|
||||
'oprc' => 'application/vnd.palm',
|
||||
'str' => 'application/vnd.pg.format',
|
||||
'ei6' => 'application/vnd.pg.osasli',
|
||||
'efif' => 'application/vnd.picsel',
|
||||
'plf' => 'application/vnd.pocketlearn',
|
||||
'pbd' => 'application/vnd.powerbuilder6',
|
||||
'box' => 'application/vnd.previewsystems.box',
|
||||
'mgz' => 'application/vnd.proteus.magazine',
|
||||
'qps' => 'application/vnd.publishare-delta-tree',
|
||||
'ptid' => 'application/vnd.pvi.ptid1',
|
||||
'qxd' => 'application/vnd.quark.quarkxpress',
|
||||
'qxt' => 'application/vnd.quark.quarkxpress',
|
||||
'qwd' => 'application/vnd.quark.quarkxpress',
|
||||
'qwt' => 'application/vnd.quark.quarkxpress',
|
||||
'qxl' => 'application/vnd.quark.quarkxpress',
|
||||
'qxb' => 'application/vnd.quark.quarkxpress',
|
||||
'mxl' => 'application/vnd.recordare.musicxml',
|
||||
'rm' => 'application/vnd.rn-realmedia',
|
||||
'see' => 'application/vnd.seemail',
|
||||
'sema' => 'application/vnd.sema',
|
||||
'semd' => 'application/vnd.semd',
|
||||
'semf' => 'application/vnd.semf',
|
||||
'ifm' => 'application/vnd.shana.informed.formdata',
|
||||
'itp' => 'application/vnd.shana.informed.formtemplate',
|
||||
'iif' => 'application/vnd.shana.informed.interchange',
|
||||
'ipk' => 'application/vnd.shana.informed.package',
|
||||
'twd' => 'application/vnd.simtech-mindmapper',
|
||||
'twds' => 'application/vnd.simtech-mindmapper',
|
||||
'mmf' => 'application/vnd.smaf',
|
||||
'sdkm' => 'application/vnd.solent.sdkm+xml',
|
||||
'sdkd' => 'application/vnd.solent.sdkm+xml',
|
||||
'dxp' => 'application/vnd.spotfire.dxp',
|
||||
'sfs' => 'application/vnd.spotfire.sfs',
|
||||
'sus' => 'application/vnd.sus-calendar',
|
||||
'susp' => 'application/vnd.sus-calendar',
|
||||
'svd' => 'application/vnd.svd',
|
||||
'xsm' => 'application/vnd.syncml+xml',
|
||||
'bdm' => 'application/vnd.syncml.dm+wbxml',
|
||||
'xdm' => 'application/vnd.syncml.dm+xml',
|
||||
'tao' => 'application/vnd.tao.intent-module-archive',
|
||||
'tmo' => 'application/vnd.tmobile-livetv',
|
||||
'tpt' => 'application/vnd.trid.tpt',
|
||||
'mxs' => 'application/vnd.triscape.mxs',
|
||||
'tra' => 'application/vnd.trueapp',
|
||||
'ufd' => 'application/vnd.ufdl',
|
||||
'ufdl' => 'application/vnd.ufdl',
|
||||
'utz' => 'application/vnd.uiq.theme',
|
||||
'umj' => 'application/vnd.umajin',
|
||||
'unityweb' => 'application/vnd.unity',
|
||||
'uoml' => 'application/vnd.uoml+xml',
|
||||
'vcx' => 'application/vnd.vcx',
|
||||
'vsd' => 'application/vnd.visio',
|
||||
'vst' => 'application/vnd.visio',
|
||||
'vss' => 'application/vnd.visio',
|
||||
'vsw' => 'application/vnd.visio',
|
||||
'vis' => 'application/vnd.visionary',
|
||||
'vsf' => 'application/vnd.vsf',
|
||||
'wbxml' => 'application/vnd.wap.wbxml',
|
||||
'wmlc' => 'application/vnd.wap.wmlc',
|
||||
'wmlsc' => 'application/vnd.wap.wmlscriptc',
|
||||
'wtb' => 'application/vnd.webturbo',
|
||||
'wpd' => 'application/vnd.wordperfect',
|
||||
'wqd' => 'application/vnd.wqd',
|
||||
'stf' => 'application/vnd.wt.stf',
|
||||
'xar' => 'application/vnd.xara',
|
||||
'xfdl' => 'application/vnd.xfdl',
|
||||
'hvd' => 'application/vnd.yamaha.hv-dic',
|
||||
'hvs' => 'application/vnd.yamaha.hv-script',
|
||||
'hvp' => 'application/vnd.yamaha.hv-voice',
|
||||
'saf' => 'application/vnd.yamaha.smaf-audio',
|
||||
'spf' => 'application/vnd.yamaha.smaf-phrase',
|
||||
'cmp' => 'application/vnd.yellowriver-custom-menu',
|
||||
'zaz' => 'application/vnd.zzazz.deck+xml',
|
||||
'vxml' => 'application/voicexml+xml',
|
||||
'hlp' => 'application/winhlp',
|
||||
'wsdl' => 'application/wsdl+xml',
|
||||
'wspolicy' => 'application/wspolicy+xml',
|
||||
'ace' => 'application/x-ace-compressed',
|
||||
'bcpio' => 'application/x-bcpio',
|
||||
'torrent' => 'application/x-bittorrent',
|
||||
'bz' => 'application/x-bzip',
|
||||
'bz2' => 'application/x-bzip2',
|
||||
'boz' => 'application/x-bzip2',
|
||||
'vcd' => 'application/x-cdlink',
|
||||
'chat' => 'application/x-chat',
|
||||
'pgn' => 'application/x-chess-pgn',
|
||||
'cpio' => 'application/x-cpio',
|
||||
'csh' => 'application/x-csh',
|
||||
'dcr' => 'application/x-director',
|
||||
'dir' => 'application/x-director',
|
||||
'dxr' => 'application/x-director',
|
||||
'fgd' => 'application/x-director',
|
||||
'dvi' => 'application/x-dvi',
|
||||
'spl' => 'application/x-futuresplash',
|
||||
'gtar' => 'application/x-gtar',
|
||||
'hdf' => 'application/x-hdf',
|
||||
'jnlp' => 'application/x-java-jnlp-file',
|
||||
'latex' => 'application/x-latex',
|
||||
'wmd' => 'application/x-ms-wmd',
|
||||
'wmz' => 'application/x-ms-wmz',
|
||||
'mdb' => 'application/x-msaccess',
|
||||
'obd' => 'application/x-msbinder',
|
||||
'crd' => 'application/x-mscardfile',
|
||||
'clp' => 'application/x-msclip',
|
||||
'exe' => 'application/x-msdownload',
|
||||
'dll' => 'application/x-msdownload',
|
||||
'com' => 'application/x-msdownload',
|
||||
'bat' => 'application/x-msdownload',
|
||||
'msi' => 'application/x-msdownload',
|
||||
'mvb' => 'application/x-msmediaview',
|
||||
'm13' => 'application/x-msmediaview',
|
||||
'm14' => 'application/x-msmediaview',
|
||||
'wmf' => 'application/x-msmetafile',
|
||||
'mny' => 'application/x-msmoney',
|
||||
'pub' => 'application/x-mspublisher',
|
||||
'scd' => 'application/x-msschedule',
|
||||
'trm' => 'application/x-msterminal',
|
||||
'wri' => 'application/x-mswrite',
|
||||
'nc' => 'application/x-netcdf',
|
||||
'cdf' => 'application/x-netcdf',
|
||||
'p12' => 'application/x-pkcs12',
|
||||
'pfx' => 'application/x-pkcs12',
|
||||
'p7b' => 'application/x-pkcs7-certificates',
|
||||
'spc' => 'application/x-pkcs7-certificates',
|
||||
'p7r' => 'application/x-pkcs7-certreqresp',
|
||||
'rar' => 'application/x-rar-compressed',
|
||||
'sh' => 'application/x-sh',
|
||||
'shar' => 'application/x-shar',
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
'sit' => 'application/x-stuffit',
|
||||
'sitx' => 'application/x-stuffitx',
|
||||
'sv4cpio' => 'application/x-sv4cpio',
|
||||
'sv4crc' => 'application/x-sv4crc',
|
||||
'tar' => 'application/x-tar',
|
||||
'tcl' => 'application/x-tcl',
|
||||
'tex' => 'application/x-tex',
|
||||
'texinfo' => 'application/x-texinfo',
|
||||
'texi' => 'application/x-texinfo',
|
||||
'ustar' => 'application/x-ustar',
|
||||
'src' => 'application/x-wais-source',
|
||||
'der' => 'application/x-x509-ca-cert',
|
||||
'crt' => 'application/x-x509-ca-cert',
|
||||
'xenc' => 'application/xenc+xml',
|
||||
'xhtml' => 'application/xhtml+xml',
|
||||
'xht' => 'application/xhtml+xml',
|
||||
'xml' => 'application/xml',
|
||||
'xsl' => 'application/xml',
|
||||
'dtd' => 'application/xml-dtd',
|
||||
'xop' => 'application/xop+xml',
|
||||
'xslt' => 'application/xslt+xml',
|
||||
'xspf' => 'application/xspf+xml',
|
||||
'mxml' => 'application/xv+xml',
|
||||
'xhvml' => 'application/xv+xml',
|
||||
'xvml' => 'application/xv+xml',
|
||||
'xvm' => 'application/xv+xml',
|
||||
'zip' => 'application/zip',
|
||||
'au' => 'audio/basic',
|
||||
'snd' => 'audio/basic',
|
||||
'mid' => 'audio/midi',
|
||||
'midi' => 'audio/midi',
|
||||
'kar' => 'audio/midi',
|
||||
'rmi' => 'audio/midi',
|
||||
'mp4a' => 'audio/mp4',
|
||||
'm4a' => 'audio/mp4a-latm',
|
||||
'm4p' => 'audio/mp4a-latm',
|
||||
'mpga' => 'audio/mpeg',
|
||||
'mp2' => 'audio/mpeg',
|
||||
'mp2a' => 'audio/mpeg',
|
||||
'mp3' => 'audio/mpeg',
|
||||
'm2a' => 'audio/mpeg',
|
||||
'm3a' => 'audio/mpeg',
|
||||
'eol' => 'audio/vnd.digital-winds',
|
||||
'lvp' => 'audio/vnd.lucent.voice',
|
||||
'ecelp4800' => 'audio/vnd.nuera.ecelp4800',
|
||||
'ecelp7470' => 'audio/vnd.nuera.ecelp7470',
|
||||
'ecelp9600' => 'audio/vnd.nuera.ecelp9600',
|
||||
'wav' => 'audio/wav',
|
||||
'aif' => 'audio/x-aiff',
|
||||
'aiff' => 'audio/x-aiff',
|
||||
'aifc' => 'audio/x-aiff',
|
||||
'm3u' => 'audio/x-mpegurl',
|
||||
'wax' => 'audio/x-ms-wax',
|
||||
'wma' => 'audio/x-ms-wma',
|
||||
'ram' => 'audio/x-pn-realaudio',
|
||||
'ra' => 'audio/x-pn-realaudio',
|
||||
'rmp' => 'audio/x-pn-realaudio-plugin',
|
||||
'cdx' => 'chemical/x-cdx',
|
||||
'cif' => 'chemical/x-cif',
|
||||
'cmdf' => 'chemical/x-cmdf',
|
||||
'cml' => 'chemical/x-cml',
|
||||
'csml' => 'chemical/x-csml',
|
||||
'xyz' => 'chemical/x-xyz',
|
||||
'bmp' => 'image/bmp',
|
||||
'cgm' => 'image/cgm',
|
||||
'g3' => 'image/g3fax',
|
||||
'gif' => 'image/gif',
|
||||
'ief' => 'image/ief',
|
||||
'jp2' => 'image/jp2',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'jpe' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'pict' => 'image/pict',
|
||||
'pic' => 'image/pict',
|
||||
'pct' => 'image/pict',
|
||||
'png' => 'image/png',
|
||||
'btif' => 'image/prs.btif',
|
||||
'svg' => 'image/svg+xml',
|
||||
'svgz' => 'image/svg+xml',
|
||||
'tiff' => 'image/tiff',
|
||||
'tif' => 'image/tiff',
|
||||
'psd' => 'image/vnd.adobe.photoshop',
|
||||
'djvu' => 'image/vnd.djvu',
|
||||
'djv' => 'image/vnd.djvu',
|
||||
'dwg' => 'image/vnd.dwg',
|
||||
'dxf' => 'image/vnd.dxf',
|
||||
'fbs' => 'image/vnd.fastbidsheet',
|
||||
'fpx' => 'image/vnd.fpx',
|
||||
'fst' => 'image/vnd.fst',
|
||||
'mmr' => 'image/vnd.fujixerox.edmics-mmr',
|
||||
'rlc' => 'image/vnd.fujixerox.edmics-rlc',
|
||||
'ico' => 'image/vnd.microsoft.icon',
|
||||
'mdi' => 'image/vnd.ms-modi',
|
||||
'npx' => 'image/vnd.net-fpx',
|
||||
'wbmp' => 'image/vnd.wap.wbmp',
|
||||
'xif' => 'image/vnd.xiff',
|
||||
'ras' => 'image/x-cmu-raster',
|
||||
'cmx' => 'image/x-cmx',
|
||||
'pntg' => 'image/x-macpaint',
|
||||
'pnt' => 'image/x-macpaint',
|
||||
'mac' => 'image/x-macpaint',
|
||||
'pcx' => 'image/x-pcx',
|
||||
'pnm' => 'image/x-portable-anymap',
|
||||
'pbm' => 'image/x-portable-bitmap',
|
||||
'pgm' => 'image/x-portable-graymap',
|
||||
'ppm' => 'image/x-portable-pixmap',
|
||||
'qtif' => 'image/x-quicktime',
|
||||
'qti' => 'image/x-quicktime',
|
||||
'rgb' => 'image/x-rgb',
|
||||
'xbm' => 'image/x-xbitmap',
|
||||
'xpm' => 'image/x-xpixmap',
|
||||
'xwd' => 'image/x-xwindowdump',
|
||||
'eml' => 'message/rfc822',
|
||||
'mime' => 'message/rfc822',
|
||||
'igs' => 'model/iges',
|
||||
'iges' => 'model/iges',
|
||||
'msh' => 'model/mesh',
|
||||
'mesh' => 'model/mesh',
|
||||
'silo' => 'model/mesh',
|
||||
'dwf' => 'model/vnd.dwf',
|
||||
'gdl' => 'model/vnd.gdl',
|
||||
'gtw' => 'model/vnd.gtw',
|
||||
'mts' => 'model/vnd.mts',
|
||||
'vtu' => 'model/vnd.vtu',
|
||||
'wrl' => 'model/vrml',
|
||||
'vrml' => 'model/vrml',
|
||||
'ics' => 'text/calendar',
|
||||
'ifb' => 'text/calendar',
|
||||
'css' => 'text/css',
|
||||
'csv' => 'text/csv',
|
||||
'html' => 'text/html',
|
||||
'htm' => 'text/html',
|
||||
'txt' => 'text/plain',
|
||||
'text' => 'text/plain',
|
||||
'conf' => 'text/plain',
|
||||
'def' => 'text/plain',
|
||||
'list' => 'text/plain',
|
||||
'log' => 'text/plain',
|
||||
'in' => 'text/plain',
|
||||
'dsc' => 'text/prs.lines.tag',
|
||||
'rtx' => 'text/richtext',
|
||||
'sgml' => 'text/sgml',
|
||||
'sgm' => 'text/sgml',
|
||||
'tsv' => 'text/tab-separated-values',
|
||||
't' => 'text/troff',
|
||||
'tr' => 'text/troff',
|
||||
'roff' => 'text/troff',
|
||||
'man' => 'text/troff',
|
||||
'me' => 'text/troff',
|
||||
'ms' => 'text/troff',
|
||||
'uri' => 'text/uri-list',
|
||||
'uris' => 'text/uri-list',
|
||||
'urls' => 'text/uri-list',
|
||||
'fly' => 'text/vnd.fly',
|
||||
'flx' => 'text/vnd.fmi.flexstor',
|
||||
'3dml' => 'text/vnd.in3d.3dml',
|
||||
'spot' => 'text/vnd.in3d.spot',
|
||||
'jad' => 'text/vnd.sun.j2me.app-descriptor',
|
||||
'wml' => 'text/vnd.wap.wml',
|
||||
'wmls' => 'text/vnd.wap.wmlscript',
|
||||
's' => 'text/x-asm',
|
||||
'asm' => 'text/x-asm',
|
||||
'c' => 'text/x-c',
|
||||
'cc' => 'text/x-c',
|
||||
'cxx' => 'text/x-c',
|
||||
'cpp' => 'text/x-c',
|
||||
'h' => 'text/x-c',
|
||||
'hh' => 'text/x-c',
|
||||
'dic' => 'text/x-c',
|
||||
'f' => 'text/x-fortran',
|
||||
'for' => 'text/x-fortran',
|
||||
'f77' => 'text/x-fortran',
|
||||
'f90' => 'text/x-fortran',
|
||||
'p' => 'text/x-pascal',
|
||||
'pas' => 'text/x-pascal',
|
||||
'java' => 'text/x-java-source',
|
||||
'etx' => 'text/x-setext',
|
||||
'uu' => 'text/x-uuencode',
|
||||
'vcs' => 'text/x-vcalendar',
|
||||
'vcf' => 'text/x-vcard',
|
||||
'3gp' => 'video/3gpp',
|
||||
'3g2' => 'video/3gpp2',
|
||||
'h261' => 'video/h261',
|
||||
'h263' => 'video/h263',
|
||||
'h264' => 'video/h264',
|
||||
'jpgv' => 'video/jpeg',
|
||||
'jpm' => 'video/jpm',
|
||||
'jpgm' => 'video/jpm',
|
||||
'mj2' => 'video/mj2',
|
||||
'mjp2' => 'video/mj2',
|
||||
'mp4' => 'video/mp4',
|
||||
'mp4v' => 'video/mp4',
|
||||
'mpg4' => 'video/mp4',
|
||||
'm4v' => 'video/mp4',
|
||||
'mpeg' => 'video/mpeg',
|
||||
'mpg' => 'video/mpeg',
|
||||
'mpe' => 'video/mpeg',
|
||||
'm1v' => 'video/mpeg',
|
||||
'm2v' => 'video/mpeg',
|
||||
'qt' => 'video/quicktime',
|
||||
'mov' => 'video/quicktime',
|
||||
'fvt' => 'video/vnd.fvt',
|
||||
'mxu' => 'video/vnd.mpegurl',
|
||||
'm4u' => 'video/vnd.mpegurl',
|
||||
'viv' => 'video/vnd.vivo',
|
||||
'dv' => 'video/x-dv',
|
||||
'dif' => 'video/x-dv',
|
||||
'fli' => 'video/x-fli',
|
||||
'asx' => 'video/x-ms-asf',
|
||||
'wm' => 'video/x-ms-wm',
|
||||
'wmv' => 'video/x-ms-wmv',
|
||||
'wmx' => 'video/x-ms-wmx',
|
||||
'wvx' => 'video/x-ms-wvx',
|
||||
'avi' => 'video/x-msvideo',
|
||||
'movie' => 'video/x-sgi-movie',
|
||||
'ice' => 'x-conference/x-cooltalk',
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns extensions for given mimes types
|
||||
*
|
||||
* @param array $mimesTypes The mimes types, e.g. ['video/mpeg', 'image/jpeg']
|
||||
* @param bool $asUpperCase (optional) If is set to true, extensions are returned as upper case. Otherwise - lower
|
||||
* case.
|
||||
* @return array
|
||||
*/
|
||||
public static function getExtensions(array $mimesTypes, $asUpperCase = false)
|
||||
{
|
||||
if (empty($mimesTypes)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$extensions = [];
|
||||
|
||||
foreach ($mimesTypes as $mimeType) {
|
||||
$extension = self::getExtension($mimeType);
|
||||
|
||||
/*
|
||||
* No extension for given mime type?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($extension)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extensions should be returned as upper case?
|
||||
*/
|
||||
if ($asUpperCase) {
|
||||
if (is_array($extension)) {
|
||||
array_walk($extension, function (&$value) {
|
||||
$value = strtoupper($value);
|
||||
});
|
||||
} else {
|
||||
$extension = strtoupper($extension);
|
||||
}
|
||||
}
|
||||
|
||||
$extensions[$mimeType] = $extension;
|
||||
}
|
||||
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns extension for given mime type
|
||||
*
|
||||
* @param string $mimeType The mime type, e.g. "video/mpeg"
|
||||
* @return string|array
|
||||
*/
|
||||
public static function getExtension($mimeType)
|
||||
{
|
||||
if (is_string($mimeType) && in_array($mimeType, self::$mimeTypes)) {
|
||||
$data = Arrays::setKeysAsValues(self::$mimeTypes, false);
|
||||
|
||||
return $data[$mimeType];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information whether file with the given path is an image
|
||||
*
|
||||
* @param string $path Path of the file to check
|
||||
* @return bool
|
||||
*/
|
||||
public static function isImagePath($path)
|
||||
{
|
||||
$mimeType = self::getMimeType($path);
|
||||
|
||||
return self::isImage($mimeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns mime type of given file
|
||||
*
|
||||
* @param string $filePath Path of the file to check
|
||||
* @return string
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public static function getMimeType($filePath)
|
||||
{
|
||||
/*
|
||||
* The file does not exist?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (!is_string($filePath) || !is_readable($filePath)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/*
|
||||
* 1st possibility: the finfo class
|
||||
*/
|
||||
if (class_exists('finfo')) {
|
||||
$finfo = new \finfo();
|
||||
|
||||
return $finfo->file($filePath, FILEINFO_MIME_TYPE);
|
||||
}
|
||||
|
||||
/*
|
||||
* 2nd possibility: the mime_content_type function
|
||||
*/
|
||||
if (function_exists('mime_content_type')) {
|
||||
return mime_content_type($filePath);
|
||||
}
|
||||
|
||||
/*
|
||||
* Oops, there is no possibility to read the mime type
|
||||
*/
|
||||
$template = 'Neither \'finfo\' class nor \'mime_content_type\' function exists. There is no way to read the'
|
||||
. ' mime type of file \'%s\'.';
|
||||
|
||||
$message = sprintf($template, $filePath);
|
||||
throw new \RuntimeException($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information whether the given file type is an image
|
||||
*
|
||||
* @param string $mimeType The mime type of file
|
||||
* @return bool
|
||||
*/
|
||||
public static function isImage($mimeType)
|
||||
{
|
||||
if (in_array($mimeType, self::$mimeTypes)) {
|
||||
return (bool)preg_match('|^image/.+$|', $mimeType);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,633 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Utilities;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Util\ClassUtils;
|
||||
use Doctrine\Common\Util\Inflector;
|
||||
use Meritoo\Common\Exception\Reflection\CannotResolveClassNameException;
|
||||
use Meritoo\Common\Exception\Reflection\MissingChildClassesException;
|
||||
use Meritoo\Common\Exception\Reflection\TooManyChildClassesException;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use ReflectionMethod;
|
||||
use ReflectionObject;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Useful reflection methods
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
*/
|
||||
class Reflection
|
||||
{
|
||||
/**
|
||||
* Returns names of methods for given class / object
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @param bool $withoutInheritance (optional) If is set to true, only methods for given class are returned.
|
||||
* Otherwise - all methods, with inherited methods too.
|
||||
* @return array
|
||||
*/
|
||||
public static function getMethods($class, $withoutInheritance = false)
|
||||
{
|
||||
$effect = [];
|
||||
|
||||
$reflection = new ReflectionClass($class);
|
||||
$methods = $reflection->getMethods();
|
||||
|
||||
if (!empty($methods)) {
|
||||
$className = self::getClassName($class);
|
||||
|
||||
foreach ($methods as $method) {
|
||||
if ($method instanceof ReflectionMethod) {
|
||||
if ($withoutInheritance && $className !== $method->class) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$effect[] = $method->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $effect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns constants of given class / object
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @return array
|
||||
*/
|
||||
public static function getConstants($class)
|
||||
{
|
||||
$reflection = new ReflectionClass($class);
|
||||
|
||||
return $reflection->getConstants();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns maximum constant from all constants of given class / object.
|
||||
* Values of constants should be integers.
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @return int|null
|
||||
*/
|
||||
public static function getMaxNumberConstant($class)
|
||||
{
|
||||
$constants = self::getConstants($class);
|
||||
|
||||
if (empty($constants)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$maxNumber = 0;
|
||||
|
||||
foreach ($constants as $constant) {
|
||||
if (is_numeric($constant) && $constant > $maxNumber) {
|
||||
$maxNumber = $constant;
|
||||
}
|
||||
}
|
||||
|
||||
return $maxNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given class / object has given method
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @param string $method Name of the method to find
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasMethod($class, $method)
|
||||
{
|
||||
$reflection = new ReflectionClass($class);
|
||||
|
||||
return $reflection->hasMethod($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given class / object has given property
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @param string $property Name of the property to find
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasProperty($class, $property)
|
||||
{
|
||||
$reflection = new ReflectionClass($class);
|
||||
|
||||
return $reflection->hasProperty($property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given class / object has given constant
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @param string $constant Name of the constant to find
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasConstant($class, $constant)
|
||||
{
|
||||
$reflection = new ReflectionClass($class);
|
||||
|
||||
return $reflection->hasConstant($constant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value of given constant
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @param string $constant Name of the constant that contains a value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getConstantValue($class, $constant)
|
||||
{
|
||||
$reflection = new ReflectionClass($class);
|
||||
|
||||
if (self::hasConstant($class, $constant)) {
|
||||
return $reflection->getConstant($constant);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value of given property.
|
||||
* Looks for proper getter for the property.
|
||||
*
|
||||
* @param mixed $object Object that should contains given property
|
||||
* @param string $property Name of the property that contains a value. It may be also multiple properties
|
||||
* dot-separated, e.g. "invoice.user.email".
|
||||
* @param bool $force (optional) If is set to true, try to retrieve value even if the object doesn't have
|
||||
* property. Otherwise - not.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getPropertyValue($object, $property, $force = false)
|
||||
{
|
||||
$value = null;
|
||||
|
||||
/*
|
||||
* Property is a dot-separated string?
|
||||
* Let's find all values of the chain, of the dot-separated properties
|
||||
*/
|
||||
if (Regex::contains($property, '.')) {
|
||||
$exploded = explode('.', $property);
|
||||
|
||||
$property = $exploded[0];
|
||||
$object = self::getPropertyValue($object, $property, $force);
|
||||
|
||||
/*
|
||||
* Value of processed property from the chain is not null?
|
||||
* Let's dig more and get proper value
|
||||
*
|
||||
* Required to avoid bug:
|
||||
* ReflectionObject::__construct() expects parameter 1 to be object, null given
|
||||
* (...)
|
||||
* 4. at ReflectionObject->__construct (null)
|
||||
* 5. at Reflection ::getPropertyValue (null, 'name', true)
|
||||
* 6. at ListService->getItemValue (object(Deal), 'project.name', '0')
|
||||
*
|
||||
* while using "project.name" as property - $project has $name property ($project exists in the Deal class)
|
||||
* and the $project equals null
|
||||
*
|
||||
* Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* 2016-11-07
|
||||
*/
|
||||
if ($object !== null) {
|
||||
unset($exploded[0]);
|
||||
|
||||
$property = implode('.', $exploded);
|
||||
$value = self::getPropertyValue($object, $property, $force);
|
||||
}
|
||||
} else {
|
||||
$className = self::getClassName($object);
|
||||
$reflectionProperty = null;
|
||||
|
||||
/*
|
||||
* 1st try:
|
||||
* Use \ReflectionObject class
|
||||
*/
|
||||
try {
|
||||
$reflectionProperty = new ReflectionProperty($className, $property);
|
||||
$value = $reflectionProperty->getValue($object);
|
||||
} catch (ReflectionException $exception) {
|
||||
/*
|
||||
* 2nd try:
|
||||
* Look for the get / has / is methods
|
||||
*/
|
||||
$class = new ReflectionObject($object);
|
||||
$valueFound = false;
|
||||
|
||||
if ($class->hasProperty($property) || $force) {
|
||||
$property = Inflector::classify($property);
|
||||
|
||||
$methodPrefixes = [
|
||||
'get',
|
||||
'has',
|
||||
'is',
|
||||
];
|
||||
|
||||
foreach ($methodPrefixes as $prefix) {
|
||||
$method = sprintf('%s%s', $prefix, $property);
|
||||
|
||||
if ($class->hasMethod($method)) {
|
||||
$value = $object->{$method}();
|
||||
$valueFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$valueFound && $reflectionProperty !== null) {
|
||||
/*
|
||||
* Oops, we have got exception.
|
||||
*
|
||||
* 3rd try:
|
||||
* Let's try modify accessibility of the property and try again to get value.
|
||||
*/
|
||||
$reflectionProperty->setAccessible(true);
|
||||
$value = $reflectionProperty->getValue($object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns values of given property for given objects.
|
||||
* Looks for proper getter for the property.
|
||||
*
|
||||
* @param Collection|object|array $objects The objects that should contain given property. It may be also one
|
||||
* object.
|
||||
* @param string $property Name of the property that contains a value
|
||||
* @param bool $force (optional) If is set to true, try to retrieve value even if the
|
||||
* object does not have property. Otherwise - not.
|
||||
* @return array
|
||||
*/
|
||||
public static function getPropertyValues($objects, $property, $force = false)
|
||||
{
|
||||
if ($objects instanceof Collection) {
|
||||
$objects = $objects->toArray();
|
||||
}
|
||||
|
||||
$values = [];
|
||||
$objects = Arrays::makeArray($objects);
|
||||
|
||||
foreach ($objects as $entity) {
|
||||
$value = self::getPropertyValue($entity, $property, $force);
|
||||
|
||||
if ($value !== null) {
|
||||
$values[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a class name for given source
|
||||
*
|
||||
* @param array|object|string $source An array of objects, namespaces, object or namespace
|
||||
* @param bool $withoutNamespace (optional) If is set to true, namespace is omitted. Otherwise -
|
||||
* not, full name of class is returned, with namespace.
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getClassName($source, $withoutNamespace = false)
|
||||
{
|
||||
/*
|
||||
* First argument is not proper source of class?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($source) || (!is_array($source) && !is_object($source) && !is_string($source))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$name = '';
|
||||
|
||||
/*
|
||||
* An array of objects was provided?
|
||||
* Let's use first of them
|
||||
*/
|
||||
if (is_array($source)) {
|
||||
$source = Arrays::getFirstElement($source);
|
||||
}
|
||||
|
||||
/*
|
||||
* Let's prepare name of class
|
||||
*/
|
||||
if (is_object($source)) {
|
||||
$name = get_class($source);
|
||||
} elseif (is_string($source) && (class_exists($source) || trait_exists($source))) {
|
||||
$name = $source;
|
||||
}
|
||||
|
||||
/*
|
||||
* Name of class is still unknown?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Namespace is not required?
|
||||
* Let's return name of class only
|
||||
*/
|
||||
if ($withoutNamespace) {
|
||||
$classOnly = Miscellaneous::getLastElementOfString($name, '\\');
|
||||
|
||||
if ($classOnly !== null) {
|
||||
$name = $classOnly;
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
return ClassUtils::getRealClass($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns namespace of class for given source
|
||||
*
|
||||
* @param array|object|string $source An array of objects, namespaces, object or namespace
|
||||
* @return string
|
||||
*/
|
||||
public static function getClassNamespace($source)
|
||||
{
|
||||
$fullClassName = self::getClassName($source);
|
||||
|
||||
if (empty($fullClassName)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$className = self::getClassName($source, true);
|
||||
|
||||
if ($className == $fullClassName) {
|
||||
return $className;
|
||||
}
|
||||
|
||||
return Miscellaneous::getStringWithoutLastElement($fullClassName, '\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given interface is implemented by given class / object
|
||||
*
|
||||
* @param array|object|string $source An array of objects, namespaces, object or namespace
|
||||
* @param string $interface The interface that should be implemented
|
||||
* @return bool
|
||||
*/
|
||||
public static function isInterfaceImplemented($source, $interface)
|
||||
{
|
||||
$className = self::getClassName($source);
|
||||
$interfaces = class_implements($className);
|
||||
|
||||
return in_array($interface, $interfaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given child class is a subclass of given parent class
|
||||
*
|
||||
* @param array|object|string $childClass The child class. An array of objects, namespaces, object or namespace.
|
||||
* @param array|object|string $parentClass The parent class. An array of objects, namespaces, object or namespace.
|
||||
* @return bool
|
||||
*/
|
||||
public static function isChildOfClass($childClass, $parentClass)
|
||||
{
|
||||
$childClassName = self::getClassName($childClass);
|
||||
$parentClassName = self::getClassName($parentClass);
|
||||
|
||||
$parents = class_parents($childClassName);
|
||||
|
||||
if (is_array($parents)) {
|
||||
return in_array($parentClassName, $parents);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns given object properties
|
||||
*
|
||||
* @param array|object|string $source An array of objects, namespaces, object or namespace
|
||||
* @param int $filter (optional) Filter of properties. Uses ReflectionProperty class constants.
|
||||
* By default all properties are returned.
|
||||
* @return array|ReflectionProperty
|
||||
*/
|
||||
public static function getProperties($source, $filter = null)
|
||||
{
|
||||
$className = self::getClassName($source);
|
||||
$reflection = new ReflectionClass($className);
|
||||
|
||||
if ($filter === null) {
|
||||
$filter = ReflectionProperty::IS_PRIVATE
|
||||
+ ReflectionProperty::IS_PROTECTED
|
||||
+ ReflectionProperty::IS_PUBLIC
|
||||
+ ReflectionProperty::IS_STATIC;
|
||||
}
|
||||
|
||||
return $reflection->getProperties($filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a parent class
|
||||
*
|
||||
* @param array|object|string $source An array of objects, namespaces, object or namespace
|
||||
* @return ReflectionClass
|
||||
*/
|
||||
public static function getParentClass($source)
|
||||
{
|
||||
$className = self::getClassName($source);
|
||||
$reflection = new ReflectionClass($className);
|
||||
|
||||
return $reflection->getParentClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns child classes of given class.
|
||||
* It's an array of namespaces of the child classes or null (if given class has not child classes).
|
||||
*
|
||||
* @param array|object|string $class Class who child classes should be returned. An array of objects, strings,
|
||||
* object or string.
|
||||
* @return array|null
|
||||
* @throws CannotResolveClassNameException
|
||||
*/
|
||||
public static function getChildClasses($class)
|
||||
{
|
||||
$allClasses = get_declared_classes();
|
||||
|
||||
/*
|
||||
* No classes?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($allClasses)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$className = self::getClassName($class);
|
||||
|
||||
/*
|
||||
* Oops, cannot resolve class
|
||||
*/
|
||||
if ($className === null) {
|
||||
throw new CannotResolveClassNameException($class);
|
||||
}
|
||||
|
||||
$childClasses = [];
|
||||
|
||||
foreach ($allClasses as $oneClass) {
|
||||
if (self::isChildOfClass($oneClass, $className)) {
|
||||
/*
|
||||
* Attention. I have to use ClassUtils::getRealClass() method to avoid problem with the proxy / cache
|
||||
* classes. Example:
|
||||
* - My\ExtraBundle\Entity\MyEntity
|
||||
* - Proxies\__CG__\My\ExtraBundle\Entity\MyEntity
|
||||
*
|
||||
* It's actually the same class, so I have to skip it.
|
||||
*/
|
||||
$realClass = ClassUtils::getRealClass($oneClass);
|
||||
|
||||
if (in_array($realClass, $childClasses)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$childClasses[] = $realClass;
|
||||
}
|
||||
}
|
||||
|
||||
return $childClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns namespace of one child class which extends given class.
|
||||
* Extended class should has only one child class.
|
||||
*
|
||||
* @param array|object|string $parentClass Class who child class should be returned. An array of objects,
|
||||
* namespaces, object or namespace.
|
||||
* @return mixed
|
||||
*
|
||||
* @throws MissingChildClassesException
|
||||
* @throws TooManyChildClassesException
|
||||
*/
|
||||
public static function getOneChildClass($parentClass)
|
||||
{
|
||||
$childClasses = self::getChildClasses($parentClass);
|
||||
|
||||
/*
|
||||
* No child classes?
|
||||
* Oops, the base / parent class hasn't child class
|
||||
*/
|
||||
if (empty($childClasses)) {
|
||||
throw new MissingChildClassesException($parentClass);
|
||||
}
|
||||
|
||||
/*
|
||||
* More than 1 child class?
|
||||
* Oops, the base / parent class has too many child classes
|
||||
*/
|
||||
if (count($childClasses) > 1) {
|
||||
throw new TooManyChildClassesException($parentClass, $childClasses);
|
||||
}
|
||||
|
||||
return trim($childClasses[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns property, the ReflectionProperty instance, of given object
|
||||
*
|
||||
* @param array|object|string $class An array of objects, namespaces, object or namespace
|
||||
* @param string $property Name of the property
|
||||
* @param int $filter (optional) Filter of properties. Uses ReflectionProperty class constants.
|
||||
* By default all properties are allowed / processed.
|
||||
* @return null|ReflectionProperty
|
||||
*/
|
||||
public static function getProperty($class, $property, $filter = null)
|
||||
{
|
||||
$className = self::getClassName($class);
|
||||
$properties = self::getProperties($className, $filter);
|
||||
|
||||
if (!empty($properties)) {
|
||||
/* @var $reflectionProperty ReflectionProperty */
|
||||
foreach ($properties as $reflectionProperty) {
|
||||
if ($reflectionProperty->getName() == $property) {
|
||||
return $reflectionProperty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given class / object uses / implements given trait
|
||||
*
|
||||
* @param array|object|string $class An array of objects, namespaces, object or namespace
|
||||
* @param array|string $trait An array of strings or string
|
||||
* @param bool $verifyParents If is set to true, parent classes are verified if they use given
|
||||
* trait. Otherwise - not.
|
||||
* @return bool|null
|
||||
* @throws CannotResolveClassNameException
|
||||
*/
|
||||
public static function usesTrait($class, $trait, $verifyParents = false)
|
||||
{
|
||||
$className = self::getClassName($class);
|
||||
$traitName = self::getClassName($trait);
|
||||
|
||||
/*
|
||||
* Oops, cannot resolve class
|
||||
*/
|
||||
if (empty($className)) {
|
||||
throw new CannotResolveClassNameException($class);
|
||||
}
|
||||
|
||||
/*
|
||||
* Oops, cannot resolve trait
|
||||
*/
|
||||
if (empty($traitName)) {
|
||||
throw new CannotResolveClassNameException($class, false);
|
||||
}
|
||||
|
||||
$reflection = new ReflectionClass($className);
|
||||
$traitsNames = $reflection->getTraitNames();
|
||||
|
||||
$uses = in_array($traitName, $traitsNames);
|
||||
|
||||
if (!$uses && $verifyParents) {
|
||||
$parentClassName = self::getParentClassName($className);
|
||||
|
||||
if ($parentClassName !== null) {
|
||||
return self::usesTrait($parentClassName, $trait, true);
|
||||
}
|
||||
}
|
||||
|
||||
return $uses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns name of the parent class.
|
||||
* If given class does not extend another, returns null.
|
||||
*
|
||||
* @param array|object|string $class An array of objects, namespaces, object or namespace
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getParentClassName($class)
|
||||
{
|
||||
$className = self::getClassName($class);
|
||||
$reflection = new ReflectionClass($className);
|
||||
$parentClass = $reflection->getParentClass();
|
||||
|
||||
if ($parentClass === null || $parentClass === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $parentClass->getName();
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Utilities;
|
||||
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
/**
|
||||
* Useful methods for repository
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
*/
|
||||
class Repository
|
||||
{
|
||||
/**
|
||||
* Replenishes positions of given items
|
||||
*
|
||||
* @param array $items The items
|
||||
* @param bool $asLast (optional) If is set to true, items are placed at the end. Otherwise - at the top.
|
||||
* @param bool $force (optional) If is set to true, positions are set even there is no extreme position.
|
||||
* Otherwise - if extreme position is not found (is null) replenishment is stopped / skipped.
|
||||
*/
|
||||
public static function replenishPositions($items, $asLast = true, $force = false)
|
||||
{
|
||||
$position = self::getExtremePosition($items, $asLast);
|
||||
|
||||
if ($position === null && $force) {
|
||||
$position = 0;
|
||||
}
|
||||
|
||||
if ($position !== null && !empty($items)) {
|
||||
foreach ($items as $item) {
|
||||
if (method_exists($item, 'getPosition')) {
|
||||
if ($item->getPosition() === null) {
|
||||
if ($asLast) {
|
||||
++$position;
|
||||
} else {
|
||||
--$position;
|
||||
}
|
||||
|
||||
if (method_exists($item, 'setPosition')) {
|
||||
$item->setPosition($position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns extreme position (max or min) of given items
|
||||
*
|
||||
* @param array $items The items
|
||||
* @param bool $max (optional) If is set to true, maximum value is returned. Otherwise - minimum.
|
||||
* @return int
|
||||
*/
|
||||
public static function getExtremePosition($items, $max = true)
|
||||
{
|
||||
$extreme = null;
|
||||
|
||||
if (!empty($items)) {
|
||||
foreach ($items as $item) {
|
||||
if (Reflection::hasMethod($item, 'getPosition')) {
|
||||
$position = $item->getPosition();
|
||||
|
||||
if ($max) {
|
||||
if ($position > $extreme) {
|
||||
$extreme = $position;
|
||||
}
|
||||
} else {
|
||||
if ($position < $extreme) {
|
||||
$extreme = $position;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $extreme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns query builder for given entity's repository.
|
||||
* The entity should contain given property, e.g. "name".
|
||||
*
|
||||
* @param EntityRepository $repository Repository of the entity
|
||||
* @param string $property (optional) Name of property used by the ORDER BY clause
|
||||
* @param string $direction (optional) Direction used by the ORDER BY clause ("ASC" or "DESC")
|
||||
* @return QueryBuilder
|
||||
*/
|
||||
public static function getEntityOrderedQueryBuilder(
|
||||
EntityRepository $repository,
|
||||
$property = 'name',
|
||||
$direction = 'ASC'
|
||||
) {
|
||||
$alias = 'qb';
|
||||
|
||||
return $repository
|
||||
->createQueryBuilder($alias)
|
||||
->orderBy(sprintf('%s.%s', $alias, $property), $direction);
|
||||
}
|
||||
}
|
||||
23
src/Test/Base/BaseTestCase.php
Normal file
23
src/Test/Base/BaseTestCase.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.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Test\Base;
|
||||
|
||||
use Meritoo\Common\Traits\Test\Base\BaseTestCaseTrait;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Base test case with common methods and data providers
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
abstract class BaseTestCase extends TestCase
|
||||
{
|
||||
use BaseTestCaseTrait;
|
||||
}
|
||||
22
src/Test/Base/BaseTypeTestCase.php
Normal file
22
src/Test/Base/BaseTypeTestCase.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\Test\Base;
|
||||
|
||||
use Meritoo\Common\Traits\Test\Base\BaseTypeTestCaseTrait;
|
||||
|
||||
/**
|
||||
* Base test case for the type of something
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
abstract class BaseTypeTestCase extends BaseTestCase
|
||||
{
|
||||
use BaseTypeTestCaseTrait;
|
||||
}
|
||||
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,9 +31,9 @@ abstract class BaseType
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll()
|
||||
public function getAll(): array
|
||||
{
|
||||
if ($this->all === null) {
|
||||
if (null === $this->all) {
|
||||
$this->all = Reflection::getConstants($this);
|
||||
}
|
||||
|
||||
@@ -43,11 +43,11 @@ abstract class BaseType
|
||||
/**
|
||||
* Returns information if given type is correct
|
||||
*
|
||||
* @param string $type The type to check
|
||||
* @param null|string $type The type to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isCorrectType($type)
|
||||
public static function isCorrectType(?string $type): bool
|
||||
{
|
||||
return in_array($type, $this->getAll(), true);
|
||||
return in_array($type, (new static())->getAll());
|
||||
}
|
||||
}
|
||||
@@ -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,153 +6,116 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Utilities;
|
||||
namespace Meritoo\Common\Type;
|
||||
|
||||
use DateTime;
|
||||
use Meritoo\Common\Type\Base\BaseType;
|
||||
use Meritoo\Common\Utilities\Date;
|
||||
|
||||
/**
|
||||
* A date's period.
|
||||
* Contains start and end date of the period.
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class DatePeriod
|
||||
class DatePeriod extends BaseType
|
||||
{
|
||||
/**
|
||||
* The period constant: last month
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const LAST_MONTH = 4;
|
||||
public const LAST_MONTH = '4';
|
||||
|
||||
/**
|
||||
* The period constant: last week
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const LAST_WEEK = 1;
|
||||
public const LAST_WEEK = '1';
|
||||
|
||||
/**
|
||||
* The period constant: last year
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const LAST_YEAR = 7;
|
||||
public const LAST_YEAR = '7';
|
||||
|
||||
/**
|
||||
* The period constant: next month
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const NEXT_MONTH = 6;
|
||||
public const NEXT_MONTH = '6';
|
||||
|
||||
/**
|
||||
* The period constant: next week
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const NEXT_WEEK = 3;
|
||||
public const NEXT_WEEK = '3';
|
||||
|
||||
/**
|
||||
* The period constant: next year
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const NEXT_YEAR = 9;
|
||||
public const NEXT_YEAR = '9';
|
||||
|
||||
/**
|
||||
* The period constant: this month
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const THIS_MONTH = 5;
|
||||
public const THIS_MONTH = '5';
|
||||
|
||||
/**
|
||||
* The period constant: this week
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const THIS_WEEK = 2;
|
||||
public const THIS_WEEK = '2';
|
||||
|
||||
/**
|
||||
* The period constant: this year
|
||||
*
|
||||
* @var int
|
||||
* @var string
|
||||
*/
|
||||
const THIS_YEAR = 8;
|
||||
public const THIS_YEAR = '8';
|
||||
|
||||
/**
|
||||
* The start date of period
|
||||
*
|
||||
* @var DateTime
|
||||
* @var null|DateTime
|
||||
*/
|
||||
private $startDate;
|
||||
|
||||
/**
|
||||
* The end date of period
|
||||
*
|
||||
* @var DateTime
|
||||
* @var null|DateTime
|
||||
*/
|
||||
private $endDate;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param DateTime $startDate (optional) The start date of period
|
||||
* @param DateTime $endDate (optional) The end date of period
|
||||
* @param null|DateTime $startDate (optional) The start date of period
|
||||
* @param null|DateTime $endDate (optional) The end date of period
|
||||
*/
|
||||
public function __construct(DateTime $startDate = null, DateTime $endDate = null)
|
||||
public function __construct(?DateTime $startDate = null, ?DateTime $endDate = null)
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
$this->endDate = $endDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given period is correct
|
||||
*
|
||||
* @param int $period The period to verify
|
||||
* @return bool
|
||||
*/
|
||||
public static function isCorrectPeriod($period)
|
||||
{
|
||||
return in_array($period, Reflection::getConstants(__CLASS__));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted one of the period's date: start date or end date
|
||||
*
|
||||
* @param string $format Format used to format the date
|
||||
* @param bool $startDate (optional) If is set to true, start date is formatted. Otherwise - end date.
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedDate($format, $startDate = true)
|
||||
{
|
||||
$date = $this->getEndDate();
|
||||
|
||||
/*
|
||||
* Start date should be formatted?
|
||||
*/
|
||||
if ($startDate) {
|
||||
$date = $this->getStartDate();
|
||||
}
|
||||
|
||||
/*
|
||||
* Unknown date or format is invalid?
|
||||
*/
|
||||
if ($date === null || !Date::isValidDateFormat($format)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $date->format($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the end date of period
|
||||
*
|
||||
* @return DateTime
|
||||
* @return null|DateTime
|
||||
*/
|
||||
public function getEndDate()
|
||||
public function getEndDate(): ?DateTime
|
||||
{
|
||||
return $this->endDate;
|
||||
}
|
||||
@@ -160,22 +123,48 @@ class DatePeriod
|
||||
/**
|
||||
* Sets the end date of period
|
||||
*
|
||||
* @param DateTime $endDate (optional) The end date of period
|
||||
* @param null|DateTime $endDate (optional) The end date of period. Default: null.
|
||||
* @return $this
|
||||
*/
|
||||
public function setEndDate(DateTime $endDate = null)
|
||||
public function setEndDate(?DateTime $endDate = null): self
|
||||
{
|
||||
$this->endDate = $endDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted one of the period's date: start date or end date
|
||||
*
|
||||
* @param string $format Format used to format the date
|
||||
* @param bool $startDate (optional) If is set to true, start date will be formatted (default behaviour).
|
||||
* Otherwise - end date.
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedDate(string $format, bool $startDate = true): string
|
||||
{
|
||||
$date = $this->getEndDate();
|
||||
|
||||
// Start date should be formatted?
|
||||
if ($startDate) {
|
||||
$date = $this->getStartDate();
|
||||
}
|
||||
|
||||
// Unknown date or format is invalid?
|
||||
// Nothing to do
|
||||
if (null === $date || !Date::isValidDateFormat($format)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $date->format($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start date of period
|
||||
*
|
||||
* @return DateTime
|
||||
* @return null|DateTime
|
||||
*/
|
||||
public function getStartDate()
|
||||
public function getStartDate(): ?DateTime
|
||||
{
|
||||
return $this->startDate;
|
||||
}
|
||||
@@ -183,10 +172,10 @@ class DatePeriod
|
||||
/**
|
||||
* Sets the start date of period
|
||||
*
|
||||
* @param DateTime $startDate (optional) The start date of period
|
||||
* @param null|DateTime $startDate (optional) The start date of period. Default: null.
|
||||
* @return $this
|
||||
*/
|
||||
public function setStartDate(DateTime $startDate = null)
|
||||
public function setStartDate(?DateTime $startDate = null): self
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
77
src/Utilities/Bundle.php
Normal file
77
src/Utilities/Bundle.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Utilities;
|
||||
|
||||
use Meritoo\Common\Exception\Bundle\IncorrectBundleNameException;
|
||||
|
||||
/**
|
||||
* Useful methods for bundle
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class Bundle
|
||||
{
|
||||
/**
|
||||
* Returns path of given bundle to view / template with given extension
|
||||
*
|
||||
* @param string $viewPath Path of the view / template, e.g. "MyDirectory/my-template". Extension is not required.
|
||||
* @param string $bundleName Full name of the bundle, e.g. "MyExtraBundle"
|
||||
* @param string $extension (optional) Extension of the view / template (default: "html.twig")
|
||||
* @return null|string
|
||||
* @throws IncorrectBundleNameException
|
||||
*/
|
||||
public static function getBundleViewPath(
|
||||
string $viewPath,
|
||||
string $bundleName,
|
||||
string $extension = 'html.twig'
|
||||
): ?string {
|
||||
// Nothing to do, because at least one unknown argument provided
|
||||
if (empty($viewPath) || empty($bundleName) || empty($extension)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Oops, given name of bundle is invalid
|
||||
if (!Regex::isValidBundleName($bundleName)) {
|
||||
throw IncorrectBundleNameException::create($bundleName);
|
||||
}
|
||||
|
||||
// Make sure that path of the view / template ends with given extension
|
||||
if (!Regex::endsWith($viewPath, $extension)) {
|
||||
$viewPath = sprintf('%s.%s', $viewPath, $extension);
|
||||
}
|
||||
|
||||
// Prepare short name of bundle and path of view / template with "/" (instead of ":")
|
||||
$shortName = static::getShortBundleName($bundleName);
|
||||
$path = str_replace(':', '/', $viewPath);
|
||||
|
||||
return sprintf('@%s/%s', $shortName, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns short name of bundle (without "Bundle")
|
||||
*
|
||||
* @param string $fullBundleName Full name of the bundle, e.g. "MyExtraBundle"
|
||||
* @return null|string
|
||||
* @throws IncorrectBundleNameException
|
||||
*/
|
||||
public static function getShortBundleName(string $fullBundleName): ?string
|
||||
{
|
||||
// Oops, given name of bundle is invalid
|
||||
if (!Regex::isValidBundleName($fullBundleName)) {
|
||||
throw new IncorrectBundleNameException($fullBundleName);
|
||||
}
|
||||
|
||||
$matches = [];
|
||||
$pattern = Regex::getBundleNamePattern();
|
||||
preg_match($pattern, $fullBundleName, $matches);
|
||||
|
||||
return $matches[1];
|
||||
}
|
||||
}
|
||||
@@ -8,13 +8,11 @@
|
||||
|
||||
namespace Meritoo\Common\Utilities;
|
||||
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Useful Composer-related methods (only static functions)
|
||||
*
|
||||
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
|
||||
* @copyright Meritoo.pl
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class Composer
|
||||
{
|
||||
@@ -23,23 +21,18 @@ class Composer
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FILE_NAME_MAIN = 'composer.json';
|
||||
public const FILE_NAME_MAIN = 'composer.json';
|
||||
|
||||
/**
|
||||
* Returns value from composer.json file
|
||||
*
|
||||
* @param string $composerJsonPath Path of composer.json file
|
||||
* @param string $nodeName Name of node who value should be returned
|
||||
* @return string|null
|
||||
* @return null|string
|
||||
*/
|
||||
public static function getValue($composerJsonPath, $nodeName)
|
||||
public static function getValue(string $composerJsonPath, string $nodeName): ?string
|
||||
{
|
||||
$composerJsonString = is_string($composerJsonPath);
|
||||
$composerJsonReadable = false;
|
||||
|
||||
if ($composerJsonString) {
|
||||
$composerJsonReadable = is_readable($composerJsonPath);
|
||||
}
|
||||
$composerJsonReadable = is_readable($composerJsonPath);
|
||||
|
||||
/*
|
||||
* Provided path or name of node are invalid?
|
||||
@@ -48,22 +41,21 @@ class Composer
|
||||
*
|
||||
* Nothing to do
|
||||
*/
|
||||
if (!$composerJsonString || !is_string($nodeName) || !$composerJsonReadable || empty($nodeName)) {
|
||||
if (!$composerJsonReadable || empty($nodeName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$content = file_get_contents($composerJsonPath);
|
||||
$data = json_decode($content);
|
||||
$data = json_decode($content, false);
|
||||
|
||||
/*
|
||||
* Unknown data from the composer.json file or there is no node with given name?
|
||||
* Nothing to do
|
||||
*/
|
||||
if ($data === null || !isset($data->{$nodeName})) {
|
||||
if (null === $data || !isset($data->{$nodeName})) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* @var stdClass $data */
|
||||
return $data->{$nodeName};
|
||||
}
|
||||
}
|
||||
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 ($period == DatePeriod::LAST_YEAR || $period == DatePeriod::NEXT_YEAR) {
|
||||
$yearDifference = 1;
|
||||
|
||||
if ($period == DatePeriod::LAST_YEAR) {
|
||||
$yearDifference *= -1;
|
||||
}
|
||||
|
||||
$modifyString = sprintf('%s year', $yearDifference);
|
||||
$dateStart->modify($modifyString);
|
||||
$dateEnd->modify($modifyString);
|
||||
}
|
||||
|
||||
$year = $dateStart->format('Y');
|
||||
$dateStart->setDate($year, 1, 1);
|
||||
$dateEnd->setDate($year, 12, 31);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($dateStart !== null && $dateEnd !== null) {
|
||||
$dateStart->setTime(0, 0, 0);
|
||||
$dateEnd->setTime(23, 59, 59);
|
||||
|
||||
$datePeriod = new DatePeriod($dateStart, $dateEnd);
|
||||
}
|
||||
}
|
||||
|
||||
return $datePeriod;
|
||||
}
|
||||
public const DATE_DIFFERENCE_UNIT_YEARS = 'years';
|
||||
|
||||
/**
|
||||
* Generates and returns random time (the hour, minute and second values)
|
||||
*
|
||||
* @param string $format (optional) Format of returned value. A string acceptable by the DateTime::format()
|
||||
* method.
|
||||
* @return string|null
|
||||
* @return null|string
|
||||
*/
|
||||
public static function generateRandomTime($format = 'H:i:s')
|
||||
public static function generateRandomTime($format = 'H:i:s'): ?string
|
||||
{
|
||||
$dateTime = new DateTime();
|
||||
|
||||
@@ -194,16 +98,15 @@ class Date
|
||||
$seconds[] = $i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare random time (hour, minute and second)
|
||||
*/
|
||||
// Prepare random time (hour, minute and second)
|
||||
$hour = $hours[array_rand($hours)];
|
||||
$minute = $minutes[array_rand($minutes)];
|
||||
$second = $seconds[array_rand($seconds)];
|
||||
|
||||
return $dateTime
|
||||
->setTime($hour, $minute, $second)
|
||||
->format($format);
|
||||
->format($format)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,113 +114,33 @@ class Date
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getCurrentDayOfWeek()
|
||||
public static function getCurrentDayOfWeek(): int
|
||||
{
|
||||
$now = new DateTime();
|
||||
|
||||
$year = $now->format('Y');
|
||||
$month = $now->format('m');
|
||||
$day = $now->format('d');
|
||||
$year = (int) $now->format('Y');
|
||||
$month = (int) $now->format('m');
|
||||
$day = (int) $now->format('d');
|
||||
|
||||
return self::getDayOfWeek($year, $month, $day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns day of week (number 0 to 6, 0 - sunday, 6 - saturday).
|
||||
* Based on the Zeller's algorithm (http://pl.wikipedia.org/wiki/Kalendarz_wieczny).
|
||||
*
|
||||
* @param int $year The year value
|
||||
* @param int $month The month value
|
||||
* @param int $day The day value
|
||||
*
|
||||
* @return int
|
||||
* @throws 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 ($encoding === false) {
|
||||
$name = mb_convert_encoding($name, 'UTF-8', 'ISO-8859-2');
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns difference between given dates.
|
||||
*
|
||||
@@ -333,9 +156,9 @@ class Date
|
||||
* If the unit of date difference is null, all units are returned in array (units are keys of the array).
|
||||
* Otherwise - one, integer value is returned.
|
||||
*
|
||||
* @param string|DateTime $dateStart The start date
|
||||
* @param string|DateTime $dateEnd The end date
|
||||
* @param int $differenceUnit (optional) Unit of date difference. One of this class
|
||||
* @param DateTime|string $dateStart The start date
|
||||
* @param DateTime|string $dateEnd The end date
|
||||
* @param string $differenceUnit (optional) Unit of date difference. One of this class
|
||||
* DATE_DIFFERENCE_UNIT_* constants. If is set to null all units are
|
||||
* returned in the array.
|
||||
* @return array|int
|
||||
@@ -356,11 +179,11 @@ class Date
|
||||
return null;
|
||||
}
|
||||
|
||||
$dateStart = self::getDateTime($dateStart, true);
|
||||
$dateEnd = self::getDateTime($dateEnd, true);
|
||||
$start = self::getDateTime($dateStart, true);
|
||||
$end = self::getDateTime($dateEnd, true);
|
||||
|
||||
$difference = [];
|
||||
$dateDiff = $dateEnd->getTimestamp() - $dateStart->getTimestamp();
|
||||
$dateDiff = $end->getTimestamp() - $start->getTimestamp();
|
||||
|
||||
$daysInSeconds = 0;
|
||||
$hoursInSeconds = 0;
|
||||
@@ -378,85 +201,71 @@ class Date
|
||||
self::DATE_DIFFERENCE_UNIT_MINUTES,
|
||||
];
|
||||
|
||||
if ($differenceUnit === null || $differenceUnit == self::DATE_DIFFERENCE_UNIT_YEARS) {
|
||||
$diff = $dateEnd->diff($dateStart);
|
||||
$differenceYear = self::DATE_DIFFERENCE_UNIT_YEARS === $differenceUnit;
|
||||
$differenceMonth = self::DATE_DIFFERENCE_UNIT_MONTHS === $differenceUnit;
|
||||
$differenceMinutes = self::DATE_DIFFERENCE_UNIT_MINUTES === $differenceUnit;
|
||||
|
||||
/*
|
||||
* Difference between dates in years should be returned only?
|
||||
*/
|
||||
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_YEARS) {
|
||||
if (null === $differenceUnit || $differenceYear) {
|
||||
$diff = $end->diff($start);
|
||||
|
||||
// Difference between dates in years should be returned only?
|
||||
if ($differenceYear) {
|
||||
return $diff->y;
|
||||
}
|
||||
|
||||
$difference[self::DATE_DIFFERENCE_UNIT_YEARS] = $diff->y;
|
||||
}
|
||||
|
||||
if ($differenceUnit === null || $differenceUnit == self::DATE_DIFFERENCE_UNIT_MONTHS) {
|
||||
$diff = $dateEnd->diff($dateStart);
|
||||
if (null === $differenceUnit || $differenceMonth) {
|
||||
$diff = $end->diff($start);
|
||||
|
||||
/*
|
||||
* Difference between dates in months should be returned only?
|
||||
*/
|
||||
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_MONTHS) {
|
||||
// Difference between dates in months should be returned only?
|
||||
if ($differenceMonth) {
|
||||
return $diff->m;
|
||||
}
|
||||
|
||||
$difference[self::DATE_DIFFERENCE_UNIT_MONTHS] = $diff->m;
|
||||
}
|
||||
|
||||
if ($differenceUnit === null || in_array($differenceUnit, $relatedUnits)) {
|
||||
$days = (int)floor($dateDiff / $daySeconds);
|
||||
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
|
||||
$days = (int) floor($dateDiff / $daySeconds);
|
||||
|
||||
/*
|
||||
* Difference between dates in days should be returned only?
|
||||
*/
|
||||
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_DAYS) {
|
||||
// Difference between dates in days should be returned only?
|
||||
if (self::DATE_DIFFERENCE_UNIT_DAYS === $differenceUnit) {
|
||||
return $days;
|
||||
}
|
||||
|
||||
/*
|
||||
* All units should be returned?
|
||||
*/
|
||||
if ($differenceUnit === null) {
|
||||
// All units should be returned?
|
||||
if (null === $differenceUnit) {
|
||||
$difference[self::DATE_DIFFERENCE_UNIT_DAYS] = $days;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculation for later usage
|
||||
*/
|
||||
// Calculation for later usage
|
||||
$daysInSeconds = $days * $daySeconds;
|
||||
}
|
||||
|
||||
if ($differenceUnit === null || in_array($differenceUnit, $relatedUnits)) {
|
||||
$hours = (int)floor(($dateDiff - $daysInSeconds) / $hourSeconds);
|
||||
if (null === $differenceUnit || in_array($differenceUnit, $relatedUnits, true)) {
|
||||
$hours = (int) floor(($dateDiff - $daysInSeconds) / $hourSeconds);
|
||||
|
||||
/*
|
||||
* Difference between dates in hours should be returned only?
|
||||
*/
|
||||
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_HOURS) {
|
||||
// Difference between dates in hours should be returned only?
|
||||
if (self::DATE_DIFFERENCE_UNIT_HOURS === $differenceUnit) {
|
||||
return $hours;
|
||||
}
|
||||
|
||||
/*
|
||||
* All units should be returned?
|
||||
*/
|
||||
if ($differenceUnit === null) {
|
||||
// All units should be returned?
|
||||
if (null === $differenceUnit) {
|
||||
$difference[self::DATE_DIFFERENCE_UNIT_HOURS] = $hours;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculation for later usage
|
||||
*/
|
||||
// Calculation for later usage
|
||||
$hoursInSeconds = $hours * $hourSeconds;
|
||||
}
|
||||
|
||||
if ($differenceUnit === null || $differenceUnit == self::DATE_DIFFERENCE_UNIT_MINUTES) {
|
||||
$minutes = (int)floor(($dateDiff - $daysInSeconds - $hoursInSeconds) / 60);
|
||||
if (null === $differenceUnit || $differenceMinutes) {
|
||||
$minutes = (int) floor(($dateDiff - $daysInSeconds - $hoursInSeconds) / 60);
|
||||
|
||||
/*
|
||||
* Difference between dates in minutes should be returned only?
|
||||
*/
|
||||
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_MINUTES) {
|
||||
// Difference between dates in minutes should be returned only?
|
||||
if ($differenceMinutes) {
|
||||
return $minutes;
|
||||
}
|
||||
|
||||
@@ -466,85 +275,6 @@ class Date
|
||||
return $difference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns collection / set of dates for given start date and count of dates.
|
||||
* Start from given date, add next, iterated value to given date interval and returns requested count of dates.
|
||||
*
|
||||
* @param DateTime $startDate The start date. Start of the collection / set.
|
||||
* @param int $datesCount Count of dates in resulting collection / set
|
||||
* @param string $intervalTemplate (optional) Template used to build date interval. It should contain "%d" as the
|
||||
* placeholder which is replaced with a number that represents each iteration.
|
||||
* Default: interval for days.
|
||||
* @return array
|
||||
*/
|
||||
public static function getDatesCollection(DateTime $startDate, $datesCount, $intervalTemplate = 'P%dD')
|
||||
{
|
||||
$dates = [];
|
||||
|
||||
/*
|
||||
* The template used to build date interval have to be string.
|
||||
* Otherwise cannot run preg_match() function and an error occurs.
|
||||
*/
|
||||
if (is_string($intervalTemplate)) {
|
||||
/*
|
||||
* Let's verify the interval template. It should contains the "%d" placeholder and something before and
|
||||
* after it.
|
||||
*
|
||||
* Examples:
|
||||
* - P%dD
|
||||
* - P%dM
|
||||
* - P1Y%dMT1H
|
||||
*/
|
||||
$intervalPattern = '/^(\w*)\%d(\w*)$/';
|
||||
$matches = [];
|
||||
$matchCount = preg_match($intervalPattern, $intervalTemplate, $matches);
|
||||
|
||||
if ($matchCount > 0 && (!empty($matches[1]) || !empty($matches[2]))) {
|
||||
$datesCount = (int)$datesCount;
|
||||
|
||||
for ($index = 1; $index <= $datesCount; ++$index) {
|
||||
$date = clone $startDate;
|
||||
$dates[$index] = $date->add(new DateInterval(sprintf($intervalTemplate, $index)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns random date based on given start date
|
||||
*
|
||||
* @param DateTime $startDate The start date. Start of the random date.
|
||||
* @param int $start (optional) Start of random partition
|
||||
* @param int $end (optional) End of random partition
|
||||
* @param string $intervalTemplate (optional) Template used to build date interval. The placeholder is replaced
|
||||
* with next, iterated value.
|
||||
* @return DateTime
|
||||
*/
|
||||
public static function getRandomDate(DateTime $startDate = null, $start = 1, $end = 100, $intervalTemplate = 'P%sD')
|
||||
{
|
||||
if ($startDate === null) {
|
||||
$startDate = new DateTime();
|
||||
}
|
||||
|
||||
$start = (int)$start;
|
||||
$end = (int)$end;
|
||||
|
||||
/*
|
||||
* Incorrect end of random partition?
|
||||
* Use start as the end of random partition
|
||||
*/
|
||||
if ($end < $start) {
|
||||
$end = $start;
|
||||
}
|
||||
|
||||
$randomDate = clone $startDate;
|
||||
$randomInterval = new DateInterval(sprintf($intervalTemplate, rand($start, $end)));
|
||||
|
||||
return $randomDate->add($randomInterval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DateTime object for given value.
|
||||
* If the DateTime object cannot be created, false is returned.
|
||||
@@ -552,11 +282,12 @@ class Date
|
||||
* @param mixed $value The value which maybe is a date
|
||||
* @param bool $allowCompoundFormats (optional) If is set to true, the compound formats used to create an
|
||||
* instance of DateTime class are allowed (e.g. "now", "last day of next
|
||||
* month", "yyyy"). Otherwise - not and every incorrect value is refused.
|
||||
* month", "yyyy"). Otherwise - not and every incorrect value is refused
|
||||
* (default behaviour).
|
||||
* @param string $dateFormat (optional) Format of date used to verify if given value is actually a date.
|
||||
* It should be format matched to the given value, e.g. "Y-m-d H:i" for
|
||||
* "2015-01-01 10:00" value.
|
||||
* @return DateTime|bool
|
||||
* "2015-01-01 10:00" value. Default: "Y-m-d".
|
||||
* @return bool|DateTime
|
||||
*/
|
||||
public static function getDateTime($value, $allowCompoundFormats = false, $dateFormat = 'Y-m-d')
|
||||
{
|
||||
@@ -590,7 +321,7 @@ class Date
|
||||
*/
|
||||
$dateFromFormat = DateTime::createFromFormat($dateFormat, $value);
|
||||
|
||||
if ($dateFromFormat === false) {
|
||||
if (false === $dateFromFormat) {
|
||||
/*
|
||||
* Nothing to do more, because:
|
||||
* a) instance of the DateTime was created
|
||||
@@ -623,7 +354,7 @@ class Date
|
||||
* So, I have to refuse those special compound formats if they are not explicitly declared as
|
||||
* compound (2nd argument of this method, set to false by default)
|
||||
*/
|
||||
if (in_array($value, $specialFormats)) {
|
||||
if (in_array($value, $specialFormats, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -631,12 +362,10 @@ class Date
|
||||
* Verify instance of the DateTime created by constructor and by createFromFormat() method.
|
||||
* After formatting, these dates should be the same.
|
||||
*/
|
||||
else {
|
||||
if ($dateFromFormat->format($dateFormat) === $value) {
|
||||
return $date;
|
||||
}
|
||||
elseif ($dateFromFormat->format($dateFormat) === $value) {
|
||||
return $date;
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
} catch (Exception $exception) {
|
||||
if (!$allowCompoundFormats) {
|
||||
return false;
|
||||
}
|
||||
@@ -648,15 +377,284 @@ class Date
|
||||
*/
|
||||
$dateString = (new DateTime())->format($value);
|
||||
|
||||
if ($dateString != $value) {
|
||||
if ($dateString !== (string) $value) {
|
||||
return new DateTime($dateString);
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
} catch (Exception $exception) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns collection / set of dates for given start date and count of dates.
|
||||
* Start from given date, add next, iterated value to given date interval and returns requested count of dates.
|
||||
*
|
||||
* @param DateTime $startDate The start date. Start of the collection / set.
|
||||
* @param int $datesCount Count of dates in resulting collection / set
|
||||
* @param string $intervalTemplate (optional) Template used to build date interval. It should contain "%d" as the
|
||||
* placeholder which is replaced with a number that represents each iteration.
|
||||
* Default: interval for days.
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getDatesCollection(DateTime $startDate, $datesCount, $intervalTemplate = 'P%dD'): array
|
||||
{
|
||||
$dates = [];
|
||||
|
||||
/*
|
||||
* The template used to build date interval have to be string.
|
||||
* Otherwise cannot run preg_match() function and an error occurs.
|
||||
*/
|
||||
if (is_string($intervalTemplate)) {
|
||||
/*
|
||||
* Let's verify the interval template. It should contains the "%d" placeholder and something before and
|
||||
* after it.
|
||||
*
|
||||
* Examples:
|
||||
* - P%dD
|
||||
* - P%dM
|
||||
* - P1Y%dMT1H
|
||||
*/
|
||||
$intervalPattern = '/^(\w*)\%d(\w*)$/';
|
||||
$matches = [];
|
||||
$matchCount = preg_match($intervalPattern, $intervalTemplate, $matches);
|
||||
|
||||
if ($matchCount > 0 && (!empty($matches[1]) || !empty($matches[2]))) {
|
||||
$datesCount = (int) $datesCount;
|
||||
|
||||
for ($index = 1; $index <= $datesCount; ++$index) {
|
||||
$date = clone $startDate;
|
||||
$dates[$index] = $date->add(new DateInterval(sprintf($intervalTemplate, $index)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns date's period (that contains start and end date) for given period
|
||||
*
|
||||
* @param string $period The period, type of period. One of DatePeriod class constants, e.g. DatePeriod::LAST_WEEK.
|
||||
* @return null|DatePeriod
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getDatesForPeriod(string $period): ?DatePeriod
|
||||
{
|
||||
/*
|
||||
* Type of period is incorrect?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (!DatePeriod::isCorrectType($period)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dateStart = null;
|
||||
$dateEnd = null;
|
||||
|
||||
switch ($period) {
|
||||
case DatePeriod::LAST_WEEK:
|
||||
$thisWeekStart = new DateTime('this week');
|
||||
|
||||
$dateStart = clone $thisWeekStart;
|
||||
$dateEnd = clone $thisWeekStart;
|
||||
|
||||
$dateStart->sub(new DateInterval('P7D'));
|
||||
$dateEnd->sub(new DateInterval('P1D'));
|
||||
|
||||
break;
|
||||
case DatePeriod::THIS_WEEK:
|
||||
$dateStart = new DateTime('this week');
|
||||
|
||||
$dateEnd = clone $dateStart;
|
||||
$dateEnd->add(new DateInterval('P6D'));
|
||||
|
||||
break;
|
||||
case DatePeriod::NEXT_WEEK:
|
||||
$dateStart = new DateTime('this week');
|
||||
$dateStart->add(new DateInterval('P7D'));
|
||||
|
||||
$dateEnd = clone $dateStart;
|
||||
$dateEnd->add(new DateInterval('P6D'));
|
||||
|
||||
break;
|
||||
case DatePeriod::LAST_MONTH:
|
||||
$dateStart = new DateTime('first day of last month');
|
||||
$dateEnd = new DateTime('last day of last month');
|
||||
|
||||
break;
|
||||
case DatePeriod::THIS_MONTH:
|
||||
$lastMonth = self::getDatesForPeriod(DatePeriod::LAST_MONTH);
|
||||
$nextMonth = self::getDatesForPeriod(DatePeriod::NEXT_MONTH);
|
||||
|
||||
if (null !== $lastMonth) {
|
||||
$dateStart = $lastMonth->getEndDate();
|
||||
|
||||
if (null !== $dateStart) {
|
||||
$dateStart->add(new DateInterval('P1D'));
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $nextMonth) {
|
||||
$dateEnd = $nextMonth->getStartDate();
|
||||
|
||||
if (null !== $dateEnd) {
|
||||
$dateEnd->sub(new DateInterval('P1D'));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case DatePeriod::NEXT_MONTH:
|
||||
$dateStart = new DateTime('first day of next month');
|
||||
$dateEnd = new DateTime('last day of next month');
|
||||
|
||||
break;
|
||||
case DatePeriod::LAST_YEAR:
|
||||
case DatePeriod::THIS_YEAR:
|
||||
case DatePeriod::NEXT_YEAR:
|
||||
$dateStart = new DateTime();
|
||||
$dateEnd = new DateTime();
|
||||
|
||||
$yearPeriod = [
|
||||
DatePeriod::LAST_YEAR,
|
||||
DatePeriod::NEXT_YEAR,
|
||||
];
|
||||
|
||||
if (in_array($period, $yearPeriod, true)) {
|
||||
$yearDifference = 1;
|
||||
|
||||
if (DatePeriod::LAST_YEAR === $period) {
|
||||
$yearDifference *= -1;
|
||||
}
|
||||
|
||||
$modifyString = sprintf('%s year', $yearDifference);
|
||||
$dateStart->modify($modifyString);
|
||||
$dateEnd->modify($modifyString);
|
||||
}
|
||||
|
||||
$year = (int) $dateStart->format('Y');
|
||||
$dateStart->setDate($year, 1, 1);
|
||||
$dateEnd->setDate($year, 12, 31);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start or end date is unknown?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (null === $dateStart || null === $dateEnd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dateStart->setTime(0, 0);
|
||||
$dateEnd->setTime(23, 59, 59);
|
||||
|
||||
return new DatePeriod($dateStart, $dateEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns day of week (number 0 to 6, 0 - sunday, 6 - saturday).
|
||||
* Based on the Zeller's algorithm (https://en.wikipedia.org/wiki/Perpetual_calendar).
|
||||
*
|
||||
* @param int $year The year value
|
||||
* @param int $month The month value
|
||||
* @param int $day The day value
|
||||
*
|
||||
* @return int
|
||||
* @throws UnknownDatePartTypeException
|
||||
*/
|
||||
public static function getDayOfWeek(int $year, int $month, int $day): int
|
||||
{
|
||||
static::validateYear($year);
|
||||
static::validateMonth($month);
|
||||
static::validateDay($day);
|
||||
|
||||
if ($month < 3) {
|
||||
$count = 0;
|
||||
$yearValue = $year - 1;
|
||||
} else {
|
||||
$count = 2;
|
||||
$yearValue = $year;
|
||||
}
|
||||
|
||||
$firstPart = floor(23 * $month / 9);
|
||||
$secondPart = floor($yearValue / 4);
|
||||
$thirdPart = floor($yearValue / 100);
|
||||
$fourthPart = floor($yearValue / 400);
|
||||
|
||||
return ($firstPart + $day + 4 + $year + $secondPart - $thirdPart + $fourthPart - $count) % 7;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns name of weekday based on locale
|
||||
*
|
||||
* @param int $year The year value
|
||||
* @param int $month The month value
|
||||
* @param int $day The day value
|
||||
* @return string
|
||||
*/
|
||||
public static function getDayOfWeekName($year, $month, $day): string
|
||||
{
|
||||
$hour = 0;
|
||||
$minute = 0;
|
||||
$second = 0;
|
||||
|
||||
$time = mktime($hour, $minute, $second, $month, $day, $year);
|
||||
$name = strftime('%A', $time);
|
||||
|
||||
$encoding = mb_detect_encoding($name);
|
||||
|
||||
if (false === $encoding) {
|
||||
$name = mb_convert_encoding($name, 'UTF-8', 'ISO-8859-2');
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns random date based on given start date
|
||||
*
|
||||
* @param DateTime $startDate (optional) Beginning of the random date. If not provided, current date will
|
||||
* be used (default behaviour).
|
||||
* @param int $start (optional) Start of random partition. If not provided, 1 will be used
|
||||
* (default behaviour).
|
||||
* @param int $end (optional) End of random partition. If not provided, 100 will be used
|
||||
* (default behaviour).
|
||||
* @param string $intervalTemplate (optional) Template used to build date interval. The placeholder is replaced
|
||||
* with next, iterated value. If not provided, "P%sD" will be used (default
|
||||
* behaviour).
|
||||
* @return DateTime
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getRandomDate(
|
||||
DateTime $startDate = null,
|
||||
$start = 1,
|
||||
$end = 100,
|
||||
$intervalTemplate = 'P%sD'
|
||||
): DateTime {
|
||||
if (null === $startDate) {
|
||||
$startDate = new DateTime();
|
||||
}
|
||||
|
||||
$start = (int) $start;
|
||||
$end = (int) $end;
|
||||
|
||||
/*
|
||||
* Incorrect end of random partition?
|
||||
* Use start as the end of random partition
|
||||
*/
|
||||
if ($end < $start) {
|
||||
$end = $start;
|
||||
}
|
||||
|
||||
$randomDate = clone $startDate;
|
||||
$randomInterval = new DateInterval(sprintf($intervalTemplate, random_int($start, $end)));
|
||||
|
||||
return $randomDate->add($randomInterval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given value is valid date
|
||||
*
|
||||
@@ -666,7 +664,7 @@ class Date
|
||||
* month", "yyyy"). Otherwise - not and every incorrect value is refused.
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidDate($value, $allowCompoundFormats = false)
|
||||
public static function isValidDate($value, $allowCompoundFormats = false): bool
|
||||
{
|
||||
return self::getDateTime($value, $allowCompoundFormats) instanceof DateTime;
|
||||
}
|
||||
@@ -677,38 +675,77 @@ class Date
|
||||
* @param string $format The validated format of date
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidDateFormat($format)
|
||||
public static function isValidDateFormat($format): bool
|
||||
{
|
||||
if (empty($format) || !is_string($format)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Datetime to string
|
||||
*/
|
||||
$formatted = (new DateTime())->format($format);
|
||||
|
||||
/*
|
||||
* Formatted date it's the format who is validated?
|
||||
* The format is invalid
|
||||
*/
|
||||
if ($formatted == $format) {
|
||||
// Formatted date it's the format who is validated?
|
||||
// The format is invalid
|
||||
if ($formatted === $format) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate the format used to create the datetime
|
||||
*/
|
||||
// Validate the format used to create the datetime
|
||||
$fromFormat = DateTime::createFromFormat($format, $formatted);
|
||||
|
||||
/*
|
||||
* It's instance of DateTime?
|
||||
* The format is valid
|
||||
*/
|
||||
// It's instance of DateTime?
|
||||
// The format is valid
|
||||
if ($fromFormat instanceof DateTime) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $fromFormat instanceof DateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies/validates given day
|
||||
*
|
||||
* @param int $day Day to verify/validate
|
||||
* @throws UnknownDatePartTypeException
|
||||
*/
|
||||
private static function validateDay(int $day): void
|
||||
{
|
||||
// Oops, given day is incorrect
|
||||
if ($day >= 1 && $day <= 31) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw UnknownDatePartTypeException::createException(DatePartType::DAY, $day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies/validates given month
|
||||
*
|
||||
* @param int $month Month to verify/validate
|
||||
* @throws UnknownDatePartTypeException
|
||||
*/
|
||||
private static function validateMonth(int $month): void
|
||||
{
|
||||
// Oops, given month is incorrect
|
||||
if ($month >= 1 && $month <= 12) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw UnknownDatePartTypeException::createException(DatePartType::MONTH, $month);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies/validates given year
|
||||
*
|
||||
* @param int $year Year to verify/validate
|
||||
* @throws UnknownDatePartTypeException
|
||||
*/
|
||||
private static function validateYear(int $year): void
|
||||
{
|
||||
// Oops, given year is incorrect
|
||||
if ($year >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw UnknownDatePartTypeException::createException(DatePartType::YEAR, $year);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
810
src/Utilities/MimeTypes.php
Normal file
810
src/Utilities/MimeTypes.php
Normal file
@@ -0,0 +1,810 @@
|
||||
<?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 finfo;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Useful methods for mime types of files
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class MimeTypes
|
||||
{
|
||||
/**
|
||||
* Mime types data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $mimeTypes = [
|
||||
'7z' => 'application/x-7z-compressed',
|
||||
'ez' => 'application/andrew-inset',
|
||||
'atom' => 'application/atom+xml',
|
||||
'atomcat' => 'application/atomcat+xml',
|
||||
'atomsvc' => 'application/atomsvc+xml',
|
||||
'ccxml' => 'application/ccxml+xml',
|
||||
'davmount' => 'application/davmount+xml',
|
||||
'ecma' => 'application/ecmascript',
|
||||
'pfr' => 'application/font-tdpfr',
|
||||
'stk' => 'application/hyperstudio',
|
||||
'js' => 'application/javascript',
|
||||
'json' => 'application/json',
|
||||
'hqx' => 'application/mac-binhex40',
|
||||
'cpt' => 'application/mac-compactpro',
|
||||
'mrc' => 'application/marc',
|
||||
'ma' => 'application/mathematica',
|
||||
'nb' => 'application/mathematica',
|
||||
'mb' => 'application/mathematica',
|
||||
'mathml' => 'application/mathml+xml',
|
||||
'mbox' => 'application/mbox',
|
||||
'mscml' => 'application/mediaservercontrol+xml',
|
||||
'mp4s' => 'application/mp4',
|
||||
'dot' => 'application/msword',
|
||||
'doc' => 'application/msword',
|
||||
/*
|
||||
* MS Office system file format MIME types
|
||||
* http://technet.microsoft.com/en-us/library/ee309278%28office.12%29.aspx
|
||||
*/
|
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'mxf' => 'application/mxf',
|
||||
'bin' => 'application/octet-stream',
|
||||
'dms' => 'application/octet-stream',
|
||||
'lha' => 'application/octet-stream',
|
||||
'lzh' => 'application/octet-stream',
|
||||
'class' => 'application/octet-stream',
|
||||
'so' => 'application/octet-stream',
|
||||
'iso' => 'application/octet-stream',
|
||||
'dmg' => 'application/octet-stream',
|
||||
'dist' => 'application/octet-stream',
|
||||
'distz' => 'application/octet-stream',
|
||||
'pkg' => 'application/octet-stream',
|
||||
'bpk' => 'application/octet-stream',
|
||||
'dump' => 'application/octet-stream',
|
||||
'elc' => 'application/octet-stream',
|
||||
'scpt' => 'application/octet-stream',
|
||||
'oda' => 'application/oda',
|
||||
'ogg' => 'application/ogg',
|
||||
'pdf' => 'application/pdf',
|
||||
'pgp' => 'application/pgp-encrypted',
|
||||
'asc' => 'application/pgp-signature',
|
||||
'sig' => 'application/pgp-signature',
|
||||
'prf' => 'application/pics-rules',
|
||||
'p10' => 'application/pkcs10',
|
||||
'p7m' => 'application/pkcs7-mime',
|
||||
'p7c' => 'application/pkcs7-mime',
|
||||
'p7s' => 'application/pkcs7-signature',
|
||||
'cer' => 'application/pkix-cert',
|
||||
'crl' => 'application/pkix-crl',
|
||||
'pkipath' => 'application/pkix-pkipath',
|
||||
'pki' => 'application/pkixcmp',
|
||||
'pls' => 'application/pls+xml',
|
||||
'ai' => 'application/postscript',
|
||||
'eps' => 'application/postscript',
|
||||
'ps' => 'application/postscript',
|
||||
'cww' => 'application/prs.cww',
|
||||
'rdf' => 'application/rdf+xml',
|
||||
'rif' => 'application/reginfo+xml',
|
||||
'rnc' => 'application/relax-ng-compact-syntax',
|
||||
'rl' => 'application/resource-lists+xml',
|
||||
'rs' => 'application/rls-services+xml',
|
||||
'rsd' => 'application/rsd+xml',
|
||||
'rss' => 'application/rss+xml',
|
||||
'rtf' => 'application/rtf',
|
||||
'sbml' => 'application/sbml+xml',
|
||||
'sdp' => 'application/sdp',
|
||||
'setpay' => 'application/set-payment-initiation',
|
||||
'setreg' => 'application/set-registration-initiation',
|
||||
'shf' => 'application/shf+xml',
|
||||
'smi' => 'application/smil+xml',
|
||||
'smil' => 'application/smil+xml',
|
||||
'gram' => 'application/srgs',
|
||||
'grxml' => 'application/srgs+xml',
|
||||
'ssml' => 'application/ssml+xml',
|
||||
'plb' => 'application/vnd.3gpp.pic-bw-large',
|
||||
'psb' => 'application/vnd.3gpp.pic-bw-small',
|
||||
'pvb' => 'application/vnd.3gpp.pic-bw-var',
|
||||
'pwn' => 'application/vnd.3m.post-it-notes',
|
||||
'aso' => 'application/vnd.accpac.simply.aso',
|
||||
'imp' => 'application/vnd.accpac.simply.imp',
|
||||
'acu' => 'application/vnd.acucobol',
|
||||
'atc' => 'application/vnd.acucorp',
|
||||
'acutc' => 'application/vnd.acucorp',
|
||||
'xdp' => 'application/vnd.adobe.xdp+xml',
|
||||
'xfdf' => 'application/vnd.adobe.xfdf',
|
||||
'ami' => 'application/vnd.amiga.ami',
|
||||
'cii' => 'application/vnd.anser-web-certificate-issue-initiation',
|
||||
'fti' => 'application/vnd.anser-web-funds-transfer-initiation',
|
||||
'atx' => 'application/vnd.antix.game-component',
|
||||
'mpkg' => 'application/vnd.apple.installer+xml',
|
||||
'aep' => 'application/vnd.audiograph',
|
||||
'mpm' => 'application/vnd.blueice.multipass',
|
||||
'bmi' => 'application/vnd.bmi',
|
||||
'rep' => 'application/vnd.businessobjects',
|
||||
'cdxml' => 'application/vnd.chemdraw+xml',
|
||||
'mmd' => 'application/vnd.chipnuts.karaoke-mmd',
|
||||
'cdy' => 'application/vnd.cinderella',
|
||||
'cla' => 'application/vnd.claymore',
|
||||
'c4g' => 'application/vnd.clonk.c4group',
|
||||
'c4d' => 'application/vnd.clonk.c4group',
|
||||
'c4f' => 'application/vnd.clonk.c4group',
|
||||
'c4p' => 'application/vnd.clonk.c4group',
|
||||
'c4u' => 'application/vnd.clonk.c4group',
|
||||
'csp' => 'application/vnd.commonspace',
|
||||
'cst' => 'application/vnd.commonspace',
|
||||
'cdbcmsg' => 'application/vnd.contact.cmsg',
|
||||
'cmc' => 'application/vnd.cosmocaller',
|
||||
'clkx' => 'application/vnd.crick.clicker',
|
||||
'clkk' => 'application/vnd.crick.clicker.keyboard',
|
||||
'clkp' => 'application/vnd.crick.clicker.palette',
|
||||
'clkt' => 'application/vnd.crick.clicker.template',
|
||||
'clkw' => 'application/vnd.crick.clicker.wordbank',
|
||||
'wbs' => 'application/vnd.criticaltools.wbs+xml',
|
||||
'pml' => 'application/vnd.ctc-posml',
|
||||
'ppd' => 'application/vnd.cups-ppd',
|
||||
'curl' => 'application/vnd.curl',
|
||||
'rdz' => 'application/vnd.data-vision.rdz',
|
||||
'dna' => 'application/vnd.dna',
|
||||
'mlp' => 'application/vnd.dolby.mlp',
|
||||
'dpg' => 'application/vnd.dpgraph',
|
||||
'dfac' => 'application/vnd.dreamfactory',
|
||||
'mag' => 'application/vnd.ecowin.chart',
|
||||
'nml' => 'application/vnd.enliven',
|
||||
'esf' => 'application/vnd.epson.esf',
|
||||
'msf' => 'application/vnd.epson.msf',
|
||||
'qam' => 'application/vnd.epson.quickanime',
|
||||
'slt' => 'application/vnd.epson.salt',
|
||||
'ssf' => 'application/vnd.epson.ssf',
|
||||
'es3' => 'application/vnd.eszigno3+xml',
|
||||
'et3' => 'application/vnd.eszigno3+xml',
|
||||
'ez2' => 'application/vnd.ezpix-album',
|
||||
'ez3' => 'application/vnd.ezpix-package',
|
||||
'fdf' => 'application/vnd.fdf',
|
||||
'gph' => 'application/vnd.flographit',
|
||||
'ftc' => 'application/vnd.fluxtime.clip',
|
||||
'fm' => 'application/vnd.framemaker',
|
||||
'frame' => 'application/vnd.framemaker',
|
||||
'maker' => 'application/vnd.framemaker',
|
||||
'fnc' => 'application/vnd.frogans.fnc',
|
||||
'ltf' => 'application/vnd.frogans.ltf',
|
||||
'fsc' => 'application/vnd.fsc.weblaunch',
|
||||
'oas' => 'application/vnd.fujitsu.oasys',
|
||||
'oa2' => 'application/vnd.fujitsu.oasys2',
|
||||
'oa3' => 'application/vnd.fujitsu.oasys3',
|
||||
'fg5' => 'application/vnd.fujitsu.oasysgp',
|
||||
'bh2' => 'application/vnd.fujitsu.oasysprs',
|
||||
'ddd' => 'application/vnd.fujixerox.ddd',
|
||||
'xdw' => 'application/vnd.fujixerox.docuworks',
|
||||
'xbd' => 'application/vnd.fujixerox.docuworks.binder',
|
||||
'fzs' => 'application/vnd.fuzzysheet',
|
||||
'txd' => 'application/vnd.genomatix.tuxedo',
|
||||
'kml' => 'application/vnd.google-earth.kml+xml',
|
||||
'kmz' => 'application/vnd.google-earth.kmz',
|
||||
'gqf' => 'application/vnd.grafeq',
|
||||
'gqs' => 'application/vnd.grafeq',
|
||||
'gac' => 'application/vnd.groove-account',
|
||||
'ghf' => 'application/vnd.groove-help',
|
||||
'gim' => 'application/vnd.groove-identity-message',
|
||||
'grv' => 'application/vnd.groove-injector',
|
||||
'gtm' => 'application/vnd.groove-tool-message',
|
||||
'tpl' => 'application/vnd.groove-tool-template',
|
||||
'vcg' => 'application/vnd.groove-vcard',
|
||||
'zmm' => 'application/vnd.handheld-entertainment+xml',
|
||||
'hbci' => 'application/vnd.hbci',
|
||||
'les' => 'application/vnd.hhe.lesson-player',
|
||||
'hpgl' => 'application/vnd.hp-hpgl',
|
||||
'hpid' => 'application/vnd.hp-hpid',
|
||||
'hps' => 'application/vnd.hp-hps',
|
||||
'jlt' => 'application/vnd.hp-jlyt',
|
||||
'pcl' => 'application/vnd.hp-pcl',
|
||||
'pclxl' => 'application/vnd.hp-pclxl',
|
||||
'x3d' => 'application/vnd.hzn-3d-crossword',
|
||||
'mpy' => 'application/vnd.ibm.minipay',
|
||||
'afp' => 'application/vnd.ibm.modcap',
|
||||
'listafp' => 'application/vnd.ibm.modcap',
|
||||
'list3820' => 'application/vnd.ibm.modcap',
|
||||
'irm' => 'application/vnd.ibm.rights-management',
|
||||
'sc' => 'application/vnd.ibm.secure-container',
|
||||
'igl' => 'application/vnd.igloader',
|
||||
'ivp' => 'application/vnd.immervision-ivp',
|
||||
'ivu' => 'application/vnd.immervision-ivu',
|
||||
'xpw' => 'application/vnd.intercon.formnet',
|
||||
'xpx' => 'application/vnd.intercon.formnet',
|
||||
'qbo' => 'application/vnd.intu.qbo',
|
||||
'qfx' => 'application/vnd.intu.qfx',
|
||||
'rcprofile' => 'application/vnd.ipunplugged.rcprofile',
|
||||
'irp' => 'application/vnd.irepository.package+xml',
|
||||
'xpr' => 'application/vnd.is-xpr',
|
||||
'jam' => 'application/vnd.jam',
|
||||
'rms' => 'application/vnd.jcp.javame.midlet-rms',
|
||||
'jisp' => 'application/vnd.jisp',
|
||||
'ktz' => 'application/vnd.kahootz',
|
||||
'ktr' => 'application/vnd.kahootz',
|
||||
'karbon' => 'application/vnd.kde.karbon',
|
||||
'chrt' => 'application/vnd.kde.kchart',
|
||||
'kfo' => 'application/vnd.kde.kformula',
|
||||
'flw' => 'application/vnd.kde.kivio',
|
||||
'kon' => 'application/vnd.kde.kontour',
|
||||
'kpr' => 'application/vnd.kde.kpresenter',
|
||||
'kpt' => 'application/vnd.kde.kpresenter',
|
||||
'ksp' => 'application/vnd.kde.kspread',
|
||||
'kwd' => 'application/vnd.kde.kword',
|
||||
'kwt' => 'application/vnd.kde.kword',
|
||||
'htke' => 'application/vnd.kenameaapp',
|
||||
'kia' => 'application/vnd.kidspiration',
|
||||
'kne' => 'application/vnd.kinar',
|
||||
'knp' => 'application/vnd.kinar',
|
||||
'skp' => 'application/vnd.koan',
|
||||
'skd' => 'application/vnd.koan',
|
||||
'skt' => 'application/vnd.koan',
|
||||
'skm' => 'application/vnd.koan',
|
||||
'lbd' => 'application/vnd.llamagraphics.life-balance.desktop',
|
||||
'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml',
|
||||
'123' => 'application/vnd.lotus-1-2-3',
|
||||
'apr' => 'application/vnd.lotus-approach',
|
||||
'pre' => 'application/vnd.lotus-freelance',
|
||||
'nsf' => 'application/vnd.lotus-notes',
|
||||
'org' => 'application/vnd.lotus-organizer',
|
||||
'scm' => 'application/vnd.lotus-screencam',
|
||||
'lwp' => 'application/vnd.lotus-wordpro',
|
||||
'portpkg' => 'application/vnd.macports.portpkg',
|
||||
'mcd' => 'application/vnd.mcd',
|
||||
'mc1' => 'application/vnd.medcalcdata',
|
||||
'cdkey' => 'application/vnd.mediastation.cdkey',
|
||||
'mwf' => 'application/vnd.mfer',
|
||||
'mfm' => 'application/vnd.mfmp',
|
||||
'flo' => 'application/vnd.micrografx.flo',
|
||||
'igx' => 'application/vnd.micrografx.igx',
|
||||
'mif' => 'application/vnd.mif',
|
||||
'daf' => 'application/vnd.mobius.daf',
|
||||
'dis' => 'application/vnd.mobius.dis',
|
||||
'mbk' => 'application/vnd.mobius.mbk',
|
||||
'mqy' => 'application/vnd.mobius.mqy',
|
||||
'msl' => 'application/vnd.mobius.msl',
|
||||
'plc' => 'application/vnd.mobius.plc',
|
||||
'txf' => 'application/vnd.mobius.txf',
|
||||
'mpn' => 'application/vnd.mophun.application',
|
||||
'mpc' => 'application/vnd.mophun.certificate',
|
||||
'xul' => 'application/vnd.mozilla.xul+xml',
|
||||
'cil' => 'application/vnd.ms-artgalry',
|
||||
'asf' => 'application/vnd.ms-asf',
|
||||
'cab' => 'application/vnd.ms-cab-compressed',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'xlm' => 'application/vnd.ms-excel',
|
||||
'xla' => 'application/vnd.ms-excel',
|
||||
'xlc' => 'application/vnd.ms-excel',
|
||||
'xlt' => 'application/vnd.ms-excel',
|
||||
'xlw' => 'application/vnd.ms-excel',
|
||||
'eot' => 'application/vnd.ms-fontobject',
|
||||
'chm' => 'application/vnd.ms-htmlhelp',
|
||||
'ims' => 'application/vnd.ms-ims',
|
||||
'lrm' => 'application/vnd.ms-lrm',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'pps' => 'application/vnd.ms-powerpoint',
|
||||
'pot' => 'application/vnd.ms-powerpoint',
|
||||
'mpp' => 'application/vnd.ms-project',
|
||||
'mpt' => 'application/vnd.ms-project',
|
||||
'wps' => 'application/vnd.ms-works',
|
||||
'wks' => 'application/vnd.ms-works',
|
||||
'wcm' => 'application/vnd.ms-works',
|
||||
'wdb' => 'application/vnd.ms-works',
|
||||
'wpl' => 'application/vnd.ms-wpl',
|
||||
'xps' => 'application/vnd.ms-xpsdocument',
|
||||
'mseq' => 'application/vnd.mseq',
|
||||
'mus' => 'application/vnd.musician',
|
||||
'nlu' => 'application/vnd.neurolanguage.nlu',
|
||||
'nnd' => 'application/vnd.noblenet-directory',
|
||||
'nns' => 'application/vnd.noblenet-sealer',
|
||||
'nnw' => 'application/vnd.noblenet-web',
|
||||
'ngdat' => 'application/vnd.nokia.n-gage.data',
|
||||
'n-gage' => 'application/vnd.nokia.n-gage.symbian.install',
|
||||
'rpst' => 'application/vnd.nokia.radio-preset',
|
||||
'rpss' => 'application/vnd.nokia.radio-presets',
|
||||
'edm' => 'application/vnd.novadigm.edm',
|
||||
'edx' => 'application/vnd.novadigm.edx',
|
||||
'ext' => 'application/vnd.novadigm.ext',
|
||||
'odc' => 'application/vnd.oasis.opendocument.chart',
|
||||
'otc' => 'application/vnd.oasis.opendocument.chart-template',
|
||||
'odf' => 'application/vnd.oasis.opendocument.formula',
|
||||
'otf' => 'application/vnd.oasis.opendocument.formula-template',
|
||||
'odg' => 'application/vnd.oasis.opendocument.graphics',
|
||||
'otg' => 'application/vnd.oasis.opendocument.graphics-template',
|
||||
'odi' => 'application/vnd.oasis.opendocument.image',
|
||||
'oti' => 'application/vnd.oasis.opendocument.image-template',
|
||||
'odp' => 'application/vnd.oasis.opendocument.presentation',
|
||||
'otp' => 'application/vnd.oasis.opendocument.presentation-template',
|
||||
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
||||
'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
|
||||
'odt' => 'application/vnd.oasis.opendocument.text',
|
||||
'otm' => 'application/vnd.oasis.opendocument.text-master',
|
||||
'ott' => 'application/vnd.oasis.opendocument.text-template',
|
||||
'oth' => 'application/vnd.oasis.opendocument.text-web',
|
||||
'xo' => 'application/vnd.olpc-sugar',
|
||||
'dd2' => 'application/vnd.oma.dd2+xml',
|
||||
'oxt' => 'application/vnd.openofficeorg.extension',
|
||||
'dp' => 'application/vnd.osgi.dp',
|
||||
'prc' => 'application/vnd.palm',
|
||||
'pdb' => 'application/vnd.palm',
|
||||
'pqa' => 'application/vnd.palm',
|
||||
'oprc' => 'application/vnd.palm',
|
||||
'str' => 'application/vnd.pg.format',
|
||||
'ei6' => 'application/vnd.pg.osasli',
|
||||
'efif' => 'application/vnd.picsel',
|
||||
'plf' => 'application/vnd.pocketlearn',
|
||||
'pbd' => 'application/vnd.powerbuilder6',
|
||||
'box' => 'application/vnd.previewsystems.box',
|
||||
'mgz' => 'application/vnd.proteus.magazine',
|
||||
'qps' => 'application/vnd.publishare-delta-tree',
|
||||
'ptid' => 'application/vnd.pvi.ptid1',
|
||||
'qxd' => 'application/vnd.quark.quarkxpress',
|
||||
'qxt' => 'application/vnd.quark.quarkxpress',
|
||||
'qwd' => 'application/vnd.quark.quarkxpress',
|
||||
'qwt' => 'application/vnd.quark.quarkxpress',
|
||||
'qxl' => 'application/vnd.quark.quarkxpress',
|
||||
'qxb' => 'application/vnd.quark.quarkxpress',
|
||||
'mxl' => 'application/vnd.recordare.musicxml',
|
||||
'rm' => 'application/vnd.rn-realmedia',
|
||||
'see' => 'application/vnd.seemail',
|
||||
'sema' => 'application/vnd.sema',
|
||||
'semd' => 'application/vnd.semd',
|
||||
'semf' => 'application/vnd.semf',
|
||||
'ifm' => 'application/vnd.shana.informed.formdata',
|
||||
'itp' => 'application/vnd.shana.informed.formtemplate',
|
||||
'iif' => 'application/vnd.shana.informed.interchange',
|
||||
'ipk' => 'application/vnd.shana.informed.package',
|
||||
'twd' => 'application/vnd.simtech-mindmapper',
|
||||
'twds' => 'application/vnd.simtech-mindmapper',
|
||||
'mmf' => 'application/vnd.smaf',
|
||||
'sdkm' => 'application/vnd.solent.sdkm+xml',
|
||||
'sdkd' => 'application/vnd.solent.sdkm+xml',
|
||||
'dxp' => 'application/vnd.spotfire.dxp',
|
||||
'sfs' => 'application/vnd.spotfire.sfs',
|
||||
'sus' => 'application/vnd.sus-calendar',
|
||||
'susp' => 'application/vnd.sus-calendar',
|
||||
'svd' => 'application/vnd.svd',
|
||||
'xsm' => 'application/vnd.syncml+xml',
|
||||
'bdm' => 'application/vnd.syncml.dm+wbxml',
|
||||
'xdm' => 'application/vnd.syncml.dm+xml',
|
||||
'tao' => 'application/vnd.tao.intent-module-archive',
|
||||
'tmo' => 'application/vnd.tmobile-livetv',
|
||||
'tpt' => 'application/vnd.trid.tpt',
|
||||
'mxs' => 'application/vnd.triscape.mxs',
|
||||
'tra' => 'application/vnd.trueapp',
|
||||
'ufd' => 'application/vnd.ufdl',
|
||||
'ufdl' => 'application/vnd.ufdl',
|
||||
'utz' => 'application/vnd.uiq.theme',
|
||||
'umj' => 'application/vnd.umajin',
|
||||
'unityweb' => 'application/vnd.unity',
|
||||
'uoml' => 'application/vnd.uoml+xml',
|
||||
'vcx' => 'application/vnd.vcx',
|
||||
'vsd' => 'application/vnd.visio',
|
||||
'vst' => 'application/vnd.visio',
|
||||
'vss' => 'application/vnd.visio',
|
||||
'vsw' => 'application/vnd.visio',
|
||||
'vis' => 'application/vnd.visionary',
|
||||
'vsf' => 'application/vnd.vsf',
|
||||
'wbxml' => 'application/vnd.wap.wbxml',
|
||||
'wmlc' => 'application/vnd.wap.wmlc',
|
||||
'wmlsc' => 'application/vnd.wap.wmlscriptc',
|
||||
'wtb' => 'application/vnd.webturbo',
|
||||
'wpd' => 'application/vnd.wordperfect',
|
||||
'wqd' => 'application/vnd.wqd',
|
||||
'stf' => 'application/vnd.wt.stf',
|
||||
'xar' => 'application/vnd.xara',
|
||||
'xfdl' => 'application/vnd.xfdl',
|
||||
'hvd' => 'application/vnd.yamaha.hv-dic',
|
||||
'hvs' => 'application/vnd.yamaha.hv-script',
|
||||
'hvp' => 'application/vnd.yamaha.hv-voice',
|
||||
'saf' => 'application/vnd.yamaha.smaf-audio',
|
||||
'spf' => 'application/vnd.yamaha.smaf-phrase',
|
||||
'cmp' => 'application/vnd.yellowriver-custom-menu',
|
||||
'zaz' => 'application/vnd.zzazz.deck+xml',
|
||||
'vxml' => 'application/voicexml+xml',
|
||||
'hlp' => 'application/winhlp',
|
||||
'wsdl' => 'application/wsdl+xml',
|
||||
'wspolicy' => 'application/wspolicy+xml',
|
||||
'ace' => 'application/x-ace-compressed',
|
||||
'bcpio' => 'application/x-bcpio',
|
||||
'torrent' => 'application/x-bittorrent',
|
||||
'bz' => 'application/x-bzip',
|
||||
'bz2' => 'application/x-bzip2',
|
||||
'boz' => 'application/x-bzip2',
|
||||
'vcd' => 'application/x-cdlink',
|
||||
'chat' => 'application/x-chat',
|
||||
'pgn' => 'application/x-chess-pgn',
|
||||
'cpio' => 'application/x-cpio',
|
||||
'csh' => 'application/x-csh',
|
||||
'dcr' => 'application/x-director',
|
||||
'dir' => 'application/x-director',
|
||||
'dxr' => 'application/x-director',
|
||||
'fgd' => 'application/x-director',
|
||||
'dvi' => 'application/x-dvi',
|
||||
'spl' => 'application/x-futuresplash',
|
||||
'gtar' => 'application/x-gtar',
|
||||
'hdf' => 'application/x-hdf',
|
||||
'jnlp' => 'application/x-java-jnlp-file',
|
||||
'latex' => 'application/x-latex',
|
||||
'wmd' => 'application/x-ms-wmd',
|
||||
'wmz' => 'application/x-ms-wmz',
|
||||
'mdb' => 'application/x-msaccess',
|
||||
'obd' => 'application/x-msbinder',
|
||||
'crd' => 'application/x-mscardfile',
|
||||
'clp' => 'application/x-msclip',
|
||||
'exe' => 'application/x-msdownload',
|
||||
'dll' => 'application/x-msdownload',
|
||||
'com' => 'application/x-msdownload',
|
||||
'bat' => 'application/x-msdownload',
|
||||
'msi' => 'application/x-msdownload',
|
||||
'mvb' => 'application/x-msmediaview',
|
||||
'm13' => 'application/x-msmediaview',
|
||||
'm14' => 'application/x-msmediaview',
|
||||
'wmf' => 'application/x-msmetafile',
|
||||
'mny' => 'application/x-msmoney',
|
||||
'pub' => 'application/x-mspublisher',
|
||||
'scd' => 'application/x-msschedule',
|
||||
'trm' => 'application/x-msterminal',
|
||||
'wri' => 'application/x-mswrite',
|
||||
'nc' => 'application/x-netcdf',
|
||||
'cdf' => 'application/x-netcdf',
|
||||
'p12' => 'application/x-pkcs12',
|
||||
'pfx' => 'application/x-pkcs12',
|
||||
'p7b' => 'application/x-pkcs7-certificates',
|
||||
'spc' => 'application/x-pkcs7-certificates',
|
||||
'p7r' => 'application/x-pkcs7-certreqresp',
|
||||
'rar' => 'application/x-rar-compressed',
|
||||
'sh' => 'application/x-sh',
|
||||
'shar' => 'application/x-shar',
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
'sit' => 'application/x-stuffit',
|
||||
'sitx' => 'application/x-stuffitx',
|
||||
'sv4cpio' => 'application/x-sv4cpio',
|
||||
'sv4crc' => 'application/x-sv4crc',
|
||||
'tar' => 'application/x-tar',
|
||||
'tcl' => 'application/x-tcl',
|
||||
'tex' => 'application/x-tex',
|
||||
'texinfo' => 'application/x-texinfo',
|
||||
'texi' => 'application/x-texinfo',
|
||||
'ustar' => 'application/x-ustar',
|
||||
'src' => 'application/x-wais-source',
|
||||
'der' => 'application/x-x509-ca-cert',
|
||||
'crt' => 'application/x-x509-ca-cert',
|
||||
'xenc' => 'application/xenc+xml',
|
||||
'xhtml' => 'application/xhtml+xml',
|
||||
'xht' => 'application/xhtml+xml',
|
||||
'xml' => 'application/xml',
|
||||
'xsl' => 'application/xml',
|
||||
'dtd' => 'application/xml-dtd',
|
||||
'xop' => 'application/xop+xml',
|
||||
'xslt' => 'application/xslt+xml',
|
||||
'xspf' => 'application/xspf+xml',
|
||||
'mxml' => 'application/xv+xml',
|
||||
'xhvml' => 'application/xv+xml',
|
||||
'xvml' => 'application/xv+xml',
|
||||
'xvm' => 'application/xv+xml',
|
||||
'zip' => 'application/zip',
|
||||
'au' => 'audio/basic',
|
||||
'snd' => 'audio/basic',
|
||||
'mid' => 'audio/midi',
|
||||
'midi' => 'audio/midi',
|
||||
'kar' => 'audio/midi',
|
||||
'rmi' => 'audio/midi',
|
||||
'mp4a' => 'audio/mp4',
|
||||
'm4a' => 'audio/mp4a-latm',
|
||||
'm4p' => 'audio/mp4a-latm',
|
||||
'mpga' => 'audio/mpeg',
|
||||
'mp2' => 'audio/mpeg',
|
||||
'mp2a' => 'audio/mpeg',
|
||||
'mp3' => 'audio/mpeg',
|
||||
'm2a' => 'audio/mpeg',
|
||||
'm3a' => 'audio/mpeg',
|
||||
'eol' => 'audio/vnd.digital-winds',
|
||||
'lvp' => 'audio/vnd.lucent.voice',
|
||||
'ecelp4800' => 'audio/vnd.nuera.ecelp4800',
|
||||
'ecelp7470' => 'audio/vnd.nuera.ecelp7470',
|
||||
'ecelp9600' => 'audio/vnd.nuera.ecelp9600',
|
||||
'wav' => 'audio/wav',
|
||||
'aif' => 'audio/x-aiff',
|
||||
'aiff' => 'audio/x-aiff',
|
||||
'aifc' => 'audio/x-aiff',
|
||||
'm3u' => 'audio/x-mpegurl',
|
||||
'wax' => 'audio/x-ms-wax',
|
||||
'wma' => 'audio/x-ms-wma',
|
||||
'ram' => 'audio/x-pn-realaudio',
|
||||
'ra' => 'audio/x-pn-realaudio',
|
||||
'rmp' => 'audio/x-pn-realaudio-plugin',
|
||||
'cdx' => 'chemical/x-cdx',
|
||||
'cif' => 'chemical/x-cif',
|
||||
'cmdf' => 'chemical/x-cmdf',
|
||||
'cml' => 'chemical/x-cml',
|
||||
'csml' => 'chemical/x-csml',
|
||||
'xyz' => 'chemical/x-xyz',
|
||||
'bmp' => 'image/bmp',
|
||||
'cgm' => 'image/cgm',
|
||||
'g3' => 'image/g3fax',
|
||||
'gif' => 'image/gif',
|
||||
'ief' => 'image/ief',
|
||||
'jp2' => 'image/jp2',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'jpe' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'pict' => 'image/pict',
|
||||
'pic' => 'image/pict',
|
||||
'pct' => 'image/pict',
|
||||
'png' => 'image/png',
|
||||
'btif' => 'image/prs.btif',
|
||||
'svg' => 'image/svg+xml',
|
||||
'svgz' => 'image/svg+xml',
|
||||
'tiff' => 'image/tiff',
|
||||
'tif' => 'image/tiff',
|
||||
'psd' => 'image/vnd.adobe.photoshop',
|
||||
'djvu' => 'image/vnd.djvu',
|
||||
'djv' => 'image/vnd.djvu',
|
||||
'dwg' => 'image/vnd.dwg',
|
||||
'dxf' => 'image/vnd.dxf',
|
||||
'fbs' => 'image/vnd.fastbidsheet',
|
||||
'fpx' => 'image/vnd.fpx',
|
||||
'fst' => 'image/vnd.fst',
|
||||
'mmr' => 'image/vnd.fujixerox.edmics-mmr',
|
||||
'rlc' => 'image/vnd.fujixerox.edmics-rlc',
|
||||
'ico' => 'image/vnd.microsoft.icon',
|
||||
'mdi' => 'image/vnd.ms-modi',
|
||||
'npx' => 'image/vnd.net-fpx',
|
||||
'wbmp' => 'image/vnd.wap.wbmp',
|
||||
'xif' => 'image/vnd.xiff',
|
||||
'ras' => 'image/x-cmu-raster',
|
||||
'cmx' => 'image/x-cmx',
|
||||
'pntg' => 'image/x-macpaint',
|
||||
'pnt' => 'image/x-macpaint',
|
||||
'mac' => 'image/x-macpaint',
|
||||
'pcx' => 'image/x-pcx',
|
||||
'pnm' => 'image/x-portable-anymap',
|
||||
'pbm' => 'image/x-portable-bitmap',
|
||||
'pgm' => 'image/x-portable-graymap',
|
||||
'ppm' => 'image/x-portable-pixmap',
|
||||
'qtif' => 'image/x-quicktime',
|
||||
'qti' => 'image/x-quicktime',
|
||||
'rgb' => 'image/x-rgb',
|
||||
'xbm' => 'image/x-xbitmap',
|
||||
'xpm' => 'image/x-xpixmap',
|
||||
'xwd' => 'image/x-xwindowdump',
|
||||
'eml' => 'message/rfc822',
|
||||
'mime' => 'message/rfc822',
|
||||
'igs' => 'model/iges',
|
||||
'iges' => 'model/iges',
|
||||
'msh' => 'model/mesh',
|
||||
'mesh' => 'model/mesh',
|
||||
'silo' => 'model/mesh',
|
||||
'dwf' => 'model/vnd.dwf',
|
||||
'gdl' => 'model/vnd.gdl',
|
||||
'gtw' => 'model/vnd.gtw',
|
||||
'mts' => 'model/vnd.mts',
|
||||
'vtu' => 'model/vnd.vtu',
|
||||
'wrl' => 'model/vrml',
|
||||
'vrml' => 'model/vrml',
|
||||
'ics' => 'text/calendar',
|
||||
'ifb' => 'text/calendar',
|
||||
'css' => 'text/css',
|
||||
'csv' => 'text/csv',
|
||||
'html' => 'text/html',
|
||||
'htm' => 'text/html',
|
||||
'txt' => 'text/plain',
|
||||
'text' => 'text/plain',
|
||||
'conf' => 'text/plain',
|
||||
'def' => 'text/plain',
|
||||
'list' => 'text/plain',
|
||||
'log' => 'text/plain',
|
||||
'in' => 'text/plain',
|
||||
'dsc' => 'text/prs.lines.tag',
|
||||
'rtx' => 'text/richtext',
|
||||
'sgml' => 'text/sgml',
|
||||
'sgm' => 'text/sgml',
|
||||
'tsv' => 'text/tab-separated-values',
|
||||
't' => 'text/troff',
|
||||
'tr' => 'text/troff',
|
||||
'roff' => 'text/troff',
|
||||
'man' => 'text/troff',
|
||||
'me' => 'text/troff',
|
||||
'ms' => 'text/troff',
|
||||
'uri' => 'text/uri-list',
|
||||
'uris' => 'text/uri-list',
|
||||
'urls' => 'text/uri-list',
|
||||
'fly' => 'text/vnd.fly',
|
||||
'flx' => 'text/vnd.fmi.flexstor',
|
||||
'3dml' => 'text/vnd.in3d.3dml',
|
||||
'spot' => 'text/vnd.in3d.spot',
|
||||
'jad' => 'text/vnd.sun.j2me.app-descriptor',
|
||||
'wml' => 'text/vnd.wap.wml',
|
||||
'wmls' => 'text/vnd.wap.wmlscript',
|
||||
's' => 'text/x-asm',
|
||||
'asm' => 'text/x-asm',
|
||||
'c' => 'text/x-c',
|
||||
'cc' => 'text/x-c',
|
||||
'cxx' => 'text/x-c',
|
||||
'cpp' => 'text/x-c',
|
||||
'h' => 'text/x-c',
|
||||
'hh' => 'text/x-c',
|
||||
'dic' => 'text/x-c',
|
||||
'f' => 'text/x-fortran',
|
||||
'for' => 'text/x-fortran',
|
||||
'f77' => 'text/x-fortran',
|
||||
'f90' => 'text/x-fortran',
|
||||
'p' => 'text/x-pascal',
|
||||
'pas' => 'text/x-pascal',
|
||||
'java' => 'text/x-java-source',
|
||||
'etx' => 'text/x-setext',
|
||||
'uu' => 'text/x-uuencode',
|
||||
'vcs' => 'text/x-vcalendar',
|
||||
'vcf' => 'text/x-vcard',
|
||||
'3gp' => 'video/3gpp',
|
||||
'3g2' => 'video/3gpp2',
|
||||
'h261' => 'video/h261',
|
||||
'h263' => 'video/h263',
|
||||
'h264' => 'video/h264',
|
||||
'jpgv' => 'video/jpeg',
|
||||
'jpm' => 'video/jpm',
|
||||
'jpgm' => 'video/jpm',
|
||||
'mj2' => 'video/mj2',
|
||||
'mjp2' => 'video/mj2',
|
||||
'mp4' => 'video/mp4',
|
||||
'mp4v' => 'video/mp4',
|
||||
'mpg4' => 'video/mp4',
|
||||
'm4v' => 'video/mp4',
|
||||
'mpeg' => 'video/mpeg',
|
||||
'mpg' => 'video/mpeg',
|
||||
'mpe' => 'video/mpeg',
|
||||
'm1v' => 'video/mpeg',
|
||||
'm2v' => 'video/mpeg',
|
||||
'qt' => 'video/quicktime',
|
||||
'mov' => 'video/quicktime',
|
||||
'fvt' => 'video/vnd.fvt',
|
||||
'mxu' => 'video/vnd.mpegurl',
|
||||
'm4u' => 'video/vnd.mpegurl',
|
||||
'viv' => 'video/vnd.vivo',
|
||||
'dv' => 'video/x-dv',
|
||||
'dif' => 'video/x-dv',
|
||||
'fli' => 'video/x-fli',
|
||||
'asx' => 'video/x-ms-asf',
|
||||
'wm' => 'video/x-ms-wm',
|
||||
'wmv' => 'video/x-ms-wmv',
|
||||
'wmx' => 'video/x-ms-wmx',
|
||||
'wvx' => 'video/x-ms-wvx',
|
||||
'avi' => 'video/x-msvideo',
|
||||
'movie' => 'video/x-sgi-movie',
|
||||
'ice' => 'x-conference/x-cooltalk',
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns extension for given mime type
|
||||
*
|
||||
* @param string $mimeType The mime type, e.g. "video/mpeg"
|
||||
* @return array|string
|
||||
*/
|
||||
public static function getExtension($mimeType)
|
||||
{
|
||||
if (is_string($mimeType) && in_array($mimeType, self::$mimeTypes, true)) {
|
||||
$data = Arrays::setKeysAsValues(self::$mimeTypes, false);
|
||||
|
||||
return $data[$mimeType];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns extensions for given mimes types
|
||||
*
|
||||
* @param array $mimesTypes The mimes types, e.g. ['video/mpeg', 'image/jpeg']
|
||||
* @param bool $asUpperCase (optional) If is set to true, extensions are returned as upper case. Otherwise - lower
|
||||
* case.
|
||||
* @return array
|
||||
*/
|
||||
public static function getExtensions(array $mimesTypes, $asUpperCase = false)
|
||||
{
|
||||
if (empty($mimesTypes)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$extensions = [];
|
||||
|
||||
foreach ($mimesTypes as $mimeType) {
|
||||
$extension = self::getExtension($mimeType);
|
||||
|
||||
/*
|
||||
* No extension for given mime type?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($extension)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($asUpperCase) {
|
||||
if (is_array($extension)) {
|
||||
array_walk($extension, function (&$value) {
|
||||
$value = strtoupper($value);
|
||||
});
|
||||
} else {
|
||||
$extension = strtoupper($extension);
|
||||
}
|
||||
}
|
||||
|
||||
$extensions[$mimeType] = $extension;
|
||||
}
|
||||
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns mime type of given file
|
||||
*
|
||||
* @param string $filePath Path of the file to check
|
||||
* @return string
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function getMimeType($filePath)
|
||||
{
|
||||
/*
|
||||
* The file does not exist?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (!is_string($filePath) || !is_readable($filePath)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// 1st possibility: the finfo class
|
||||
if (class_exists('finfo')) {
|
||||
$finfo = new finfo();
|
||||
|
||||
return $finfo->file($filePath, FILEINFO_MIME_TYPE);
|
||||
}
|
||||
|
||||
// 2nd possibility: the mime_content_type function
|
||||
if (function_exists('mime_content_type')) {
|
||||
return mime_content_type($filePath);
|
||||
}
|
||||
|
||||
// Oops, there is no possibility to read the mime type
|
||||
$template = 'Neither \'finfo\' class nor \'mime_content_type\' function exists. There is no way to read the'
|
||||
.' mime type of file \'%s\'.';
|
||||
|
||||
$message = sprintf($template, $filePath);
|
||||
|
||||
throw new RuntimeException($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information whether the given file type is an image
|
||||
*
|
||||
* @param string $mimeType The mime type of file
|
||||
* @return bool
|
||||
*/
|
||||
public static function isImage($mimeType)
|
||||
{
|
||||
if (in_array($mimeType, self::$mimeTypes, true)) {
|
||||
return (bool) preg_match('|^image/.+$|', $mimeType);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information whether file with the given path is an image
|
||||
*
|
||||
* @param string $path Path of the file to check
|
||||
* @return bool
|
||||
*/
|
||||
public static function isImagePath($path)
|
||||
{
|
||||
$mimeType = self::getMimeType($path);
|
||||
|
||||
return self::isImage($mimeType);
|
||||
}
|
||||
}
|
||||
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 (count($value) == 2) {
|
||||
$compareOperator = $value[1];
|
||||
}
|
||||
|
||||
$value = $value[0];
|
||||
}
|
||||
|
||||
$predicate = sprintf('%s.%s %s :%s', $alias, $column, $compareOperator, $column);
|
||||
|
||||
if ($value === null) {
|
||||
$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;
|
||||
831
src/Utilities/Reflection.php
Normal file
831
src/Utilities/Reflection.php
Normal file
@@ -0,0 +1,831 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* (c) Meritoo.pl, http://www.meritoo.pl
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Meritoo\Common\Utilities;
|
||||
|
||||
use Doctrine\Inflector\InflectorFactory;
|
||||
use Doctrine\Persistence\Proxy;
|
||||
use Meritoo\Common\Contract\Collection\CollectionInterface;
|
||||
use Meritoo\Common\Exception\Reflection\CannotResolveClassNameException;
|
||||
use Meritoo\Common\Exception\Reflection\MissingChildClassesException;
|
||||
use Meritoo\Common\Exception\Reflection\NotExistingPropertyException;
|
||||
use Meritoo\Common\Exception\Reflection\TooManyChildClassesException;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use ReflectionMethod;
|
||||
use ReflectionObject;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* Useful reflection methods
|
||||
*
|
||||
* @author Meritoo <github@meritoo.pl>
|
||||
* @copyright Meritoo <http://www.meritoo.pl>
|
||||
*/
|
||||
class Reflection
|
||||
{
|
||||
/**
|
||||
* Returns child classes of given class.
|
||||
* It's an array of namespaces of the child classes or null (if given class has not child classes).
|
||||
*
|
||||
* @param array|object|string $class Class who child classes should be returned. An array of objects, strings,
|
||||
* object or string.
|
||||
* @return null|array
|
||||
* @throws CannotResolveClassNameException
|
||||
*/
|
||||
public static function getChildClasses($class): ?array
|
||||
{
|
||||
$allClasses = get_declared_classes();
|
||||
|
||||
/*
|
||||
* No classes?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($allClasses)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$className = self::getClassName($class);
|
||||
|
||||
// Oops, cannot resolve class
|
||||
if (null === $className) {
|
||||
throw CannotResolveClassNameException::create('');
|
||||
}
|
||||
|
||||
$childClasses = [];
|
||||
|
||||
foreach ($allClasses as $oneClass) {
|
||||
if (self::isChildOfClass($oneClass, $className)) {
|
||||
/*
|
||||
* Attention. I have to use static::getRealClass() method to avoid problem with the proxy / cache
|
||||
* classes. Example:
|
||||
* - My\ExtraBundle\Entity\MyEntity
|
||||
* - Proxies\__CG__\My\ExtraBundle\Entity\MyEntity
|
||||
*
|
||||
* It's actually the same class, so I have to skip it.
|
||||
*/
|
||||
$realClass = static::getRealClass($oneClass);
|
||||
|
||||
if (in_array($realClass, $childClasses, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$childClasses[] = $realClass;
|
||||
}
|
||||
}
|
||||
|
||||
return $childClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a class name for given source
|
||||
*
|
||||
* @param array|object|string $source An array of objects, namespaces, object or namespace
|
||||
* @param bool $withoutNamespace (optional) If is set to true, namespace is omitted. Otherwise -
|
||||
* not, full name of class is returned, with namespace.
|
||||
* @return null|string
|
||||
*/
|
||||
public static function getClassName($source, bool $withoutNamespace = false): ?string
|
||||
{
|
||||
/*
|
||||
* First argument is not proper source of class?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($source) || (!is_array($source) && !is_object($source) && !is_string($source))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$name = '';
|
||||
|
||||
/*
|
||||
* An array of objects was provided?
|
||||
* Let's use first of them
|
||||
*/
|
||||
if (is_array($source)) {
|
||||
$source = Arrays::getFirstElement($source);
|
||||
}
|
||||
|
||||
// Let's prepare name of class
|
||||
if (is_object($source)) {
|
||||
$name = get_class($source);
|
||||
} elseif (is_string($source) && (class_exists($source) || trait_exists($source))) {
|
||||
$name = $source;
|
||||
}
|
||||
|
||||
/*
|
||||
* Name of class is still unknown?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Namespace is not required?
|
||||
* Let's return name of class only
|
||||
*/
|
||||
if ($withoutNamespace) {
|
||||
$classOnly = Miscellaneous::getLastElementOfString($name, '\\');
|
||||
|
||||
if (null !== $classOnly) {
|
||||
$name = $classOnly;
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
return static::getRealClass($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns namespace of class for given source
|
||||
*
|
||||
* @param array|object|string $source An array of objects, namespaces, object or namespace
|
||||
* @return string
|
||||
*/
|
||||
public static function getClassNamespace($source): string
|
||||
{
|
||||
$fullClassName = self::getClassName($source);
|
||||
|
||||
if (null === $fullClassName || '' === $fullClassName) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$className = self::getClassName($source, true);
|
||||
|
||||
if ($className === $fullClassName) {
|
||||
return $className;
|
||||
}
|
||||
|
||||
return Miscellaneous::getStringWithoutLastElement($fullClassName, '\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value of given constant
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @param string $constant Name of the constant that contains a value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getConstantValue($class, string $constant)
|
||||
{
|
||||
$reflection = new ReflectionClass($class);
|
||||
|
||||
if (self::hasConstant($class, $constant)) {
|
||||
return $reflection->getConstant($constant);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns constants of given class / object
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @return array
|
||||
*/
|
||||
public static function getConstants($class): array
|
||||
{
|
||||
$reflection = new ReflectionClass($class);
|
||||
|
||||
return $reflection->getConstants();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns maximum integer value of constant of given class / object.
|
||||
* Constants whose values are integers are considered only.
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @return null|int
|
||||
*/
|
||||
public static function getMaxNumberConstant($class): ?int
|
||||
{
|
||||
$constants = self::getConstants($class);
|
||||
|
||||
if (empty($constants)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$maxNumber = 0;
|
||||
|
||||
foreach ($constants as $constant) {
|
||||
if (is_numeric($constant) && $constant > $maxNumber) {
|
||||
$maxNumber = $constant;
|
||||
}
|
||||
}
|
||||
|
||||
return $maxNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns names of methods for given class / object
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @param bool $withoutInheritance (optional) If is set to true, only methods for given class are returned.
|
||||
* Otherwise - all methods, with inherited methods too.
|
||||
* @return array
|
||||
*/
|
||||
public static function getMethods($class, bool $withoutInheritance = false): array
|
||||
{
|
||||
$effect = [];
|
||||
|
||||
$reflection = new ReflectionClass($class);
|
||||
$methods = $reflection->getMethods();
|
||||
|
||||
if (!empty($methods)) {
|
||||
$className = self::getClassName($class);
|
||||
|
||||
foreach ($methods as $method) {
|
||||
if ($method instanceof ReflectionMethod) {
|
||||
if ($withoutInheritance && $className !== $method->class) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$effect[] = $method->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $effect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns namespace of one child class which extends given class.
|
||||
* Extended class should has only one child class.
|
||||
*
|
||||
* @param array|object|string $parentClass Class who child class should be returned. An array of objects,
|
||||
* namespaces, object or namespace.
|
||||
* @return mixed
|
||||
* @throws TooManyChildClassesException|MissingChildClassesException|CannotResolveClassNameException
|
||||
*/
|
||||
public static function getOneChildClass($parentClass)
|
||||
{
|
||||
$childClasses = self::getChildClasses($parentClass);
|
||||
|
||||
/*
|
||||
* No child classes?
|
||||
* Oops, the base / parent class hasn't child class
|
||||
*/
|
||||
if (empty($childClasses)) {
|
||||
throw MissingChildClassesException::create($parentClass);
|
||||
}
|
||||
|
||||
/*
|
||||
* More than 1 child class?
|
||||
* Oops, the base / parent class has too many child classes
|
||||
*/
|
||||
if (count($childClasses) > 1) {
|
||||
throw TooManyChildClassesException::create($parentClass, $childClasses);
|
||||
}
|
||||
|
||||
return trim($childClasses[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a parent class or false if there is no parent class
|
||||
*
|
||||
* @param array|object|string $source An array of objects, namespaces, object or namespace
|
||||
* @return false|ReflectionClass
|
||||
*/
|
||||
public static function getParentClass($source)
|
||||
{
|
||||
$className = self::getClassName($source);
|
||||
$reflection = new ReflectionClass($className);
|
||||
|
||||
return $reflection->getParentClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns name of the parent class.
|
||||
* If given class does not extend another, returns null.
|
||||
*
|
||||
* @param array|object|string $class An array of objects, namespaces, object or namespace
|
||||
* @return null|string
|
||||
*/
|
||||
public static function getParentClassName($class): ?string
|
||||
{
|
||||
$className = self::getClassName($class);
|
||||
$reflection = new ReflectionClass($className);
|
||||
$parentClass = $reflection->getParentClass();
|
||||
|
||||
if (null === $parentClass || false === $parentClass) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $parentClass->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns given object properties
|
||||
*
|
||||
* @param array|object|string $source An array of objects, namespaces, object or namespace
|
||||
* @param int $filter (optional) Filter of properties. Uses \ReflectionProperty class
|
||||
* constants. By default all properties are returned.
|
||||
* @param bool $includeParents (optional) If is set to true, properties of parent classes are
|
||||
* included (recursively). Otherwise - not.
|
||||
* @return ReflectionProperty[]
|
||||
*/
|
||||
public static function getProperties($source, int $filter = null, bool $includeParents = false): array
|
||||
{
|
||||
$className = self::getClassName($source);
|
||||
$reflection = new ReflectionClass($className);
|
||||
|
||||
if (null === $filter) {
|
||||
$filter = ReflectionProperty::IS_PRIVATE
|
||||
+ ReflectionProperty::IS_PROTECTED
|
||||
+ ReflectionProperty::IS_PUBLIC
|
||||
+ ReflectionProperty::IS_STATIC;
|
||||
}
|
||||
|
||||
$properties = $reflection->getProperties($filter);
|
||||
$parentProperties = [];
|
||||
|
||||
if ($includeParents) {
|
||||
$parent = self::getParentClass($source);
|
||||
|
||||
if (false !== $parent) {
|
||||
$parentClass = $parent->getName();
|
||||
$parentProperties = self::getProperties($parentClass, $filter, $includeParents);
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge($properties, $parentProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns property, the \ReflectionProperty instance, of given object
|
||||
*
|
||||
* @param array|object|string $class An array of objects, namespaces, object or namespace
|
||||
* @param string $property Name of the property
|
||||
* @param int|null $filter (optional) Filter of properties. Uses \ReflectionProperty class constants.
|
||||
* By default all properties are allowed / processed.
|
||||
* @return null|ReflectionProperty
|
||||
*/
|
||||
public static function getProperty($class, string $property, int $filter = null): ?ReflectionProperty
|
||||
{
|
||||
$className = self::getClassName($class);
|
||||
$properties = self::getProperties($className, $filter);
|
||||
|
||||
if (!empty($properties)) {
|
||||
foreach ($properties as $reflectionProperty) {
|
||||
if ($reflectionProperty->getName() === $property) {
|
||||
return $reflectionProperty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value of given property
|
||||
*
|
||||
* @param mixed $source Object that should contains given property
|
||||
* @param string $property Name of the property that contains a value. It may be also multiple properties
|
||||
* dot-separated, e.g. "invoice.user.email".
|
||||
* @param bool $force (optional) If is set to true, try to retrieve value even if the object doesn't have
|
||||
* property. Otherwise - not.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getPropertyValue($source, string $property, bool $force = false)
|
||||
{
|
||||
if (Regex::contains($property, '.')) {
|
||||
return self::getPropertyValueByPropertiesChain($source, $property, $force);
|
||||
}
|
||||
|
||||
[
|
||||
$value,
|
||||
$valueFound,
|
||||
] = self::getPropertyValueByReflectionProperty($source, $property);
|
||||
|
||||
if (!$valueFound) {
|
||||
[
|
||||
$value,
|
||||
$valueFound,
|
||||
] = self::getPropertyValueByParentClasses($source, $property);
|
||||
}
|
||||
|
||||
if (!$valueFound && ($force || self::hasProperty($source, $property))) {
|
||||
[
|
||||
$value,
|
||||
$valueFound,
|
||||
] = self::getPropertyValueByGetter($source, $property);
|
||||
}
|
||||
|
||||
if (!$valueFound) {
|
||||
$byReflectionProperty = self::getPropertyValueByReflectionProperty($source, $property);
|
||||
$value = $byReflectionProperty[0];
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns values of given property for given objects.
|
||||
* Looks for proper getter for the property.
|
||||
*
|
||||
* @param array|CollectionInterface|object $objects The objects that should contain given property. It may be also
|
||||
* one object.
|
||||
* @param string $property Name of the property that contains a value
|
||||
* @param bool $force (optional) If is set to true, try to retrieve value even if
|
||||
* the object does not have property. Otherwise - not.
|
||||
* @return array
|
||||
*/
|
||||
public static function getPropertyValues($objects, string $property, bool $force = false): array
|
||||
{
|
||||
/*
|
||||
* No objects?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($objects)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($objects instanceof CollectionInterface) {
|
||||
$objects = $objects->toArray();
|
||||
}
|
||||
|
||||
$values = [];
|
||||
$objects = Arrays::makeArray($objects);
|
||||
|
||||
foreach ($objects as $object) {
|
||||
$value = self::getPropertyValue($object, $property, $force);
|
||||
|
||||
if (null !== $value) {
|
||||
$values[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given class / object has given constant
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @param string $constant Name of the constant to find
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasConstant($class, string $constant): bool
|
||||
{
|
||||
$reflection = new ReflectionClass($class);
|
||||
|
||||
return $reflection->hasConstant($constant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given class / object has given method
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @param string $method Name of the method to find
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasMethod($class, string $method): bool
|
||||
{
|
||||
$reflection = new ReflectionClass($class);
|
||||
|
||||
return $reflection->hasMethod($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given class / object has given property
|
||||
*
|
||||
* @param object|string $class The object or name of object's class
|
||||
* @param string $property Name of the property to find
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasProperty($class, string $property): bool
|
||||
{
|
||||
$reflection = new ReflectionClass($class);
|
||||
|
||||
return $reflection->hasProperty($property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given child class is a subclass of given parent class
|
||||
*
|
||||
* @param array|object|string $childClass The child class. An array of objects, namespaces, object or namespace.
|
||||
* @param array|object|string $parentClass The parent class. An array of objects, namespaces, object or namespace.
|
||||
* @return bool
|
||||
*/
|
||||
public static function isChildOfClass($childClass, $parentClass): bool
|
||||
{
|
||||
$childClassName = self::getClassName($childClass);
|
||||
$parentClassName = self::getClassName($parentClass);
|
||||
|
||||
$parents = class_parents($childClassName);
|
||||
|
||||
if (is_array($parents) && 0 < count($parents)) {
|
||||
return in_array($parentClassName, $parents, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given interface is implemented by given class / object
|
||||
*
|
||||
* @param array|object|string $source An array of objects, namespaces, object or namespace
|
||||
* @param string $interface The interface that should be implemented
|
||||
* @return bool
|
||||
*/
|
||||
public static function isInterfaceImplemented($source, string $interface): bool
|
||||
{
|
||||
$className = self::getClassName($source);
|
||||
$interfaces = class_implements($className);
|
||||
|
||||
return in_array($interface, $interfaces, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets values of properties in given object
|
||||
*
|
||||
* @param mixed $object Object that should contains given property
|
||||
* @param array $propertiesValues Key-value pairs, where key - name of the property, value - value of the property
|
||||
*/
|
||||
public static function setPropertiesValues($object, array $propertiesValues): void
|
||||
{
|
||||
/*
|
||||
* No properties?
|
||||
* Nothing to do
|
||||
*/
|
||||
if (empty($propertiesValues)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($propertiesValues as $property => $value) {
|
||||
static::setPropertyValue($object, $property, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets value of given property in given object
|
||||
*
|
||||
* @param mixed $object Object that should contains given property
|
||||
* @param string $property Name of the property
|
||||
* @param mixed $value Value of the property
|
||||
* @throws NotExistingPropertyException
|
||||
*/
|
||||
public static function setPropertyValue($object, string $property, $value): void
|
||||
{
|
||||
$reflectionProperty = self::getProperty($object, $property);
|
||||
|
||||
// Oops, property does not exist
|
||||
if (null === $reflectionProperty) {
|
||||
throw NotExistingPropertyException::create($object, $property);
|
||||
}
|
||||
|
||||
$isPublic = $reflectionProperty->isPublic();
|
||||
|
||||
if (!$isPublic) {
|
||||
$reflectionProperty->setAccessible(true);
|
||||
}
|
||||
|
||||
$reflectionProperty->setValue($object, $value);
|
||||
|
||||
if (!$isPublic) {
|
||||
$reflectionProperty->setAccessible(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information if given class / object uses / implements given trait
|
||||
*
|
||||
* @param array|object|string $class An array of objects, namespaces, object or namespace
|
||||
* @param array|string $trait An array of strings or string
|
||||
* @param bool $verifyParents If is set to true, parent classes are verified if they use given
|
||||
* trait. Otherwise - not.
|
||||
* @return null|bool
|
||||
* @throws CannotResolveClassNameException|ReflectionException
|
||||
*/
|
||||
public static function usesTrait($class, $trait, bool $verifyParents = false): ?bool
|
||||
{
|
||||
$className = self::getClassName($class);
|
||||
$traitName = self::getClassName($trait);
|
||||
|
||||
// Oops, cannot resolve class
|
||||
if (null === $className || '' === $className) {
|
||||
throw CannotResolveClassNameException::create('');
|
||||
}
|
||||
|
||||
// Oops, cannot resolve trait
|
||||
if (null === $traitName || '' === $traitName) {
|
||||
throw CannotResolveClassNameException::create('', false);
|
||||
}
|
||||
|
||||
$reflection = new ReflectionClass($className);
|
||||
$traitsNames = $reflection->getTraitNames();
|
||||
|
||||
$uses = in_array($traitName, $traitsNames, true);
|
||||
|
||||
if (!$uses && $verifyParents) {
|
||||
$parentClassName = self::getParentClassName($className);
|
||||
|
||||
if (null !== $parentClassName) {
|
||||
return self::usesTrait($parentClassName, $trait, true);
|
||||
}
|
||||
}
|
||||
|
||||
return $uses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value of given property using getter of the property
|
||||
*
|
||||
* An array with 2 elements is returned:
|
||||
* - value of given property
|
||||
* - information if the value was found (because null may be returned)
|
||||
*
|
||||
* @param mixed $source Object that should contains given property
|
||||
* @param string $property Name of the property that contains a value
|
||||
* @return array
|
||||
*/
|
||||
private static function getPropertyValueByGetter($source, string $property): array
|
||||
{
|
||||
$value = null;
|
||||
$valueFound = false;
|
||||
|
||||
$reflectionObject = new ReflectionObject($source);
|
||||
$inflector = InflectorFactory::create()->build();
|
||||
$property = $inflector->classify($property);
|
||||
|
||||
$gettersPrefixes = [
|
||||
'get',
|
||||
'has',
|
||||
'is',
|
||||
];
|
||||
|
||||
foreach ($gettersPrefixes as $prefix) {
|
||||
$getter = sprintf('%s%s', $prefix, $property);
|
||||
|
||||
if ($reflectionObject->hasMethod($getter)) {
|
||||
$method = new ReflectionMethod($source, $getter);
|
||||
|
||||
/*
|
||||
* Getter is not accessible publicly?
|
||||
* I have to skip it, to avoid an error like this:
|
||||
*
|
||||
* Call to protected method My\ExtraClass::getExtraProperty() from context 'My\ExtraClass'
|
||||
*/
|
||||
if ($method->isProtected() || $method->isPrivate()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $source->{$getter}();
|
||||
$valueFound = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
$value,
|
||||
$valueFound,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value of given property using parent classes
|
||||
*
|
||||
* @param mixed $source Object that should contains given property
|
||||
* @param string $property Name of the property that contains a value
|
||||
* @return array
|
||||
*/
|
||||
private static function getPropertyValueByParentClasses($source, string $property): array
|
||||
{
|
||||
$properties = self::getProperties($source, null, true);
|
||||
|
||||
if (empty($properties)) {
|
||||
return [
|
||||
null,
|
||||
false,
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($properties as $reflectionProperty) {
|
||||
if ($reflectionProperty->getName() === $property) {
|
||||
$byReflectionProperty = self::getPropertyValueByReflectionProperty(
|
||||
$source,
|
||||
$property,
|
||||
$reflectionProperty
|
||||
);
|
||||
|
||||
return [
|
||||
$byReflectionProperty[0],
|
||||
true,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
null,
|
||||
false,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value of given property represented as chain of properties
|
||||
*
|
||||
* @param mixed $source Object that should contains given property
|
||||
* @param string $property Dot-separated properties, e.g. "invoice.user.email"
|
||||
* @param bool $force (optional) If is set to true, try to retrieve value even if the object doesn't have
|
||||
* property. Otherwise - not.
|
||||
* @return mixed
|
||||
*/
|
||||
private static function getPropertyValueByPropertiesChain($source, string $property, bool $force)
|
||||
{
|
||||
$exploded = explode('.', $property);
|
||||
|
||||
$property = $exploded[0];
|
||||
$source = self::getPropertyValue($source, $property, $force);
|
||||
|
||||
/*
|
||||
* Value of processed property from the chain is not null?
|
||||
* Let's dig more and get proper value
|
||||
*
|
||||
* Required to avoid bug:
|
||||
* \ReflectionObject::__construct() expects parameter 1 to be object, null given
|
||||
* (...)
|
||||
* 4. at \ReflectionObject->__construct (null)
|
||||
* 5. at Reflection ::getPropertyValue (null, 'name', true)
|
||||
* 6. at ListService->getItemValue (object(Deal), 'project.name', '0')
|
||||
*
|
||||
* while using "project.name" as property - $project has $name property ($project exists in the Deal class)
|
||||
* and the $project equals null
|
||||
*
|
||||
* Meritoo <github@meritoo.pl>
|
||||
* 2016-11-07
|
||||
*/
|
||||
if (null !== $source) {
|
||||
unset($exploded[0]);
|
||||
$property = implode('.', $exploded);
|
||||
|
||||
return self::getPropertyValue($source, $property, $force);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value of given property using the property represented by reflection.
|
||||
* If value cannot be fetched, makes the property accessible temporarily.
|
||||
*
|
||||
* @param mixed $object Object that should contains given property
|
||||
* @param string $property Name of the property that contains a value
|
||||
* @param null|ReflectionProperty $reflectionProperty (optional) Property represented by reflection
|
||||
* @return mixed
|
||||
*/
|
||||
private static function getPropertyValueByReflectionProperty(
|
||||
$object,
|
||||
string $property,
|
||||
?ReflectionProperty $reflectionProperty = null
|
||||
) {
|
||||
$value = null;
|
||||
$valueFound = false;
|
||||
$className = self::getClassName($object);
|
||||
|
||||
try {
|
||||
if (null === $reflectionProperty) {
|
||||
$reflectionProperty = new ReflectionProperty($className, $property);
|
||||
}
|
||||
|
||||
$value = $reflectionProperty->getValue($object);
|
||||
$valueFound = true;
|
||||
} catch (ReflectionException $exception) {
|
||||
}
|
||||
|
||||
if (null !== $reflectionProperty) {
|
||||
$reflectionProperty->setAccessible(true);
|
||||
|
||||
$value = $reflectionProperty->getValue($object);
|
||||
$valueFound = true;
|
||||
|
||||
$reflectionProperty->setAccessible(false);
|
||||
}
|
||||
|
||||
return [
|
||||
$value,
|
||||
$valueFound,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the real class name of a class name that could be a proxy
|
||||
*
|
||||
* @param string $class Class to verify
|
||||
* @return string
|
||||
*/
|
||||
private static function getRealClass(string $class): string
|
||||
{
|
||||
if (false === $pos = strrpos($class, '\\'.Proxy::MARKER.'\\')) {
|
||||
return $class;
|
||||
}
|
||||
|
||||
return substr($class, $pos + Proxy::MARKER_LENGTH + 2);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user