From: Roland Häder Date: Sun, 16 Jul 2017 10:43:03 +0000 (+0200) Subject: Continued a bit: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=8caddd87d0df2a41a9cf31aeb0b168e610bbc31e;p=core.git Continued a bit: - start of rewriting unit tests, these old where not very well written anyway - created phpunit.xml.dist - created composer.json/lock files. No, I'm not going to replace my class loader with it. I still like mine better. :-) - created tests/bootstrap.php which contains an ugly hack for loading my tests first. Maybe there is a better way? - moved class to proper (deeper) location Signed-off-by: Roland Häder --- diff --git a/.gitignore b/.gitignore index 0577ff27..f713dcee 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,6 @@ /docs/html/* /docs/latex/* /docs/warn.log -/reports/*.* +/reports/ +/vendor/ +/phpunit.xml diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..7f3d93cd --- /dev/null +++ b/composer.json @@ -0,0 +1,5 @@ +{ + "require-dev": { + "phpunit/phpunit": "^6.2" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..ed31707f --- /dev/null +++ b/composer.lock @@ -0,0 +1,1467 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "ebbdcb2d7a774f380d3bf42653902646", + "packages": [], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14T21:17:01+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8e6e04167378abf1ddb4d3522d8755c5fd90d102", + "reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "doctrine/collections": "1.*", + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "homepage": "https://github.com/myclabs/DeepCopy", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2017-04-12T18:52:22+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2015-12-27T11:43:31+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "46f7e8bb075036c92695b15a1ddb6971c751e585" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/46f7e8bb075036c92695b15a1ddb6971c751e585", + "reference": "46f7e8bb075036c92695b15a1ddb6971c751e585", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-07-15T11:38:20+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1|^2.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8 || ^5.6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2017-03-02T20:05:34+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "5.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "dc421f9ca5082a0c0cb04afb171c765f79add85b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/dc421f9ca5082a0c0cb04afb171c765f79add85b", + "reference": "dc421f9ca5082a0c0cb04afb171c765f79add85b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.0", + "phpunit/php-file-iterator": "^1.3", + "phpunit/php-text-template": "^1.2", + "phpunit/php-token-stream": "^1.4.11 || ^2.0", + "sebastian/code-unit-reverse-lookup": "^1.0", + "sebastian/environment": "^3.0", + "sebastian/version": "^2.0", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "ext-xdebug": "^2.5", + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-xdebug": "^2.5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2017-04-21T08:03:57+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2016-10-03T07:40:28+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.11", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2017-02-27T10:12:30+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "6.2.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "fa5711d0559fc4b64deba0702be52d41434cbcb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fa5711d0559fc4b64deba0702be52d41434cbcb7", + "reference": "fa5711d0559fc4b64deba0702be52d41434cbcb7", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.3", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.0", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^5.2", + "phpunit/php-file-iterator": "^1.4", + "phpunit/php-text-template": "^1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^4.0", + "sebastian/comparator": "^2.0", + "sebastian/diff": "^1.4.3 || ^2.0", + "sebastian/environment": "^3.0.2", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^1.1 || ^2.0", + "sebastian/object-enumerator": "^3.0.2", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2", + "phpunit/dbunit": "<3.0" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "^1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2017-07-03T15:54:24+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "d8833b396dce9162bb2eb5d59aee5a3ab3cfa5b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/d8833b396dce9162bb2eb5d59aee5a3ab3cfa5b4", + "reference": "d8833b396dce9162bb2eb5d59aee5a3ab3cfa5b4", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^3.0" + }, + "conflict": { + "phpunit/phpunit": "<6.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2017-06-30T08:15:21+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "20f84f468cb67efee293246e6a09619b891f55f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/20f84f468cb67efee293246e6a09619b891f55f0", + "reference": "20f84f468cb67efee293246e6a09619b891f55f0", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/diff": "^1.2", + "sebastian/exporter": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2017-03-03T06:26:08+00:00" + }, + { + "name": "sebastian/diff", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2017-05-22T07:24:03+00:00" + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2017-07-01T08:51:00+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2017-04-03T13:19:02+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "31dd3379d16446c5d86dec32ab1ad1f378581ad8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/31dd3379d16446c5d86dec32ab1ad1f378581ad8", + "reference": "31dd3379d16446c5d86dec32ab1ad1f378581ad8", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-03-12T15:17:29+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2016-11-23T20:04:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/framework/config-global.php b/framework/config-global.php index d4bdf2bf..68af380e 100644 --- a/framework/config-global.php +++ b/framework/config-global.php @@ -50,10 +50,6 @@ $cfg->setConfigEntry('local_database_path', $cfg->getConfigEntry('root_base_path // CFG: TIME-ZONE $cfg->setDefaultTimezone('Europe/Berlin'); -// CFG: MAGIC-QUOTES-RUNTIME -// @DEPRECATED As PHP is deprecating this -$cfg->setMagicQuotesRuntime(false); - // CFG: CLASS-PREFIX $cfg->setConfigEntry('class_prefix', 'class_'); diff --git a/framework/main/classes/database/backend/class_CachedLocalFileDatabase.php b/framework/main/classes/database/backend/class_CachedLocalFileDatabase.php deleted file mode 100644 index e8a8555a..00000000 --- a/framework/main/classes/database/backend/class_CachedLocalFileDatabase.php +++ /dev/null @@ -1,687 +0,0 @@ - - * @version 0.0.0 - * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team - * @license GNU GPL 3.0 or any newer version - * @link http://www.shipsimu.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -class CachedLocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackend { - /** - * The file's extension - */ - private $fileExtension = 'serialized'; - - /** - * The last read file's name - */ - private $lastFile = ''; - - /** - * The last read file's content including header information - */ - private $lastContents = array(); - - /** - * Whether the "connection is already up - */ - private $alreadyConnected = false; - - /** - * Table information array - */ - private $tableInfo = array(); - - /** - * Element for index - */ - private $indexKey = '__idx'; - - /** - * The protected constructor. Do never instance from outside! You need to - * set a local file path. The class will then validate it. - * - * @return void - */ - protected function __construct () { - // Call parent constructor - parent::__construct(__CLASS__); - } - - /** - * Create an object of CachedLocalFileDatabase and set the save path from - * configuration for local files. - * - * @return $databaseInstance An instance of CachedLocalFileDatabase - */ - public static final function createCachedLocalFileDatabase () { - // Get an instance - $databaseInstance = new CachedLocalFileDatabase(); - - // Get a new compressor channel instance - $compressorInstance = ObjectFactory::createObjectByConfiguredName('compressor_channel_class'); - - // Set the compressor channel - $databaseInstance->setCompressorChannel($compressorInstance); - - // Get a file IO handler - $fileIoInstance = ObjectFactory::createObjectByConfiguredName('file_io_class'); - - // ... and set it - $databaseInstance->setFileIoInstance($fileIoInstance); - - // "Connect" to the database - $databaseInstance->connectToDatabase(); - - // Return database instance - return $databaseInstance; - } - - /** - * Setter for the last read file - * - * @param $fqfn The FQFN of the last read file - * @return void - */ - private final function setLastFile ($fqfn) { - // Cast string and set it - $this->lastFile = (string) $fqfn; - } - - /** - * Getter for last read file - * - * @return $lastFile The last read file's name with full path - */ - public final function getLastFile () { - return $this->lastFile; - } - - /** - * Setter for contents of the last read file - * - * @param $contents An array with header and data elements - * @return void - */ - private final function setLastFileContents (array $contents) { - // Set array - $this->lastContents = $contents; - } - - /** - * Getter for last read file's content as an array - * - * @return $lastContent The array with elements 'header' and 'data'. - */ - public final function getLastContents () { - return $this->lastContents; - } - - /** - * Getter for file extension - * - * @return $fileExtension The array with elements 'header' and 'data'. - */ - public final function getFileExtension () { - return $this->fileExtension; - } - - /** - * Getter for index key - * - * @return $indexKey Index key - */ - public final function getIndexKey () { - return $this->indexKey; - } - - /** - * Reads a local data file and returns it's contents in an array - * - * @param $fqfn The FQFN for the requested file - * @return $dataArray - */ - private function getDataArrayFromFile ($fqfn) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Reading elements from database file ' . $fqfn . ' ...'); - - // Init compressed data - $compressedData = $this->getFileIoInstance()->loadFileContents($fqfn); - $compressedData = $compressedData['data']; - - // Close the file and throw the instance away - unset($fileInstance); - - // Decompress it - $serializedData = $this->getCompressorChannel()->getCompressor()->decompressStream($compressedData); - - // Unserialize it - $dataArray = json_decode($serializedData, true); - - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Read ' . count($dataArray) . ' elements from database file ' . $fqfn . '.'); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataArray=' . print_r($dataArray, true)); - - // Finally return it - return $dataArray; - } - - /** - * Writes data array to local file - * - * @param $fqfn The FQFN of the local file - * @param $dataArray An array with all the data we shall write - * @return void - */ - private function writeDataArrayToFqfn ($fqfn, array $dataArray) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Flushing ' . count($dataArray) . ' elements to database file ' . $fqfn . ' ...'); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataArray=' . print_r($dataArray, true)); - - // Serialize and compress it - $compressedData = $this->getCompressorChannel()->getCompressor()->compressStream(json_encode($dataArray)); - - // Write data - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Writing ' . strlen($compressedData) . ' bytes ...'); - - // Write this data BASE64 encoded to the file - $this->getFileIoInstance()->saveStreamToFile($fqfn, $compressedData, $this); - - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Flushing ' . count($dataArray) . ' elements to database file completed.'); - } - - /** - * Getter for table information file contents or an empty if info file was not created - * - * @param $dataSetInstance An instance of a database set class - * @return $infoArray An array with all table informations - */ - private function getContentsFromTableInfoFile (StoreableCriteria $dataSetInstance) { - // Default content is no data - $infoArray = array(); - - // Create FQFN for getting the table information file - $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); - - // Get the file contents - try { - $infoArray = $this->getDataArrayFromFile($fqfn); - } catch (FileNotFoundException $e) { - // Not found, so ignore it here - } - - // ... and return it - return $infoArray; - } - - /** - * Generates an FQFN from given dataset instance and string - * - * @param $dataSetInstance An instance of a database set class - * @param $rowName Name of the row - * @return $fqfn The FQFN for this row - */ - private function generateFqfnFromDataSet (Criteria $dataSetInstance, $rowName) { - // This is the FQFN - $fqfn = $this->getConfigInstance()->getConfigEntry('local_database_path') . $dataSetInstance->getTableName() . DIRECTORY_SEPARATOR . $rowName . '.' . $this->getFileExtension(); - - // Return it - return $fqfn; - } - - /** - * Creates the table info file from given dataset instance - * - * @param $dataSetInstance An instance of a database set class - * @return void - */ - private function createTableInfoFile (StoreableCriteria $dataSetInstance) { - // Create FQFN for creating the table information file - $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); - - // Get the data out from dataset in a local array - $this->tableInfo[$dataSetInstance->getTableName()] = array( - 'primary' => $dataSetInstance->getPrimaryKey(), - 'created' => time(), - 'last_updated' => time() - ); - - // Write the data to the file - $this->writeDataArrayToFqfn($fqfn, $this->tableInfo[$dataSetInstance->getTableName()]); - } - - /** - * Updates the table info file from given dataset instance - * - * @param $dataSetInstance An instance of a database set class - * @return void - */ - private function updateTableInfoFile (StoreableCriteria $dataSetInstance) { - // Get table name from criteria - $tableName = $dataSetInstance->getTableName(); - - // Create FQFN for creating the table information file - $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); - - // Get the data out from dataset in a local array - $this->tableInfo[$tableName]['primary'] = $dataSetInstance->getPrimaryKey(); - $this->tableInfo[$tableName]['last_updated'] = time(); - - // Write the data to the file - $this->writeDataArrayToFqfn($fqfn, $this->tableInfo[$tableName]); - } - - /** - * Updates the primary key information or creates the table info file if not found - * - * @param $dataSetInstance An instance of a database set class - * @return void - */ - private function updatePrimaryKey (StoreableCriteria $dataSetInstance) { - // Get table name from criteria - $tableName = $dataSetInstance->getTableName(); - - // Get the information array from lower method - $infoArray = $this->getContentsFromTableInfoFile($dataSetInstance); - - // Is the primary key there? - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: tableInfo=' . print_r($this->tableInfo, true)); - if (!isset($this->tableInfo[$tableName]['primary'])) { - // Then create the info file - $this->createTableInfoFile($dataSetInstance); - } elseif (($this->getConfigInstance()->getConfigEntry('db_update_primary_forced') == 'Y') && ($dataSetInstance->getPrimaryKey() != $this->tableInfo[$tableName]['primary'])) { - // Set the array element - $this->tableInfo[$tableName]['primary'] = $dataSetInstance->getPrimaryKey(); - - // Update the entry - $this->updateTableInfoFile($dataSetInstance); - } - } - - /** - * Makes sure that the database connection is alive - * - * @return void - * @todo Do some checks on the database directory and files here - */ - public function connectToDatabase () { - } - - /** - * Starts a SELECT query on the database by given return type, table name - * and search criteria - * - * @param $tableName Name of the database table - * @param $searchInstance Local search criteria class - * @return $resultData Result data of the query - * @throws UnsupportedCriteriaException If the criteria is unsupported - * @throws SqlException If an 'SQL error' occurs - */ - public function querySelect ($tableName, LocalSearchCriteria $searchInstance) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: tableName=' . $tableName . ' - CALLED!'); - - // The result is null by any errors - $resultData = NULL; - - // Create full path name - $pathName = $this->getConfigInstance()->getConfigEntry('local_database_path') . $tableName . DIRECTORY_SEPARATOR; - - /* - * A 'select' query is not that easy on local files, so first try to - * find the 'table' which is in fact a directory on the server - */ - try { - // Get a directory pointer instance - $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($pathName)); - - // Initialize the result data, this need to be rewritten e.g. if a local file cannot be read - $resultData = array( - BaseDatabaseBackend::RESULT_INDEX_STATUS => self::RESULT_OKAY, - BaseDatabaseBackend::RESULT_INDEX_ROWS => array() - ); - - // Initialize limit/skip - $limitFound = 0; - $skipFound = 0; - $idx = 1; - - // Read the directory with some exceptions - while (($dataFile = $directoryInstance->readDirectoryExcept(array('.htaccess', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',this->getFileExtension()=' . $this->getFileExtension()); - - // Does the extension match? - if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { - // Skip this file! - continue; - } // END - if - - // Read the file - $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',dataArray='.print_r($dataArray, true)); - - // Is this an array? - if (is_array($dataArray)) { - // Default is nothing found - $isFound = true; - - // Search in the criteria with FMFW (First Matches, First Wins) - foreach ($dataArray as $key => $value) { - // Make sure value is not bool - assert(!is_bool($value)); - - // Found one entry? - $isFound = (($isFound === true) && ($searchInstance->isCriteriaMatching($key, $value))); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: key=' . $key . ',value=' . $value . ',isFound=' . intval($isFound)); - } // END - foreach - - // Is all found? - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: isFound=' . intval($isFound) . ',limitFound=' . $limitFound . ',limit=' . $searchInstance->getLimit()); - if ($isFound === true) { - // Shall we skip this entry? - if ($searchInstance->getSkip() > 0) { - // We shall skip some entries - if ($skipFound < $searchInstance->getSkip()) { - // Skip this entry - $skipFound++; - break; - } // END - if - } // END - if - - // Set id number - $dataArray[$this->getIndexKey()] = $idx; - - // Entry found! - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: indexKey=' . $this->getIndexKey() . ',idx=' . $idx . ',dataArray=' . print_r($dataArray, true)); - array_push($resultData[BaseDatabaseBackend::RESULT_INDEX_ROWS], $dataArray); - - // Count found entries up - $limitFound++; - } // END - if - } else { - // Throw an exception here - throw new SqlException(array($this, sprintf('File '%s' contains invalid data.', $dataFile), self::DB_CODE_DATA_FILE_CORRUPT), self::EXCEPTION_SQL_QUERY); - } - - // Count entry up - $idx++; - } // END - while - - // Close directory and throw the instance away - $directoryInstance->closeDirectory(); - unset($directoryInstance); - - // Reset last exception - $this->resetLastException(); - } catch (PathIsNoDirectoryException $e) { - // Path not found means "table not found" for real databases... - $this->setLastException($e); - - // So throw an SqlException here with faked error message - throw new SqlException (array($this, sprintf('Table '%s' not found', $tableName), self::DB_CODE_TABLE_MISSING), self::EXCEPTION_SQL_QUERY); - } catch (FrameworkException $e) { - // Catch all exceptions and store them in last error - $this->setLastException($e); - } - - // Return the gathered result - return $resultData; - } - - /** - * "Inserts" a data set instance into a local file database folder - * - * @param $dataSetInstance A storeable data set - * @return void - * @throws SqlException If an SQL error occurs - */ - public function queryInsertDataSet (StoreableCriteria $dataSetInstance) { - // Try to save the request away - try { - // Create full path name - $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, md5($dataSetInstance->getUniqueValue())); - - // Write the data away - $this->writeDataArrayToFqfn($fqfn, $dataSetInstance->getCriteriaArray()); - - // Update the primary key - $this->updatePrimaryKey($dataSetInstance); - - // Reset last exception - $this->resetLastException(); - } catch (FrameworkException $e) { - // Catch all exceptions and store them in last error - $this->setLastException($e); - - // Throw an SQL exception - throw new SqlException(array($this, sprintf('Cannot write data to table '%s', is the table created?', $dataSetInstance->getTableName()), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY); - } - } - - /** - * "Updates" a data set instance with a database layer - * - * @param $dataSetInstance A storeable data set - * @return void - * @throws SqlException If an SQL error occurs - */ - public function queryUpdateDataSet (StoreableCriteria $dataSetInstance) { - // Create full path name - $pathName = $this->getConfigInstance()->getConfigEntry('local_database_path') . $dataSetInstance->getTableName() . DIRECTORY_SEPARATOR; - - // Try all the requests - try { - // Get a file pointer instance - $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($pathName)); - - // Initialize limit/skip - $limitFound = 0; - $skipFound = 0; - - // Get the criteria array from the dataset - $searchArray = $dataSetInstance->getCriteriaArray(); - - // Get search criteria - $searchInstance = $dataSetInstance->getSearchInstance(); - - // Read the directory with some exceptions - while (($dataFile = $directoryInstance->readDirectoryExcept(array('.htaccess', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { - // Does the extension match? - if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',getFileExtension()=' . $this->getFileExtension() . ' - SKIPPED!'); - // Skip this file! - continue; - } // END - if - - // Open this file for reading - $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',dataArray='.print_r($dataArray, true)); - - // Is this an array? - if (is_array($dataArray)) { - // Default is nothing found - $isFound = true; - - // Search in the criteria with FMFW (First Matches, First Wins) - foreach ($dataArray as $key => $value) { - // Make sure value is not bool - assert(!is_bool($value)); - - // Found one entry? - $isFound = (($isFound === true) && ($searchInstance->isCriteriaMatching($key, $value))); - } // END - foreach - - // Is all found? - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: isFound=' . intval($isFound)); - if ($isFound === true) { - // Shall we skip this entry? - if ($searchInstance->getSkip() > 0) { - // We shall skip some entries - if ($skipFound < $searchInstance->getSkip()) { - // Skip this entry - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Found entry, but skipping ...'); - $skipFound++; - break; - } // END - if - } // END - if - - // Entry found, so update it - foreach ($searchArray as $searchKey => $searchValue) { - // Make sure the value is not bool again - assert(!is_bool($searchValue)); - assert($searchKey != $this->indexKey); - - // Debug message + add/update it - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: criteriaKey=' . $searchKey . ',criteriaValue=' . $searchValue); - $dataArray[$searchKey] = $searchValue; - } // END - foreach - - // Write the data to a local file - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Writing dataArray()=' . count($dataArray) . ' to ' . $dataFile . ' ...'); - $this->writeDataArrayToFqfn($pathName . $dataFile, $dataArray); - - // Count found entries up - $limitFound++; - } // END - if - } // END - if - } // END - while - - // Close the file pointer - $directoryInstance->closeDirectory(); - - // Update the primary key - $this->updatePrimaryKey($dataSetInstance); - - // Reset last exception - $this->resetLastException(); - } catch (FrameworkException $e) { - // Catch all exceptions and store them in last error - $this->setLastException($e); - - // Throw an SQL exception - throw new SqlException(array($this, sprintf('Cannot write data to table '%s', is the table created? Exception: %s, message:%s', $dataSetInstance->getTableName(), $e->__toString(), $e->getMessage()), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY); - } - } - - /** - * Getter for primary key of specified table or if not found null will be - * returned. This must be database-specific. - * - * @param $tableName Name of the table we need the primary key from - * @return $primaryKey Primary key column of the given table - */ - public function getPrimaryKeyOfTable ($tableName) { - // Default key is null - $primaryKey = NULL; - - // Does the table information exist? - if (isset($this->tableInfo[$tableName])) { - // Then return the primary key - $primaryKey = $this->tableInfo[$tableName]['primary']; - } // END - if - - // Return the column - return $primaryKey; - } - - /** - * Removes non-public data from given array. - * - * @param $data An array with possible non-public data that needs to be removed. - * @return $data A cleaned up array with only public data. - * @todo Add more generic non-public data for removal - */ - public function removeNonPublicDataFromArray (array $data) { - // Remove '__idx' - unset($data[$this->indexKey]); - - // Return it - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: data[' . gettype($data) . ']='.print_r($data, true)); - return $data; - } - - /** - * Counts total rows of given table - * - * @param $tableName Table name - * @return $count Total rows of given table - */ - public function countTotalRows($tableName) { - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: tableName=' . $tableName . ' - CALLED!'); - - // Create full path name - $pathName = $this->getConfigInstance()->getConfigEntry('local_database_path') . $tableName . DIRECTORY_SEPARATOR; - - // Try all the requests - try { - // Get a file pointer instance - $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($pathName)); - - // Initialize counter - $count = 0; - - // Read the directory with some exceptions - while ($dataFile = $directoryInstance->readDirectoryExcept(array('.htaccess', 'info.' . $this->getFileExtension()))) { - // Does the extension match? - if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',getFileExtension()=' . $this->getFileExtension() . ' - SKIPPED!'); - // Skip this file! - continue; - } // END - if - - // Count this row up - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',getFileExtension()=' . $this->getFileExtension() . ' - COUNTED!'); - $count++; - } // END - while - } catch (FrameworkException $e) { - // Catch all exceptions and store them in last error - $this->setLastException($e); - - // Throw an SQL exception - throw new SqlException(array($this, sprintf('Cannot count on table '%s', is the table created?', $dataSetInstance->getTableName()), self::DB_CODE_TABLE_NOT_FOUND), self::EXCEPTION_SQL_QUERY); - } - - // Return count - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: tableName=' . $tableName . ',count=' . $count . ' - EXIT!'); - return $count; - } - -} diff --git a/framework/main/classes/database/backend/lfdb_legacy/.htaccess b/framework/main/classes/database/backend/lfdb_legacy/.htaccess new file mode 100644 index 00000000..3a428827 --- /dev/null +++ b/framework/main/classes/database/backend/lfdb_legacy/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/framework/main/classes/database/backend/lfdb_legacy/class_CachedLocalFileDatabase.php b/framework/main/classes/database/backend/lfdb_legacy/class_CachedLocalFileDatabase.php new file mode 100644 index 00000000..e8a8555a --- /dev/null +++ b/framework/main/classes/database/backend/lfdb_legacy/class_CachedLocalFileDatabase.php @@ -0,0 +1,687 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.shipsimu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class CachedLocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackend { + /** + * The file's extension + */ + private $fileExtension = 'serialized'; + + /** + * The last read file's name + */ + private $lastFile = ''; + + /** + * The last read file's content including header information + */ + private $lastContents = array(); + + /** + * Whether the "connection is already up + */ + private $alreadyConnected = false; + + /** + * Table information array + */ + private $tableInfo = array(); + + /** + * Element for index + */ + private $indexKey = '__idx'; + + /** + * The protected constructor. Do never instance from outside! You need to + * set a local file path. The class will then validate it. + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Create an object of CachedLocalFileDatabase and set the save path from + * configuration for local files. + * + * @return $databaseInstance An instance of CachedLocalFileDatabase + */ + public static final function createCachedLocalFileDatabase () { + // Get an instance + $databaseInstance = new CachedLocalFileDatabase(); + + // Get a new compressor channel instance + $compressorInstance = ObjectFactory::createObjectByConfiguredName('compressor_channel_class'); + + // Set the compressor channel + $databaseInstance->setCompressorChannel($compressorInstance); + + // Get a file IO handler + $fileIoInstance = ObjectFactory::createObjectByConfiguredName('file_io_class'); + + // ... and set it + $databaseInstance->setFileIoInstance($fileIoInstance); + + // "Connect" to the database + $databaseInstance->connectToDatabase(); + + // Return database instance + return $databaseInstance; + } + + /** + * Setter for the last read file + * + * @param $fqfn The FQFN of the last read file + * @return void + */ + private final function setLastFile ($fqfn) { + // Cast string and set it + $this->lastFile = (string) $fqfn; + } + + /** + * Getter for last read file + * + * @return $lastFile The last read file's name with full path + */ + public final function getLastFile () { + return $this->lastFile; + } + + /** + * Setter for contents of the last read file + * + * @param $contents An array with header and data elements + * @return void + */ + private final function setLastFileContents (array $contents) { + // Set array + $this->lastContents = $contents; + } + + /** + * Getter for last read file's content as an array + * + * @return $lastContent The array with elements 'header' and 'data'. + */ + public final function getLastContents () { + return $this->lastContents; + } + + /** + * Getter for file extension + * + * @return $fileExtension The array with elements 'header' and 'data'. + */ + public final function getFileExtension () { + return $this->fileExtension; + } + + /** + * Getter for index key + * + * @return $indexKey Index key + */ + public final function getIndexKey () { + return $this->indexKey; + } + + /** + * Reads a local data file and returns it's contents in an array + * + * @param $fqfn The FQFN for the requested file + * @return $dataArray + */ + private function getDataArrayFromFile ($fqfn) { + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Reading elements from database file ' . $fqfn . ' ...'); + + // Init compressed data + $compressedData = $this->getFileIoInstance()->loadFileContents($fqfn); + $compressedData = $compressedData['data']; + + // Close the file and throw the instance away + unset($fileInstance); + + // Decompress it + $serializedData = $this->getCompressorChannel()->getCompressor()->decompressStream($compressedData); + + // Unserialize it + $dataArray = json_decode($serializedData, true); + + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Read ' . count($dataArray) . ' elements from database file ' . $fqfn . '.'); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataArray=' . print_r($dataArray, true)); + + // Finally return it + return $dataArray; + } + + /** + * Writes data array to local file + * + * @param $fqfn The FQFN of the local file + * @param $dataArray An array with all the data we shall write + * @return void + */ + private function writeDataArrayToFqfn ($fqfn, array $dataArray) { + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Flushing ' . count($dataArray) . ' elements to database file ' . $fqfn . ' ...'); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataArray=' . print_r($dataArray, true)); + + // Serialize and compress it + $compressedData = $this->getCompressorChannel()->getCompressor()->compressStream(json_encode($dataArray)); + + // Write data + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Writing ' . strlen($compressedData) . ' bytes ...'); + + // Write this data BASE64 encoded to the file + $this->getFileIoInstance()->saveStreamToFile($fqfn, $compressedData, $this); + + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Flushing ' . count($dataArray) . ' elements to database file completed.'); + } + + /** + * Getter for table information file contents or an empty if info file was not created + * + * @param $dataSetInstance An instance of a database set class + * @return $infoArray An array with all table informations + */ + private function getContentsFromTableInfoFile (StoreableCriteria $dataSetInstance) { + // Default content is no data + $infoArray = array(); + + // Create FQFN for getting the table information file + $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); + + // Get the file contents + try { + $infoArray = $this->getDataArrayFromFile($fqfn); + } catch (FileNotFoundException $e) { + // Not found, so ignore it here + } + + // ... and return it + return $infoArray; + } + + /** + * Generates an FQFN from given dataset instance and string + * + * @param $dataSetInstance An instance of a database set class + * @param $rowName Name of the row + * @return $fqfn The FQFN for this row + */ + private function generateFqfnFromDataSet (Criteria $dataSetInstance, $rowName) { + // This is the FQFN + $fqfn = $this->getConfigInstance()->getConfigEntry('local_database_path') . $dataSetInstance->getTableName() . DIRECTORY_SEPARATOR . $rowName . '.' . $this->getFileExtension(); + + // Return it + return $fqfn; + } + + /** + * Creates the table info file from given dataset instance + * + * @param $dataSetInstance An instance of a database set class + * @return void + */ + private function createTableInfoFile (StoreableCriteria $dataSetInstance) { + // Create FQFN for creating the table information file + $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); + + // Get the data out from dataset in a local array + $this->tableInfo[$dataSetInstance->getTableName()] = array( + 'primary' => $dataSetInstance->getPrimaryKey(), + 'created' => time(), + 'last_updated' => time() + ); + + // Write the data to the file + $this->writeDataArrayToFqfn($fqfn, $this->tableInfo[$dataSetInstance->getTableName()]); + } + + /** + * Updates the table info file from given dataset instance + * + * @param $dataSetInstance An instance of a database set class + * @return void + */ + private function updateTableInfoFile (StoreableCriteria $dataSetInstance) { + // Get table name from criteria + $tableName = $dataSetInstance->getTableName(); + + // Create FQFN for creating the table information file + $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info'); + + // Get the data out from dataset in a local array + $this->tableInfo[$tableName]['primary'] = $dataSetInstance->getPrimaryKey(); + $this->tableInfo[$tableName]['last_updated'] = time(); + + // Write the data to the file + $this->writeDataArrayToFqfn($fqfn, $this->tableInfo[$tableName]); + } + + /** + * Updates the primary key information or creates the table info file if not found + * + * @param $dataSetInstance An instance of a database set class + * @return void + */ + private function updatePrimaryKey (StoreableCriteria $dataSetInstance) { + // Get table name from criteria + $tableName = $dataSetInstance->getTableName(); + + // Get the information array from lower method + $infoArray = $this->getContentsFromTableInfoFile($dataSetInstance); + + // Is the primary key there? + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: tableInfo=' . print_r($this->tableInfo, true)); + if (!isset($this->tableInfo[$tableName]['primary'])) { + // Then create the info file + $this->createTableInfoFile($dataSetInstance); + } elseif (($this->getConfigInstance()->getConfigEntry('db_update_primary_forced') == 'Y') && ($dataSetInstance->getPrimaryKey() != $this->tableInfo[$tableName]['primary'])) { + // Set the array element + $this->tableInfo[$tableName]['primary'] = $dataSetInstance->getPrimaryKey(); + + // Update the entry + $this->updateTableInfoFile($dataSetInstance); + } + } + + /** + * Makes sure that the database connection is alive + * + * @return void + * @todo Do some checks on the database directory and files here + */ + public function connectToDatabase () { + } + + /** + * Starts a SELECT query on the database by given return type, table name + * and search criteria + * + * @param $tableName Name of the database table + * @param $searchInstance Local search criteria class + * @return $resultData Result data of the query + * @throws UnsupportedCriteriaException If the criteria is unsupported + * @throws SqlException If an 'SQL error' occurs + */ + public function querySelect ($tableName, LocalSearchCriteria $searchInstance) { + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: tableName=' . $tableName . ' - CALLED!'); + + // The result is null by any errors + $resultData = NULL; + + // Create full path name + $pathName = $this->getConfigInstance()->getConfigEntry('local_database_path') . $tableName . DIRECTORY_SEPARATOR; + + /* + * A 'select' query is not that easy on local files, so first try to + * find the 'table' which is in fact a directory on the server + */ + try { + // Get a directory pointer instance + $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($pathName)); + + // Initialize the result data, this need to be rewritten e.g. if a local file cannot be read + $resultData = array( + BaseDatabaseBackend::RESULT_INDEX_STATUS => self::RESULT_OKAY, + BaseDatabaseBackend::RESULT_INDEX_ROWS => array() + ); + + // Initialize limit/skip + $limitFound = 0; + $skipFound = 0; + $idx = 1; + + // Read the directory with some exceptions + while (($dataFile = $directoryInstance->readDirectoryExcept(array('.htaccess', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',this->getFileExtension()=' . $this->getFileExtension()); + + // Does the extension match? + if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { + // Skip this file! + continue; + } // END - if + + // Read the file + $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',dataArray='.print_r($dataArray, true)); + + // Is this an array? + if (is_array($dataArray)) { + // Default is nothing found + $isFound = true; + + // Search in the criteria with FMFW (First Matches, First Wins) + foreach ($dataArray as $key => $value) { + // Make sure value is not bool + assert(!is_bool($value)); + + // Found one entry? + $isFound = (($isFound === true) && ($searchInstance->isCriteriaMatching($key, $value))); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: key=' . $key . ',value=' . $value . ',isFound=' . intval($isFound)); + } // END - foreach + + // Is all found? + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: isFound=' . intval($isFound) . ',limitFound=' . $limitFound . ',limit=' . $searchInstance->getLimit()); + if ($isFound === true) { + // Shall we skip this entry? + if ($searchInstance->getSkip() > 0) { + // We shall skip some entries + if ($skipFound < $searchInstance->getSkip()) { + // Skip this entry + $skipFound++; + break; + } // END - if + } // END - if + + // Set id number + $dataArray[$this->getIndexKey()] = $idx; + + // Entry found! + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: indexKey=' . $this->getIndexKey() . ',idx=' . $idx . ',dataArray=' . print_r($dataArray, true)); + array_push($resultData[BaseDatabaseBackend::RESULT_INDEX_ROWS], $dataArray); + + // Count found entries up + $limitFound++; + } // END - if + } else { + // Throw an exception here + throw new SqlException(array($this, sprintf('File '%s' contains invalid data.', $dataFile), self::DB_CODE_DATA_FILE_CORRUPT), self::EXCEPTION_SQL_QUERY); + } + + // Count entry up + $idx++; + } // END - while + + // Close directory and throw the instance away + $directoryInstance->closeDirectory(); + unset($directoryInstance); + + // Reset last exception + $this->resetLastException(); + } catch (PathIsNoDirectoryException $e) { + // Path not found means "table not found" for real databases... + $this->setLastException($e); + + // So throw an SqlException here with faked error message + throw new SqlException (array($this, sprintf('Table '%s' not found', $tableName), self::DB_CODE_TABLE_MISSING), self::EXCEPTION_SQL_QUERY); + } catch (FrameworkException $e) { + // Catch all exceptions and store them in last error + $this->setLastException($e); + } + + // Return the gathered result + return $resultData; + } + + /** + * "Inserts" a data set instance into a local file database folder + * + * @param $dataSetInstance A storeable data set + * @return void + * @throws SqlException If an SQL error occurs + */ + public function queryInsertDataSet (StoreableCriteria $dataSetInstance) { + // Try to save the request away + try { + // Create full path name + $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, md5($dataSetInstance->getUniqueValue())); + + // Write the data away + $this->writeDataArrayToFqfn($fqfn, $dataSetInstance->getCriteriaArray()); + + // Update the primary key + $this->updatePrimaryKey($dataSetInstance); + + // Reset last exception + $this->resetLastException(); + } catch (FrameworkException $e) { + // Catch all exceptions and store them in last error + $this->setLastException($e); + + // Throw an SQL exception + throw new SqlException(array($this, sprintf('Cannot write data to table '%s', is the table created?', $dataSetInstance->getTableName()), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY); + } + } + + /** + * "Updates" a data set instance with a database layer + * + * @param $dataSetInstance A storeable data set + * @return void + * @throws SqlException If an SQL error occurs + */ + public function queryUpdateDataSet (StoreableCriteria $dataSetInstance) { + // Create full path name + $pathName = $this->getConfigInstance()->getConfigEntry('local_database_path') . $dataSetInstance->getTableName() . DIRECTORY_SEPARATOR; + + // Try all the requests + try { + // Get a file pointer instance + $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($pathName)); + + // Initialize limit/skip + $limitFound = 0; + $skipFound = 0; + + // Get the criteria array from the dataset + $searchArray = $dataSetInstance->getCriteriaArray(); + + // Get search criteria + $searchInstance = $dataSetInstance->getSearchInstance(); + + // Read the directory with some exceptions + while (($dataFile = $directoryInstance->readDirectoryExcept(array('.htaccess', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) { + // Does the extension match? + if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',getFileExtension()=' . $this->getFileExtension() . ' - SKIPPED!'); + // Skip this file! + continue; + } // END - if + + // Open this file for reading + $dataArray = $this->getDataArrayFromFile($pathName . $dataFile); + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',dataArray='.print_r($dataArray, true)); + + // Is this an array? + if (is_array($dataArray)) { + // Default is nothing found + $isFound = true; + + // Search in the criteria with FMFW (First Matches, First Wins) + foreach ($dataArray as $key => $value) { + // Make sure value is not bool + assert(!is_bool($value)); + + // Found one entry? + $isFound = (($isFound === true) && ($searchInstance->isCriteriaMatching($key, $value))); + } // END - foreach + + // Is all found? + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: isFound=' . intval($isFound)); + if ($isFound === true) { + // Shall we skip this entry? + if ($searchInstance->getSkip() > 0) { + // We shall skip some entries + if ($skipFound < $searchInstance->getSkip()) { + // Skip this entry + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Found entry, but skipping ...'); + $skipFound++; + break; + } // END - if + } // END - if + + // Entry found, so update it + foreach ($searchArray as $searchKey => $searchValue) { + // Make sure the value is not bool again + assert(!is_bool($searchValue)); + assert($searchKey != $this->indexKey); + + // Debug message + add/update it + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: criteriaKey=' . $searchKey . ',criteriaValue=' . $searchValue); + $dataArray[$searchKey] = $searchValue; + } // END - foreach + + // Write the data to a local file + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: Writing dataArray()=' . count($dataArray) . ' to ' . $dataFile . ' ...'); + $this->writeDataArrayToFqfn($pathName . $dataFile, $dataArray); + + // Count found entries up + $limitFound++; + } // END - if + } // END - if + } // END - while + + // Close the file pointer + $directoryInstance->closeDirectory(); + + // Update the primary key + $this->updatePrimaryKey($dataSetInstance); + + // Reset last exception + $this->resetLastException(); + } catch (FrameworkException $e) { + // Catch all exceptions and store them in last error + $this->setLastException($e); + + // Throw an SQL exception + throw new SqlException(array($this, sprintf('Cannot write data to table '%s', is the table created? Exception: %s, message:%s', $dataSetInstance->getTableName(), $e->__toString(), $e->getMessage()), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY); + } + } + + /** + * Getter for primary key of specified table or if not found null will be + * returned. This must be database-specific. + * + * @param $tableName Name of the table we need the primary key from + * @return $primaryKey Primary key column of the given table + */ + public function getPrimaryKeyOfTable ($tableName) { + // Default key is null + $primaryKey = NULL; + + // Does the table information exist? + if (isset($this->tableInfo[$tableName])) { + // Then return the primary key + $primaryKey = $this->tableInfo[$tableName]['primary']; + } // END - if + + // Return the column + return $primaryKey; + } + + /** + * Removes non-public data from given array. + * + * @param $data An array with possible non-public data that needs to be removed. + * @return $data A cleaned up array with only public data. + * @todo Add more generic non-public data for removal + */ + public function removeNonPublicDataFromArray (array $data) { + // Remove '__idx' + unset($data[$this->indexKey]); + + // Return it + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: data[' . gettype($data) . ']='.print_r($data, true)); + return $data; + } + + /** + * Counts total rows of given table + * + * @param $tableName Table name + * @return $count Total rows of given table + */ + public function countTotalRows($tableName) { + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: tableName=' . $tableName . ' - CALLED!'); + + // Create full path name + $pathName = $this->getConfigInstance()->getConfigEntry('local_database_path') . $tableName . DIRECTORY_SEPARATOR; + + // Try all the requests + try { + // Get a file pointer instance + $directoryInstance = ObjectFactory::createObjectByConfiguredName('directory_class', array($pathName)); + + // Initialize counter + $count = 0; + + // Read the directory with some exceptions + while ($dataFile = $directoryInstance->readDirectoryExcept(array('.htaccess', 'info.' . $this->getFileExtension()))) { + // Does the extension match? + if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) { + // Debug message + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',getFileExtension()=' . $this->getFileExtension() . ' - SKIPPED!'); + // Skip this file! + continue; + } // END - if + + // Count this row up + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',getFileExtension()=' . $this->getFileExtension() . ' - COUNTED!'); + $count++; + } // END - while + } catch (FrameworkException $e) { + // Catch all exceptions and store them in last error + $this->setLastException($e); + + // Throw an SQL exception + throw new SqlException(array($this, sprintf('Cannot count on table '%s', is the table created?', $dataSetInstance->getTableName()), self::DB_CODE_TABLE_NOT_FOUND), self::EXCEPTION_SQL_QUERY); + } + + // Return count + //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('DATABASE: tableName=' . $tableName . ',count=' . $count . ' - EXIT!'); + return $count; + } + +} diff --git a/nbproject/project.properties b/nbproject/project.properties index 7982449d..2d50fcf3 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -5,9 +5,9 @@ auxiliary.org-netbeans-modules-css-prep.sass_2e_compiler_2e_options= auxiliary.org-netbeans-modules-css-prep.sass_2e_enabled=false auxiliary.org-netbeans-modules-css-prep.sass_2e_mappings=/scss:/css auxiliary.org-netbeans-modules-javascript2-requirejs.enabled=false -auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_create_2e_tests=false -auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_enabled=false -auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_path= +auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_create_2e_tests=true +auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_enabled=true +auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_path=tests/bootstrap.php auxiliary.org-netbeans-modules-php-phpunit.configuration_2e_enabled=false auxiliary.org-netbeans-modules-php-phpunit.configuration_2e_path= auxiliary.org-netbeans-modules-php-phpunit.customSuite_2e_enabled=false diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 00000000..48142e8e --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,32 @@ + + + + + + ./tests/ + + + + + + framework + + framework/main/third_party/ + + + + + + + + diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 00000000..35eb2b2a --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,36 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @author Roland Haeder + */ +// TODO: check include path +//ini_set('include_path', ini_get('include_path')); + +// Bad and ugly: +$_SERVER['argv'][1] = 'app=tests'; + +// Pre-run own tests +require dirname(__DIR__) . '/index.php'; + +// Remove it to prevent leak to PHPUnit +unset($_SERVER['argv'][1]); + +// Autoload more stuff +require dirname(__DIR__) . '/vendor/autoload.php';