First, initial commit

This commit is contained in:
Meritoo
2017-08-29 22:37:19 +02:00
commit d9ab2a082e
67 changed files with 18377 additions and 0 deletions

189
.gitignore vendored Normal file
View File

@@ -0,0 +1,189 @@
# ----------------------------------------------------------------------------------------------------------------------
### Vendors
# ----------------------------------------------------------------------------------------------------------------------
/vendor/
# ----------------------------------------------------------------------------------------------------------------------
### 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 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/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml
# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
# Gradle:
.idea/**/gradle.xml
.idea/**/libraries
# CMake
cmake-build-debug/
# Mongo Explorer plugin:
.idea/**/mongoSettings.xml
## File-based project format:
*.iws
## Plugin-specific files:
# 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
# ----------------------------------------------------------------------------------------------------------------------
### NetBeans template
# ----------------------------------------------------------------------------------------------------------------------
nbproject/private/
build/
nbbuild/
dist/
nbdist/
nbactions.xml
.nb-gradle/
# ----------------------------------------------------------------------------------------------------------------------
### OSX template
# ----------------------------------------------------------------------------------------------------------------------
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# ----------------------------------------------------------------------------------------------------------------------
### 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
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk

1
.idea/.name generated Normal file
View File

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

210
.idea/Common Library (GitHub).iml generated Normal file
View File

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

9
.idea/composerJson.xml generated Normal file
View File

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

6
.idea/encodings.xml generated Normal file
View File

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

8
.idea/modules.xml generated Normal file
View File

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

75
.idea/php.xml generated Normal file
View File

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

14
.idea/webResources.xml generated Normal file
View File

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

30
.php_cs.dist Normal file
View File

@@ -0,0 +1,30 @@
<?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',
]);
return PhpCsFixer\Config::create()
->setRules([
'@Symfony' => true,
'phpdoc_summary' => false,
'phpdoc_separation' => false,
'phpdoc_align' => false,
'cast_spaces' => false,
'binary_operator_spaces' => [
'align_double_arrow' => true,
],
'concat_space' => [
'spacing' => 'one',
],
])
->setFinder($finder);

20
LICENSE Normal file
View File

@@ -0,0 +1,20 @@
MIT License
Copyright (c) Meritoo.pl, http://www.meritoo.pl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

38
README.md Normal file
View File

@@ -0,0 +1,38 @@
# Meritoo Common Library
Useful classes, methods, extensions etc.
## Installation
#### Composer
1. Open ```composer.json``` and add address of repository in ```repositories``` section:
```json
"repositories": [
{
"type": "vcs",
"url": "git@github.com:meritoo/common-library.git"
}
]
```
2. Run [Composer](https://getcomposer.org) to install new package:
```bash
$ composer require meritoo/common-library
```
> How to install Composer: https://getcomposer.org/download
## Usage
This package contains a lot of static methods, so usage is not so complicated. Just run the static method who would you like to use. Example:
```php
use Meritoo\Common\Utilities\Arrays;
$firstElement = Arrays::getFirstElement(['lorem' 'ipsum']);
// result: "lorem"
```
Enjoy!

46
build.xml Normal file
View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="Meritoo Common Library" basedir="." default="build:main" phingVersion="2.14.0">
<!-- Properties -->
<if>
<available file="phing/properties" property="custom.properties.available"/>
<then>
<property file="phing/properties" />
</then>
<else>
<property file="phing/properties.dist" />
</else>
</if>
<!-- Default / main target -->
<target name="build:main"
depends="build:app, build:tests"
description="Builds everything and runs all tests" />
<!-- Build app -->
<target name="build:app" description="Prepares app to build and tests">
<phing phingfile="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>
</project>

34
composer.json Normal file
View File

@@ -0,0 +1,34 @@
{
"name": "meritoo/common-library",
"description": "Useful classes, methods, extensions etc.",
"license": "MIT",
"version": "0.0.1",
"authors": [
{
"name": "Meritoo.pl",
"email": "github@meritoo.pl",
"homepage": "http://www.meritoo.pl"
}
],
"require": {
"php": ">=5.6.0",
"doctrine/orm": "^2.5",
"gedmo/doctrine-extensions": "^2.4",
"symfony/http-foundation": "^3.3"
},
"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"
},
"autoload": {
"psr-4": {
"Meritoo\\Common\\": "src/Meritoo/Common/",
"Meritoo\\Common\\Tests\\": "tests/Meritoo/Common/Tests/"
}
}
}

3518
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

7
data/tests/composer.json Normal file
View File

@@ -0,0 +1,7 @@
{
"name": "test/test",
"license": "proprietary",
"version": "1.0.2",
"type": "library",
"description": "For testing purposes only"
}

View File

@@ -0,0 +1 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae.

BIN
data/tests/minion.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

89
phing/app.xml Normal file
View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="Meritoo Common Library" basedir="." default="build:main" phingVersion="2.14.0">
<!-- Properties -->
<if>
<available file="phing/properties" property="custom.properties.available"/>
<then>
<property file="phing/properties" />
</then>
<else>
<property file="phing/properties.dist" />
</else>
</if>
<!-- Default / main target -->
<target name="build:main"
depends="build:app"
description="Builds the application" />
<!-- App target -->
<target name="build:app"
depends="app:composer, app:vendors, app:checkout"
description="Prepares app to build." />
<!-- Check / update composer -->
<target name="app:composer" description="Checks / updates composer">
<echo msg="Checking / updating composer..." />
<if>
<available file="composer.phar" />
<then>
<echo msg="[Skipped] Downloading of Composer skipped, because exist in the project..." />
</then>
<else>
<if>
<os family="windows" />
<then>
<fail message="Composer not found! Go to http://getcomposer.org/download and download the Composer." />
</then>
<else>
<exec command="${composer.download_command}" checkreturn="true" />
</else>
</if>
</else>
</if>
<composer command="selfupdate" />
</target>
<!-- Project Install/update vendors -->
<target name="app:vendors" description="Installs / updates vendors">
<echo msg="Installing / updating vendors..." />
<if>
<istrue value="${composer.self-update}"/>
<then>
<composer php="${composer.php}" composer="${composer.path}" command="self-update"/>
</then>
</if>
<if>
<istrue value="${composer.validate}"/>
<then>
<composer php="${composer.php}" composer="${composer.path}" command="validate"/>
</then>
</if>
<if>
<equals arg1="${env}" arg2="prod" />
<then>
<composer php="${composer.php}" composer="${composer.path}" command="install">
<arg value="--optimize-autoloader" />
</composer>
</then>
<else>
<composer php="${composer.php}" composer="${composer.path}" command="install" />
</else>
</if>
</target>
<!-- Checkout and finalization -->
<target name="app:checkout">
<tstamp>
<format property="date_end" pattern="%Y-%m-%d %H:%M" />
</tstamp>
<echo msg="------------------------------------" />
<echo msg="Build finished at: ${date_end}" />
<echo msg="------------------------------------" />
</target>
</project>

125
phing/properties.dist Normal file
View File

@@ -0,0 +1,125 @@
# --------------------------------------------------------------------------------
# Information
# --------------------------------------------------------------------------------
# Property files contain key/value pairs
# key = value
#
# Property keys may contain alphanumeric chars and colons, but
# not special chars. This way you can create pseudo-namespaces
#
# You can refer to values of other properties by enclosing their keys in "${}".
# Example: dir.js = ${dir.web}/js
#
# Everything behind the equal sign is the value, you do
# not have to enclose strings: text=This is some text, Your OS is ${php.os}
# --------------------------------------------------------------------------------
# Common, e.g. default environment
# --------------------------------------------------------------------------------
# Default environment
#
env = dev
# Install assets using symlinks
#
assets.installWithSymlink = true
# Clear cache with the "warmup" option
#
cache.clearWithWarmup = true
# --------------------------------------------------------------------------------
# Composer
# --------------------------------------------------------------------------------
composer.download_command = php -r "eval('?>'.file_get_contents('https://getcomposer.org/installer'));"
# Path to composer executable or composer.phar file
#
composer.path = composer.phar
#composer.path = /usr/local/bin/composer
# Path to php executable used by composer
#
composer.php = php
# Self update of the composer
#
composer.self-update = false
# Validate the composer.json file
#
composer.validate = false
# --------------------------------------------------------------------------------
# Directories
# --------------------------------------------------------------------------------
# System directories
#
dir.data = ${project.basedir}/data
dir.src = ${project.basedir}/src
dir.tests = ${project.basedir}/tests
# --------------------------------------------------------------------------------
# Build directories
# --------------------------------------------------------------------------------
dir.build = ${project.basedir}/build
dir.reports = ${dir.build}/logs
dir.reports.pdepend = ${dir.reports}/pdepend
dir.reports.coverage = ${dir.reports}/phpunit_coverage
#
# Disabled, because unnecessary right now
# phpdocumentor/phpdocumentor cannot be installed via Composer
#
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
# 2017-02-22
#
#dir.docs = ${dir.build}/docs
#dir.docs.phpdoc2 = ${dir.docs}/phpdoc2
# --------------------------------------------------------------------------------
# Data directories
# --------------------------------------------------------------------------------
dir.data.tests = ${dir.data}/tests
dir.data.temporary = ${dir.data}/tmp
# --------------------------------------------------------------------------------
# Testing
# --------------------------------------------------------------------------------
# Test database path
#
tests.database = ${dir.data.temporary}/database.sqlite
#
# Disabled, because unnecessary right now
# PHPUnit is installed and loaded by Composer
#
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
# 2017-02-22
#
# Run PHPUnit using exec task instead of phpunitTask
#phpunit.useExec = false
#
# Disabled, because unnecessary right now
# We want generate code coverage always
#
# Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
# 2017-02-22
#
# Collect coverage data during tests
#phpunit.withCoverage = true
# Path of the PHPUnit (https://phpunit.de)
#
phpUnit.path = ./vendor/bin/phpunit
# Path of the PHP Coding Standards Fixer (http://cs.sensiolabs.org)
#
phpCsFixer.path = ./vendor/bin/php-cs-fixer

315
phing/tests.xml Normal file
View File

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

35
phpunit.xml.dist Normal file
View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="true"
bootstrap="./vendor/autoload.php"
>
<testsuites>
<testsuite name="Meritoo's Common Library Test Suite">
<directory>./tests/</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" />
</logging>
</phpunit>

View File

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

View File

@@ -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\Date;
use Exception;
/**
* An exception used while given part of date is incorrect, e.g. value of year is incorrect
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class IncorrectDatePartException extends Exception
{
/**
* Class constructor
*
* @param string $value Incorrect value
* @param string $datePart Type of date part, e.g. "year". One of \Meritoo\Common\Type\DatePartType class constants.
*/
public function __construct($value, $datePart)
{
$message = sprintf('Value of %s \'%s\' is incorrect. Is there everything ok?', $datePart, $value);
parent::__construct($message);
}
}

View File

@@ -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;
/**
* An exception used while length of given hexadecimal value of color is incorrect
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class IncorrectColorHexLengthException extends \Exception
{
/**
* Class constructor
*
* @param string $color Incorrect hexadecimal value of color
*/
public function __construct($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?';
$message = sprintf($template, $color, strlen($color));
parent::__construct($message);
}
}

View File

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

View File

@@ -0,0 +1,47 @@
<?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 name of class or trait cannot be resolved
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class CannotResolveClassNameException extends Exception
{
/**
* Class constructor
*
* @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.
*/
public function __construct($source, $forClass = true)
{
$forWho = 'trait';
$value = '';
if ($forClass) {
$forWho = 'class';
}
if (is_scalar($source)) {
$value = sprintf(' %s', (string)$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);
}
}

View File

@@ -0,0 +1,38 @@
<?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;
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
*/
class MissingChildClassesException extends Exception
{
/**
* Class constructor
*
* @param array|object|string $parentClass Class that hasn't child classes, but it should. An array of objects,
* strings, object or string.
*/
public function __construct($parentClass)
{
$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?';
$parentClassName = Reflection::getClassName($parentClass);
$message = sprintf($template, $parentClassName);
parent::__construct($message);
}
}

View File

@@ -0,0 +1,39 @@
<?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;
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
*/
class TooManyChildClassesException extends Exception
{
/**
* Class constructor
*
* @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
*/
public function __construct($parentClass, array $childClasses)
{
$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?";
$parentClassName = Reflection::getClassName($parentClass);
$message = sprintf($template, $parentClassName, implode("\n- ", $childClasses), $parentClassName);
parent::__construct($message);
}
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Type\Base;
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
*/
abstract class BaseType
{
/**
* All types
*
* @var array
*/
private $all;
/**
* Returns all types
*
* @return array
*/
public function getAll()
{
if ($this->all === null) {
$this->all = Reflection::getConstants($this);
}
return $this->all;
}
/**
* Returns information if given type is correct
*
* @param string $type The type to check
* @return bool
*/
public function isCorrectType($type)
{
return in_array($type, $this->getAll(), true);
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Meritoo\Common\Type;
use Meritoo\Common\Type\Base\BaseType;
/**
* Type of date part, e.g. "year"
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class DatePartType extends BaseType
{
/**
* The "day" date part
*
* @var string
*/
const DAY = 'day';
/**
* The "hour" date part
*
* @var string
*/
const HOUR = 'hour';
/**
* The "minute" date part
*
* @var string
*/
const MINUTE = 'minute';
/**
* The "month" date part
*
* @var string
*/
const MONTH = 'month';
/**
* The "second" date part
*
* @var string
*/
const SECOND = 'second';
/**
* The "year" date part
*
* @var string
*/
const YEAR = 'year';
}

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -0,0 +1,69 @@
<?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 stdClass;
/**
* Useful Composer-related methods (only static functions)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Composer
{
/**
* Name of the Composer's main file with configuration in Json format
*
* @var string
*/
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
*/
public static function getValue($composerJsonPath, $nodeName)
{
$composerJsonString = is_string($composerJsonPath);
$composerJsonReadable = false;
if ($composerJsonString) {
$composerJsonReadable = is_readable($composerJsonPath);
}
/*
* Provided path or name of node are invalid?
* The composer.json file doesn't exist or isn't readable?
* Name of node is unknown?
*
* Nothing to do
*/
if (!$composerJsonString || !is_string($nodeName) || !$composerJsonReadable || empty($nodeName)) {
return null;
}
$content = file_get_contents($composerJsonPath);
$data = json_decode($content);
/*
* Unknown data from the composer.json file or there is no node with given name?
* Nothing to do
*/
if ($data === null || !isset($data->{$nodeName})) {
return null;
}
/* @var stdClass $data */
return $data->{$nodeName};
}
}

View File

@@ -0,0 +1,714 @@
<?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 DateInterval;
use DateTime;
use Meritoo\Common\Exception\Date\IncorrectDatePartException;
use Meritoo\Common\Type\DatePartType;
/**
* Useful date methods
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Date
{
/**
* The 'days' unit of date difference.
* Difference between dates in days.
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_DAYS = 'days';
/**
* The 'hours' unit of date difference.
* Difference between dates in hours.
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_HOURS = 'hours';
/**
* The 'minutes' unit of date difference.
* Difference between dates in minutes.
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_MINUTES = 'minutes';
/**
* The 'months' unit of date difference.
* Difference between dates in months.
*
* @var string
*/
const DATE_DIFFERENCE_UNIT_MONTHS = 'months';
/**
* The 'years' unit of date difference.
* Difference between dates in years.
*
* @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;
}
/**
* 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
*/
public static function generateRandomTime($format = 'H:i:s')
{
$dateTime = new DateTime();
/*
* Format si empty or is incorrect?
* Nothing to do
*/
if (empty($format) || $dateTime->format($format) === $format) {
return null;
}
$hours = [];
$minutes = [];
$seconds = [];
for ($i = 1; $i <= 23; ++$i) {
$hours[] = $i;
}
for ($i = 1; $i <= 59; ++$i) {
$minutes[] = $i;
}
for ($i = 1; $i <= 59; ++$i) {
$seconds[] = $i;
}
/*
* 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);
}
/**
* Returns current day of week
*
* @return int
*/
public static function getCurrentDayOfWeek()
{
$now = new DateTime();
$year = $now->format('Y');
$month = $now->format('m');
$day = $now->format('d');
return self::getDayOfWeek($year, $month, $day);
}
/**
* Returns day of week (number 0 to 6, 0 - sunday, 6 - saturday).
* Based on the Zeller's algorithm (http://pl.wikipedia.org/wiki/Kalendarz_wieczny).
*
* @param int $year The year value
* @param int $month The month value
* @param int $day The day value
*
* @return int
* @throws IncorrectDatePartException
*/
public static function getDayOfWeek($year, $month, $day)
{
$year = (int)$year;
$month = (int)$month;
$day = (int)$day;
/*
* Oops, incorrect year
*/
if ($year <= 0) {
throw new IncorrectDatePartException($year, DatePartType::YEAR);
}
/*
* Oops, incorrect month
*/
if ($month < 1 || $month > 12) {
throw new IncorrectDatePartException($month, DatePartType::MONTH);
}
/*
* Oops, incorrect day
*/
if ($day < 1 || $day > 31) {
throw new IncorrectDatePartException($day, DatePartType::DAY);
}
if ($month < 3) {
$count = 0;
$yearValue = $year - 1;
} else {
$count = 2;
$yearValue = $year;
}
$firstPart = floor(23 * $month / 9);
$secondPart = floor($yearValue / 4);
$thirdPart = floor($yearValue / 100);
$fourthPart = floor($yearValue / 400);
return ($firstPart + $day + 4 + $year + $secondPart - $thirdPart + $fourthPart - $count) % 7;
}
/**
* Returns based on locale name of current weekday
*
* @return string
*/
public static function getCurrentDayOfWeekName()
{
$now = new DateTime();
$year = $now->format('Y');
$month = $now->format('m');
$day = $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.
*
* The difference is calculated in units based on the 3rd argument or all available unit of date difference
* (defined as DATE_DIFFERENCE_UNIT_* constants of this class).
*
* The difference is also whole / complete value for given unit instead of relative value as may be received by
* DateTime::diff() method, e.g.:
* - 2 days, 50 hours
* instead of
* - 2 days, 2 hours
*
* 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
* DATE_DIFFERENCE_UNIT_* constants. If is set to null all units are
* returned in the array.
* @return array|int
*/
public static function getDateDifference($dateStart, $dateEnd, $differenceUnit = null)
{
$validDateStart = self::isValidDate($dateStart, true);
$validDateEnd = self::isValidDate($dateEnd, true);
/*
* The start or end date is unknown?
* or
* The start or end date is not valid date?
*
* Nothing to do
*/
if (empty($dateStart) || empty($dateEnd) || !$validDateStart || !$validDateEnd) {
return null;
}
$dateStart = self::getDateTime($dateStart, true);
$dateEnd = self::getDateTime($dateEnd, true);
$difference = [];
$dateDiff = $dateEnd->getTimestamp() - $dateStart->getTimestamp();
$daysInSeconds = 0;
$hoursInSeconds = 0;
$hourSeconds = 60 * 60;
$daySeconds = $hourSeconds * 24;
/*
* These units are related, because while calculating difference in the lowest unit, difference in the
* highest unit is required, e.g. while calculating hours I have to know difference in days
*/
$relatedUnits = [
self::DATE_DIFFERENCE_UNIT_DAYS,
self::DATE_DIFFERENCE_UNIT_HOURS,
self::DATE_DIFFERENCE_UNIT_MINUTES,
];
if ($differenceUnit === null || $differenceUnit == self::DATE_DIFFERENCE_UNIT_YEARS) {
$diff = $dateEnd->diff($dateStart);
/*
* Difference between dates in years should be returned only?
*/
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_YEARS) {
return $diff->y;
}
$difference[self::DATE_DIFFERENCE_UNIT_YEARS] = $diff->y;
}
if ($differenceUnit === null || $differenceUnit == self::DATE_DIFFERENCE_UNIT_MONTHS) {
$diff = $dateEnd->diff($dateStart);
/*
* Difference between dates in months should be returned only?
*/
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_MONTHS) {
return $diff->m;
}
$difference[self::DATE_DIFFERENCE_UNIT_MONTHS] = $diff->m;
}
if ($differenceUnit === null || in_array($differenceUnit, $relatedUnits)) {
$days = (int)floor($dateDiff / $daySeconds);
/*
* Difference between dates in days should be returned only?
*/
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_DAYS) {
return $days;
}
/*
* All units should be returned?
*/
if ($differenceUnit === null) {
$difference[self::DATE_DIFFERENCE_UNIT_DAYS] = $days;
}
/*
* Calculation for later usage
*/
$daysInSeconds = $days * $daySeconds;
}
if ($differenceUnit === null || in_array($differenceUnit, $relatedUnits)) {
$hours = (int)floor(($dateDiff - $daysInSeconds) / $hourSeconds);
/*
* Difference between dates in hours should be returned only?
*/
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_HOURS) {
return $hours;
}
/*
* All units should be returned?
*/
if ($differenceUnit === null) {
$difference[self::DATE_DIFFERENCE_UNIT_HOURS] = $hours;
}
/*
* Calculation for later usage
*/
$hoursInSeconds = $hours * $hourSeconds;
}
if ($differenceUnit === null || $differenceUnit == self::DATE_DIFFERENCE_UNIT_MINUTES) {
$minutes = (int)floor(($dateDiff - $daysInSeconds - $hoursInSeconds) / 60);
/*
* Difference between dates in minutes should be returned only?
*/
if ($differenceUnit == self::DATE_DIFFERENCE_UNIT_MINUTES) {
return $minutes;
}
$difference[self::DATE_DIFFERENCE_UNIT_MINUTES] = $minutes;
}
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.
*
* @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.
* @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
*/
public static function getDateTime($value, $allowCompoundFormats = false, $dateFormat = 'Y-m-d')
{
/*
* Empty value?
* Nothing to do :)
*/
if (empty($value)) {
return false;
}
/*
* Instance of DateTime class?
* Nothing to do :)
*/
if ($value instanceof DateTime) {
return $value;
}
try {
try {
/*
* Pass the value to the constructor. Maybe it's one of the allowed relative formats.
* Examples: "now", "last day of next month"
*/
$date = new DateTime($value);
/*
* Instance of the DateTime class was created.
* Let's verify if given value is really proper date.
*/
$dateFromFormat = DateTime::createFromFormat($dateFormat, $value);
if ($dateFromFormat === false) {
/*
* Nothing to do more, because:
* a) instance of the DateTime was created
* and
* b) if createFromFormat() method failed, given value is one of the allowed relative formats
* ("now", "last day of next month")
* and...
*/
if ($allowCompoundFormats) {
/*
* ...and
* c) it's not an integer, e.g. not 10 or 100 or 1000
*/
if (!is_numeric($value)) {
return $date;
}
} else {
$specialFormats = [
'now',
];
/*
* ...and
* c) it's special compound format that contains characters that each may be used by
* DateTime::format() method and it raises problem while trying to verify the value at the end
* of this method:
*
* (new DateTime())->format($value);
*
* 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)) {
return false;
}
}
} /*
* 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;
}
}
} catch (\Exception $exception) {
if (!$allowCompoundFormats) {
return false;
}
}
/*
* Does the value is a string that may be used to format date?
* Example: "Y-m-d"
*/
$dateString = (new DateTime())->format($value);
if ($dateString != $value) {
return new DateTime($dateString);
}
} catch (\Exception $exception) {
}
return false;
}
/**
* Returns information if given value is valid 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.
* @return bool
*/
public static function isValidDate($value, $allowCompoundFormats = false)
{
return self::getDateTime($value, $allowCompoundFormats) instanceof DateTime;
}
/**
* Returns information if given format of date is valid
*
* @param string $format The validated format of date
* @return bool
*/
public static function isValidDateFormat($format)
{
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) {
return false;
}
/*
* Validate the format used to create the datetime
*/
$fromFormat = DateTime::createFromFormat($format, $formatted);
/*
* It's instance of DateTime?
* The format is valid
*/
if ($fromFormat instanceof DateTime) {
return true;
}
return $fromFormat instanceof DateTime;
}
}

View File

@@ -0,0 +1,195 @@
<?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 DateTime;
/**
* A date's period.
* Contains start and end date of the period.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class DatePeriod
{
/**
* The period constant: last month
*
* @var int
*/
const LAST_MONTH = 4;
/**
* The period constant: last week
*
* @var int
*/
const LAST_WEEK = 1;
/**
* The period constant: last year
*
* @var int
*/
const LAST_YEAR = 7;
/**
* The period constant: next month
*
* @var int
*/
const NEXT_MONTH = 6;
/**
* The period constant: next week
*
* @var int
*/
const NEXT_WEEK = 3;
/**
* The period constant: next year
*
* @var int
*/
const NEXT_YEAR = 9;
/**
* The period constant: this month
*
* @var int
*/
const THIS_MONTH = 5;
/**
* The period constant: this week
*
* @var int
*/
const THIS_WEEK = 2;
/**
* The period constant: this year
*
* @var int
*/
const THIS_YEAR = 8;
/**
* The start date of period
*
* @var DateTime
*/
private $startDate;
/**
* The end date of period
*
* @var DateTime
*/
private $endDate;
/**
* Class constructor
*
* @param DateTime $startDate (optional) The start date of period
* @param DateTime $endDate (optional) The end date of period
*/
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
*/
public function getEndDate()
{
return $this->endDate;
}
/**
* Sets the end date of period
*
* @param DateTime $endDate (optional) The end date of period
* @return $this
*/
public function setEndDate(DateTime $endDate = null)
{
$this->endDate = $endDate;
return $this;
}
/**
* Returns the start date of period
*
* @return DateTime
*/
public function getStartDate()
{
return $this->startDate;
}
/**
* Sets the start date of period
*
* @param DateTime $startDate (optional) The start date of period
* @return $this
*/
public function setStartDate(DateTime $startDate = null)
{
$this->startDate = $startDate;
return $this;
}
}

View File

@@ -0,0 +1,37 @@
<?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 Generator;
/**
* Useful methods for the Generator class (only static functions)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class GeneratorUtility
{
/**
* Returns elements of generator
*
* @param Generator $generator The generator who elements should be returned
* @return array
*/
public static function getGeneratorElements(Generator $generator)
{
$elements = [];
for (; $generator->valid(); $generator->next()) {
$elements[] = $generator->current();
}
return $elements;
}
}

View File

@@ -0,0 +1,106 @@
<?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 locale methods
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Locale
{
/**
* 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 bool
*
* 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)) {
return false;
}
$localeLongForm = self::getLongForm($languageCode, $countryCode);
setlocale($category, $localeLongForm);
return true;
}
/**
* Returns long form of the locale
*
* @param string $languageCode Language code, in ISO 639-1 format. Short form of the locale, e.g. "fr".
* @param string $countryCode (optional) Country code, in ISO 3166-1 alpha-2 format, e.g. "FR"
* @param string $encoding (optional) Encoding of the final locale
* @return string
*
* Example:
* - language code: fr
* - country code: ''
* - result: fr_FR
*/
public static function getLongForm($languageCode, $countryCode = '', $encoding = 'UTF-8')
{
if (is_string($languageCode)) {
$languageCode = trim($languageCode);
}
/*
* Language code not provided?
* Nothing to do
*/
if (empty($languageCode)) {
return '';
}
/*
* Country code not provided?
* Let's use language code
*/
if (empty($countryCode)) {
$countryCode = $languageCode;
}
if (!empty($encoding)) {
$encoding = sprintf('.%s', $encoding);
}
return sprintf('%s_%s%s', $languageCode, strtoupper($countryCode), $encoding);
}
}

View File

@@ -0,0 +1,816 @@
<?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;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,194 @@
<?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\ArrayCollection;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\Query\Parameter;
use Doctrine\ORM\QueryBuilder;
/**
* Useful methods for query builder (the Doctrine's QueryBuilder class)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class QueryBuilderUtility
{
/**
* 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();
if (empty($aliases)) {
return null;
}
return Arrays::getFirstElement($aliases);
}
/**
* Returns alias of given property joined in given query builder
* If 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
* @param string $property Name of property that maybe is joined
* @return null|string
*/
public static function getJoinedPropertyAlias(QueryBuilder $queryBuilder, $property)
{
$joins = $queryBuilder->getDQLPart('join');
if (empty($joins)) {
return null;
}
$patternTemplate = '/^.+\.%s$/'; // e.g. "SomeThing.PropertyName"
$pattern = sprintf($patternTemplate, $property);
foreach ($joins as $joinExpressions) {
/* @var $expression Join */
foreach ($joinExpressions as $expression) {
$joinedProperty = $expression->getJoin();
if (preg_match($pattern, $joinedProperty)) {
return $expression->getAlias();
}
}
}
return null;
}
/**
* Sets the WHERE criteria in given query builder
*
* @param QueryBuilder $queryBuilder The query builder
* @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
* @return QueryBuilder
*
* Example of the $criteria argument:
* [
* 'created_at' => [
* '2012-11-17 20:00',
* '<'
* ],
* 'title' => [
* '%test%',
* 'like'
* ],
* '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)
{
/*
* No entities found?
* 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;
}
/**
* 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();
}
$queryBuilder->setParameter($name, $value);
}
}
return $queryBuilder;
}
}

View File

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

View File

@@ -0,0 +1,726 @@
<?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\IncorrectColorHexLengthException;
use Meritoo\Common\Exception\InvalidColorHexValueException;
/**
* Useful regular expressions methods
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Regex
{
/**
* Patterns used to validate / verify values
*
* @var array
*/
private static $patterns = [
'email' => '/[\w-]{2,}@[\w-]+\.[\w]{2,}+/',
'phone' => '/^\+?[0-9 ]+$/',
'camelCasePart' => '/([a-z]|[A-Z]){1}[a-z]*/',
'urlProtocol' => '/^([a-z]+:\/\/)',
'urlDomain' => '([\da-z\.-]+)\.([a-z\.]{2,6})(\/)?([\w\.\-]*)?(\?)?([\w \.\-\/=&]*)\/?$/i',
'letterOrDigit' => '/[a-zA-Z0-9]+/',
'htmlEntity' => '/&[a-z0-9]+;/',
'fileName' => '/.+\.\w+$/',
'isQuoted' => '/^[\'"]{1}.+[\'"]{1}$/',
'windowsBasedPath' => '/^[A-Z]{1}:\\\.*$/',
'money' => '/^[-+]?\d+([\.,]{1}\d*)?$/',
'color' => '/^[a-f0-9]{6}$/i',
];
/**
* Returns information if given e-mail address is valid
*
* @param string $email E-mail address to validate / verify
* @return bool
*
* Examples:
* a) valid e-mails:
* - ni@g-m.pl
* - ni@gm.pl
* - ni@g_m.pl
* b) invalid e-mails:
* - ni@g-m.p
* - n@g-m.pl
*/
public static function isValidEmail($email)
{
$pattern = self::getEmailPattern();
return (bool)preg_match($pattern, $email);
}
/**
* Returns information if given tax ID (in polish: NIP) is valid
*
* @param string $taxidString Tax ID (NIP) string
* @return bool
*/
public static function isValidTaxid($taxidString)
{
if (!empty($taxidString)) {
$weights = [
6,
5,
7,
2,
3,
4,
5,
6,
7,
];
$taxid = preg_replace('/[\s-]/', '', $taxidString);
$sum = 0;
if (strlen($taxid) == 10 && is_numeric($taxid)) {
for ($x = 0; $x <= 8; ++$x) {
$sum += $taxid[$x] * $weights[$x];
}
if ((($sum % 11) % 10) == $taxid[9]) {
return true;
}
}
}
return false;
}
/**
* Returns information if given url address is valid
*
* @param string $url The url to validate / verify
* @param bool $requireProtocol (optional) If is set to true, the protocol is required to be passed in the url.
* Otherwise - not.
* @return bool
*/
public static function isValidUrl($url, $requireProtocol = false)
{
$pattern = self::getUrlPattern($requireProtocol);
return (bool)preg_match($pattern, $url);
}
/**
* Returns information if given phone number is valid
*
* @param string $phoneNumber The phone number to validate / verify
* @return bool
*/
public static function isValidPhoneNumber($phoneNumber)
{
$pattern = self::getPhoneNumberPattern();
return (bool)preg_match($pattern, $phoneNumber);
}
/**
* Returns array values that matches given pattern (or values that keys matches)
*
* @param string $pattern Pattern to match
* @param array $dataArray The array
* @param bool $itsKeyPattern (optional) If is set to true, keys are checks if they match pattern. Otherwise -
* values are checks.
* @return array
*/
public static function getArrayValuesByPattern($pattern, $dataArray, $itsKeyPattern = false)
{
if ($itsKeyPattern) {
$effect = [];
if (!empty($dataArray)) {
$matches = [];
foreach ($dataArray as $key => $value) {
if (preg_match($pattern, $key, $matches)) {
$effect[$key] = $value;
}
}
}
return $effect;
}
return preg_grep($pattern, $dataArray);
}
/**
* Filters array by given expression and column
*
* Expression can be simple compare expression, like ' == 2', or regular expression.
* Returns filtered array.
*
* @param array $array The array that should be filtered
* @param string $arrayColumnKey Column name
* @param string $filterExpression Filter expression, e.g. '== 2' or '!= \'home\''
* @param bool $itsRegularExpression (optional) If is set to true, means that filter expression is a
* regular expression
* @return array
*/
public static function arrayFilter($array, $arrayColumnKey, $filterExpression, $itsRegularExpression = false)
{
$effect = [];
if (!empty($array)) {
$effect = $array;
foreach ($effect as $key => &$item) {
if (isset($item[$arrayColumnKey])) {
$value = $item[$arrayColumnKey];
if ($itsRegularExpression) {
$matches = [];
$pattern = '|' . $filterExpression . '|';
$matchesCount = preg_match($pattern, $value, $matches);
$remove = $matchesCount == 0;
} else {
if ($value == '') {
$value = '\'\'';
} elseif (is_string($value)) {
$value = '\'' . $value . '\'';
}
eval('$isTrue = ' . $value . $filterExpression . ';');
/* @var bool $isTrue */
$remove = !$isTrue;
}
if ($remove) {
unset($effect[$key]);
}
}
}
}
return $effect;
}
/**
* Perform regular expression match with many given patterns.
* Returns information if given $subject matches one or all given $patterns.
*
* @param array|string $patterns The patterns to match
* @param string $subject The string to check
* @param bool $mustAllMatch (optional) If is set to true, $subject must match all $patterns. Otherwise -
* not.
* @return bool
*/
public static function pregMultiMatch($patterns, $subject, $mustAllMatch = false)
{
$effect = false;
$patterns = Arrays::makeArray($patterns);
if (!empty($patterns)) {
if ($mustAllMatch) {
$effect = true;
}
foreach ($patterns as $pattern) {
$matches = [];
$matched = (bool)preg_match_all($pattern, $subject, $matches);
if ($mustAllMatch) {
$effect = $effect && $matched;
} else {
if ($matched) {
$effect = $matched;
break;
}
}
}
}
return $effect;
}
/**
* Returns string in human readable style generated from given camel case string / text
*
* @param string $string The string / text to convert
* @param bool $applyUpperCaseFirst (optional) If is set to true, first word / element from the converted
* string is uppercased. Otherwise - not.
* @return string
*/
public static function camelCase2humanReadable($string, $applyUpperCaseFirst = false)
{
$parts = self::getCamelCaseParts($string);
if (!empty($parts)) {
$elements = [];
foreach ($parts as $part) {
$elements[] = strtolower($part);
}
$string = implode(' ', $elements);
if ($applyUpperCaseFirst) {
$string = ucfirst($string);
}
}
return $string;
}
/**
* Returns parts of given camel case string / text
*
* @param string $string The string / text to retrieve parts
* @return array
*/
public static function getCamelCaseParts($string)
{
$pattern = self::getCamelCasePartPattern();
$matches = [];
preg_match_all($pattern, $string, $matches);
return $matches[0];
}
/**
* Returns simple, lowercase string generated from given camel case string / text
*
* @param string $string The string / text to convert
* @param string $separator (optional) Separator used to concatenate parts of the string, e.g. '-' or '_'
* @param bool $applyLowercase (optional) If is set to true, returned string will be lowercased. Otherwise - not.
* @return string
*/
public static function camelCase2simpleLowercase($string, $separator = '', $applyLowercase = true)
{
$parts = self::getCamelCaseParts($string);
if (!empty($parts)) {
$string = implode($separator, $parts);
if ($applyLowercase) {
$string = strtolower($string);
}
}
return $string;
}
/**
* Returns pattern used to validate / verify or get e-mail address
*
* @return string
*/
public static function getEmailPattern()
{
return self::$patterns['email'];
}
/**
* Returns pattern used to validate / verify or get phone number
*
* @return string
*/
public static function getPhoneNumberPattern()
{
return self::$patterns['phone'];
}
/**
* Returns pattern used to validate / verify or get camel case parts of string
*
* @return string
*/
public static function getCamelCasePartPattern()
{
return self::$patterns['camelCasePart'];
}
/**
* Returns pattern used to validate / verify or get url address
*
* @param bool $requireProtocol (optional) If is set to true, the protocol is required to be passed in the url.
* Otherwise - not.
* @return string
*/
public static function getUrlPattern($requireProtocol = false)
{
$urlProtocol = self::$patterns['urlProtocol'];
$urlDomain = self::$patterns['urlDomain'];
$protocolPatternPart = '?';
if ($requireProtocol) {
$protocolPatternPart = '';
}
return sprintf('%s%s%s', $urlProtocol, $protocolPatternPart, $urlDomain);
}
/**
* Returns information if given path is sub-path of another path, e.g. path file is owned by path of directory
*
* @param string $subPath Path to verify, probably sub-path
* @param string $path Main / parent path
* @return bool
*/
public static function isSubPathOf($subPath, $path)
{
/*
* Empty path?
* Nothing to do
*/
if (empty($path) || empty($subPath)) {
return false;
}
/*
* I have to escape all slashes (directory separators): "/" -> "\/"
*/
$prepared = preg_quote($path, '/');
/*
* Slash at the ending is optional
*/
if (self::endsWith($path, '/')) {
$prepared .= '?';
}
$pattern = sprintf('/^%s.*/', $prepared);
return (bool)preg_match($pattern, $subPath);
}
/**
* Returns pattern used to validate / verify letter or digit
*
* @return string
*/
public static function getLetterOrDigitPattern()
{
return self::$patterns['letterOrDigit'];
}
/**
* Returns information if given character is a letter or digit
*
* @param string $char Character to check
* @return bool
*/
public static function isLetterOrDigit($char)
{
$pattern = self::getLetterOrDigitPattern();
return is_scalar($char) && (bool)preg_match($pattern, $char);
}
/**
* Returns information if the string starts with given beginning / characters
*
* @param string $string String to check
* @param string $beginning The beginning of string, one or more characters
* @return bool
*/
public static function startsWith($string, $beginning)
{
if (!empty($string) && !empty($beginning)) {
if (strlen($beginning) == 1 && !self::isLetterOrDigit($beginning)) {
$beginning = '\\' . $beginning;
}
$pattern = sprintf('|^%s|', $beginning);
return (bool)preg_match($pattern, $string);
}
return false;
}
/**
* Returns information if the string ends with given ending / characters
*
* @param string $string String to check
* @param string $ending The ending of string, one or more characters
* @return bool
*/
public static function endsWith($string, $ending)
{
if (strlen($ending) == 1 && !self::isLetterOrDigit($ending)) {
$ending = '\\' . $ending;
}
return (bool)preg_match('|' . $ending . '$|', $string);
}
/**
* Returns information if the string starts with directory's separator
*
* @param string $string String that may contain a directory's separator at the start / beginning
* @param string $separator (optional) The directory's separator, e.g. "/". If is empty (not provided), system's
* separator is used.
* @return bool
*/
public static function startsWithDirectorySeparator($string, $separator = '')
{
if (empty($separator)) {
$separator = DIRECTORY_SEPARATOR;
}
return self::startsWith($string, $separator);
}
/**
* Returns information if the string ends with directory's separator
*
* @param string $text String that may contain a directory's separator at the end
* @param string $separator (optional) The directory's separator, e.g. "/". If is empty (not provided), system's
* separator is used.
* @return string
*/
public static function endsWithDirectorySeparator($text, $separator = '')
{
if (empty($separator)) {
$separator = DIRECTORY_SEPARATOR;
}
return self::endsWith($text, $separator);
}
/**
* Returns information if uri contains parameter
*
* @param string $uri Uri string (e.g. $_SERVER['REQUEST_URI'])
* @param string $parameterName Uri parameter name
* @return bool
*/
public static function isSetUriParameter($uri, $parameterName)
{
return (bool)preg_match('|[?&]{1}' . $parameterName . '=|', $uri); // e.g. ?name=phil&type=4 -> '$type='
}
/**
* Returns pattern used to validate / verify html entity
*
* @return string
*/
public static function getHtmlEntityPattern()
{
return self::$patterns['htmlEntity'];
}
/**
* Returns information if the string contains html entities
*
* @param string $string String to check
* @return bool
*/
public static function containsEntities($string)
{
$pattern = self::getHtmlEntityPattern();
return (bool)preg_match_all($pattern, $string);
}
/**
* Returns information if one string contains another string
*
* @param string $haystack The string to search in
* @param string $needle The string to be search for
* @return bool
*/
public static function contains($haystack, $needle)
{
if (strlen($needle) == 1 && !self::isLetterOrDigit($needle)) {
$needle = '\\' . $needle;
}
return (bool)preg_match('|.*' . $needle . '.*|', $haystack);
}
/**
* Returns pattern used to validate / verify name of file
*
* @return string
*/
public static function getFileNamePattern()
{
return self::$patterns['fileName'];
}
/**
* Returns information if given name of file is a really name of file.
* Verifies if given name contains a dot and an extension, e.g. "My File 001.jpg".
*
* @param string $fileName Name of file to check. It may be path of file also.
* @return bool
*/
public static function isFileName($fileName)
{
$pattern = self::getFileNamePattern();
return (bool)preg_match($pattern, $fileName);
}
/**
* Returns pattern used to validate / verify if value is quoted (by apostrophes or quotation marks)
*
* @return string
*/
public static function getIsQuotedPattern()
{
return self::$patterns['isQuoted'];
}
/**
* Returns information if given value is quoted (by apostrophes or quotation marks)
*
* @param mixed $value The value to check
* @return bool
*/
public static function isQuoted($value)
{
$pattern = self::getIsQuotedPattern();
return is_scalar($value) && (bool)preg_match($pattern, $value);
}
/**
* Returns pattern used to validate / verify if given path is a Windows-based path, e.g. "C:\path\to\file.jpg"
*
* @return string
*/
public static function getWindowsBasedPathPattern()
{
return self::$patterns['windowsBasedPath'];
}
/**
* Returns information if given path is a Windows-based path, e.g. "C:\path\to\file.jpg"
*
* @param string $path The path to verify
* @return bool
*/
public static function isWindowsBasedPath($path)
{
$pattern = self::getWindowsBasedPathPattern();
return (bool)preg_match($pattern, $path);
}
/**
* Returns information if given NIP number is valid
*
* @param string $nip A given NIP number
* @return bool
*
* @see https://pl.wikipedia.org/wiki/NIP#Znaczenie_numeru
*/
public static function isValidNip($nip)
{
$nip = preg_replace('/[^0-9]/', '', $nip);
$invalidNips = [
'1234567890',
'0000000000',
];
if (!preg_match('/^[0-9]{10}$/', $nip) || in_array($nip, $invalidNips)) {
return false;
}
$sum = 0;
$weights = [
6,
5,
7,
2,
3,
4,
5,
6,
7,
];
for ($i = 0; $i < 9; ++$i) {
$sum += $weights[$i] * $nip[$i];
}
$modulo = $sum % 11;
$numberControl = ($modulo == 10) ? 0 : $modulo;
return $numberControl == $nip[9];
}
/**
* Returns pattern used to validate / verify if given value is money-related value
*
* @return string
*/
public static function getMoneyPattern()
{
return self::$patterns['money'];
}
/**
* Returns information if given value is valid money-related value
*
* @param mixed $value Value to verify
* @return bool
*/
public static function isValidMoneyValue($value)
{
$pattern = self::getMoneyPattern();
return (bool)preg_match($pattern, $value);
}
/**
* Returns valid given hexadecimal value of color.
* If the value is invalid, throws an exception or returns false.
*
* @param string $color Color to verify
* @param bool $throwException (optional) If is set to true, throws an exception if given color is invalid
* (default behaviour). Otherwise - not.
* @return string|bool
*
* @throws IncorrectColorHexLengthException
* @throws InvalidColorHexValueException
*/
public static function getValidColorHexValue($color, $throwException = true)
{
$color = Miscellaneous::replace($color, '/#/', '');
$length = strlen($color);
if ($length === 3) {
$color = Miscellaneous::replace($color, '/(.)(.)(.)/', '$1$1$2$2$3$3');
} else {
if ($length !== 6) {
if ($throwException) {
throw new IncorrectColorHexLengthException($color);
}
return false;
}
}
$pattern = self::$patterns['color'];
$match = (bool)preg_match($pattern, $color);
if (!$match) {
if ($throwException) {
throw new InvalidColorHexValueException($color);
}
return false;
}
return strtolower($color);
}
}

View File

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

View File

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

View File

@@ -0,0 +1,310 @@
<?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 uri methods (only static functions)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Uri
{
/**
* Returns full uri string
*
* @param bool $withoutHost (optional) If is set to true, means that host / server name is omitted
* @return string
*/
public static function getFullUri($withoutHost = false)
{
$effect = Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'REQUEST_URI');
if ($withoutHost) {
return $effect;
}
return self::getServerNameOrIp(true) . $effect;
}
/**
* Returns server name or IP address
*
* @param bool $withProtocol (optional) If is set to true, protocol name is included. Otherwise isn't.
* @return string
*/
public static function getServerNameOrIp($withProtocol = false)
{
$protocol = '';
if ($withProtocol) {
$protocol .= self::getProtocolName() . '://';
}
return $protocol . Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'HTTP_HOST');
}
/**
* Returns protocol name
*
* @return string
*/
public static function getProtocolName()
{
$effect = '';
$matches = [];
$protocolData = Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'SERVER_PROTOCOL'); // e.g. HTTP/1.1
$matchCount = preg_match('|(.+)\/(.+)|', $protocolData, $matches);
/*
* $matches[1] - protocol name, e.g. HTTP
* $matches[2] - protocol version, e.g. 1.1
*/
if ($matchCount > 0) {
$effect = strtolower($matches[1]);
}
return $effect;
}
/**
* Returns http referer uri
*
* @return string
*/
public static function getRefererUri()
{
$effect = '';
if (filter_has_var(INPUT_SERVER, 'HTTP_REFERER')) {
$effect = Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'HTTP_REFERER');
}
return $effect;
}
/**
* Returns user's IP address
*
* @return string
*/
public static function getUserAddressIp()
{
return Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'REMOTE_ADDR');
}
/**
* Returns name and version of user's web browser
*
* @param bool $withVersion (optional) If is set to true, version of the browser is returned too. Otherwise -
* name only.
* @return string
*/
public static function getUserWebBrowserName($withVersion = false)
{
$info = self::getUserWebBrowserInfo();
$knownBrowsers = [
'Firefox/([\d\.]+)$' => 'Mozilla Firefox',
'OPR/([\d\.]+)$' => 'Opera',
'Chrome/([\d\.]+)$' => 'Google Chrome',
'Safari/([\d\.]+)$' => 'Apple Safari',
];
foreach ($knownBrowsers as $pattern => $browserName) {
$matches = [];
$matchCount = preg_match(sprintf('|%s|', $pattern), $info, $matches);
if ($matchCount > 0) {
if ($withVersion) {
$version = $matches[1];
return sprintf('%s %s', $browserName, $version);
}
return $browserName;
}
}
return '';
}
/**
* Returns user's web browser information
*
* @return string
*
* Examples:
* - Mozilla Firefox:
* 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:34.0) Gecko/20100101 Firefox/34.0'
*
* - Google Chrome:
* 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95
* Safari/537.36'
*
* - Opera:
* 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65
* Safari/537.36 OPR/26.0.1656.24'
*
* - Apple Safari:
* 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5 (KHTML, like Gecko) Version/8.0.2
* Safari/600.2.5'
*/
public static function getUserWebBrowserInfo()
{
return Miscellaneous::getSafelyGlobalVariable(INPUT_SERVER, 'HTTP_USER_AGENT');
}
/**
* Returns name of user's operating system
*
* @return string
*/
public static function getUserOperatingSystemName()
{
$info = self::getUserWebBrowserInfo();
$knownSystems = [
'Linux' => 'Linux',
'Win' => 'Windows',
'Mac' => 'Mac OS',
];
foreach ($knownSystems as $pattern => $systemName) {
$matches = [];
$matchCount = preg_match(sprintf('|%s|', $pattern), $info, $matches);
if ($matchCount > 0) {
return $systemName;
}
}
return '';
}
/**
* Returns information if running server is localhost
*
* @return bool
*/
public static function isServerLocalhost()
{
$serverNameOrIp = strtolower(self::getServerNameOrIp());
return in_array($serverNameOrIp, [
'localhost',
'127.0.0.1',
'127.0.1.1',
]);
}
/**
* Returns information if given url is external, from another server / domain
*
* @param string $url The url to check
* @return bool
*/
public static function isExternalUrl($url)
{
$currentUrl = self::getServerNameOrIp(true);
$url = self::replenishProtocol($url);
return !Regex::contains($currentUrl, $url);
}
/**
* Replenishes protocol in the given url
*
* @param string $url The url to check and replenish
* @param string $protocol (optional) The protocol which is replenished. If is empty, protocol of current request
* is used.
* @return string
*/
public static function replenishProtocol($url, $protocol = '')
{
/*
* Let's trim the url
*/
if (is_string($url)) {
$url = trim($url);
}
/*
* Url is not provided?
* Nothing to do
*/
if (empty($url)) {
return '';
}
/*
* It's a valid url?
* Let's return it
*/
if (Regex::isValidUrl($url, true)) {
return $url;
}
/*
* Protocol is not provided?
*/
if (empty($protocol)) {
$protocol = self::getProtocolName();
}
return sprintf('%s://%s', $protocol, $url);
}
/**
* Returns url to resource secured by given htpasswd login and password
*
* @param string $url A path / url to some resource, e.g. page, image, css file
* @param string $user (optional) User name used to log in
* @param string $password (optional) User password used to log in
* @return string
*/
public static function getSecuredUrl($url, $user = '', $password = '')
{
$protocol = self::getProtocolName();
$host = self::getServerNameOrIp();
if (!Regex::startsWith($url, '/')) {
$url = sprintf('/%s', $url);
}
$url = $host . $url;
if (!empty($user) && !empty($password)) {
$url = sprintf('%s:%s@%s', $user, $password, $url);
}
return sprintf('%s://%s', $protocol, $url);
}
/**
* Adds protocol to given url, if the url does not contain given protocol.
* Returns the new url.
*
* @param string $url Url string
* @param string $protocol (optional) Protocol string
* @return string
*/
public static function addProtocolToUrl($url, $protocol = 'http')
{
$pattern = sprintf('/^%s.*/', $protocol);
if ((bool)preg_match($pattern, $url)) {
return $url;
}
return sprintf('%s://%s', $protocol, $url);
}
}

View File

@@ -0,0 +1,54 @@
<?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 DOMDocument;
use DOMXPath;
use SimpleXMLElement;
/**
* Useful XML-related methods (only static functions)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class Xml
{
/**
* Merges nodes of given elements.
* Returns merged instance of SimpleXMLElement.
*
* @param SimpleXMLElement $element1 First element to merge
* @param SimpleXMLElement $element2 Second element to merge
* @return SimpleXMLElement
*/
public static function mergeNodes(SimpleXMLElement $element1, SimpleXMLElement $element2)
{
$document1 = new DOMDocument();
$document2 = new DOMDocument();
$document1->loadXML($element1->asXML());
$document2->loadXML($element2->asXML());
$path = new DOMXPath($document2);
$query = $path->query('/*/*');
$nodesCount = $query->length;
if ($nodesCount == 0) {
return $element1;
}
for ($i = 0; $i < $nodesCount; ++$i) {
$node = $document1->importNode($query->item($i), true);
$document1->documentElement->appendChild($node);
}
return simplexml_import_dom($document1);
}
}

View File

@@ -0,0 +1,90 @@
<?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\Tests\Exception\Base;
use Meritoo\Common\Exception\Base\UnknownTypeException;
use Meritoo\Common\Type\Base\BaseType;
/**
* Tests of the exception used while type of something is unknown
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class UnknownTypeExceptionTest extends \PHPUnit_Framework_TestCase
{
public function testWithoutException()
{
self::assertEquals('Test 2', (new TestService())->getTranslatedType('test_2'));
}
public function testTheException()
{
$this->expectException(UnknownTestTypeException::class);
self::assertEmpty((new TestService())->getTranslatedType('test_3'));
}
}
/**
* Type of something (for testing purposes)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class TestType extends BaseType
{
const TEST_1 = 'test_1';
const TEST_2 = 'test_2';
}
/**
* An exception used while type of something is unknown (for testing purposes)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class UnknownTestTypeException extends UnknownTypeException
{
/**
* Class constructor
*
* @param int|string $unknownType The unknown type of something (for testing purposes)
*/
public function __construct($unknownType)
{
parent::__construct($unknownType, new TestType(), 'type of something used for testing');
}
}
/**
* Service used together with type of something (for testing purposes)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class TestService
{
/**
* Returns translated type (for testing purposes)
*
* @param string $type Type of something (for testing purposes)
* @return string
*
* @throws UnknownTestTypeException
*/
public function getTranslatedType($type)
{
if ((new TestType())->isCorrectType($type)) {
return ucfirst(str_replace('_', ' ', $type));
}
throw new UnknownTestTypeException($type);
}
}

View File

@@ -0,0 +1,199 @@
<?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\Tests\Type\Base;
use Generator;
use Meritoo\Common\Type\Base\BaseType;
/**
* Tests of the base / abstract type of something
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class BaseTypeTest extends \PHPUnit_Framework_TestCase
{
/**
* @param BaseType $type Type of something
* @param array $expectedTypes Expected concrete types of given instance of type
*
* @dataProvider provideType
*/
public function testGetAll(BaseType $type, array $expectedTypes)
{
$all = $type->getAll();
self::assertEquals($expectedTypes, $all);
}
/**
* @param BaseType $type Type of something
* @param string $toVerifyType Concrete type to verify (of given instance of type)
* @param bool $isCorrect Expected information if given type is correct
*
* @dataProvider provideTypeWithConcreteType
*/
public function testIsCorrectType(BaseType $type, $toVerifyType, $isCorrect)
{
self::assertEquals($isCorrect, $type->isCorrectType($toVerifyType));
}
/**
* Provides type of something for testing the getAll() method
*
* @return Generator
*/
public function provideType()
{
yield[
new TestEmptyType(),
[],
];
yield[
new TestType(),
[
'TEST_1' => TestType::TEST_1,
'TEST_2' => TestType::TEST_2,
],
];
}
/**
* Provides type of something for testing the isCorrectType() method
*
* @return Generator
*/
public function provideTypeWithConcreteType()
{
yield[
new TestEmptyType(),
null,
false,
];
yield[
new TestEmptyType(),
false,
false,
];
yield[
new TestEmptyType(),
true,
false,
];
yield[
new TestEmptyType(),
'',
false,
];
yield[
new TestEmptyType(),
0,
false,
];
yield[
new TestEmptyType(),
1,
false,
];
yield[
new TestEmptyType(),
'lorem',
false,
];
yield[
new TestType(),
null,
false,
];
yield[
new TestType(),
false,
false,
];
yield[
new TestType(),
true,
false,
];
yield[
new TestType(),
'',
false,
];
yield[
new TestType(),
0,
false,
];
yield[
new TestType(),
1,
false,
];
yield[
new TestType(),
'lorem',
false,
];
yield[
new TestType(),
'test',
false,
];
yield[
new TestType(),
TestType::TEST_1,
true,
];
yield[
new TestType(),
TestType::TEST_2,
true,
];
}
}
/**
* Empty type of something used for testing
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class TestEmptyType extends BaseType
{
}
/**
* Type of something used for testing
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class TestType extends BaseType
{
const TEST_1 = 'test_1';
const TEST_2 = 'test_2';
}

View File

@@ -0,0 +1,106 @@
<?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\Tests\Type;
use Generator;
use Meritoo\Common\Type\DatePartType;
/**
* Tests of the type of date part, e.g. "year"
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class DatePartTypeTest extends \PHPUnit_Framework_TestCase
{
public function testGetAll()
{
$expectedTypes = [
'DAY' => DatePartType::DAY,
'HOUR' => DatePartType::HOUR,
'MINUTE' => DatePartType::MINUTE,
'MONTH' => DatePartType::MONTH,
'SECOND' => DatePartType::SECOND,
'YEAR' => DatePartType::YEAR,
];
$all = (new DatePartType())->getAll();
self::assertEquals($expectedTypes, $all);
}
/**
* @param string $toVerifyType Concrete type to verify (of given instance of type)
* @param bool $isCorrect Expected information if given type is correct
*
* @dataProvider provideConcreteType
*/
public function testIsCorrectType($toVerifyType, $isCorrect)
{
$type = new DatePartType();
self::assertEquals($isCorrect, $type->isCorrectType($toVerifyType));
}
/**
* Provides type of something for testing the isCorrectType() method
*
* @return Generator
*/
public function provideConcreteType()
{
yield[
'',
false,
];
yield[
null,
false,
];
yield[
0,
false,
];
yield[
1,
false,
];
yield[
'day',
true,
];
yield[
'hour',
true,
];
yield[
'minute',
true,
];
yield[
'month',
true,
];
yield[
'second',
true,
];
yield[
'year',
true,
];
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
<?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\Tests\Utilities;
use Meritoo\Common\Utilities\Bundle;
/**
* Tests of the useful methods for bundle
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class BundleTest extends \PHPUnit_Framework_TestCase
{
public function testGetBundleViewPathEmptyPathAndBundle()
{
self::assertNull(Bundle::getBundleViewPath('', ''));
self::assertNull(Bundle::getBundleViewPath('test', ''));
self::assertNull(Bundle::getBundleViewPath('', 'test'));
}
public function testGetBundleViewPathWithDefaultExtension()
{
self::assertEquals('Lorem:Ipsum.html.twig', Bundle::getBundleViewPath('Ipsum', 'Lorem'));
self::assertEquals('LobortisTincidunt:FusceElementum.html.twig', Bundle::getBundleViewPath('FusceElementum', 'LobortisTincidunt'));
}
public function testGetBundleViewPathWithCustomExtension()
{
self::assertNull(Bundle::getBundleViewPath('Ipsum', 'Lorem', ''));
self::assertEquals('Lorem:Ipsum.js.twig', Bundle::getBundleViewPath('Ipsum', 'Lorem', 'js.twig'));
}
}

View File

@@ -0,0 +1,87 @@
<?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\Tests\Utilities;
use Meritoo\Common\Utilities\Composer;
use Meritoo\Common\Utilities\TestCase;
/**
* Tests of the useful Composer-related methods
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class ComposerTest extends TestCase
{
/**
* Path of existing composer.json used as source of data for tests
*
* @var string
*/
private $composerJsonPath;
/**
* @param string $composerJsonPath Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetValueNotExistingComposerJson($composerJsonPath)
{
self::assertNull(Composer::getValue($composerJsonPath, ''));
self::assertNull(Composer::getValue('not/existing/composer.json', ''));
}
/**
* @param string $nodeName Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetValueNotExistingNode($nodeName)
{
self::assertNull(Composer::getValue($this->composerJsonPath, $nodeName));
self::assertNull(Composer::getValue($this->composerJsonPath, 'not_existing_node'));
}
/**
* @param string $nodeName Name of existing node
* @param string $nodeValue Value of existing node
*
* @dataProvider getExistingNode
*/
public function testGetValueExistingNode($nodeName, $nodeValue)
{
self::assertEquals($nodeValue, Composer::getValue($this->composerJsonPath, $nodeName));
}
/**
* Provides names and values of existing nodes
*
* @return \Generator
*/
public function getExistingNode()
{
yield[
'name',
'test/test',
];
yield[
'version',
'1.0.2',
];
}
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->composerJsonPath = $this->getFilePathToTests(Composer::FILE_NAME_MAIN);
}
}

View File

@@ -0,0 +1,261 @@
<?php
namespace Meritoo\Common\Tests\Utilities;
use DateTime;
use Generator;
use Meritoo\Common\Utilities\DatePeriod;
use Meritoo\Common\Utilities\TestCase;
/**
* Tests of date's period
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class DatePeriodTest extends TestCase
{
/**
* @param DateTime $startDate (optional) Start date of period
* @param DateTime $endDate (optional) End date of period
*
* @dataProvider provideDatePeriod
*/
public function testConstruct(DateTime $startDate = null, DateTime $endDate = null)
{
$period = new DatePeriod($startDate, $endDate);
self::assertEquals($startDate, $period->getStartDate());
self::assertEquals($endDate, $period->getEndDate());
}
/**
* @param DateTime $startDate (optional) Start date of period
* @param DateTime $endDate (optional) End date of period
*
* @dataProvider provideDatePeriod
*/
public function testGettersAndSetters(DateTime $startDate = null, DateTime $endDate = null)
{
$period = new DatePeriod();
$period->setStartDate($startDate);
self::assertEquals($startDate, $period->getStartDate());
$period->setEndDate($endDate);
self::assertEquals($endDate, $period->getEndDate());
}
/**
* @param mixed $period Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testIsCorrectPeriodEmptyPeriod($period)
{
self::assertFalse(DatePeriod::isCorrectPeriod($period));
}
/**
* @param int $period Incorrect period to verify
* @dataProvider provideIncorrectPeriod
*/
public function testIsCorrectPeriodIncorrectPeriod($period)
{
self::assertFalse(DatePeriod::isCorrectPeriod($period));
}
/**
* @param int $period The period to verify
* @dataProvider providePeriod
*/
public function testIsCorrectPeriod($period)
{
self::assertTrue(DatePeriod::isCorrectPeriod($period));
}
/**
* @param DatePeriod $period The date period to verify
* @param string $format Format used to format the date
*
* @dataProvider provideDatePeriodAndIncorrectDateFormat
*/
public function testGetFormattedDateIncorrectDateFormat(DatePeriod $period, $format)
{
self::assertEquals('', $period->getFormattedDate($format));
}
/**
* @param DatePeriod $period The date period to verify
* @param string $format Format used to format the date
* @param bool $startDate If is set to true, start date is formatted. Otherwise - end date.
* @param string $expected Expected, formatted date
*
* @dataProvider provideDatePeriodAndDateFormat
*/
public function testGetFormattedDate(DatePeriod $period, $format, $startDate, $expected)
{
self::assertEquals($expected, $period->getFormattedDate($format, $startDate));
}
/**
* Provides the start and end date of date period
*
* @return Generator
*/
public function provideDatePeriod()
{
$startDate = new DateTime('2001-01-01');
$endDate = new DateTime('2002-02-02');
yield[
null,
null,
];
yield[
$startDate,
$startDate,
null,
];
yield[
null,
null,
$endDate,
];
yield[
$startDate,
$endDate,
];
}
/**
* Provides incorrect period
*
* @return Generator
*/
public function provideIncorrectPeriod()
{
yield[-1];
yield[0];
yield[10];
}
/**
* Provides period to verify
*
* @return Generator
*/
public function providePeriod()
{
yield[DatePeriod::LAST_WEEK];
yield[DatePeriod::THIS_WEEK];
yield[DatePeriod::NEXT_WEEK];
yield[DatePeriod::LAST_MONTH];
yield[DatePeriod::THIS_MONTH];
yield[DatePeriod::NEXT_MONTH];
yield[DatePeriod::LAST_YEAR];
yield[DatePeriod::THIS_YEAR];
yield[DatePeriod::NEXT_YEAR];
}
/**
* Provides period and incorrect format of date to verify
*
* @return Generator
*/
public function provideDatePeriodAndIncorrectDateFormat()
{
$startDate = new DateTime('2001-01-01');
$endDate = new DateTime('2002-02-02');
yield[
new DatePeriod($startDate, $endDate),
'',
];
yield[
new DatePeriod($startDate, $endDate),
null,
];
yield[
new DatePeriod($startDate, $endDate),
false,
];
}
/**
* Provides period and format of date to verify
*
* @return Generator
*/
public function provideDatePeriodAndDateFormat()
{
$startDate = new DateTime('2001-01-01');
$endDate = new DateTime('2002-02-02');
/*
* For start date
*/
yield[
new DatePeriod($startDate, $endDate),
'Y',
true,
'2001',
];
yield[
new DatePeriod($startDate, $endDate),
'D',
true,
'Mon',
];
yield[
new DatePeriod($startDate, $endDate),
'Y-m-d',
true,
'2001-01-01',
];
yield[
new DatePeriod($startDate, $endDate),
'Y-m-d H:i',
true,
'2001-01-01 00:00',
];
/*
* For end date
*/
yield[
new DatePeriod($startDate, $endDate),
'Y',
false,
'2002',
];
yield[
new DatePeriod($startDate, $endDate),
'D',
false,
'Sat',
];
yield[
new DatePeriod($startDate, $endDate),
'Y-m-d',
false,
'2002-02-02',
];
yield[
new DatePeriod($startDate, $endDate),
'Y-m-d H:i',
false,
'2002-02-02 00:00',
];
}
}

View File

@@ -0,0 +1,748 @@
<?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\Tests\Utilities;
use DateInterval;
use DateTime;
use Generator;
use Meritoo\Common\Exception\Date\IncorrectDatePartException;
use Meritoo\Common\Utilities\Date;
use Meritoo\Common\Utilities\TestCase;
/**
* Tests of the Date methods (only static functions)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class DateTest extends TestCase
{
/**
* @param mixed $value Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetDateTimeEmptyValue($value)
{
self::assertFalse(Date::getDateTime($value));
}
/**
* @param mixed $value Incorrect source of DateTime
* @dataProvider provideIncorrectDateTimeValue
*/
public function testGetDateTimeIncorrectValue($value)
{
self::assertFalse(Date::getDateTime($value));
}
/**
* @param bool $value The value which maybe is a date
* @dataProvider provideBooleanValue
*/
public function testGetDateTimeBoolean($value)
{
self::assertFalse(Date::getDateTime($value));
}
/**
* @param string $relativeFormat Relative / compound format of DateTime
* @dataProvider provideDateTimeRelativeFormat
*/
public function testGetDateTimeRelativeFormats($relativeFormat)
{
/*
* Values based on relative / compound formats, but... without explicitly declaring them as compound
* (2nd argument set to false by default)
*
* http://php.net/manual/en/datetime.formats.compound.php
*/
self::assertFalse(Date::getDateTime($relativeFormat));
/*
* Values based on relative / compound formats
* http://php.net/manual/en/datetime.formats.compound.php
*/
self::assertInstanceOf(DateTime::class, Date::getDateTime($relativeFormat, true));
}
/**
* @param DateTime $dateTime Instance of DateTime class
* @dataProvider provideDateTimeInstance
*/
public function testGetDateTimeInstanceDateTime(DateTime $dateTime)
{
self::assertInstanceOf(DateTime::class, Date::getDateTime($dateTime));
}
public function testGetDateTimeConcreteDates()
{
/*
* Using the standard date format provided by the tested method
*/
self::assertInstanceOf(DateTime::class, Date::getDateTime('2015-03-20'));
/*
* Using custom date format
*/
self::assertInstanceOf(DateTime::class, Date::getDateTime('2015-03-20 11:30', false, 'Y-m-d H:i'));
self::assertInstanceOf(DateTime::class, Date::getDateTime('20.03.2015', false, 'd.m.Y'));
}
/**
* @param mixed $value Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testIsValidDateEmptyDates($value)
{
self::assertFalse(Date::isValidDate($value));
}
/**
* @param mixed $value Incorrect source of DateTime
* @dataProvider provideIncorrectDateTimeValue
*/
public function testIsValidDateIncorrectDates($value)
{
self::assertFalse(Date::isValidDate($value));
}
public function testIsValidDateValidDates()
{
self::assertTrue(Date::isValidDate('2017-01-01'));
self::assertTrue(Date::isValidDate('2017-01-01 10:30', true));
self::assertTrue(Date::isValidDate('2017-01-01 14:00', true));
self::assertTrue(Date::isValidDate(new DateTime()));
self::assertTrue(Date::isValidDate(new DateTime('now')));
self::assertTrue(Date::isValidDate(new DateTime('tomorrow')));
self::assertTrue(Date::isValidDate(new DateTime('m')));
}
/**
* @param mixed $value Empty source of date format
* @dataProvider provideEmptyValue
*/
public function testIsValidDateFormatEmptyFormats($value)
{
self::assertFalse(Date::isValidDateFormat($value));
}
/**
* @param mixed $format Invalid format of date
* @dataProvider provideInvalidDateFormats
*/
public function testIsValidDateFormatInvalidFormats($format)
{
self::assertFalse(Date::isValidDateFormat($format));
}
public function testIsValidDateFormatValidFormats()
{
self::assertTrue(Date::isValidDateFormat('Y'));
self::assertTrue(Date::isValidDateFormat('yy'));
self::assertTrue(Date::isValidDateFormat('M'));
self::assertTrue(Date::isValidDateFormat('i'));
self::assertTrue(Date::isValidDateFormat('l'));
self::assertTrue(Date::isValidDateFormat('l, d F'));
self::assertTrue(Date::isValidDateFormat('Y-m-d'));
self::assertTrue(Date::isValidDateFormat('H:i:s'));
self::assertTrue(Date::isValidDateFormat('Y/m/d H:i:s'));
}
/**
* @param mixed $value Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGenerateRandomTimeEmptyFormat($value)
{
self::assertNull(Date::generateRandomTime($value));
}
public function testGenerateRandomTimeIncorrectFormat()
{
self::assertNull(Date::generateRandomTime(','));
self::assertNull(Date::generateRandomTime(';'));
self::assertNull(Date::generateRandomTime('|'));
self::assertNull(Date::generateRandomTime('?'));
}
public function testGenerateRandomTimeDefaultFormat()
{
self::assertRegExp('/\d{2}:\d{2}:\d{2}/', Date::generateRandomTime());
}
public function testGenerateRandomTimeCustomFormat()
{
self::assertRegExp('/^0[1-9]{1}|1[0-2]{1}$/', Date::generateRandomTime('h')); // 01 through 12
self::assertRegExp('/^[0-5]?[0-9]$/', Date::generateRandomTime('i')); // 00 through 59
self::assertRegExp('/^[0-5]?[0-9]$/', Date::generateRandomTime('s')); // 00 through 59
self::assertRegExp('/^\d{2}:\d{2}$/', Date::generateRandomTime('H:i'));
self::assertRegExp('/^[1-9]|1[0-2]:\d{2}$/', Date::generateRandomTime('g:i'));
}
public function testGetCurrentDayOfWeek()
{
self::assertRegExp('/^[0-6]{1}$/', (string)Date::getCurrentDayOfWeek());
}
public function testGetCurrentDayOfWeekName()
{
$days = [
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
];
$pattern = sprintf('/^%s$/', implode('|', $days));
self::assertRegExp($pattern, Date::getCurrentDayOfWeekName());
}
/**
* @param int $year The year value
* @param int $month The month value
* @param int $day The day value
*
* @dataProvider provideIncorrectYearMonthDay
*/
public function testGetDayOfWeekIncorrectValues($year, $month, $day)
{
$this->expectException(IncorrectDatePartException::class);
self::assertEmpty(Date::getDayOfWeek($year, $month, $day));
}
/**
* @param int $year The year value
* @param int $month The month value
* @param int $day The day value
*
* @dataProvider provideYearMonthDay
*/
public function testGetDayOfWeek($year, $month, $day)
{
self::assertRegExp('/^[0-6]{1}$/', (string)Date::getDayOfWeek($year, $month, $day));
}
/**
* @param string|DateTime $dateStart The start date
* @param string|DateTime $dateEnd The end date
*
* @dataProvider provideEmptyDatesForDateDifference
*/
public function testGetDateDifferenceEmptyDates($dateStart, $dateEnd)
{
self::assertNull(Date::getDateDifference($dateStart, $dateEnd));
}
public function testGetDateDifferenceInvalidDates()
{
self::assertNull(Date::getDateDifference('2017-01-40', '2017-13-01'));
self::assertNull(Date::getDateDifference('xyz', 'lorem'));
}
public function testGetDateDifferenceOneDay()
{
/*
* Difference of 1 day
*/
$dateStart = '2017-01-01';
$dateEnd = '2017-01-02';
$effect = [
Date::DATE_DIFFERENCE_UNIT_YEARS => 0,
Date::DATE_DIFFERENCE_UNIT_MONTHS => 0,
Date::DATE_DIFFERENCE_UNIT_DAYS => 1,
Date::DATE_DIFFERENCE_UNIT_HOURS => 0,
Date::DATE_DIFFERENCE_UNIT_MINUTES => 0,
];
self::assertEquals($effect, Date::getDateDifference($dateStart, $dateEnd));
self::assertEquals($effect, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd)));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(1, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(1, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_DAYS));
/*
* Difference of 1 day (using the relative date format)
*/
$effect = [
Date::DATE_DIFFERENCE_UNIT_YEARS => 0,
Date::DATE_DIFFERENCE_UNIT_MONTHS => 0,
Date::DATE_DIFFERENCE_UNIT_DAYS => 1,
Date::DATE_DIFFERENCE_UNIT_HOURS => 0,
Date::DATE_DIFFERENCE_UNIT_MINUTES => 0,
];
self::assertEquals($effect, Date::getDateDifference(new DateTime('yesterday'), new DateTime('midnight')));
self::assertEquals(1, Date::getDateDifference(new DateTime('yesterday'), new DateTime('midnight'), Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(0, Date::getDateDifference(new DateTime('yesterday'), new DateTime('midnight'), Date::DATE_DIFFERENCE_UNIT_HOURS));
}
public function testGetDateDifferenceOneDayTwoHours()
{
/*
* Difference of 1 day, 2 hours and 15 minutes
*/
$dateStart = '2017-01-01 12:00';
$dateEnd = '2017-01-02 14:15';
$effect = [
Date::DATE_DIFFERENCE_UNIT_YEARS => 0,
Date::DATE_DIFFERENCE_UNIT_MONTHS => 0,
Date::DATE_DIFFERENCE_UNIT_DAYS => 1,
Date::DATE_DIFFERENCE_UNIT_HOURS => 2,
Date::DATE_DIFFERENCE_UNIT_MINUTES => 15,
];
self::assertEquals($effect, Date::getDateDifference($dateStart, $dateEnd));
self::assertEquals($effect, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd)));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(2, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(2, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(15, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MINUTES));
self::assertEquals(15, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MINUTES));
}
public function testGetDateDifferenceOneMonthFortyOneDays()
{
/*
* Difference of 1 month, 41 days, 4 hours and 30 minutes
*/
$dateStart = '2017-01-01 12:00';
$dateEnd = '2017-02-11 16:30';
$effect = [
Date::DATE_DIFFERENCE_UNIT_YEARS => 0,
Date::DATE_DIFFERENCE_UNIT_MONTHS => 1,
Date::DATE_DIFFERENCE_UNIT_DAYS => 41,
Date::DATE_DIFFERENCE_UNIT_HOURS => 4,
Date::DATE_DIFFERENCE_UNIT_MINUTES => 30,
];
self::assertEquals($effect, Date::getDateDifference($dateStart, $dateEnd));
self::assertEquals($effect, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd)));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(1, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(1, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(41, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(41, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(30, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MINUTES));
self::assertEquals(30, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MINUTES));
}
public function testGetDateDifferenceNoDifference()
{
/*
* No difference
*/
$dateStart = '2017-01-01 12:00';
$dateEnd = $dateStart;
$effect = [
Date::DATE_DIFFERENCE_UNIT_YEARS => 0,
Date::DATE_DIFFERENCE_UNIT_MONTHS => 0,
Date::DATE_DIFFERENCE_UNIT_DAYS => 0,
Date::DATE_DIFFERENCE_UNIT_HOURS => 0,
Date::DATE_DIFFERENCE_UNIT_MINUTES => 0,
];
self::assertEquals($effect, Date::getDateDifference($dateStart, $dateEnd));
self::assertEquals($effect, Date::getDateDifference(new DateTime(), new DateTime()));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference(new DateTime(), new DateTime(), Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(0, Date::getDateDifference(new DateTime(), new DateTime(), Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MINUTES));
self::assertEquals(0, Date::getDateDifference(new DateTime(), new DateTime(), Date::DATE_DIFFERENCE_UNIT_MINUTES));
}
/**
* @param mixed $invalidCount Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetDatesCollectionInvalidCount($invalidCount)
{
self::assertEquals([], Date::getDatesCollection(new DateTime(), $invalidCount));
self::assertEquals([], Date::getDatesCollection(new DateTime(), -1));
}
/**
* @param mixed $invalidInterval Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetDatesCollectionInvalidInterval($invalidInterval)
{
self::assertEquals([], Date::getDatesCollection(new DateTime(), 2, $invalidInterval));
self::assertEquals([], Date::getDatesCollection(new DateTime(), 2, 'lorem'));
self::assertEquals([], Date::getDatesCollection(new DateTime(), 2, '%d'));
}
public function testGetDatesCollection()
{
/*
* 1 date only
*/
$effect = [
1 => new DateTime('2017-01-02'),
];
self::assertEquals($effect, Date::getDatesCollection(new DateTime('2017-01-01'), 1));
/*
* 3 dates with default date interval (days)
*/
$effect = [
1 => new DateTime('2017-01-02'),
2 => new DateTime('2017-01-03'),
3 => new DateTime('2017-01-04'),
];
self::assertEquals($effect, Date::getDatesCollection(new DateTime('2017-01-01'), 3));
/*
* 3 dates with custom date interval (hours)
*/
$effect = [
1 => new DateTime('2017-01-01 10:30'),
2 => new DateTime('2017-01-01 11:30'),
3 => new DateTime('2017-01-01 12:30'),
];
self::assertEquals($effect, Date::getDatesCollection(new DateTime('2017-01-01 09:30'), 3, 'PT%dH'));
/*
* 3 dates with custom date interval (months)
*/
$effect = [
1 => new DateTime('2017-02-01'),
2 => new DateTime('2017-03-01'),
3 => new DateTime('2017-04-01'),
];
self::assertEquals($effect, Date::getDatesCollection(new DateTime('2017-01-01'), 3, 'P%dM'));
}
public function testGetRandomDateUsingDefaults()
{
$startDate = new DateTime();
$start = 1;
$end = 100;
$intervalMinDate = (clone $startDate)->add(new DateInterval(sprintf('P%dD', $start)));
$intervalMaxDate = (clone $startDate)->add(new DateInterval(sprintf('P%dD', $end)));
$randomDate = Date::getRandomDate();
self::assertTrue($randomDate >= $intervalMinDate && $randomDate <= $intervalMaxDate);
}
/**
* @param DateTime $startDate The start date. Start of the random date.
* @param int $start Start of random partition
* @param int $end End of random partition
*
* @dataProvider provideDataOfRandomDateIncorrectEnd
*/
public function testGetRandomDateIncorrectEnd(DateTime $startDate, $start, $end)
{
$randomDate = Date::getRandomDate($startDate, $start, $end);
$intervalDate = (clone $startDate)->add(new DateInterval(sprintf('P%dD', $start)));
self::assertTrue($randomDate >= $intervalDate && $randomDate <= $intervalDate);
}
/**
* @param DateTime $startDate The start date. Start of the random date.
* @param int $start Start of random partition
* @param int $end End of random partition
*
* @dataProvider provideDataOfRandomDate
*/
public function testGetRandomDate(DateTime $startDate, $start, $end)
{
$randomDate = Date::getRandomDate($startDate, $start, $end);
$intervalMinDate = (clone $startDate)->add(new DateInterval(sprintf('P%dD', $start)));
$intervalMaxDate = (clone $startDate)->add(new DateInterval(sprintf('P%dD', $end)));
self::assertTrue($randomDate >= $intervalMinDate && $randomDate <= $intervalMaxDate);
}
/**
* Provides incorrect invalidCount of DateTime
*
* @return Generator
*/
public function provideIncorrectDateTimeValue()
{
/*
* Incorrect one-character values
*/
yield['a'];
yield['m'];
/*
* Incorrect strings
*/
yield['ss'];
yield['sss'];
yield['mm'];
yield['yy'];
yield['yyyy'];
/*
* Incorrect integer values
*/
yield[1];
yield[10];
yield[15];
yield[100];
yield[1000];
/*
* Incorrect string / numeric values
*/
yield['1'];
yield['10'];
yield['15'];
yield['100'];
yield['1000'];
/*
* Incorrect dates
*/
yield['0-0-0'];
yield['20-01-01'];
yield['2015-0-0'];
yield['2015-00-00'];
yield['2015-16-01'];
}
/**
* Provides invalid format of date
*
* @return Generator
*/
public function provideInvalidDateFormats()
{
yield[0];
yield[9];
yield['[]'];
yield['invalid'];
yield['Q'];
yield[','];
yield['.'];
yield['aa###'];
yield['Y/m/d H:i:invalid'];
}
/**
* Provide empty dates for date difference
*
* @return Generator
*/
public function provideEmptyDatesForDateDifference()
{
yield[
null,
null,
];
yield[
'',
'',
];
yield[
null,
new DateTime(),
];
yield[
new DateTime(),
null,
];
}
/**
* Provides incorrect values of year, month and day
*
* @return Generator
*/
public function provideIncorrectYearMonthDay()
{
yield[
null,
null,
null,
];
yield[
'',
'',
'',
];
yield[
0,
0,
0,
];
yield[
-1,
-1,
-1,
];
yield[
5000,
50,
50,
];
yield[
2000,
13,
01,
];
yield[
2000,
01,
40,
];
}
/**
* Provides values of year, month and day
*
* @return Generator
*/
public function provideYearMonthDay()
{
yield[
2000,
01,
01,
];
yield[
2000,
1,
1,
];
yield[
2000,
2,
2,
];
yield[
2000,
6,
1,
];
yield[
2000,
12,
01,
];
yield[
2000,
12,
1,
];
yield[
2000,
12,
31,
];
}
/**
* Provides data for the random date with incorrect end of random partition
*
* @return Generator
*/
public function provideDataOfRandomDateIncorrectEnd()
{
yield[
new DateTime('2000-01-01'),
100,
1,
];
}
/**
* Provides data for the random date
*
* @return Generator
*/
public function provideDataOfRandomDate()
{
yield[
new DateTime('2000-01-01'),
1,
100,
];
yield[
new DateTime('2000-12-01'),
1,
100,
];
yield[
new DateTime('2000-01-01'),
'1',
'100',
];
yield[
new DateTime('2000-12-01'),
'1',
'100',
];
yield[
new DateTime('2000-01-01'),
10,
50,
];
yield[
new DateTime('2000-12-01'),
10,
50,
];
}
}

View File

@@ -0,0 +1,56 @@
<?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\Tests\Utilities;
use Meritoo\Common\Utilities\GeneratorUtility;
use Meritoo\Common\Utilities\TestCase;
/**
* Tests of the useful methods for the Generator class
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class GeneratorUtilityTest extends TestCase
{
public function testGetGeneratorElements()
{
/*
* Generator that provides boolean value
*/
$elements = [
[false],
[true],
];
$generator = $this->provideBooleanValue();
self::assertEquals($elements, GeneratorUtility::getGeneratorElements($generator));
$elements = [
[''],
[' '],
[null],
[0],
[false],
[[]],
];
/*
* Generator that provides an empty value
*/
$generator = $this->provideEmptyValue();
self::assertEquals($elements, GeneratorUtility::getGeneratorElements($generator));
/*
* Generator that provides instance of DateTime class
*/
$generator = $this->provideDateTimeInstance();
self::assertCount(4, GeneratorUtility::getGeneratorElements($generator));
}
}

View File

@@ -0,0 +1,129 @@
<?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\Tests\Utilities;
use Generator;
use Meritoo\Common\Utilities\Locale;
use Meritoo\Common\Utilities\TestCase;
/**
* Tests of the useful locale methods
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class LocaleTest extends TestCase
{
/**
* @param mixed $languageCode Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetLongFormEmptyLanguageCode($languageCode)
{
self::assertEquals('', Locale::getLongForm($languageCode));
}
/**
* @param string $languageCode Language code, in ISO 639-1 format. Short form of the locale, e.g. "fr".
* @param string $countryCode Country code, in ISO 3166-1 alpha-2 format, e.g. "FR"
* @param string $encoding Encoding of the final locale
* @param string $expected Expected long form of the locale
*
* @dataProvider provideLanguageAndCountryCode
*/
public function testGetLongForm($languageCode, $countryCode, $encoding, $expected)
{
self::assertEquals($expected, Locale::getLongForm($languageCode, $countryCode, $encoding));
}
/**
* @param mixed $emptyValue Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testSetLocaleEmptyCategoryAndLanguageCode($emptyValue)
{
self::assertFalse(Locale::setLocale($emptyValue, $emptyValue));
}
/**
* @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".
*
* @dataProvider provideCategoryAndLanguageCode
*/
public function testSetLocale($category, $languageCode)
{
self::assertTrue(Locale::setLocale($category, $languageCode));
}
/**
* Provides language and country code
*
* @return Generator
*/
public function provideLanguageAndCountryCode()
{
yield[
'fr',
'',
'',
'fr_FR',
];
yield[
'fr',
'',
'UTF-8',
'fr_FR.UTF-8',
];
yield[
'fr',
'FR',
'',
'fr_FR',
];
yield[
'fr',
'FR',
'UTF-8',
'fr_FR.UTF-8',
];
}
/**
* Provides category and language
*
* @return Generator
*/
public function provideCategoryAndLanguageCode()
{
yield[
LC_ALL,
'fr',
];
yield[
LC_COLLATE,
'fr',
];
yield[
LC_CTYPE,
'en',
];
yield[
LC_NUMERIC,
'en',
];
}
}

View File

@@ -0,0 +1,472 @@
<?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\Tests\Utilities;
use Generator;
use Meritoo\Common\Utilities\MimeTypes;
use Meritoo\Common\Utilities\TestCase;
/**
* Tests of the useful methods for mime types of files
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class MimeTypesTest extends TestCase
{
/**
* @param mixed $mimeType Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetExtensionEmptyMimeType($mimeType)
{
self::assertEquals('', MimeTypes::getExtension($mimeType));
}
/**
* @param bool $mimeType The mime type, e.g. "video/mpeg"
* @dataProvider provideBooleanValue
*/
public function testGetExtensionBooleanMimeType($mimeType)
{
self::assertEquals('', MimeTypes::getExtension($mimeType));
}
/**
* @param string $mimeType Not existing mime type, e.g. "lorem/ipsum"
* @dataProvider provideNotExistingMimeType
*/
public function testGetExtensionNotExistingMimeType($mimeType)
{
self::assertEquals('', MimeTypes::getExtension($mimeType));
}
/**
* @param string $mimeType The mime type, e.g. "video/mpeg"
* @param string $extension Expected extension
*
* @dataProvider provideMimeTypeToGetSingleExtension
*/
public function testGetExtensionSingle($mimeType, $extension)
{
self::assertEquals($extension, MimeTypes::getExtension($mimeType));
}
/**
* @param string $mimeType The mime type, e.g. "video/mpeg"
* @param array $extensions Expected extensions
*
* @dataProvider provideMimeTypeToGetMultipleExtension
*/
public function testGetExtensionMultiple($mimeType, $extensions)
{
self::assertEquals($extensions, MimeTypes::getExtension($mimeType));
}
/**
* @param array $mimesTypes Not existing mimes types, e.g. ['lorem/ipsum']
* @dataProvider provideNotExistingMimeTypes
*/
public function testGetExtensionsNotExistingMimeTypes($mimesTypes)
{
self::assertEquals([], MimeTypes::getExtensions($mimesTypes));
}
/**
* @param array $mimesTypes The mimes types, e.g. ['video/mpeg', 'image/jpeg']
* @param array $extensions Expected extensions
*
* @dataProvider provideMimesTypesToGetExtensions
*/
public function testGetExtensions($mimesTypes, $extensions)
{
self::assertEquals($extensions, MimeTypes::getExtensions($mimesTypes));
}
/**
* @param array $mimesTypes The mimes types, e.g. ['video/mpeg', 'image/jpeg']
* @param array $extensions Expected extensions
*
* @dataProvider provideMimesTypesToGetExtensionsUpperCase
*/
public function testGetExtensionsUpperCase($mimesTypes, $extensions)
{
self::assertEquals($extensions, MimeTypes::getExtensions($mimesTypes, true));
}
/**
* @param mixed $filePath Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetMimeTypeEmptyPath($filePath)
{
self::assertEquals('', MimeTypes::getMimeType($filePath));
}
/**
* @param string $filePath Path of the file to check
* @param string $mimeType Expected mime type
*
* @dataProvider provideFilePathToGetMimeTypeOfRealFile
*/
public function testGetMimeTypeOfRealFile($filePath, $mimeType)
{
self::assertEquals($mimeType, MimeTypes::getMimeType($filePath));
}
/**
* @param mixed $mimeType Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testIsImageEmptyMimeType($mimeType)
{
self::assertFalse(MimeTypes::isImage($mimeType));
}
/**
* @param string $mimeType Not existing mime type, e.g. "lorem/ipsum"
* @dataProvider provideNotExistingMimeType
*/
public function testIsImageNotExistingMimeType($mimeType)
{
self::assertFalse(MimeTypes::isImage($mimeType));
}
/**
* @param string $mimeType Mime type of non-image, e.g. "text/plain"
* @dataProvider provideNonImageMimeType
*/
public function testIsImageNonImageMimeType($mimeType)
{
self::assertFalse(MimeTypes::isImage($mimeType));
}
/**
* @param mixed $path Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testIsImagePathEmptyPath($path)
{
self::assertFalse(MimeTypes::isImagePath($path));
}
/**
* @param mixed $path Path of not existing file, e.g. "lorem/ipsum.jpg"
* @dataProvider provideNotExistingFilePath
*/
public function testIsImagePathNotExistingPath($path)
{
self::assertFalse(MimeTypes::isImagePath($path));
}
/**
* @param string $path Path of the file to check
* @param bool $isImage Expected information if the file is an image
*
* @dataProvider provideExistingFilePathToCheckIsImagePath
*/
public function testIsImagePathExistingPath($path, $isImage)
{
self::assertEquals($isImage, MimeTypes::isImagePath($path));
}
/**
* @param string $mimeType Mime type of image, e.g. "image/jpeg"
* @dataProvider provideImageMimeType
*/
public function testIsImageImageMimeType($mimeType)
{
self::assertTrue(MimeTypes::isImage($mimeType));
}
/**
* Provides not existing mime type
*
* @return Generator
*/
public function provideNotExistingMimeType()
{
yield['lorem/ipsum'];
yield['dolor'];
yield['x/y/z'];
}
/**
* Provides mime type of non-image
*
* @return Generator
*/
public function provideNonImageMimeType()
{
yield['application/rtf'];
yield['audio/mp4'];
yield['text/plain'];
yield['text/html'];
}
/**
* Provides mime type of image
*
* @return Generator
*/
public function provideImageMimeType()
{
yield['image/bmp'];
yield['image/jpeg'];
yield['image/png'];
yield['image/tiff'];
yield['image/vnd.microsoft.icon'];
yield['image/x-rgb'];
}
/**
* Provides existing mime type used to get single, one extension
*
* @return Generator
*/
public function provideMimeTypeToGetSingleExtension()
{
yield[
'application/x-7z-compressed',
'7z',
];
yield[
'application/json',
'json',
];
yield[
'application/zip',
'zip',
];
}
/**
* Provides existing mime type used to get multiple, more than one extension
*
* @return Generator
*/
public function provideMimeTypeToGetMultipleExtension()
{
yield[
'application/postscript',
[
'ai',
'eps',
'ps',
],
];
yield[
'audio/midi',
[
'mid',
'midi',
'kar',
'rmi',
],
];
yield[
'image/jpeg',
[
'jpeg',
'jpe',
'jpg',
],
];
yield[
'text/html',
[
'html',
'htm',
],
];
yield[
'text/plain',
[
'txt',
'text',
'conf',
'def',
'list',
'log',
'in',
],
];
yield[
'video/mp4',
[
'mp4',
'mp4v',
'mpg4',
'm4v',
],
];
}
/**
* Provides not existing mime types
*
* @return Generator
*/
public function provideNotExistingMimeTypes()
{
yield[
[],
];
yield[
[
'',
null,
false,
0,
],
];
yield[
[
'lorem/ipsum',
'dolor/sit',
],
];
}
/**
* Provides mime types used to get extensions
*
* @return Generator
*/
public function provideMimesTypesToGetExtensions()
{
yield[
[
'application/x-7z-compressed',
'application/json',
],
[
'application/x-7z-compressed' => '7z',
'application/json' => 'json',
],
];
yield[
[
'application/mathematica',
'application/xml',
'audio/mp4',
'video/mp4',
],
[
'application/mathematica' => [
'ma',
'nb',
'mb',
],
'application/xml' => [
'xml',
'xsl',
],
'audio/mp4' => 'mp4a',
'video/mp4' => [
'mp4',
'mp4v',
'mpg4',
'm4v',
],
],
];
}
/**
* Provides mime types used to get extensions as upper case
*
* @return Generator
*/
public function provideMimesTypesToGetExtensionsUpperCase()
{
yield[
[
'application/x-7z-compressed',
'application/json',
],
[
'application/x-7z-compressed' => '7Z',
'application/json' => 'JSON',
],
];
yield[
[
'application/xml',
'audio/mp4',
'text/html',
'video/mp4',
],
[
'application/xml' => [
'XML',
'XSL',
],
'audio/mp4' => 'MP4A',
'text/html' => [
'HTML',
'HTM',
],
'video/mp4' => [
'MP4',
'MP4V',
'MPG4',
'M4V',
],
],
];
}
/**
* Provides real file path to get mime type
*
* @return Generator
*/
public function provideFilePathToGetMimeTypeOfRealFile()
{
yield[
$this->getFilePathToTests('minion.jpg'),
'image/jpeg',
];
yield[
$this->getFilePathToTests('lorem-ipsum.txt'),
'text/plain',
];
}
/**
* Provides real file path to get information if the file is an image
*
* @return Generator
*/
public function provideExistingFilePathToCheckIsImagePath()
{
yield[
$this->getFilePathToTests('minion.jpg'),
true,
];
yield[
$this->getFilePathToTests('lorem-ipsum.txt'),
false,
];
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
<?php
namespace Meritoo\Common\Tests\Utilities\Reflection;
/**
* The A class.
* Used for testing the Reflection class.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class A
{
use E;
protected function lorem()
{
return 'ipsum';
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Meritoo\Common\Tests\Utilities\Reflection;
/**
* The B class.
* Used for testing the Reflection class.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class B extends A
{
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Meritoo\Common\Tests\Utilities\Reflection;
/**
* The C class.
* Used for testing the Reflection class.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class C extends B
{
public function getPositive()
{
return true;
}
public function getNegative()
{
return false;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Meritoo\Common\Tests\Utilities\Reflection;
/**
* The D class.
* Used for testing the Reflection class.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class D
{
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Meritoo\Common\Tests\Utilities\Reflection;
/**
* The E trait.
* Used for testing the Reflection class.
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
trait E
{
}

View File

@@ -0,0 +1,246 @@
<?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\Tests\Utilities;
use DateTime;
use Generator;
use Meritoo\Common\Exception\Reflection\CannotResolveClassNameException;
use Meritoo\Common\Exception\Reflection\MissingChildClassesException;
use Meritoo\Common\Exception\Reflection\TooManyChildClassesException;
use Meritoo\Common\Tests\Utilities\Reflection\A;
use Meritoo\Common\Tests\Utilities\Reflection\B;
use Meritoo\Common\Tests\Utilities\Reflection\C;
use Meritoo\Common\Tests\Utilities\Reflection\D;
use Meritoo\Common\Tests\Utilities\Reflection\E;
use Meritoo\Common\Utilities\Reflection;
use Meritoo\Common\Utilities\TestCase;
/**
* Tests of the useful reflection methods
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class ReflectionTest extends TestCase
{
/**
* @param mixed $invalidClass Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetClassNameInvalidClass($invalidClass)
{
self::assertNull(Reflection::getClassName($invalidClass));
self::assertNull(Reflection::getClassName(123));
}
public function testGetClassNameNotExistingClass()
{
/*
* Not existing class
*/
self::assertEquals('', Reflection::getClassName('xyz'));
self::assertEquals('', Reflection::getClassName('xyz', true));
}
public function testGetClassNameExistingClass()
{
/*
* Existing class
*/
self::assertEquals(self::class, Reflection::getClassName(self::class));
self::assertEquals('ReflectionTest', Reflection::getClassName(self::class, true));
self::assertEquals(DateTime::class, Reflection::getClassName(new DateTime()));
self::assertEquals(DateTime::class, Reflection::getClassName(new DateTime(), true));
self::assertEquals(DateTime::class, Reflection::getClassName([
new DateTime(),
new DateTime('yesterday'),
]));
}
public function testGetClassNameDuplicatedName()
{
/*
* Class with namespace containing name of class (duplicated string)
*/
if (class_exists('Symfony\Bundle\SecurityBundle\SecurityBundle')) {
self::assertEquals('Symfony\Bundle\SecurityBundle\SecurityBundle', Reflection::getClassName('Symfony\Bundle\SecurityBundle\SecurityBundle'));
self::assertEquals('SecurityBundle', Reflection::getClassName('Symfony\Bundle\SecurityBundle\SecurityBundle', true));
}
}
public function testGetClassNamespaceNotExistingClass()
{
/*
* Not existing class
*/
self::assertEquals('', Reflection::getClassNamespace('xyz'));
}
public function testGetClassNamespaceExistingClass()
{
/*
* Existing class
*/
self::assertEquals('Meritoo\Common\Tests\Utilities', Reflection::getClassNamespace(self::class));
self::assertEquals(DateTime::class, Reflection::getClassNamespace(new DateTime()));
self::assertEquals(DateTime::class, Reflection::getClassNamespace([
new DateTime(),
new DateTime('yesterday'),
]));
}
public function testGetClassNamespaceDuplicatedName()
{
/*
* Class with namespace containing name of class (duplicated string)
*/
if (class_exists('Symfony\Bundle\SecurityBundle\SecurityBundle')) {
self::assertEquals('Symfony\Bundle\SecurityBundle', Reflection::getClassNamespace('Symfony\Bundle\SecurityBundle\SecurityBundle'));
}
}
/**
* @param mixed $invalidClass Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testGetChildClassesInvalidClass($invalidClass)
{
$this->expectException(CannotResolveClassNameException::class);
self::assertNull(Reflection::getChildClasses($invalidClass));
self::assertNull(Reflection::getChildClasses(123));
}
public function testGetChildClassesNotExistingClass()
{
$this->expectException(CannotResolveClassNameException::class);
self::assertEquals('', Reflection::getChildClasses('xyz'));
}
public function testGetChildClassesExistingClass()
{
/*
* Attention. I have to create instances of these classes to load them and be available while using
* get_declared_classes() function in the Reflection::getChildClasses() method. Without these instances the
* Reflection::getChildClasses() method returns an empty array even if given class has child classes.
*/
new A();
new B();
new C();
$effect = [
C::class,
];
self::assertEquals($effect, Reflection::getChildClasses(B::class));
$effect = [
B::class,
C::class,
];
self::assertEquals($effect, Reflection::getChildClasses(A::class));
}
public function testGetOneChildClassWithMissingChildClasses()
{
$this->expectException(MissingChildClassesException::class);
self::assertEquals('LoremIpsum', Reflection::getOneChildClass(C::class));
}
public function testGetOneChildClassWithTooManyChildClasses()
{
$this->expectException(TooManyChildClassesException::class);
self::assertEquals(B::class, Reflection::getOneChildClass(A::class));
self::assertEquals(C::class, Reflection::getOneChildClass(A::class));
}
public function testGetOneChildClass()
{
self::assertEquals(C::class, Reflection::getOneChildClass(B::class));
}
public function testGetMethods()
{
self::assertEquals(0, count(Reflection::getMethods(B::class, true)));
self::assertEquals(1, count(Reflection::getMethods(B::class)));
self::assertEquals(1, count(Reflection::getMethods(A::class)));
self::assertEquals(2, count(Reflection::getMethods(C::class, true)));
self::assertEquals(3, count(Reflection::getMethods(C::class)));
}
/**
* @param array|object|string $class An array of objects, namespaces, object or namespace
* @param array|string $trait An array of strings or string
*
* @dataProvider provideInvalidClassAndTrait
*/
public function testUsesTraitInvalidClass($class, $trait)
{
$this->expectException(CannotResolveClassNameException::class);
self::assertNull(Reflection::usesTrait($class, $trait));
}
/**
* @param mixed $trait Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testUsesTraitInvalidTrait($trait)
{
$this->expectException(CannotResolveClassNameException::class);
self::assertNull(Reflection::usesTrait(DateTime::class, $trait));
}
public function testUsesTraitExistingClass()
{
self::assertTrue(Reflection::usesTrait(A::class, E::class));
self::assertFalse(Reflection::usesTrait(B::class, E::class));
self::assertFalse(Reflection::usesTrait(C::class, E::class));
self::assertFalse(Reflection::usesTrait(D::class, E::class));
}
public function testUsesTraitExistingClassAndVerifyParents()
{
self::assertTrue(Reflection::usesTrait(A::class, E::class, true));
self::assertTrue(Reflection::usesTrait(B::class, E::class, true));
self::assertTrue(Reflection::usesTrait(C::class, E::class, true));
self::assertFalse(Reflection::usesTrait(D::class, E::class, true));
}
/**
* Provides invalid class and trait
*
* @return Generator
*/
public function provideInvalidClassAndTrait()
{
yield[
'',
'',
];
yield[
null,
null,
];
yield[
0,
0,
];
yield[
[],
[],
];
}
}

View File

@@ -0,0 +1,291 @@
<?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;
/**
* Tests of the useful regular expressions methods
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class RegexTest extends \PHPUnit_Framework_TestCase
{
private $simpleText;
private $camelCaseText;
public function testGetCamelCaseParts()
{
$parts = [];
self::assertEquals($parts, Regex::getCamelCaseParts(''));
$parts = [
'lorem',
];
self::assertEquals($parts, Regex::getCamelCaseParts('lorem'));
$parts = [
'lorem',
'Ipsum',
'Dolor',
'Sit',
];
self::assertEquals($parts, Regex::getCamelCaseParts($this->camelCaseText));
$parts = [
'Lorem',
'Ipsum',
'Dolor',
'Sit',
];
$string = ucfirst($this->camelCaseText); // 'LoremIpsumDolorSit'
self::assertEquals($parts, Regex::getCamelCaseParts($string));
}
public function testCamelCase2humanReadable()
{
self::assertEquals('', Regex::camelCase2humanReadable(''));
self::assertEquals('lorem', Regex::camelCase2humanReadable('lorem'));
self::assertEquals($this->simpleText, Regex::camelCase2humanReadable($this->camelCaseText));
self::assertEquals(ucfirst($this->simpleText), Regex::camelCase2humanReadable($this->camelCaseText, true));
}
public function testCamelCase2simpleLowercase()
{
self::assertEquals('', Regex::camelCase2simpleLowercase(''));
self::assertEquals('lorem', Regex::camelCase2simpleLowercase('lorem'));
self::assertEquals('Lorem', Regex::camelCase2simpleLowercase('Lorem', '', false));
self::assertEquals('lorem-ipsum-dolor-sit', Regex::camelCase2simpleLowercase($this->camelCaseText, '-'));
self::assertEquals('lorem-Ipsum-Dolor-Sit', Regex::camelCase2simpleLowercase($this->camelCaseText, '-', false));
}
public function testIsValidUrl()
{
$validUrls = [
'http://php.net',
'http://php.net/',
'http://php.net/docs.php',
'http://php.net/get-involved.php',
'http://php.net/manual/en/function.preg-match.php',
'http://domain.com/BigLetters',
'http://domain.com/Another-Big-Letters',
'http://domain.com/?a=1&b=c2d',
'http://domAin.COM/?a=1&B=c2D',
'http://domain.com/index.php?a=1&b=c2d',
'http://domain.com/another-page-2.php?a=1&b=c2d',
'https://domain.com',
'https://domain.com/',
];
$invalidUrls = [
'',
null,
false,
true,
0,
1,
123,
'123',
'http:',
'http://',
'http://abc',
'ftp://def',
];
foreach ($validUrls as $url) {
self::assertTrue(Regex::isValidUrl($url));
}
foreach ($invalidUrls as $url) {
self::assertFalse(Regex::isValidUrl($url));
}
}
public function testIsSubPathOf()
{
self::assertFalse(Regex::isSubPathOf(null, null));
self::assertFalse(Regex::isSubPathOf('', ''));
self::assertFalse(Regex::isSubPathOf('', '/my/directory'));
self::assertFalse(Regex::isSubPathOf('/my/file', ''));
self::assertFalse(Regex::isSubPathOf('/my/file', '/my/directory'));
self::assertTrue(Regex::isSubPathOf('/my/directory', '/my/directory'));
self::assertTrue(Regex::isSubPathOf('/my/directory/', '/my/directory'));
self::assertTrue(Regex::isSubPathOf('/my/directory', '/my/directory/'));
self::assertTrue(Regex::isSubPathOf('/my/directory/', '/my/directory/'));
self::assertTrue(Regex::isSubPathOf('/my/another/directory/another/file', '/my/another/directory'));
}
public function testIsLetterOrDigit()
{
self::assertTrue(Regex::isLetterOrDigit('a'));
self::assertTrue(Regex::isLetterOrDigit(10));
self::assertFalse(Regex::isLetterOrDigit(';'));
}
public function testStartsWith()
{
$string = 'Lorem ipsum dolor sit amet';
$beginning = 'Lor';
self::assertTrue(Regex::startsWith($string, $beginning));
$beginning = 'L';
self::assertTrue(Regex::startsWith($string, $beginning));
$beginning = 'X';
self::assertFalse(Regex::startsWith($string, $beginning));
$string = '1234567890';
$beginning = '1';
self::assertTrue(Regex::startsWith($string, $beginning));
$beginning = ';';
self::assertFalse(Regex::startsWith($string, $beginning));
}
public function testStartsWithDirectorySeparator()
{
/*
* Slash as separator
*/
$separatorSlash = '/';
self::assertTrue(Regex::startsWithDirectorySeparator('/my/extra/directory', $separatorSlash));
self::assertFalse(Regex::startsWithDirectorySeparator('my/extra/directory', $separatorSlash));
/*
* Backslash as separator
*/
$separatorBackslash = '\\';
self::assertTrue(Regex::startsWithDirectorySeparator('\my\extra\directory', $separatorBackslash));
self::assertFalse(Regex::startsWithDirectorySeparator('my\extra\directory', $separatorBackslash));
}
public function testEndsWithDirectorySeparator()
{
/*
* Slash as separator
*/
$separatorSlash = '/';
self::assertTrue(Regex::endsWithDirectorySeparator('my simple text/', $separatorSlash));
self::assertFalse(Regex::endsWithDirectorySeparator('my simple text', $separatorSlash));
/*
* Backslash as separator
*/
$separatorBackslash = '\\';
self::assertTrue(Regex::endsWithDirectorySeparator('my simple text\\', $separatorBackslash));
self::assertFalse(Regex::endsWithDirectorySeparator('my simple text', $separatorBackslash));
}
public function testEndsWith()
{
self::assertFalse(Regex::endsWith($this->simpleText, '\.\.\.'));
self::assertFalse(Regex::endsWith($this->simpleText, '\.'));
self::assertTrue(Regex::endsWith($this->simpleText, 't'));
}
public function testIsSetUriParameter()
{
$uri = 'www.domain.com/?name=phil&type=4';
$parameterName = 'type';
self::assertTrue(Regex::isSetUriParameter($uri, $parameterName));
$parameterName = 'color';
self::assertFalse(Regex::isSetUriParameter($uri, $parameterName));
}
public function testContainsEntities()
{
self::assertFalse(Regex::containsEntities('Lorem ipsum'));
self::assertTrue(Regex::containsEntities('Lorem ipsum &raquo;'));
}
public function testContains()
{
self::assertTrue(Regex::contains($this->simpleText, 'ipsum'));
self::assertFalse(Regex::contains($this->simpleText, 'neque'));
}
public function testIsFileName()
{
$filePath = __FILE__;
$directoryPath = dirname($filePath);
self::assertTrue(Regex::isFileName($filePath));
self::assertFalse(Regex::isFileName($directoryPath));
}
public function testIsQuoted()
{
self::assertTrue(Regex::isQuoted('\'lorem ipsum\''));
self::assertTrue(Regex::isQuoted('"lorem ipsum"'));
self::assertFalse(Regex::isQuoted('lorem ipsum'));
self::assertFalse(Regex::isQuoted(new \stdClass()));
}
public function testIsWindowsBasedPath()
{
self::assertTrue(Regex::isWindowsBasedPath('C:\path\to\directory'));
self::assertTrue(Regex::isWindowsBasedPath('C:\path\to\file.jpg'));
self::assertFalse(Regex::isWindowsBasedPath('/path/to/directory'));
self::assertFalse(Regex::isWindowsBasedPath('/path/to/file.jpg'));
}
public function testIsValidNip()
{
self::assertFalse(Regex::isValidNip(null));
self::assertFalse(Regex::isValidNip(''));
self::assertFalse(Regex::isValidNip(1234));
self::assertFalse(Regex::isValidNip(1234567890));
self::assertFalse(Regex::isValidNip(0000000000));
self::assertFalse(Regex::isValidNip('1234567890'));
self::assertFalse(Regex::isValidNip('0000000000'));
self::assertFalse(Regex::isValidNip('abc'));
self::assertFalse(Regex::isValidNip($this->simpleText));
self::assertTrue(Regex::isValidNip('7340009469')); // Onet S.A.
self::assertTrue(Regex::isValidNip('5252530705')); // Facebook Poland sp. z o.o.
}
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->simpleText = 'lorem ipsum dolor sit';
$this->camelCaseText = str_replace(' ', '', lcfirst(ucwords($this->simpleText))); // 'loremIpsumDolorSit'
}
/**
* {@inheritdoc}
*/
protected function tearDown()
{
parent::tearDown();
unset($this->simpleText);
unset($this->camelCaseText);
}
}

View File

@@ -0,0 +1,78 @@
<?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\Tests\Utilities;
use Meritoo\Common\Utilities\TestCase;
use Meritoo\Common\Utilities\Uri;
/**
* Tests of the useful uri methods (only static functions)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class UriTest extends TestCase
{
public function testAddProtocolToUrl()
{
$http = 'http';
$https = 'https';
$url = 'my.domain/some/url';
$httpUrl = sprintf('%s://%s', $http, $url);
$httpsUrl = sprintf('%s://%s', $https, $url);
self::assertEquals($httpUrl, Uri::addProtocolToUrl($httpUrl));
self::assertEquals($httpUrl, Uri::addProtocolToUrl($url));
self::assertEquals($httpsUrl, Uri::addProtocolToUrl($url, $https));
self::assertEquals($httpsUrl, Uri::addProtocolToUrl($httpsUrl, $http));
}
/**
* @param mixed $url Empty value, e.g. ""
* @dataProvider provideEmptyValue
*/
public function testReplenishProtocolEmptyUrl($url)
{
self::assertEquals('', Uri::replenishProtocol($url));
}
/**
* @param string $expected Expected result
* @param string $url The url to check and replenish
* @param string $protocol (optional) The protocol which is replenished. If is empty, protocol of current request
* is used.
*
* @dataProvider provideUrlsToReplenishProtocol
*/
public function testReplenishProtocol($expected, $url, $protocol = '')
{
self::assertSame($expected, Uri::replenishProtocol($url, $protocol));
}
/**
* Provides urls to replenish protocol
*
* @return \Generator
*/
public function provideUrlsToReplenishProtocol()
{
yield[
'://test',
'test',
'',
];
yield[
'ftp://lorem.ipsum',
'lorem.ipsum',
'ftp',
];
}
}

View File

@@ -0,0 +1,90 @@
<?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\Tests\Utilities;
use Meritoo\Common\Utilities\Xml;
use SimpleXMLElement;
/**
* Tests of the useful XML-related methods (only static functions)
*
* @author Krzysztof Niziol <krzysztof.niziol@meritoo.pl>
* @copyright Meritoo.pl
*/
class XmlTest extends \PHPUnit_Framework_TestCase
{
private $simpleXml;
private $advancedXml;
public function testMergeNodes()
{
/*
* An empty XMLs
*/
$element1 = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><cars />');
$element2 = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><employees />');
$merged = Xml::mergeNodes($element1, $element2);
self::assertEquals('', (string)$merged);
/*
* XMLs with data
*/
$element1 = new SimpleXMLElement($this->simpleXml);
$element2 = new SimpleXMLElement($this->advancedXml);
$merged = Xml::mergeNodes($element1, $element2);
self::assertEquals('John', (string)$merged->author[0]->first_name);
}
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->simpleXml = '<?xml version="1.0" encoding="UTF-8"?>
<notes>
<note>Lorem ipsum</note>
<note>Dolor sit amet</note>
<note>Consectetur adipiscing elit</note>
<note>Donec ut</note>
<note>Mi a magna</note>
<note>Dapibus bibendum</note>
</notes>
';
$this->advancedXml = '<?xml version="1.0" encoding="UTF-8"?>
<authors>
<author>
<first_name>John</first_name>
<last_name>Scott</last_name>
<email>john.scott@fake.email</email>
</author>
<author>
<first_name>Julia</first_name>
<last_name>Brown</last_name>
<email>julia.brown@fake.email</email>
</author>
</authors>
';
}
/**
* {@inheritdoc}
*/
protected function tearDown()
{
parent::tearDown();
unset($this->simpleXml);
unset($this->advancedXml);
}
}