diff options
author | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
---|---|---|
committer | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
commit | fc7369835258467bf97eb64f184b93691f9a9fd5 (patch) | |
tree | daabd60089d2dd76d9f5fb416b005fbe159c799d /www/wiki/vendor/data-values |
first commit
Diffstat (limited to 'www/wiki/vendor/data-values')
110 files changed, 10893 insertions, 0 deletions
diff --git a/www/wiki/vendor/data-values/common/.gitignore b/www/wiki/vendor/data-values/common/.gitignore new file mode 100644 index 00000000..577795cb --- /dev/null +++ b/www/wiki/vendor/data-values/common/.gitignore @@ -0,0 +1,12 @@ +*~ +*.kate-swp +*.swp + +!.* + +.idea/ +build/ +vendor/ + +composer.phar +composer.lock
\ No newline at end of file diff --git a/www/wiki/vendor/data-values/common/.scrutinizer.yml b/www/wiki/vendor/data-values/common/.scrutinizer.yml new file mode 100644 index 00000000..d6c0c6b6 --- /dev/null +++ b/www/wiki/vendor/data-values/common/.scrutinizer.yml @@ -0,0 +1,13 @@ +build: true +inherit: true + +tools: + php_code_coverage: true + php_code_sniffer: true + php_cpd: true + php_cs_fixer: true + php_loc: true + php_mess_detector: true + php_pdepend: true + php_analyzer: true + sensiolabs_security_checker: true diff --git a/www/wiki/vendor/data-values/common/.travis.yml b/www/wiki/vendor/data-values/common/.travis.yml new file mode 100644 index 00000000..1296abef --- /dev/null +++ b/www/wiki/vendor/data-values/common/.travis.yml @@ -0,0 +1,12 @@ +language: php + +php: + - 5.6 + - 7 + - hhvm-3.18 + +before_script: + - travis_retry composer install --prefer-source + +script: + - composer ci diff --git a/www/wiki/vendor/data-values/common/COPYING b/www/wiki/vendor/data-values/common/COPYING new file mode 100644 index 00000000..ebba08a4 --- /dev/null +++ b/www/wiki/vendor/data-values/common/COPYING @@ -0,0 +1,347 @@ +The license text below "----" applies to all files within this distribution, other +than those that are in a directory which contains files named "LICENSE" or +"COPYING", or a subdirectory thereof. For those files, the license text contained in +said file overrides any license information contained in directories of smaller depth. +Alternative licenses are typically used for software that is provided by external +parties, and merely packaged with this software for convenience. +---- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/www/wiki/vendor/data-values/common/Common.php b/www/wiki/vendor/data-values/common/Common.php new file mode 100644 index 00000000..5c84d978 --- /dev/null +++ b/www/wiki/vendor/data-values/common/Common.php @@ -0,0 +1,18 @@ +<?php + +/** + * Entry point of the DataValues Common library. + * + * @since 0.1 + * @codeCoverageIgnore + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ + +if ( defined( 'DATAVALUES_COMMON_VERSION' ) ) { + // Do not initialize more than once. + return 1; +} + +define( 'DATAVALUES_COMMON_VERSION', '0.4.3' ); diff --git a/www/wiki/vendor/data-values/common/README.md b/www/wiki/vendor/data-values/common/README.md new file mode 100644 index 00000000..e025348a --- /dev/null +++ b/www/wiki/vendor/data-values/common/README.md @@ -0,0 +1,126 @@ +# DataValues Common + +DataValues Common is a small library build on top of DataValues that provides common +implementations of the DataValues, ValueParsers, ValueFormatters and ValueValidators interfaces. + +It is part of the [DataValues set of libraries](https://github.com/DataValues). + +[![Build Status](https://secure.travis-ci.org/DataValues/Common.png?branch=master)](http://travis-ci.org/DataValues/Common) +[![Code Coverage](https://scrutinizer-ci.com/g/DataValues/Common/badges/coverage.png?s=728b9287ebdd13fbe15255d4d55575c5b5d47b8f)](https://scrutinizer-ci.com/g/DataValues/Common/) +[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/DataValues/Common/badges/quality-score.png?s=3195539d2e929aafaefb4bc006fb0da6c09a4d2a)](https://scrutinizer-ci.com/g/DataValues/Common/) + +On [Packagist](https://packagist.org/packages/data-values/common): +[![Latest Stable Version](https://poser.pugx.org/data-values/common/version.png)](https://packagist.org/packages/data-values/common) +[![Download count](https://poser.pugx.org/data-values/common/d/total.png)](https://packagist.org/packages/data-values/common) + +## Installation + +The recommended way to use this library is via [Composer](http://getcomposer.org/). + +### Composer + +To add this package as a local, per-project dependency to your project, simply add a +dependency on `data-values/common` to your project's `composer.json` file. +Here is a minimal example of a `composer.json` file that just defines a dependency on +version 0.3 of this package: + + { + "require": { + "data-values/common": "0.3.*" + } + } + +### Manual + +Get the code of this package, either via git, or some other means. Also get all dependencies. +You can find a list of the dependencies in the "require" section of the composer.json file. +Then take care of autoloading the classes defined in the src directory. + +## Tests + +This library comes with a set up PHPUnit tests that cover all non-trivial code. You can run these +tests using the PHPUnit configuration file found in the root directory. The tests can also be run +via TravisCI, as a TravisCI configuration file is also provided in the root directory. + +## Authors + +DataValues Common has been written by the Wikidata team, as [Wikimedia Germany] +(https://wikimedia.de) employees for the [Wikidata project](https://wikidata.org/). + +## Release notes + +### 0.4.3 (2019-06-28) + +* Fixed typo in error message in `DispatchingValueParser` + +### 0.4.2 (2018-08-16) + +* The component can now be installed together with DataValues 2.x + +### 0.4.1 (2018-08-09) + +* Fixed version number not updated before. + +### 0.4.0 (2017-08-09) + +* Removed MediaWiki integration + +### 0.3.1 (2015-08-14) + +* The component can now be installed together with DataValues Interfaces 0.1.5 + +### 0.3.0 (2015-08-11) + +* Added `DispatchingValueParser` +* Added `StringNormalizer` interface +* Added `NullStringNormalizer` +* Added `StringParser` +* Dropped deprecated constant `DataValuesCommon_VERSION`, use `DATAVALUES_COMMON_VERSION` instead +* Dropped `ValueParserTestBase::getParserClass` +* Dropped `ValueParserTestBase::newParserOptions` +* Made `ValueParserTestBase::getInstance` abstract +* Made `ValueParserTestBase::invalidInputProvider` abstract +* Lowered visibility of all class fields to private + +### 0.2.3 (2014-10-09) + +* Introduced `FORMAT_NAME` class constants on ValueParsers in order to use them as expectedFormat +* Changed ValueParsers to pass rawValue and expectedFormat arguments when constructing a `ParseException` +* Installation together with DataValues 1.x is now supported + +### 0.2.2 (2014-04-11) + +* Introduced `DataValueMismatchException` + +### 0.2.1 (2014-03-12) + +* Minor code cleanup +* Improved PHPUnit bootstrap + +### 0.2 (2013-12-16) + +* Added FloatParser (moved from data-values/number) +* Added IntParser (moved from data-values/number) + +### 0.1.1 (2013-11-22) + +* Fixed link in the MediaWiki credits + +### 0.1 (2013-11-17) + +Initial release with these features: + +* Several DataValue implementations + * MonolingualTextValue + * MultilingualTextValue +* Several ValueFormatter implementations + * StringFormatter +* Several ValueParser implementations + * BoolParser + * DecimalParser + * NullParser + +## Links + +* [DataValues Common on Packagist](https://packagist.org/packages/data-values/common) +* [DataValues Common on TravisCI](https://travis-ci.org/DataValues/Common) diff --git a/www/wiki/vendor/data-values/common/composer.json b/www/wiki/vendor/data-values/common/composer.json new file mode 100644 index 00000000..e49bdc99 --- /dev/null +++ b/www/wiki/vendor/data-values/common/composer.json @@ -0,0 +1,60 @@ +{ + "name": "data-values/common", + "type": "library", + "description": "Contains common implementations of the interfaces defined by DataValuesInterfaces", + "keywords": [ + "datavalues", + "valueparsers", + "valueformatters", + "valuevalidators", + "wikidata" + ], + "homepage": "https://github.com/DataValues/Common", + "license": "GPL-2.0+", + "authors": [ + { + "name": "Jeroen De Dauw", + "email": "jeroendedauw@gmail.com", + "homepage": "http://jeroendedauw.com", + "role": "Developer" + } + ], + "support": { + "irc": "irc://irc.freenode.net/wikidata" + }, + "require": { + "php": ">=5.3.0", + "data-values/data-values": "~2.0|~1.0|~0.1", + "data-values/interfaces": "~0.2.0|^0.1.5" + }, + "require-dev": { + "phpunit/phpunit": "~5.7" + }, + "extra": { + "branch-alias": { + "dev-master": "0.4.x-dev" + } + }, + "autoload": { + "files" : [ + "Common.php" + ], + "psr-4": { + "DataValues\\": "src/DataValues/", + "ValueFormatters\\": "src/ValueFormatters/", + "ValueParsers\\": "src/ValueParsers/" + }, + "classmap": [ + "tests/ValueParsers" + ] + }, + "scripts": { + "test": [ + "composer validate --no-interaction", + "phpunit --coverage-text=/dev/null" + ], + "ci": [ + "composer test" + ] + } +} diff --git a/www/wiki/vendor/data-values/common/phpunit.xml.dist b/www/wiki/vendor/data-values/common/phpunit.xml.dist new file mode 100644 index 00000000..1c6adb15 --- /dev/null +++ b/www/wiki/vendor/data-values/common/phpunit.xml.dist @@ -0,0 +1,24 @@ +<phpunit backupGlobals="false" + backupStaticAttributes="false" + bootstrap="tests/bootstrap.php" + cacheTokens="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + stopOnError="false" + stopOnFailure="false" + stopOnIncomplete="false" + stopOnSkipped="false" + verbose="true"> + <testsuites> + <testsuite name="DataValuesCommon"> + <directory>tests</directory> + </testsuite> + </testsuites> + <filter> + <whitelist addUncoveredFilesFromWhitelist="true"> + <directory suffix=".php">src</directory> + </whitelist> + </filter> +</phpunit> diff --git a/www/wiki/vendor/data-values/common/src/DataValues/MonolingualTextValue.php b/www/wiki/vendor/data-values/common/src/DataValues/MonolingualTextValue.php new file mode 100644 index 00000000..dcd3cd29 --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/DataValues/MonolingualTextValue.php @@ -0,0 +1,147 @@ +<?php + +namespace DataValues; + +/** + * Class representing a monolingual text value. + * + * @since 0.1 + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class MonolingualTextValue extends DataValueObject { + + /** + * @var string + */ + private $text; + + /** + * @var string + */ + private $languageCode; + + /** + * @since 0.1 + * + * @param string $languageCode + * @param string $text + * + * @throws IllegalValueException + */ + public function __construct( $languageCode, $text ) { + if ( !is_string( $languageCode ) ) { + throw new IllegalValueException( 'Can only construct MonolingualTextValue with a string language code.' ); + } + elseif ( $languageCode === '' ) { + throw new IllegalValueException( 'Can not construct a MonolingualTextValue with an empty language code.' ); + } + + if ( !is_string( $text ) ) { + throw new IllegalValueException( 'Can only construct a MonolingualTextValue with a string value.' ); + } + + $this->text = $text; + $this->languageCode = $languageCode; + } + + /** + * @see Serializable::serialize + * + * @return string + */ + public function serialize() { + return serialize( array( $this->languageCode, $this->text ) ); + } + + /** + * @see Serializable::unserialize + * + * @param string $value + */ + public function unserialize( $value ) { + list( $languageCode, $text ) = unserialize( $value ); + $this->__construct( $languageCode, $text ); + } + + /** + * @see DataValue::getType + * + * @return string + */ + public static function getType() { + return 'monolingualtext'; + } + + /** + * @see DataValue::getSortKey + * + * @return string + */ + public function getSortKey() { + // TODO: we might want to re-think this key. Perhaps the language should simply be omitted. + return $this->languageCode . $this->text; + } + + /** + * @see DataValue::getValue + * + * @return MonolingualTextValue + */ + public function getValue() { + return $this; + } + + /** + * Returns the text. + * + * @since 0.1 + * + * @return string + */ + public function getText() { + return $this->text; + } + + /** + * Returns the language code. + * + * @since 0.1 + * + * @return string + */ + public function getLanguageCode() { + return $this->languageCode; + } + + /** + * @see DataValue::getArrayValue + * + * @return string[] + */ + public function getArrayValue() { + return array( + 'text' => $this->text, + 'language' => $this->languageCode, + ); + } + + /** + * Constructs a new instance of the DataValue from the provided data. + * This can round-trip with @see getArrayValue + * + * @since 0.1 + * + * @param string[] $data + * + * @return MonolingualTextValue + * @throws IllegalValueException + */ + public static function newFromArray( $data ) { + self::requireArrayFields( $data, array( 'language', 'text' ) ); + + return new static( $data['language'], $data['text'] ); + } + +} diff --git a/www/wiki/vendor/data-values/common/src/DataValues/MultilingualTextValue.php b/www/wiki/vendor/data-values/common/src/DataValues/MultilingualTextValue.php new file mode 100644 index 00000000..97e3bbe6 --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/DataValues/MultilingualTextValue.php @@ -0,0 +1,146 @@ +<?php + +namespace DataValues; + +/** + * Class representing a multilingual text value. + * + * @since 0.1 + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class MultilingualTextValue extends DataValueObject { + + /** + * Array with language codes pointing to their associated texts. + * + * @var MonolingualTextValue[] + */ + private $texts = array(); + + /** + * @since 0.1 + * + * @param MonolingualTextValue[] $monolingualValues + * + * @throws IllegalValueException + */ + public function __construct( array $monolingualValues ) { + foreach ( $monolingualValues as $monolingualValue ) { + if ( !( $monolingualValue instanceof MonolingualTextValue ) ) { + throw new IllegalValueException( 'Can only construct MultilingualTextValue from MonolingualTextValue objects' ); + } + + $languageCode = $monolingualValue->getLanguageCode(); + + if ( array_key_exists( $languageCode, $this->texts ) ) { + throw new IllegalValueException( 'Can only add a single MonolingualTextValue per language to a MultilingualTextValue' ); + } + + $this->texts[$languageCode] = $monolingualValue; + } + } + + /** + * @see Serializable::serialize + * + * @return string + */ + public function serialize() { + return serialize( $this->texts ); + } + + /** + * @see Serializable::unserialize + * + * @param string $value + */ + public function unserialize( $value ) { + $this->__construct( unserialize( $value ) ); + } + + /** + * @see DataValue::getType + * + * @return string + */ + public static function getType() { + return 'multilingualtext'; + } + + /** + * @see DataValue::getSortKey + * + * @return string|float|int + */ + public function getSortKey() { + return empty( $this->texts ) ? '' : reset( $this->texts )->getSortKey(); + } + + /** + * Returns the texts as an array of monolingual text values. + * + * @since 0.1 + * + * @return MonolingualTextValue[] + */ + public function getTexts() { + return $this->texts; + } + + /** + * Returns the multilingual text value + * @see DataValue::getValue + * + * @return MultilingualTextValue + */ + public function getValue() { + return $this; + } + + /** + * @see DataValue::getArrayValue + * + * @return mixed + */ + public function getArrayValue() { + $values = array(); + + /** + * @var MonolingualTextValue $text + */ + foreach ( $this->texts as $text ) { + $values[] = $text->getArrayValue(); + } + + return $values; + } + + /** + * Constructs a new instance of the DataValue from the provided data. + * This can round-trip with + * @see getArrayValue + * + * @since 0.1 + * + * @param mixed $data + * + * @throws IllegalValueException if $data is not an array. + * @return MultilingualTextValue + */ + public static function newFromArray( $data ) { + if ( !is_array( $data ) ) { + throw new IllegalValueException( "array expected" ); + } + + $values = array(); + + foreach ( $data as $monolingualValue ) { + $values[] = MonolingualTextValue::newFromArray( $monolingualValue ); + } + + return new static( $values ); + } + +} diff --git a/www/wiki/vendor/data-values/common/src/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php b/www/wiki/vendor/data-values/common/src/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php new file mode 100644 index 00000000..a07825ea --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php @@ -0,0 +1,58 @@ +<?php + +namespace ValueFormatters\Exceptions; + +use Exception; +use ValueFormatters\FormattingException; + +/** + * @since 0.2.1 + * + * @licence GNU GPL v2+ + * @author Katie Filbert < aude.wiki@gmail.com > + */ +class MismatchingDataValueTypeException extends FormattingException { + + /** + * @var string + */ + private $expectedValueType; + + /** + * @var string + */ + private $dataValueType; + + /** + * @param string $expectedValueType + * @param string $dataValueType + * @param string $message + * @param Exception $previous + */ + public function __construct( $expectedValueType, $dataValueType, $message = '', + Exception $previous = null + ) { + $this->expectedValueType = $expectedValueType; + $this->dataValueType = $dataValueType; + + $message = '$dataValueType "' . $dataValueType . '" does not match $expectedValueType "' + . $expectedValueType . '": $message'; + + parent::__construct( $message, 0, $previous ); + } + + /** + * @return string + */ + public function getExpectedValueType() { + return $this->expectedValueType; + } + + /** + * @return string + */ + public function getDataValueType() { + return $this->dataValueType; + } + +} diff --git a/www/wiki/vendor/data-values/common/src/ValueFormatters/StringFormatter.php b/www/wiki/vendor/data-values/common/src/ValueFormatters/StringFormatter.php new file mode 100644 index 00000000..acb6b504 --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/ValueFormatters/StringFormatter.php @@ -0,0 +1,34 @@ +<?php + +namespace ValueFormatters; + +use DataValues\StringValue; +use InvalidArgumentException; + +/** + * Formatter for string values + * + * @since 0.1 + * + * @licence GNU GPL v2+ + * @author Katie Filbert < aude.wiki@gmail.com > + */ +class StringFormatter extends ValueFormatterBase { + + /** + * @see ValueFormatter::format + * + * @param StringValue $dataValue + * + * @throws InvalidArgumentException + * @return string Text + */ + public function format( $dataValue ) { + if ( !( $dataValue instanceof StringValue ) ) { + throw new InvalidArgumentException( 'Data value type mismatch. Expected a StringValue.' ); + } + + return $dataValue->getValue(); + } + +} diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/BoolParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/BoolParser.php new file mode 100644 index 00000000..fb73aa25 --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/ValueParsers/BoolParser.php @@ -0,0 +1,50 @@ +<?php + +namespace ValueParsers; + +use DataValues\BooleanValue; + +/** + * ValueParser that parses the string representation of a boolean. + * + * @since 0.1 + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class BoolParser extends StringValueParser { + + const FORMAT_NAME = 'bool'; + + private static $values = array( + 'yes' => true, + 'on' => true, + '1' => true, + 'true' => true, + 'no' => false, + 'off' => false, + '0' => false, + 'false' => false, + ); + + /** + * @see StringValueParser::stringParse + * + * @param string $value + * + * @return BooleanValue + * @throws ParseException + */ + protected function stringParse( $value ) { + $rawValue = $value; + + $value = strtolower( $value ); + + if ( array_key_exists( $value, self::$values ) ) { + return new BooleanValue( self::$values[$value] ); + } + + throw new ParseException( 'Not a boolean', $rawValue, self::FORMAT_NAME ); + } + +} diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/DispatchingValueParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/DispatchingValueParser.php new file mode 100644 index 00000000..5146a3e6 --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/ValueParsers/DispatchingValueParser.php @@ -0,0 +1,71 @@ +<?php + +namespace ValueParsers; + +use InvalidArgumentException; + +/** + * A generic value parser that forwards parsing to a list of other value parsers and returns the + * result of the first parse attempt that succeeded. + * + * @since 0.3 + * + * @licence GNU GPL v2+ + * @author Thiemo Mättig + */ +class DispatchingValueParser implements ValueParser { + + /** + * @var ValueParser[] + */ + private $parsers; + + /** + * @see ParseException::getExpectedFormat + * + * @var string + */ + private $format; + + /** + * @param ValueParser[] $parsers + * @param string $format An identifier describing the expected format of the values to parse. + * + * @throws InvalidArgumentException + */ + public function __construct( array $parsers, $format ) { + if ( empty( $parsers ) ) { + throw new InvalidArgumentException( '$parsers must be a non-empty array' ); + } + + if ( !is_string( $format ) || $format === '' ) { + throw new InvalidArgumentException( '$format must be a non-empty string' ); + } + + $this->parsers = $parsers; + $this->format = $format; + } + + /** + * @param mixed $value + * + * @throws ParseException + * @return mixed + */ + public function parse( $value ) { + foreach ( $this->parsers as $parser ) { + try { + return $parser->parse( $value ); + } catch ( ParseException $ex ) { + continue; + } + } + + throw new ParseException( + 'The value is not recognized by the configured parsers', + $value, + $this->format + ); + } + +} diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/FloatParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/FloatParser.php new file mode 100644 index 00000000..9472fa6f --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/ValueParsers/FloatParser.php @@ -0,0 +1,37 @@ +<?php + +namespace ValueParsers; + +use DataValues\NumberValue; + +/** + * ValueParser that parses the string representation of a float. + * + * @since 0.1 + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class FloatParser extends StringValueParser { + + const FORMAT_NAME = 'float'; + + /** + * @see StringValueParser::stringParse + * + * TODO: add options for different group and decimal separators. + * + * @param string $value + * + * @return NumberValue + * @throws ParseException + */ + protected function stringParse( $value ) { + if ( preg_match( '/^(-)?\d+((\.|,)\d+)?$/', $value ) ) { + return new NumberValue( (float)$value ); + } + + throw new ParseException( 'Not a float', $value, self::FORMAT_NAME ); + } + +} diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/IntParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/IntParser.php new file mode 100644 index 00000000..8ca2f0fe --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/ValueParsers/IntParser.php @@ -0,0 +1,37 @@ +<?php + +namespace ValueParsers; + +use DataValues\NumberValue; + +/** + * ValueParser that parses the string representation of an integer. + * + * @since 0.1 + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class IntParser extends StringValueParser { + + const FORMAT_NAME = 'int'; + + /** + * @see StringValueParser::stringParse + * + * @param string $value + * + * @return NumberValue + * @throws ParseException + */ + protected function stringParse( $value ) { + $positiveValue = strpos( $value, '-' ) === 0 ? substr( $value, 1 ) : $value; + + if ( ctype_digit( $positiveValue ) ) { + return new NumberValue( (int)$value ); + } + + throw new ParseException( 'Not an integer', $value, self::FORMAT_NAME ); + } + +} diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/NullStringNormalizer.php b/www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/NullStringNormalizer.php new file mode 100644 index 00000000..70ce3029 --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/NullStringNormalizer.php @@ -0,0 +1,31 @@ +<?php + +namespace ValueParsers\Normalizers; + +use InvalidArgumentException; + +/** + * Null implementation of StringNormalizer. + * + * @since 0.3 + * + * @license GPL 2+ + * @author Daniel Kinzler + */ +class NullStringNormalizer implements StringNormalizer { + + /** + * @param string $value + * + * @throws InvalidArgumentException if $value is not a string + * @return string the normalized value + */ + public function normalize( $value ) { + if ( !is_string( $value ) ) { + throw new InvalidArgumentException( 'Parameter $value must be a string' ); + } + + return $value; + } + +} diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/StringNormalizer.php b/www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/StringNormalizer.php new file mode 100644 index 00000000..d0cfe90e --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/StringNormalizer.php @@ -0,0 +1,25 @@ +<?php + +namespace ValueParsers\Normalizers; + +use InvalidArgumentException; + +/** + * Interface for string normalization. + * + * @since 0.3 + * + * @license GPL 2+ + * @author Daniel Kinzler + */ +interface StringNormalizer { + + /** + * @param string $value + * + * @throws InvalidArgumentException if $value is not a string + * @return string the normalized value + */ + public function normalize( $value ); + +} diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/NullParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/NullParser.php new file mode 100644 index 00000000..de6ca580 --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/ValueParsers/NullParser.php @@ -0,0 +1,28 @@ +<?php + +namespace ValueParsers; + +use DataValues\UnknownValue; + +/** + * Implementation of the ValueParser interface that does a null parse. + * + * @since 0.1 + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class NullParser implements ValueParser { + + /** + * @see ValueParser::parse + * + * @param mixed $value + * + * @return UnknownValue + */ + public function parse( $value ) { + return new UnknownValue( $value ); + } + +} diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/StringParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/StringParser.php new file mode 100644 index 00000000..820446d1 --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/ValueParsers/StringParser.php @@ -0,0 +1,49 @@ +<?php + +namespace ValueParsers; + +use DataValues\StringValue; +use InvalidArgumentException; +use ValueParsers\Normalizers\NullStringNormalizer; +use ValueParsers\Normalizers\StringNormalizer; + +/** + * Implementation of the ValueParser interface for StringValues. + * + * @since 0.3 + * + * @licence GNU GPL v2+ + * @author Daniel Kinzler + */ +class StringParser implements ValueParser { + + /** + * @var StringNormalizer + */ + private $normalizer; + + /** + * @param StringNormalizer $normalizer + */ + public function __construct( StringNormalizer $normalizer = null ) { + $this->normalizer = $normalizer ?: new NullStringNormalizer(); + } + + /** + * @see ValueParser::parse + * + * @param string $value + * + * @throws InvalidArgumentException if $value is not a string + * @return StringValue + */ + public function parse( $value ) { + if ( !is_string( $value ) ) { + throw new InvalidArgumentException( 'Parameter $value must be a string' ); + } + + $value = $this->normalizer->normalize( $value ); + return new StringValue( $value ); + } + +} diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/StringValueParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/StringValueParser.php new file mode 100644 index 00000000..0e17ac25 --- /dev/null +++ b/www/wiki/vendor/data-values/common/src/ValueParsers/StringValueParser.php @@ -0,0 +1,120 @@ +<?php + +namespace ValueParsers; + +use InvalidArgumentException; +use RuntimeException; + +/** + * ValueParser that parses the string representation of something. + * + * @since 0.1 + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +abstract class StringValueParser implements ValueParser { + + /** + * @since 0.1 + * + * @var ParserOptions + */ + protected $options; + + /** + * @since 0.1 + * + * @param ParserOptions|null $options + */ + public function __construct( ParserOptions $options = null ) { + $this->options = $options ?: new ParserOptions(); + + $this->defaultOption( ValueParser::OPT_LANG, 'en' ); + } + + /** + * @see ValueParser::parse + * + * @param mixed $value + * + * @return mixed + * @throws ParseException + */ + public function parse( $value ) { + if ( is_string( $value ) ) { + return $this->stringParse( $value ); + } + + throw new ParseException( 'Not a string' ); + } + + /** + * Parses the provided string and returns the result. + * + * @since 0.1 + * + * @param string $value + * + * @return mixed + */ + protected abstract function stringParse( $value ); + + /** + * @since 0.1 + * + * @param ParserOptions $options + */ + public function setOptions( ParserOptions $options ) { + $this->options = $options; + } + + /** + * @since 0.1 + * + * @return ParserOptions + */ + public function getOptions() { + return $this->options; + } + + /** + * Shortcut to $this->options->getOption. + * + * @since 0.1 + * + * @param string $option + * + * @throws InvalidArgumentException + * @return mixed + */ + protected final function getOption( $option ) { + return $this->options->getOption( $option ); + } + + /** + * Shortcut to $this->options->requireOption. + * + * @since 0.1 + * + * @param string $option + * + * @throws RuntimeException + */ + protected final function requireOption( $option ) { + $this->options->requireOption( $option ); + } + + /** + * Shortcut to $this->options->defaultOption. + * + * @since 0.1 + * + * @param string $option + * @param mixed $default + */ + protected final function defaultOption( $option, $default ) { + $this->options->defaultOption( $option, $default ); + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/DataValues/MonolingualTextValueTest.php b/www/wiki/vendor/data-values/common/tests/DataValues/MonolingualTextValueTest.php new file mode 100644 index 00000000..5d271f4f --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/DataValues/MonolingualTextValueTest.php @@ -0,0 +1,73 @@ +<?php + +namespace DataValues\Tests; + +use DataValues\MonolingualTextValue; + +/** + * @covers DataValues\MonolingualTextValue + * + * @since 0.1 + * + * @group DataValue + * @group DataValueExtensions + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class MonolingualTextValueTest extends DataValueTest { + + /** + * @see DataValueTest::getClass + * + * @return string + */ + public function getClass() { + return 'DataValues\MonolingualTextValue'; + } + + public function validConstructorArgumentsProvider() { + $argLists = array(); + + $argLists[] = array( 'en', 'foo' ); + $argLists[] = array( 'en', ' foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz ' ); + + return $argLists; + } + + public function invalidConstructorArgumentsProvider() { + $argLists = array(); + + $argLists[] = array( 42, null ); + $argLists[] = array( array(), null ); + $argLists[] = array( false, null ); + $argLists[] = array( true, null ); + $argLists[] = array( null, null ); + $argLists[] = array( 'en', 42 ); + $argLists[] = array( 'en', false ); + $argLists[] = array( 'en', array() ); + $argLists[] = array( 'en', null ); + $argLists[] = array( '', 'foo' ); + + return $argLists; + } + + /** + * @dataProvider instanceProvider + * @param MonolingualTextValue $text + * @param array $arguments + */ + public function testGetText( MonolingualTextValue $text, array $arguments ) { + $this->assertEquals( $arguments[1], $text->getText() ); + } + + /** + * @dataProvider instanceProvider + * @param MonolingualTextValue $text + * @param array $arguments + */ + public function testGetLanguageCode( MonolingualTextValue $text, array $arguments ) { + $this->assertEquals( $arguments[0], $text->getLanguageCode() ); + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/DataValues/MultilingualTextValueTest.php b/www/wiki/vendor/data-values/common/tests/DataValues/MultilingualTextValueTest.php new file mode 100644 index 00000000..b0cc4062 --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/DataValues/MultilingualTextValueTest.php @@ -0,0 +1,91 @@ +<?php + +namespace DataValues\Tests; + +use DataValues\MonolingualTextValue; +use DataValues\MultilingualTextValue; + +/** + * @covers DataValues\MultilingualTextValue + * + * @since 0.1 + * + * @group DataValue + * @group DataValueExtensions + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class MultilingualTextValueTest extends DataValueTest { + + /** + * @see DataValueTest::getClass + * + * @return string + */ + public function getClass() { + return 'DataValues\MultilingualTextValue'; + } + + public function validConstructorArgumentsProvider() { + $argLists = array(); + + $argLists[] = array( array() ); + $argLists[] = array( array( new MonolingualTextValue( 'en', 'foo' ) ) ); + $argLists[] = array( array( new MonolingualTextValue( 'en', 'foo' ), new MonolingualTextValue( 'de', 'foo' ) ) ); + $argLists[] = array( array( new MonolingualTextValue( 'en', 'foo' ), new MonolingualTextValue( 'de', 'bar' ) ) ); + $argLists[] = array( array( + new MonolingualTextValue( 'en', 'foo' ), + new MonolingualTextValue( 'de', ' foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz ' ) + ) ); + + return $argLists; + } + + public function invalidConstructorArgumentsProvider() { + $argLists = array(); + + $argLists[] = array( array( 42 ) ); + $argLists[] = array( array( false ) ); + $argLists[] = array( array( true ) ); + $argLists[] = array( array( null ) ); + $argLists[] = array( array( array() ) ); + $argLists[] = array( array( 'foo' ) ); + + $argLists[] = array( array( 42 => 'foo' ) ); + $argLists[] = array( array( '' => 'foo' ) ); + $argLists[] = array( array( 'en' => 42 ) ); + $argLists[] = array( array( 'en' => null ) ); + $argLists[] = array( array( 'en' => true ) ); + $argLists[] = array( array( 'en' => array() ) ); + $argLists[] = array( array( 'en' => 4.2 ) ); + + $argLists[] = array( array( new MonolingualTextValue( 'en', 'foo' ), false ) ); + $argLists[] = array( array( new MonolingualTextValue( 'en', 'foo' ), 'foobar' ) ); + + return $argLists; + } + + /** + * @dataProvider instanceProvider + * @param MultilingualTextValue $texts + * @param array $arguments + */ + public function testGetTexts( MultilingualTextValue $texts, array $arguments ) { + $actual = $texts->getTexts(); + + $this->assertInternalType( 'array', $actual ); + $this->assertContainsOnlyInstancesOf( '\DataValues\MonolingualTextValue', $actual ); + $this->assertEquals( $arguments[0], array_values( $actual ) ); + } + + /** + * @dataProvider instanceProvider + * @param MultilingualTextValue $texts + * @param array $arguments + */ + public function testGetValue( MultilingualTextValue $texts, array $arguments ) { + $this->assertInstanceOf( $this->getClass(), $texts->getValue() ); + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php b/www/wiki/vendor/data-values/common/tests/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php new file mode 100644 index 00000000..8a211871 --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php @@ -0,0 +1,59 @@ +<?php + +namespace ValueFormatters\Tests\Exceptions; + +use ValueFormatters\Exceptions\MismatchingDataValueTypeException; + +/** + * @covers ValueFormatters\Exceptions\MismatchingDataValueTypeException + * + * @group ValueFormatters + * @group DataValueExtensions + * + * @licence GNU GPL v2+ + * @author Katie Filbert < aude.wiki@gmail.com > + */ +class MismatchingDataValueTypeExceptionTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider constructorProvider + * @param string $expectedType + * @param string $actualType + */ + public function testConstructorWithRequiredArguments( $expectedType, $actualType ) { + $exception = new MismatchingDataValueTypeException( $expectedType, $actualType ); + + $this->assertEquals( $actualType, $exception->getDataValueType() ); + $this->assertEquals( $expectedType, $exception->getExpectedValueType() ); + } + + /** + * @dataProvider constructorProvider + * @param string $expectedType + * @param string $actualType + */ + public function testConstructorWithAllArguments( $expectedType, $actualType ) { + $message = 'Onoez! an error!'; + $previous = new \Exception( 'Onoez!' ); + + $exception = new MismatchingDataValueTypeException( + $expectedType, + $actualType, + $message, + $previous + ); + + $this->assertEquals( $actualType, $exception->getDataValueType() ); + $this->assertEquals( $expectedType, $exception->getExpectedValueType() ); + $this->assertContains( $message, $exception->getMessage() ); + $this->assertEquals( $previous, $exception->getPrevious() ); + } + + public function constructorProvider() { + return array( + array( 'string', 'time' ), + array( 'globecoordinate', 'string' ) + ); + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/ValueFormatters/StringFormatterTest.php b/www/wiki/vendor/data-values/common/tests/ValueFormatters/StringFormatterTest.php new file mode 100644 index 00000000..3aef1501 --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/ValueFormatters/StringFormatterTest.php @@ -0,0 +1,59 @@ +<?php + +namespace ValueFormatters\Test; + +use DataValues\StringValue; +use ValueFormatters\FormatterOptions; +use ValueFormatters\StringFormatter; + +/** + * @covers ValueFormatters\StringFormatter + * + * @group ValueFormatters + * @group DataValueExtensions + * + * @licence GNU GPL v2+ + * @author Katie Filbert < aude.wiki@gmail.com > + */ +class StringFormatterTest extends ValueFormatterTestBase { + + /** + * @deprecated since 0.2, just use getInstance. + */ + protected function getFormatterClass() { + throw new \LogicException( 'Should not be called, use getInstance' ); + } + + /** + * @see ValueFormatterTestBase::getInstance + * + * @param FormatterOptions|null $options + * + * @return StringFormatter + */ + protected function getInstance( FormatterOptions $options = null ) { + return new StringFormatter( $options ); + } + + /** + * @see ValueFormatterTestBase::validProvider + */ + public function validProvider() { + $strings = array( + 'ice cream', + 'cake', + '', + ' a ', + ' ', + ); + + $argLists = array(); + + foreach ( $strings as $string ) { + $argLists[] = array( new StringValue( $string ), $string ); + } + + return $argLists; + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/BoolParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/BoolParserTest.php new file mode 100644 index 00000000..9de03a25 --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/BoolParserTest.php @@ -0,0 +1,73 @@ +<?php + +namespace ValueParsers\Test; + +use DataValues\BooleanValue; +use ValueParsers\BoolParser; + +/** + * @covers ValueParsers\BoolParser + * + * @group ValueParsers + * @group DataValueExtensions + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class BoolParserTest extends StringValueParserTest { + + /** + * @see ValueParserTestBase::getInstance + * + * @return BoolParser + */ + protected function getInstance() { + return new BoolParser(); + } + + /** + * @see ValueParserTestBase::validInputProvider + */ + public function validInputProvider() { + $argLists = array(); + + $valid = array( + 'yes' => true, + 'on' => true, + '1' => true, + 'true' => true, + 'no' => false, + 'off' => false, + '0' => false, + 'false' => false, + + 'YeS' => true, + 'ON' => true, + 'No' => false, + 'OfF' => false, + ); + + foreach ( $valid as $value => $expected ) { + $expected = new BooleanValue( $expected ); + $argLists[] = array( (string)$value, $expected ); + } + + return $argLists; + } + + public function invalidInputProvider() { + $argLists = parent::invalidInputProvider(); + + $invalid = array( + 'foo', + '2', + ); + + foreach ( $invalid as $value ) { + $argLists[] = array( $value ); + } + + return $argLists; + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/DispatchingValueParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/DispatchingValueParserTest.php new file mode 100644 index 00000000..dc94e1f6 --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/DispatchingValueParserTest.php @@ -0,0 +1,90 @@ +<?php + +namespace ValueParsers\Test; + +use InvalidArgumentException; +use PHPUnit_Framework_MockObject_Matcher_Invocation; +use PHPUnit_Framework_TestCase; +use ValueParsers\DispatchingValueParser; +use ValueParsers\ParseException; +use ValueParsers\ValueParser; + +/** + * @covers ValueParsers\DispatchingValueParser + * + * @group ValueParsers + * @group WikibaseLib + * @group Wikibase + * + * @licence GNU GPL v2+ + * @author Thiemo Mättig + */ +class DispatchingValueParserTest extends PHPUnit_Framework_TestCase { + + /** + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $invocation + * + * @return ValueParser + */ + private function getParser( PHPUnit_Framework_MockObject_Matcher_Invocation $invocation ) { + $mock = $this->getMockBuilder( 'ValueParsers\ValueParser' ) + ->disableOriginalConstructor() + ->getMock(); + + $mock->expects( $invocation ) + ->method( 'parse' ) + ->will( $this->returnCallback( function( $value ) { + if ( $value === 'invalid' ) { + throw new ParseException( 'failed' ); + } + return $value; + } ) ); + + return $mock; + } + + /** + * @dataProvider invalidConstructorArgumentsProvider + * @expectedException InvalidArgumentException + */ + public function testGivenInvalidConstructorArguments_constructorThrowsException( $parsers, $format ) { + new DispatchingValueParser( $parsers, $format ); + } + + public function invalidConstructorArgumentsProvider() { + $parsers = array( + $this->getParser( $this->never() ), + ); + + return array( + array( array(), 'format' ), + array( $parsers, null ), + array( $parsers, '' ), + ); + } + + public function testParse() { + $parser = new DispatchingValueParser( + array( + $this->getParser( $this->once() ), + $this->getParser( $this->never() ), + ), + 'format' + ); + + $this->assertEquals( 'valid', $parser->parse( 'valid' ) ); + } + + public function testParseThrowsException() { + $parser = new DispatchingValueParser( + array( + $this->getParser( $this->once() ), + ), + 'format' + ); + + $this->setExpectedException( 'ValueParsers\ParseException' ); + $parser->parse( 'invalid' ); + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/FloatParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/FloatParserTest.php new file mode 100644 index 00000000..27d35fea --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/FloatParserTest.php @@ -0,0 +1,94 @@ +<?php + +namespace ValueParsers\Test; + +use DataValues\NumberValue; +use ValueParsers\FloatParser; + +/** + * @covers ValueParsers\FloatParser + * + * @group ValueParsers + * @group DataValueExtensions + * @group FloatParserTest + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class FloatParserTest extends StringValueParserTest { + + /** + * @see ValueParserTestBase::getInstance + * + * @return FloatParser + */ + protected function getInstance() { + return new FloatParser(); + } + + /** + * @see ValueParserTestBase::validInputProvider + */ + public function validInputProvider() { + $argLists = array(); + + $valid = array( + '0' => 0, + '1' => 1, + '42' => 42, + '01' => 01, + '9001' => 9001, + '-1' => -1, + '-42' => -42, + + '0.0' => 0, + '1.0' => 1, + '4.2' => 4.2, + '0.1' => 0.1, + '90.01' => 90.01, + '-1.0' => -1, + '-4.2' => -4.2, + ); + + foreach ( $valid as $value => $expected ) { + // Because PHP turns them into ints/floats using black magic + $value = (string)$value; + + // Because 1 is an int but will come out as a float + $expected = (float)$expected; + + $expected = new NumberValue( $expected ); + $argLists[] = array( $value, $expected ); + } + + return $argLists; + } + + public function invalidInputProvider() { + $argLists = parent::invalidInputProvider(); + + $invalid = array( + 'foo', + '', + '--1', + '1-', + '1 1', + '1,', + ',1', + ',1,', + 'one', + '0x20', + '+1', + '1+1', + '1-1', + '1.2.3', + ); + + foreach ( $invalid as $value ) { + $argLists[] = array( $value ); + } + + return $argLists; + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/IntParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/IntParserTest.php new file mode 100644 index 00000000..e039373d --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/IntParserTest.php @@ -0,0 +1,83 @@ +<?php + +namespace ValueParsers\Test; + +use DataValues\NumberValue; +use ValueParsers\IntParser; + +/** + * @covers ValueParsers\IntParser + * + * @group ValueParsers + * @group DataValueExtensions + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class IntParserTest extends StringValueParserTest { + + /** + * @see ValueParserTestBase::getInstance + * + * @return IntParser + */ + protected function getInstance() { + return new IntParser(); + } + + /** + * @see ValueParserTestBase::validInputProvider + */ + public function validInputProvider() { + $argLists = array(); + + $valid = array( + '0' => 0, + '1' => 1, + '42' => 42, + '01' => 01, + '9001' => 9001, + '-1' => -1, + '-42' => -42, + ); + + foreach ( $valid as $value => $expected ) { + // Because PHP turns them into ints using black magic + $value = (string)$value; + + $expected = new NumberValue( $expected ); + $argLists[] = array( $value, $expected ); + } + + return $argLists; + } + + public function invalidInputProvider() { + $argLists = parent::invalidInputProvider(); + + $invalid = array( + 'foo', + '4.2', + '', + '--1', + '1-', + '1 1', + '1,', + ',1', + ',1,', + 'one', + '0x20', + '+1', + '1+1', + '1-1', + '1.2.3', + ); + + foreach ( $invalid as $value ) { + $argLists[] = array( $value ); + } + + return $argLists; + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/Normalizers/NullStringNormalizerTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/Normalizers/NullStringNormalizerTest.php new file mode 100644 index 00000000..ba528370 --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/Normalizers/NullStringNormalizerTest.php @@ -0,0 +1,55 @@ +<?php + +namespace ValueParsers\Normalizers\Test; + +use DataValues\DataValue; +use DataValues\StringValue; +use PHPUnit_Framework_TestCase; +use ValueParsers\Normalizers\NullStringNormalizer; + +/** + * @covers ValueParsers\Normalizers\NullStringNormalizer + * + * @group ValueParsers + * @group DataValueExtensions + * + * @licence GNU GPL v2+ + * @author Thiemo Mättig + */ +class NullStringNormalizerTest extends PHPUnit_Framework_TestCase { + + /** + * @dataProvider stringProvider + */ + public function testNormalize( $value ) { + $normalizer = new NullStringNormalizer(); + $this->assertSame( $value, $normalizer->normalize( $value ) ); + } + + public function stringProvider() { + return array( + array( '' ), + array( 'a' ), + array( ' a ' ), + ); + } + + /** + * @dataProvider invalidValueProvider + */ + public function testNormalizeException( $value ) { + $normalizer = new NullStringNormalizer(); + $this->setExpectedException( 'InvalidArgumentException' ); + $normalizer->normalize( $value ); + } + + public function invalidValueProvider() { + return array( + array( null ), + array( true ), + array( 1 ), + array( new StringValue( '' ) ), + ); + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/NullParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/NullParserTest.php new file mode 100644 index 00000000..f4ad45fa --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/NullParserTest.php @@ -0,0 +1,75 @@ +<?php + +namespace ValueParsers\Test; + +use DataValues\UnknownValue; +use ValueParsers\NullParser; +use ValueParsers\ValueParser; + +/** + * @covers ValueParsers\NullParser + * + * @group ValueParsers + * @group DataValueExtensions + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class NullParserTest extends ValueParserTestBase { + + /** + * @see ValueParserTestBase::getInstance + * + * @return NullParser + */ + protected function getInstance() { + return new NullParser(); + } + + /** + * @see ValueParserTestBase::validInputProvider + */ + public function validInputProvider() { + $argLists = array(); + + $values = array( + '42', + 42, + false, + array(), + 'ohi there!', + null, + 4.2, + ); + + foreach ( $values as $value ) { + $argLists[] = array( + $value, + new UnknownValue( $value ) + ); + } + + return $argLists; + } + + /** + * @see ValueParserTestBase::invalidInputProvider + */ + public function invalidInputProvider() { + return array( + array( null ) + ); + } + + /** + * @see ValueParserTestBase::testParseWithInvalidInputs + * + * @dataProvider invalidInputProvider + * @param mixed $value + * @param ValueParser|null $parser + */ + public function testParseWithInvalidInputs( $value, ValueParser $parser = null ) { + $this->markTestSkipped( 'NullParser has no invalid inputs' ); + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/StringParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/StringParserTest.php new file mode 100644 index 00000000..08751663 --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/StringParserTest.php @@ -0,0 +1,63 @@ +<?php + +namespace ValueParsers\Test; + +use DataValues\DataValue; +use DataValues\StringValue; +use ValueParsers\Normalizers\StringNormalizer; +use ValueParsers\StringParser; + +/** + * @covers ValueParsers\StringParser + * + * @group ValueParsers + * @group DataValueExtensions + * + * @licence GNU GPL v2+ + * @author Daniel Kinzler + */ +class StringParserTest extends \PHPUnit_Framework_TestCase { + + public function provideParse() { + $normalizer = $this->getMock( 'ValueParsers\Normalizers\StringNormalizer' ); + $normalizer->expects( $this->once() ) + ->method( 'normalize' ) + ->will( $this->returnCallback( function( $value ) { + return strtolower( trim( $value ) ); + } ) ); + + return array( + 'simple' => array( 'hello world', null, new StringValue( 'hello world' ) ), + 'normalize' => array( ' Hello World ', $normalizer, new StringValue( 'hello world' ) ), + ); + } + + /** + * @dataProvider provideParse + */ + public function testParse( $input, StringNormalizer $normalizer = null, DataValue $expected ) { + $parser = new StringParser( $normalizer ); + $value = $parser->parse( $input ); + + $this->assertInstanceOf( 'DataValues\StringValue', $value ); + $this->assertEquals( $expected->toArray(), $value->toArray() ); + } + + public function nonStringProvider() { + return array( + 'null' => array( null ), + 'array' => array( array() ), + 'int' => array( 7 ), + ); + } + + /** + * @dataProvider nonStringProvider + */ + public function testGivenNonString_parseThrowsException( $input ) { + $parser = new StringParser(); + $this->setExpectedException( 'InvalidArgumentException' ); + $parser->parse( $input ); + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/StringValueParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/StringValueParserTest.php new file mode 100644 index 00000000..962de1d7 --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/StringValueParserTest.php @@ -0,0 +1,55 @@ +<?php + +namespace ValueParsers\Test; + +use ValueParsers\ParserOptions; +use ValueParsers\StringValueParser; + +/** + * Unit test StringValueParser class. + * + * @since 0.1 + * + * @group ValueParsers + * @group DataValueExtensions + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +abstract class StringValueParserTest extends ValueParserTestBase { + + /** + * @see ValueParserTestBase::invalidInputProvider + * + * @return array[] + */ + public function invalidInputProvider() { + return array( + array( true ), + array( false ), + array( null ), + array( 4.2 ), + array( array() ), + array( 42 ), + ); + } + + public function testSetAndGetOptions() { + /** + * @var StringValueParser $parser + */ + $parser = $this->getInstance(); + + $parser->setOptions( new ParserOptions() ); + + $this->assertEquals( new ParserOptions(), $parser->getOptions() ); + + $options = new ParserOptions(); + $options->setOption( '~=[,,_,,]:3', '~=[,,_,,]:3' ); + + $parser->setOptions( $options ); + + $this->assertEquals( $options, $parser->getOptions() ); + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/ValueParserTestBase.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/ValueParserTestBase.php new file mode 100644 index 00000000..f937f810 --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/ValueParserTestBase.php @@ -0,0 +1,109 @@ +<?php + +namespace ValueParsers\Test; + +use Comparable; +use DataValues\DataValue; +use PHPUnit_Framework_TestCase; +use ValueParsers\ParserOptions; +use ValueParsers\ValueParser; + +/** + * Base for unit tests for ValueParser implementing classes. + * + * @since 0.1 + * + * @group ValueParsers + * @group DataValueExtensions + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +abstract class ValueParserTestBase extends PHPUnit_Framework_TestCase { + + /** + * @since 0.1 + * + * @return array[] + */ + public abstract function validInputProvider(); + + /** + * @since 0.1 + * + * @return array[] + */ + public abstract function invalidInputProvider(); + + /** + * @since 0.1 + * + * @return ValueParser + */ + protected abstract function getInstance(); + + /** + * @since 0.1 + * + * @dataProvider validInputProvider + * @param mixed $value + * @param mixed $expected + * @param ValueParser|null $parser + */ + public function testParseWithValidInputs( $value, $expected, ValueParser $parser = null ) { + if ( $parser === null ) { + $parser = $this->getInstance(); + } + + $this->assertSmartEquals( $expected, $parser->parse( $value ) ); + } + + /** + * @param DataValue|mixed $expected + * @param DataValue|mixed $actual + */ + private function assertSmartEquals( $expected, $actual ) { + if ( $this->requireDataValue() || $expected instanceof Comparable ) { + if ( $expected instanceof DataValue && $actual instanceof DataValue ) { + $msg = "testing equals():\n" + . preg_replace( '/\s+/', ' ', print_r( $actual->toArray(), true ) ) . " should equal\n" + . preg_replace( '/\s+/', ' ', print_r( $expected->toArray(), true ) ); + } else { + $msg = 'testing equals()'; + } + + $this->assertTrue( $expected->equals( $actual ), $msg ); + } + else { + $this->assertEquals( $expected, $actual ); + } + } + + /** + * @since 0.1 + * + * @dataProvider invalidInputProvider + * @param mixed $value + * @param ValueParser|null $parser + */ + public function testParseWithInvalidInputs( $value, ValueParser $parser = null ) { + if ( $parser === null ) { + $parser = $this->getInstance(); + } + + $this->setExpectedException( 'ValueParsers\ParseException' ); + $parser->parse( $value ); + } + + /** + * Returns if the result of the parsing process should be checked to be a DataValue. + * + * @since 0.1 + * + * @return bool + */ + protected function requireDataValue() { + return true; + } + +} diff --git a/www/wiki/vendor/data-values/common/tests/bootstrap.php b/www/wiki/vendor/data-values/common/tests/bootstrap.php new file mode 100644 index 00000000..ac82d460 --- /dev/null +++ b/www/wiki/vendor/data-values/common/tests/bootstrap.php @@ -0,0 +1,14 @@ +<?php + +if ( PHP_SAPI !== 'cli' ) { + die( 'Not an entry point' ); +} + +error_reporting( E_ALL | E_STRICT ); +ini_set( 'display_errors', 1 ); + +if ( !is_readable( __DIR__ . '/../vendor/autoload.php' ) ) { + die( 'You need to install this package with Composer before you can run the tests' ); +} + +require_once __DIR__ . '/../vendor/autoload.php'; diff --git a/www/wiki/vendor/data-values/data-values/COPYING b/www/wiki/vendor/data-values/data-values/COPYING new file mode 100644 index 00000000..ebba08a4 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/COPYING @@ -0,0 +1,347 @@ +The license text below "----" applies to all files within this distribution, other +than those that are in a directory which contains files named "LICENSE" or +"COPYING", or a subdirectory thereof. For those files, the license text contained in +said file overrides any license information contained in directories of smaller depth. +Alternative licenses are typically used for software that is provided by external +parties, and merely packaged with this software for convenience. +---- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/www/wiki/vendor/data-values/data-values/DataValues.php b/www/wiki/vendor/data-values/data-values/DataValues.php new file mode 100644 index 00000000..1a8d2db5 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/DataValues.php @@ -0,0 +1,15 @@ +<?php + +/** + * Entry point for the DataValues library. + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ + +if ( defined( 'DATAVALUES_VERSION' ) ) { + // Do not initialize more than once. + return 1; +} + +define( 'DATAVALUES_VERSION', '2.1.1' ); diff --git a/www/wiki/vendor/data-values/data-values/README.md b/www/wiki/vendor/data-values/data-values/README.md new file mode 100644 index 00000000..a54c7077 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/README.md @@ -0,0 +1,113 @@ +# DataValues + +DataValues is a small PHP library that aims to be a common foundation for representing "simple" +values. Values such as booleans and strings. + +It is part of the [DataValues set of libraries](https://github.com/DataValues). + +[![Build Status](https://secure.travis-ci.org/DataValues/DataValues.png?branch=master)](http://travis-ci.org/DataValues/DataValues) +[![Code Coverage](https://scrutinizer-ci.com/g/DataValues/DataValues/badges/coverage.png?s=56a1ea89df94c6d9b4223ba584d0d4556e1984ef)](https://scrutinizer-ci.com/g/DataValues/DataValues/) +[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/DataValues/DataValues/badges/quality-score.png?s=ba9364790e6b521277a3829ffb91e2c2e1b68c3c)](https://scrutinizer-ci.com/g/DataValues/DataValues/) + +On [Packagist](https://packagist.org/packages/data-values/data-values): +[![Latest Stable Version](https://poser.pugx.org/data-values/data-values/version.png)](https://packagist.org/packages/data-values/data-values) +[![Download count](https://poser.pugx.org/data-values/data-values/d/total.png)](https://packagist.org/packages/data-values/data-values) + +## Requirements + +These PHP versions are supported: + +* PHP 5.5 or later, including PHP 7 +* HHVM 3.3 or later + +## Installation + +You can use [Composer](http://getcomposer.org/) to download and install +this package as well as its dependencies. Alternatively you can simply clone +the git repository and take care of loading yourself. + +### Composer + +To add this package as a local, per-project dependency to your project, simply add a +dependency on `data-values/data-values` to your project's `composer.json` file. +Here is a minimal example of a `composer.json` file that just defines a dependency on +DataValues 2.0: + + { + "require": { + "data-values/data-values": "^2.0.0" + } + } + +### Manual + +Get the DataValues code, either via git, or some other means. Also get all dependencies. +You can find a list of the dependencies in the "require" section of the composer.json file. +Load all dependencies and the load the DataValues library by including its entry point: +DataValues.php. + +## Tests + +This library comes with a set up PHPUnit tests that cover all non-trivial code. You can run these +tests using the PHPUnit configuration file found in the root directory. The tests can also be run +via TravisCI, as a TravisCI configuration file is also provided in the root directory. + +## Authors + +DataValues has been written primarily by [Jeroen De Dauw](https://www.mediawiki.org/wiki/User:Jeroen_De_Dauw), +in part as [Wikimedia Germany](https://wikimedia.de) employee for the [Wikidata project](https://wikidata.org/). + +Contributions where also made by [several other awesome people] +(https://www.ohloh.net/p/datavalues/contributors). + +## Release notes + +### 2.1.1 (2017-09-28) + +* Fixed `DataValueTest` not being installable via Composer + +### 2.1.0 (2017-08-09) + +* Removed MediaWiki integration + +### 2.0.0 (2017-08-02) + +* Dropped `Copyable` interface +* Dropped deprecated constant `DataValues_VERSION`, use `DATAVALUES_VERSION` instead +* Deprecated `newFromArray` in all `DataValue` implementations. +* Fixed and updated documentation throughout the code +* Removed broken constructor tests +* Updated minimal required PHP version from 5.3 to 5.5.9 + +### 1.0.0 (2014-09-26) + +* The CI now ensures compatibility with PHP 5.6 and HHVM +* A lot of type hints where improved +* Protected methods and fields where changed to private +* The test bootstrap no longer executes `composer update` +* The test bootstrap now sets PHP strict mode +* The contract of the `Hashable::getHash` method was updated +* The MediaWiki internationalization support has been migrated to the JSON based version + +### 0.1.1 (2013-11-22) + +* Removed support for running the tests via the MediaWiki test runner. +* The test bootstrapping file now automatically does a composer install. +* Removed custom autoloader in favour of defining autoloading in composer.json. + +### 0.1.0 (2013-11-16) + +Initial release with these features: + +* DataValue interface + * BooleanValue implementation + * NumberValue implementation + * StringValue implementation + * UnDeserializableValue implementation + * UnknownValue implementation +* Common interface definitions: Comparable, Copyable, Hashable, Immutable + +## Links + +* [DataValues on Packagist](https://packagist.org/packages/data-values/data-values) +* [DataValues on Ohloh](https://www.ohloh.net/p/datavalues) diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/BooleanValue.php b/www/wiki/vendor/data-values/data-values/src/DataValues/BooleanValue.php new file mode 100644 index 00000000..0bf01a6f --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/src/DataValues/BooleanValue.php @@ -0,0 +1,96 @@ +<?php + +namespace DataValues; + +/** + * Class representing a boolean value. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class BooleanValue extends DataValueObject { + + private $value; + + /** + * @param bool $value + * + * @throws IllegalValueException + */ + public function __construct( $value ) { + if ( !is_bool( $value ) ) { + throw new IllegalValueException( 'Can only construct BooleanValue from booleans' ); + } + + $this->value = $value; + } + + /** + * @see Serializable::serialize + * + * @return string '0' for false, '1' for true. + */ + public function serialize() { + return $this->value ? '1' : '0'; + } + + /** + * @see Serializable::unserialize + * + * @param string $value '0' for false, '1' for true. + */ + public function unserialize( $value ) { + $this->value = $value === '1'; + } + + /** + * @see DataValue::getType + * + * @return string + */ + public static function getType() { + return 'boolean'; + } + + /** + * @see DataValue::getSortKey + * + * @return int 0 for false, 1 for true. + */ + public function getSortKey() { + return $this->value ? 1 : 0; + } + + /** + * Returns the boolean. + * @see DataValue::getValue + * + * @return bool + */ + public function getValue() { + return $this->value; + } + + /** + * Constructs a new instance from the provided data. Required for @see DataValueDeserializer. + * This is expected to round-trip with @see getArrayValue. + * + * @deprecated since 1.1. Static DataValue::newFromArray constructors like this are + * underspecified (not in the DataValue interface), and misleadingly named (should be named + * newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer. + * + * @param mixed $data Warning! Even if this is expected to be a value as returned by + * @see getArrayValue, callers of this specific newFromArray implementation can not guarantee + * this. This is not guaranteed to be a boolean! + * + * @throws IllegalValueException if $data is not in the expected format. Subclasses of + * InvalidArgumentException are expected and properly handled by @see DataValueDeserializer. + * @return self + */ + public static function newFromArray( $data ) { + return new static( $data ); + } + +} diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/DataValue.php b/www/wiki/vendor/data-values/data-values/src/DataValues/DataValue.php new file mode 100644 index 00000000..5ead67ba --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/src/DataValues/DataValue.php @@ -0,0 +1,96 @@ +<?php + +namespace DataValues; + +use Comparable; +use Hashable; +use Immutable; +use Serializable; + +/** + * Interface for objects that represent a single data value. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +interface DataValue extends Hashable, Comparable, Serializable, Immutable { + + /** + * Returns the identifier of the datavalues type. + * + * This is not to be confused with the DataType provided by the DataTypes extension. + * + * @since 0.1 + * + * @return string + */ + public static function getType(); + + /** + * Returns a key that can be used to sort the data value with. + * It can be either numeric or a string. + * + * @since 0.1 + * + * @return string|float|int + */ + public function getSortKey(); + + /** + * Returns the value contained by the DataValue. If this value is not simple and + * does not have it's own type that represents it, the DataValue itself will be returned. + * In essence, this method returns the "simplest" representation of the value. + * + * Example: + * - NumberValue returns a float or integer + * - MediaWikiTitleValue returns a Title object + * - QuantityValue returns itself + * + * @since 0.1 + * + * @return mixed + */ + public function getValue(); + + /** + * Returns the value in a form suitable for an array serialization. + * + * For simple values (ie a string) the return value will be equal to that of @see getValue. + * + * Complex DataValues can provide a nicer implementation though, for instance a + * geographical coordinate value could provide an array with keys latitude, + * longitude and altitude, each pointing to a simple float value. + * + * @since 0.1 + * + * @return mixed + */ + public function getArrayValue(); + + /** + * Returns the whole DataValue in array form. + * + * The array contains: + * - value: mixed, same as the result of @see getArrayValue + * - type: string, same as the result of @see getType + * + * This is sufficient for unserialization in a factory. + * + * @since 0.1 + * + * @return array + */ + public function toArray(); + + /** + * Returns a deep copy of the object. + * + * @since 0.1 + * + * @return DataValue + */ + public function getCopy(); + +} diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/DataValueObject.php b/www/wiki/vendor/data-values/data-values/src/DataValues/DataValueObject.php new file mode 100644 index 00000000..a47f330f --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/src/DataValues/DataValueObject.php @@ -0,0 +1,93 @@ +<?php + +namespace DataValues; + +/** + * Base for objects that represent a single data value. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +abstract class DataValueObject implements DataValue { + + /** + * @see Hashable::getHash + * + * @return string + */ + public function getHash() { + return md5( serialize( $this ) ); + } + + /** + * @see Comparable::equals + * + * @param mixed $target + * + * @return bool + */ + public function equals( $target ) { + if ( $this === $target ) { + return true; + } + + return is_object( $target ) + && get_called_class() === get_class( $target ) + && serialize( $this ) === serialize( $target ); + } + + /** + * @see DataValue::getCopy + * + * @return DataValue + */ + public function getCopy() { + return unserialize( serialize( $this ) ); + } + + /** + * @see DataValue::getArrayValue + * + * @return mixed + */ + public function getArrayValue() { + return $this->getValue(); + } + + /** + * @see DataValue::toArray + * + * @return array + */ + public function toArray() { + return [ + 'value' => $this->getArrayValue(), + 'type' => $this->getType(), + ]; + } + + /** + * Checks that $data is an array and contains the given fields. + * + * @param mixed $data + * @param string[] $fields + * + * @todo: this should be removed once we got rid of all the static newFromArray() methods. + * + * @throws IllegalValueException + */ + protected static function requireArrayFields( $data, array $fields ) { + if ( !is_array( $data ) ) { + throw new IllegalValueException( "array expected" ); + } + + foreach ( $fields as $field ) { + if ( !array_key_exists( $field, $data ) ) { + throw new IllegalValueException( "$field field required" ); + } + } + } + +} diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/IllegalValueException.php b/www/wiki/vendor/data-values/data-values/src/DataValues/IllegalValueException.php new file mode 100644 index 00000000..781fb223 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/src/DataValues/IllegalValueException.php @@ -0,0 +1,15 @@ +<?php + +namespace DataValues; + +use InvalidArgumentException; + +/** + * @since 0.1 + * + * @license GPL-2.0+ + * @author Daniel Kinzler + */ +class IllegalValueException extends InvalidArgumentException { + +} diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/NumberValue.php b/www/wiki/vendor/data-values/data-values/src/DataValues/NumberValue.php new file mode 100644 index 00000000..7c440758 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/src/DataValues/NumberValue.php @@ -0,0 +1,102 @@ +<?php + +namespace DataValues; + +/** + * Class representing a simple numeric value. + * + * More complex numeric values that have associated info such as + * unit and accuracy can be represented with a @see QuantityValue. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class NumberValue extends DataValueObject { + + /** + * @var int|float + */ + private $value; + + /** + * @param int|float $value + * + * @throws IllegalValueException + */ + public function __construct( $value ) { + if ( !is_int( $value ) && !is_float( $value ) ) { + throw new IllegalValueException( 'Can only construct NumberValue from floats or integers.' ); + } + + $this->value = $value; + } + + /** + * @see Serializable::serialize + * + * @return string + */ + public function serialize() { + return serialize( $this->value ); + } + + /** + * @see Serializable::unserialize + * + * @param string $value + */ + public function unserialize( $value ) { + $this->__construct( unserialize( $value ) ); + } + + /** + * @see DataValue::getType + * + * @return string + */ + public static function getType() { + return 'number'; + } + + /** + * @see DataValue::getSortKey + * + * @return int|float + */ + public function getSortKey() { + return $this->value; + } + + /** + * Returns the number. + * @see DataValue::getValue + * + * @return int|float + */ + public function getValue() { + return $this->value; + } + + /** + * Constructs a new instance from the provided data. Required for @see DataValueDeserializer. + * This is expected to round-trip with @see getArrayValue. + * + * @deprecated since 1.1. Static DataValue::newFromArray constructors like this are + * underspecified (not in the DataValue interface), and misleadingly named (should be named + * newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer. + * + * @param mixed $data Warning! Even if this is expected to be a value as returned by + * @see getArrayValue, callers of this specific newFromArray implementation can not guarantee + * this. This is not guaranteed to be a number! + * + * @throws IllegalValueException if $data is not in the expected format. Subclasses of + * InvalidArgumentException are expected and properly handled by @see DataValueDeserializer. + * @return self + */ + public static function newFromArray( $data ) { + return new static( $data ); + } + +} diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/StringValue.php b/www/wiki/vendor/data-values/data-values/src/DataValues/StringValue.php new file mode 100644 index 00000000..7347a6ef --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/src/DataValues/StringValue.php @@ -0,0 +1,99 @@ +<?php + +namespace DataValues; + +/** + * Class representing a string value. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class StringValue extends DataValueObject { + + /** + * @var string + */ + private $value; + + /** + * @param string $value + * + * @throws IllegalValueException + */ + public function __construct( $value ) { + if ( !is_string( $value ) ) { + throw new IllegalValueException( 'Can only construct StringValue from strings' ); + } + + $this->value = $value; + } + + /** + * @see Serializable::serialize + * + * @return string + */ + public function serialize() { + return $this->value; + } + + /** + * @see Serializable::unserialize + * + * @param string $value + */ + public function unserialize( $value ) { + $this->__construct( $value ); + } + + /** + * @see DataValue::getType + * + * @return string + */ + public static function getType() { + return 'string'; + } + + /** + * @see DataValue::getSortKey + * + * @return string + */ + public function getSortKey() { + return $this->value; + } + + /** + * Returns the string. + * @see DataValue::getValue + * + * @return string + */ + public function getValue() { + return $this->value; + } + + /** + * Constructs a new instance from the provided data. Required for @see DataValueDeserializer. + * This is expected to round-trip with @see getArrayValue. + * + * @deprecated since 1.1. Static DataValue::newFromArray constructors like this are + * underspecified (not in the DataValue interface), and misleadingly named (should be named + * newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer. + * + * @param mixed $data Warning! Even if this is expected to be a value as returned by + * @see getArrayValue, callers of this specific newFromArray implementation can not guarantee + * this. This is not guaranteed to be a string! + * + * @throws IllegalValueException if $data is not in the expected format. Subclasses of + * InvalidArgumentException are expected and properly handled by @see DataValueDeserializer. + * @return self + */ + public static function newFromArray( $data ) { + return new static( $data ); + } + +} diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/UnDeserializableValue.php b/www/wiki/vendor/data-values/data-values/src/DataValues/UnDeserializableValue.php new file mode 100644 index 00000000..08a1f1c2 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/src/DataValues/UnDeserializableValue.php @@ -0,0 +1,174 @@ +<?php + +namespace DataValues; + +use InvalidArgumentException; + +/** + * Class representing a value that could not be unserialized for some reason. + * It contains the raw native data structure representing the value, + * as well as the originally intended value type and an error message. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Daniel Kinzler + */ +class UnDeserializableValue extends DataValueObject { + + /** + * @var mixed + */ + private $data; + + /** + * @var string|null + */ + private $type; + + /** + * @var string + */ + private $error; + + /** + * @param mixed $data The raw data structure + * @param string|null $type The originally intended type + * @param string $error The error that occurred when processing the original data structure. + * + * @throws InvalidArgumentException + */ + public function __construct( $data, $type, $error ) { + if ( is_object( $data ) ) { + throw new InvalidArgumentException( '$data must not be an object' ); + } + + if ( !is_string( $type ) && !is_null( $type ) ) { + throw new InvalidArgumentException( '$type must be a string or null' ); + } + + if ( !is_string( $error ) ) { + throw new InvalidArgumentException( '$error must be a string' ); + } + + $this->data = $data; + $this->type = $type; + $this->error = $error; + } + + /** + * @see Serializable::serialize + * + * @note: The serialization includes the intended type and the error message + * along with the original data. + * + * @return string + */ + public function serialize() { + return serialize( [ $this->type, $this->data, $this->error ] ); + } + + /** + * @see Serializable::unserialize + * + * @param string $value + */ + public function unserialize( $value ) { + list( $type, $data, $error ) = unserialize( $value ); + $this->__construct( $data, $type, $error ); + } + + /** + * @see DataValue::getArrayValue + * + * @note: this returns the original raw data structure. + * + * @return mixed + */ + public function getArrayValue() { + return $this->data; + } + + /** + * @see DataValue::toArray + * + * @note: This uses the originally intended type. This way, the native representation + * does not model a UnDeserializableValue, but the originally intended type of value. + * This allows for round trip compatibility with unknown types of data. + * + * @return array + */ + public function toArray() { + return [ + 'value' => $this->data, + 'type' => $this->type, + 'error' => $this->error, + ]; + } + + /** + * @see DataValue::getType + * + * @return string + */ + public static function getType() { + return 'bad'; + } + + /** + * Returns the value type that was intended for the bad data structure. + * + * @return string|null + */ + public function getTargetType() { + return $this->type; + } + + /** + * Returns a string describing the issue that caused the failure + * represented by this UnDeserializableValue object. + * + * @return string + */ + public function getReason() { + return $this->error; + } + + /** + * @see DataValue::getSortKey + * + * @return int Always 0 in this implementation. + */ + public function getSortKey() { + return 0; + } + + /** + * Returns the raw data structure. + * @see DataValue::getValue + * + * @return mixed + */ + public function getValue() { + return $this->data; + } + + /** + * @see Comparable::equals + * + * @param mixed $target + * + * @return bool + */ + public function equals( $target ) { + if ( $this === $target ) { + return true; + } + + return $target instanceof self + && $this->data === $target->data + && $this->type === $target->type + && $this->error === $target->error; + } + +} diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/UnknownValue.php b/www/wiki/vendor/data-values/data-values/src/DataValues/UnknownValue.php new file mode 100644 index 00000000..4c0c84ad --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/src/DataValues/UnknownValue.php @@ -0,0 +1,106 @@ +<?php + +namespace DataValues; + +/** + * Class representing a value of unknown type. + * This is in essence a null-wrapper, useful for instance for null-parsers. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class UnknownValue extends DataValueObject { + + /** + * @var mixed + */ + private $value; + + /** + * @param mixed $value + */ + public function __construct( $value ) { + $this->value = $value; + } + + /** + * @see Serializable::serialize + * + * @return string + */ + public function serialize() { + return serialize( $this->value ); + } + + /** + * @see Serializable::unserialize + * + * @param string $value + */ + public function unserialize( $value ) { + $this->__construct( unserialize( $value ) ); + } + + /** + * @see DataValue::getType + * + * @return string + */ + public static function getType() { + return 'unknown'; + } + + /** + * @see DataValue::getSortKey + * + * @return int Always 0 in this implementation. + */ + public function getSortKey() { + return 0; + } + + /** + * Returns the value. + * @see DataValue::getValue + * + * @return mixed + */ + public function getValue() { + return $this->value; + } + + /** + * @see Comparable::equals + * + * @param mixed $target + * + * @return bool + */ + public function equals( $target ) { + if ( $this === $target ) { + return true; + } + + return $target instanceof self + && $this->value === $target->value; + } + + /** + * Constructs a new instance from the provided data. Required for @see DataValueDeserializer. + * This is expected to round-trip with @see getArrayValue. + * + * @deprecated since 1.1. Static DataValue::newFromArray constructors like this are + * underspecified (not in the DataValue interface), and misleadingly named (should be named + * newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer. + * + * @param mixed $data + * + * @return self + */ + public static function newFromArray( $data ) { + return new static( $data ); + } + +} diff --git a/www/wiki/vendor/data-values/data-values/src/interfaces/Comparable.php b/www/wiki/vendor/data-values/data-values/src/interfaces/Comparable.php new file mode 100644 index 00000000..159180ad --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/src/interfaces/Comparable.php @@ -0,0 +1,24 @@ +<?php + +/** + * Interface for objects that have an equals method. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +interface Comparable { + + /** + * Returns if the provided value is equal to the object or not. + * + * @since 0.1 + * + * @param mixed $target + * + * @return bool + */ + public function equals( $target ); + +} diff --git a/www/wiki/vendor/data-values/data-values/src/interfaces/Hashable.php b/www/wiki/vendor/data-values/data-values/src/interfaces/Hashable.php new file mode 100644 index 00000000..dba1c531 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/src/interfaces/Hashable.php @@ -0,0 +1,24 @@ +<?php + +/** + * Interface for objects that have a getHash method. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +interface Hashable { + + /** + * Returns a string hash based on the value of the object. The string must not exceed + * 255 bytes (255 ASCII characters or less when it contains Unicode characters that + * need to be UTF-8 encoded) to allow using indexes on all database systems. + * + * @since 0.1 + * + * @return string + */ + public function getHash(); + +} diff --git a/www/wiki/vendor/data-values/data-values/src/interfaces/Immutable.php b/www/wiki/vendor/data-values/data-values/src/interfaces/Immutable.php new file mode 100644 index 00000000..c426c523 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/src/interfaces/Immutable.php @@ -0,0 +1,14 @@ +<?php + +/** + * Interface for immutable objects. + * The interface does not specify any methods and merely acts as a flag. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +interface Immutable { + +} diff --git a/www/wiki/vendor/data-values/data-values/tests/bootstrap.php b/www/wiki/vendor/data-values/data-values/tests/bootstrap.php new file mode 100644 index 00000000..43a36171 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/tests/bootstrap.php @@ -0,0 +1,14 @@ +<?php + +if ( PHP_SAPI !== 'cli' ) { + die( 'Not an entry point' ); +} + +error_reporting( -1 ); +ini_set( 'display_errors', 1 ); + +if ( !is_readable( __DIR__ . '/../vendor/autoload.php' ) ) { + die( 'You need to install this package with Composer before you can run the tests' ); +} + +require_once __DIR__ . '/../vendor/autoload.php'; diff --git a/www/wiki/vendor/data-values/data-values/tests/phpunit/BooleanValueTest.php b/www/wiki/vendor/data-values/data-values/tests/phpunit/BooleanValueTest.php new file mode 100644 index 00000000..4a04a917 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/tests/phpunit/BooleanValueTest.php @@ -0,0 +1,58 @@ +<?php + +namespace DataValues\Tests; + +use DataValues\BooleanValue; + +/** + * @covers DataValues\BooleanValue + * + * @group DataValue + * @group DataValueExtensions + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class BooleanValueTest extends DataValueTest { + + /** + * @see DataValueTest::getClass + * + * @return string + */ + public function getClass() { + return BooleanValue::class; + } + + public function validConstructorArgumentsProvider() { + $argLists = []; + + $argLists[] = [ false ]; + $argLists[] = [ true ]; + + return $argLists; + } + + public function invalidConstructorArgumentsProvider() { + $argLists = []; + + $argLists[] = [ 42 ]; + $argLists[] = [ [] ]; + $argLists[] = [ '1' ]; + $argLists[] = [ '' ]; + $argLists[] = [ 0 ]; + $argLists[] = [ 1 ]; + $argLists[] = [ 'foo' ]; + $argLists[] = [ null ]; + + return $argLists; + } + + /** + * @dataProvider instanceProvider + */ + public function testGetValue( BooleanValue $boolean, array $arguments ) { + $this->assertEquals( $arguments[0], $boolean->getValue() ); + } + +} diff --git a/www/wiki/vendor/data-values/data-values/tests/phpunit/DataValueTest.php b/www/wiki/vendor/data-values/data-values/tests/phpunit/DataValueTest.php new file mode 100644 index 00000000..f420bc61 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/tests/phpunit/DataValueTest.php @@ -0,0 +1,199 @@ +<?php + +namespace DataValues\Tests; + +use Comparable; +use DataValues\DataValue; +use Exception; +use Hashable; +use Immutable; +use PHPUnit_Framework_TestCase; +use ReflectionClass; +use Serializable; + +/** + * Base for unit tests for DataValue implementing classes. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +abstract class DataValueTest extends PHPUnit_Framework_TestCase { + + /** + * Returns the name of the concrete class tested by this test. + * + * @since 0.1 + * + * @return string + */ + abstract public function getClass(); + + abstract public function validConstructorArgumentsProvider(); + + abstract public function invalidConstructorArgumentsProvider(); + + /** + * Creates and returns a new instance of the concrete class. + * + * @since 0.1 + * + * @return mixed + */ + public function newInstance() { + $reflector = new ReflectionClass( $this->getClass() ); + $args = func_get_args(); + $instance = $reflector->newInstanceArgs( $args ); + return $instance; + } + + /** + * @since 0.1 + * + * @return array [instance, constructor args] + */ + public function instanceProvider() { + $instanceBuilder = [ $this, 'newInstance' ]; + + return array_map( + function ( array $args ) use ( $instanceBuilder ) { + return [ + call_user_func_array( $instanceBuilder, $args ), + $args + ]; + }, + $this->validConstructorArgumentsProvider() + ); + } + + /** + * @dataProvider validConstructorArgumentsProvider + * + * @since 0.1 + */ + public function testConstructorWithValidArguments() { + $dataItem = call_user_func_array( + [ $this, 'newInstance' ], + func_get_args() + ); + + $this->assertInstanceOf( $this->getClass(), $dataItem ); + } + + /** + * @dataProvider invalidConstructorArgumentsProvider + * + * @since 0.1 + */ + public function testConstructorWithInvalidArguments() { + $this->setExpectedException( Exception::class ); + + call_user_func_array( + [ $this, 'newInstance' ], + func_get_args() + ); + } + + /** + * @dataProvider instanceProvider + */ + public function testImplements( DataValue $value, array $arguments ) { + $this->assertInstanceOf( Immutable::class, $value ); + $this->assertInstanceOf( Hashable::class, $value ); + $this->assertInstanceOf( Comparable::class, $value ); + $this->assertInstanceOf( Serializable::class, $value ); + $this->assertInstanceOf( DataValue::class, $value ); + } + + /** + * @dataProvider instanceProvider + */ + public function testGetType( DataValue $value, array $arguments ) { + $valueType = $value->getType(); + $this->assertInternalType( 'string', $valueType ); + $this->assertTrue( strlen( $valueType ) > 0 ); + + // Check whether using getType statically returns the same as called from an instance: + $staticValueType = call_user_func( [ $this->getClass(), 'getType' ] ); + $this->assertEquals( $staticValueType, $valueType ); + } + + /** + * @dataProvider instanceProvider + */ + public function testSerialization( DataValue $value, array $arguments ) { + $serialization = serialize( $value ); + $this->assertInternalType( 'string', $serialization ); + + $unserialized = unserialize( $serialization ); + $this->assertInstanceOf( DataValue::class, $unserialized ); + + $this->assertTrue( $value->equals( $unserialized ) ); + $this->assertEquals( $value, $unserialized ); + } + + /** + * @dataProvider instanceProvider + */ + public function testEquals( DataValue $value, array $arguments ) { + $this->assertTrue( $value->equals( $value ) ); + + foreach ( [ true, false, null, 'foo', 42, [], 4.2 ] as $otherValue ) { + $this->assertFalse( $value->equals( $otherValue ) ); + } + } + + /** + * @dataProvider instanceProvider + */ + public function testGetHash( DataValue $value, array $arguments ) { + $hash = $value->getHash(); + + $this->assertInternalType( 'string', $hash ); + $this->assertEquals( $hash, $value->getHash() ); + $this->assertEquals( $hash, $value->getCopy()->getHash() ); + } + + /** + * @dataProvider instanceProvider + */ + public function testGetCopy( DataValue $value, array $arguments ) { + $copy = $value->getCopy(); + + $this->assertInstanceOf( DataValue::class, $copy ); + $this->assertTrue( $value->equals( $copy ) ); + } + + /** + * @dataProvider instanceProvider + */ + public function testGetValueSimple( DataValue $value, array $arguments ) { + $value->getValue(); + $this->assertTrue( true ); + } + + /** + * @dataProvider instanceProvider + */ + public function testGetArrayValueSimple( DataValue $value, array $arguments ) { + $value->getArrayValue(); + $this->assertTrue( true ); + } + + /** + * @dataProvider instanceProvider + */ + public function testToArray( DataValue $value, array $arguments ) { + $array = $value->toArray(); + + $this->assertInternalType( 'array', $array ); + + $this->assertTrue( array_key_exists( 'type', $array ) ); + $this->assertTrue( array_key_exists( 'value', $array ) ); + + $this->assertEquals( $value->getType(), $array['type'] ); + $this->assertEquals( $value->getArrayValue(), $array['value'] ); + } + +} diff --git a/www/wiki/vendor/data-values/data-values/tests/phpunit/NumberValueTest.php b/www/wiki/vendor/data-values/data-values/tests/phpunit/NumberValueTest.php new file mode 100644 index 00000000..7f1b5b12 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/tests/phpunit/NumberValueTest.php @@ -0,0 +1,64 @@ +<?php + +namespace DataValues\Tests; + +use DataValues\NumberValue; + +/** + * @covers DataValues\NumberValue + * + * @group DataValue + * @group DataValueExtensions + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class NumberValueTest extends DataValueTest { + + /** + * @see DataValueTest::getClass + * + * @return string + */ + public function getClass() { + return NumberValue::class; + } + + public function validConstructorArgumentsProvider() { + $argLists = []; + + $argLists[] = [ 42 ]; + $argLists[] = [ -42 ]; + $argLists[] = [ 4.2 ]; + $argLists[] = [ -4.2 ]; + $argLists[] = [ 0 ]; + + return $argLists; + } + + public function invalidConstructorArgumentsProvider() { + $argLists = []; + + $argLists[] = [ 'foo' ]; + $argLists[] = [ '' ]; + $argLists[] = [ '0' ]; + $argLists[] = [ '42' ]; + $argLists[] = [ '-42' ]; + $argLists[] = [ '4.2' ]; + $argLists[] = [ '-4.2' ]; + $argLists[] = [ false ]; + $argLists[] = [ true ]; + $argLists[] = [ null ]; + $argLists[] = [ '0x20' ]; + + return $argLists; + } + + /** + * @dataProvider instanceProvider + */ + public function testGetValue( NumberValue $number, array $arguments ) { + $this->assertEquals( $arguments[0], $number->getValue() ); + } + +} diff --git a/www/wiki/vendor/data-values/data-values/tests/phpunit/StringValueTest.php b/www/wiki/vendor/data-values/data-values/tests/phpunit/StringValueTest.php new file mode 100644 index 00000000..dbce05b2 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/tests/phpunit/StringValueTest.php @@ -0,0 +1,56 @@ +<?php + +namespace DataValues\Tests; + +use DataValues\StringValue; + +/** + * @covers DataValues\StringValue + * + * @group DataValue + * @group DataValueExtensions + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class StringValueTest extends DataValueTest { + + /** + * @see DataValueTest::getClass + * + * @return string + */ + public function getClass() { + return StringValue::class; + } + + public function validConstructorArgumentsProvider() { + $argLists = []; + + $argLists[] = [ 'foo' ]; + $argLists[] = [ '' ]; + $argLists[] = [ ' foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz ' ]; + + return $argLists; + } + + public function invalidConstructorArgumentsProvider() { + $argLists = []; + + $argLists[] = [ 42 ]; + $argLists[] = [ [] ]; + $argLists[] = [ false ]; + $argLists[] = [ true ]; + $argLists[] = [ null ]; + + return $argLists; + } + + /** + * @dataProvider instanceProvider + */ + public function testGetValue( StringValue $string, array $arguments ) { + $this->assertEquals( $arguments[0], $string->getValue() ); + } + +} diff --git a/www/wiki/vendor/data-values/data-values/tests/phpunit/UnDeserializableValueTest.php b/www/wiki/vendor/data-values/data-values/tests/phpunit/UnDeserializableValueTest.php new file mode 100644 index 00000000..4d132fcb --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/tests/phpunit/UnDeserializableValueTest.php @@ -0,0 +1,92 @@ +<?php + +namespace DataValues\Tests; + +use DataValues\DataValue; +use DataValues\UnDeserializableValue; + +/** + * @covers DataValues\UnDeserializableValue + * + * @group DataValue + * @group DataValueExtensions + * + * @license GPL-2.0+ + * @author Daniel Kinzler + */ +class UnDeserializableValueTest extends DataValueTest { + + /** + * @see DataValueTest::getClass + * + * @return string + */ + public function getClass() { + return UnDeserializableValue::class; + } + + public function validConstructorArgumentsProvider() { + $argLists = []; + + $argLists[] = [ null, null, 'No type and no data' ]; + $argLists[] = [ null, 'string', 'A type but no data' ]; + $argLists[] = [ [ 'stuff' ], 'string', 'A type and bad data' ]; + + return $argLists; + } + + public function invalidConstructorArgumentsProvider() { + $argLists = []; + + $argLists[] = [ new \stdClass(), null, 'No type and no data' ]; + $argLists[] = [ null, 42, 'No type and no data' ]; + $argLists[] = [ null, false, 'No type and no data' ]; + $argLists[] = [ null, [], 'No type and no data' ]; + $argLists[] = [ null, null, null ]; + $argLists[] = [ null, null, true ]; + $argLists[] = [ null, null, [] ]; + + return $argLists; + } + + /** + * @dataProvider instanceProvider + */ + public function testGetValue( UnDeserializableValue $value, array $arguments ) { + $this->assertEquals( $arguments[0], $value->getValue() ); + } + + /** + * @dataProvider instanceProvider + */ + public function testGetArrayValue( UnDeserializableValue $value, array $arguments ) { + $this->assertEquals( $arguments[0], $value->getArrayValue() ); + } + + /** + * @dataProvider instanceProvider + */ + public function testGetTargetType( UnDeserializableValue $value, array $arguments ) { + $this->assertEquals( $arguments[1], $value->getTargetType() ); + } + + /** + * @dataProvider instanceProvider + */ + public function testToArray( DataValue $value, array $arguments ) { + $array = $value->toArray(); + + $this->assertInternalType( 'array', $array ); + + $this->assertTrue( array_key_exists( 'type', $array ) ); + $this->assertTrue( array_key_exists( 'value', $array ) ); + + $this->assertEquals( $value->getTargetType(), $array['type'] ); + $this->assertEquals( $value->getValue(), $array['value'] ); + } + + public function testNewFromArray() { + $this->assertFalse( method_exists( $this->getClass(), 'newFromArray' ) ); + } + +} diff --git a/www/wiki/vendor/data-values/data-values/tests/phpunit/UnknownValueTest.php b/www/wiki/vendor/data-values/data-values/tests/phpunit/UnknownValueTest.php new file mode 100644 index 00000000..d3d79029 --- /dev/null +++ b/www/wiki/vendor/data-values/data-values/tests/phpunit/UnknownValueTest.php @@ -0,0 +1,60 @@ +<?php + +namespace DataValues\Tests; + +use DataValues\UnknownValue; + +/** + * @covers DataValues\UnknownValue + * + * @group DataValue + * @group DataValueExtensions + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class UnknownValueTest extends DataValueTest { + + /** + * @see DataValueTest::getClass + * + * @return string + */ + public function getClass() { + return UnknownValue::class; + } + + public function validConstructorArgumentsProvider() { + $argLists = []; + + $argLists[] = [ 42 ]; + $argLists[] = [ [] ]; + $argLists[] = [ false ]; + $argLists[] = [ true ]; + $argLists[] = [ null ]; + $argLists[] = [ 'foo' ]; + $argLists[] = [ '' ]; + $argLists[] = [ ' foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz ' ]; + + return $argLists; + } + + public function invalidConstructorArgumentsProvider() { + return [ + [], + ]; + } + + public function testConstructorWithInvalidArguments() { + // UnknownValue has no invalid arguments + $this->assertTrue( true ); + } + + /** + * @dataProvider instanceProvider + */ + public function testGetValue( UnknownValue $value, array $arguments ) { + $this->assertEquals( $arguments[0], $value->getValue() ); + } + +} diff --git a/www/wiki/vendor/data-values/geo/COPYING b/www/wiki/vendor/data-values/geo/COPYING new file mode 100644 index 00000000..ebba08a4 --- /dev/null +++ b/www/wiki/vendor/data-values/geo/COPYING @@ -0,0 +1,347 @@ +The license text below "----" applies to all files within this distribution, other +than those that are in a directory which contains files named "LICENSE" or +"COPYING", or a subdirectory thereof. For those files, the license text contained in +said file overrides any license information contained in directories of smaller depth. +Alternative licenses are typically used for software that is provided by external +parties, and merely packaged with this software for convenience. +---- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/www/wiki/vendor/data-values/geo/README.md b/www/wiki/vendor/data-values/geo/README.md new file mode 100644 index 00000000..9a868c00 --- /dev/null +++ b/www/wiki/vendor/data-values/geo/README.md @@ -0,0 +1,280 @@ +# DataValues Geo + +Small library for **parsing, formatting and representing coordinates**. This library supports multiple coordinate formats, +it is well tested, and it is used by the software behind Wikipedia and Wikidata. + +[![Build Status](https://travis-ci.org/DataValues/Geo.svg?branch=master)](https://travis-ci.org/DataValues/Geo) +[![Code Coverage](https://scrutinizer-ci.com/g/DataValues/Geo/badges/coverage.png?s=bf4cfd11f3b985fd05918f395c350b376a9ce0ee)](https://scrutinizer-ci.com/g/DataValues/Geo/) +[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/DataValues/Geo/badges/quality-score.png?s=e695e42b53d74fc02e5cfa2aa218420f062edbd2)](https://scrutinizer-ci.com/g/DataValues/Geo/) + +On [Packagist](https://packagist.org/packages/data-values/geo): +[![Latest Stable Version](https://poser.pugx.org/data-values/geo/version.png)](https://packagist.org/packages/data-values/geo) +[![Download count](https://poser.pugx.org/data-values/geo/d/total.png)](https://packagist.org/packages/data-values/geo) + +## Usage + +To **parse a string to a `LatLongValue` object** you use one of the coordinate parsers. + +```php +$parser = new LatLongParser(); +$latLongValue = $parser->parse('55.7557860 N, 37.6176330 W'); +var_dump($latLongValue->getLongitude()); // float: -37.6176330 +``` + +These parsers are provided: + +* `LatLongParser` - Facade for format specific parsers. In most cases you will be using this one +* `DdCoordinateParser` - Parses decimal degree coordinates +* `DmCoordinateParser` - Parses decimal minute coordinates +* `DmsCoordinateParser` - Parses degree minute second coordinates +* `FloatCoordinateParser` - Parses float coordinates +* `GlobeCoordinateParser` - Parses coordinates into `GlobeCoordinateValue` objects + +To **turn a coordinate object into a string** you use one of the coordinate formatters. + +```php +$formatter = new LatLongFormatter(); +$coordinateString = $formatter->format(new LatLongValue(42.23, 13.37)); +``` + +These formatters are provided: + +* `LatLongFormatter` - Formats a `LatLongValue` into any of the supported formats +* `GlobeCoordinateFormatter` - Formats a `GlobeCoordinateValue` + +To **represent a set of coordinates** you use one of the Value Objects. + +`LatLongValue` has a float latitude and longitude. `GlobeCoordinateValue` wraps `LatLongValue` +and adds a precision and a globe identifier. + +The **supported coordinate formats** are: + +* Degree minute second (`55° 45' 20.8296", -37° 37' 3.4788"` or `55° 45' 20.8296" N, 37° 37' 3.4788" W`) +* Decimal minute (`55° 30', -37° 30'` or `55° 30' N, 37° 30' W`) +* Decimal degree (`55.7557860°, -37.6176330°` or `55.7557860° N, 37.6176330° W`) +* Float (`55.7557860, -37.6176330` or `55.7557860 N, 37.6176330 W`) + +The parsers and formatters allow you to customize the used symbols for degrees, minutes and seconds and +to change the letters used to indicate direction (N, E, S, W). + +## Requirements + +**Geo 4.x:** PHP 7.1 or later (tested with PHP 7.1 up to PHP 7.3) + +**Geo 3.x:** PHP 5.5 or later (tested with PHP 5.5 up to PHP 7.2 and HHVM) + +## Installation + +To add this package as a local, per-project dependency to your project, simply add a +dependency on `data-values/geo` to your project's `composer.json` file. +Here is a minimal example of a `composer.json` file that just defines a dependency on +version 4.x of this package: + +```json + { + "require": { + "data-values/geo": "^4.0.0" + } + } +``` + +## Running the tests + +For tests only + + composer test + +For style checks only + + composer cs + +For a full CI run + + composer ci + +## Authors + +DataValues Geo is based upon and contains a lot of code written by +[Jeroen De Dauw](https://github.com/JeroenDeDauw) for the +[Maps](https://github.com/JeroenDeDauw/Maps) and +[Semantic MediaWiki](https://semantic-mediawiki.org/) projects. + +Significant contributions where made by the Wikidata team, as [Wikimedia Germany](https://wikimedia.de/en) +employees for the [Wikidata project](https://wikidata.org/). + +## Release notes + +### 4.1.0 (dev) + +* Added "PHP strict types" to all files +* `LatLongValue` no longer extends `DataValueObject` +* `GlobeCoordinateValue` no longer extends `DataValueObject` + +### 4.0.1 (2018-08-10) + +* Fixed parsing of coordinates with lowercase S/W directions +* Fixed parsing DMS coordinates that omit a single minute number + +### 3.0.1 (2018-08-01) + +* Fixed parsing of coordinates with lowercase S/W directions + +### 2.1.2 (2018-08-01) + +* Fixed parsing of coordinates with lowercase S/W directions + +### 4.0.0 (2018-07-13) + +* Updated minimum required PHP version from 5.5.9 to 7.1 +* Added scalar type hints +* Added return type hints +* Added nullable type hints +* Made constant visibility explicit +* Constructing an invalid `LatLongValue` now causes `InvalidArgumentException` instead of `OutOfRangeException` + +### 3.0.0 (2018-03-20) + +* Removed `DATAVALUES_GEO_VERSION` constant +* The parsers no longer extend `StringValueParser` + * They no longer have public methods `setOptions` and `getOptions` + * They no longer have protected field `options` + * They no longer have protected methods `requireOption`, `defaultOption` and `stringParse` + * `GlobeCoordinateParser` and `LatLongParser` no longer have protected method `getOption` +* Made several protected fields and methods private + * All fields of `LatLongValue` + * The `detect…Precision` methods in `GlobeCoordinateParser` + * `LatLongParser::getParsers` +* Removed public static method `LatLongParser::areCoordinates` +* Dropped dependence on the DataValues Common library +* Removed long deprecated class aliases + * `DataValues\GlobeCoordinateValue` (now in `DataValues\Geo\Values`) + * `DataValues\LatLongValue` (now in `DataValues\Geo\Values`) + * `DataValues\Geo\Formatters\GeoCoordinateFormatter` (now `LatLongFormatter`) + * `DataValues\Geo\Parsers\GeoCoordinateParser` (now `LatLongParser`) + +### 2.1.1 (2017-08-09) + +* Allow use with ~0.4.0 of DataValues/Common + +### 2.1.0 (2017-08-09) + +* Remove MediaWiki integration +* Make use of the …::class feature +* Add .gitattributes to exclude not needed files from git exports +* Use Wikibase CodeSniffer instead of Mediawiki's +* Move to short array syntax + +### 2.0.1 (2017-06-26) + +* Fixed `GlobeCoordinateValue::newFromArray` and `LatLongValue::newFromArray` not accepting mixed + values. +* Deprecated `GlobeCoordinateValue::newFromArray` and `LatLongValue::newFromArray`. +* Updated minimum required PHP version from 5.3 to 5.5.9. + +### 2.0.0 (2017-05-09) + +* `GlobeCoordinateValue` does not accept empty strings as globes any more. +* `GlobeCoordinateValue` does not accept precisions outside the [-360..+360] interval any more. +* Changed hash calculation of `GlobeCoordinateValue` in an incompatible way. +* Renamed `GeoCoordinateFormatter` to `LatLongFormatter`, leaving a deprecated alias. +* Renamed `GeoCoordinateParser` to `LatLongParser`, leaving a deprecated alias. +* Renamed `GeoCoordinateParserBase` to `LatLongParserBase`. +* Deprecated `LatLongParser::areCoordinates`. + +### 1.2.2 (2017-03-14) + +* Fixed multiple rounding issues in `GeoCoordinateFormatter`. + +### 1.2.1 (2016-12-16) + +* Fixed another IEEE issue in `GeoCoordinateFormatter`. + +### 1.2.0 (2016-11-11) + +* Added missing inline documentation to public methods and constants. +* Added a basic PHPCS rule set, can be run with `composer phpcs`. + +### 1.1.8 (2016-10-12) + +* Fixed an IEEE issue in `GeoCoordinateFormatter` +* Fixed a PHP 7.1 compatibility issue in a test + +### 1.1.7 (2016-05-25) + +* Made minor documentation improvements + +### 1.1.6 (2016-04-02) + +* Added compatibility with DataValues Common 0.3.x + +### 1.1.5 (2015-12-28) + +* The component can now be installed together with DataValues Interfaces 0.2.x + +### 1.1.4 (2014-11-25) + +* Add fall back to default on invalid precision to more places. + +### 1.1.3 (2014-11-19) + +* Fall back to default on invalid precision instead of dividing by zero. + +### 1.1.2 (2014-11-18) + +* Precision detection in `GlobeCoordinateParser` now has a lower bound of 0.00000001° + +### 1.1.1 (2014-10-21) + +* Removed remaining uses of class aliases from messages and comments +* Fixed some types in documentation + +### 1.1.0 (2014-10-09) + +* Made the component installable with DataValues 1.x +* `GeoCoordinateFormatter` now supports precision in degrees +* `GlobeCoordinateFormatter` now passes the globe precision to the `GeoCoordinateFormatter` it uses +* Introduced `FORMAT_NAME` class constants on ValueParsers in order to use them as expectedFormat +* Changed ValueParsers to pass rawValue and expectedFormat arguments when constructing a `ParseException` + +### 1.0.0 (2014-07-31) + +* All classes and interfaces have been moved into the `DataValues\Geo` namespace + * `DataValues\LatLongValue` has been left as deprecated alias + * `DataValues\GlobeCoordinateValue` has been left as deprecated alias +* Globe in `GlobeCoordinateValue` now defaults to `http://www.wikidata.org/entity/Q2` + +### 0.2.0 (2014-07-07) + +* Removed deprecated `GeoCoordinateValue` +* Added `GlobeMath` + +### 0.1.2 (2014-01-22) + +* Added support for different levels of spacing in GeoCoordinateFormatter + +### 0.1.1 (2013-11-30) + +* Added support for direction notation to GeoCoordinateFormatter +* Decreased complexity of GeoCoordinateFormatter +* Decreased complexity and coupling of GeoCoordinateFormatterTest + +### 0.1.0 (2013-11-17) + +Initial release with these features: + +* LatLongValue +* GlobeCoordinateValue +* GeoCoordinateFormatter +* GlobeCoordinateFormatter +* DdCoordinateParser +* DmCoordinateParser +* DmsCoordinateParser +* FloatCoordinateParser +* GeoCoordinateParser +* GlobeCoordinateParser + +## Links + +* [DataValues Geo on Packagist](https://packagist.org/packages/data-values/geo) +* [DataValues Geo on TravisCI](https://travis-ci.org/DataValues/Geo) +* [DataValues on Wikimedia's Phabricator](https://phabricator.wikimedia.org/project/view/122/) diff --git a/www/wiki/vendor/data-values/geo/src/Formatters/GlobeCoordinateFormatter.php b/www/wiki/vendor/data-values/geo/src/Formatters/GlobeCoordinateFormatter.php new file mode 100644 index 00000000..b651e8a5 --- /dev/null +++ b/www/wiki/vendor/data-values/geo/src/Formatters/GlobeCoordinateFormatter.php @@ -0,0 +1,53 @@ +<?php + +declare( strict_types = 1 ); + +namespace DataValues\Geo\Formatters; + +use DataValues\Geo\Values\GlobeCoordinateValue; +use InvalidArgumentException; +use ValueFormatters\FormatterOptions; +use ValueFormatters\ValueFormatter; + +/** + * Geographical coordinates formatter. + * Formats GlobeCoordinateValue objects. + * + * Formatting of latitude and longitude is done via LatLongFormatter. + * + * For now this is a trivial implementation that only forwards to LatLongFormatter. + * TODO: add formatting of globe and precision + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class GlobeCoordinateFormatter implements ValueFormatter { + + /** + * @var LatLongFormatter + */ + private $formatter; + + public function __construct( FormatterOptions $options = null ) { + $this->formatter = new LatLongFormatter( $options ); + } + + /** + * @see ValueFormatter::format + * + * @param GlobeCoordinateValue $value + * + * @return string Plain text + * @throws InvalidArgumentException + */ + public function format( $value ): string { + if ( !( $value instanceof GlobeCoordinateValue ) ) { + throw new InvalidArgumentException( 'Data value type mismatch. Expected a GlobeCoordinateValue.' ); + } + + return $this->formatter->formatLatLongValue( $value->getLatLong(), $value->getPrecision() ); + } + +} diff --git a/www/wiki/vendor/data-values/geo/src/Formatters/LatLongFormatter.php b/www/wiki/vendor/data-values/geo/src/Formatters/LatLongFormatter.php new file mode 100644 index 00000000..94e7828e --- /dev/null +++ b/www/wiki/vendor/data-values/geo/src/Formatters/LatLongFormatter.php @@ -0,0 +1,360 @@ +<?php + +declare( strict_types = 1 ); + +namespace DataValues\Geo\Formatters; + +use DataValues\Geo\Values\LatLongValue; +use InvalidArgumentException; +use ValueFormatters\FormatterOptions; +use ValueFormatters\ValueFormatterBase; + +/** + * Geographical coordinates formatter. + * Formats LatLongValue objects. + * + * Supports the following notations: + * - Degree minute second + * - Decimal degrees + * - Decimal minutes + * - Float + * + * Some code in this class has been borrowed from the + * MapsCoordinateParser class of the Maps extension for MediaWiki. + * + * @since 0.1, renamed in 2.0 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + * @author Addshore + * @author Thiemo Kreuz + */ +class LatLongFormatter extends ValueFormatterBase { + + /** + * Output formats for use with the self::OPT_FORMAT option. + */ + public const TYPE_FLOAT = 'float'; + public const TYPE_DMS = 'dms'; + public const TYPE_DM = 'dm'; + public const TYPE_DD = 'dd'; + + /** + * The symbols representing the different directions for usage in directional notation. + * @since 0.1 + */ + public const OPT_NORTH_SYMBOL = 'north'; + public const OPT_EAST_SYMBOL = 'east'; + public const OPT_SOUTH_SYMBOL = 'south'; + public const OPT_WEST_SYMBOL = 'west'; + + /** + * The symbols representing degrees, minutes and seconds. + * @since 0.1 + */ + public const OPT_DEGREE_SYMBOL = 'degree'; + public const OPT_MINUTE_SYMBOL = 'minute'; + public const OPT_SECOND_SYMBOL = 'second'; + + /** + * Flags for use with the self::OPT_SPACING_LEVEL option. + */ + public const OPT_SPACE_LATLONG = 'latlong'; + public const OPT_SPACE_DIRECTION = 'direction'; + public const OPT_SPACE_COORDPARTS = 'coordparts'; + + /** + * Option specifying the output format (also referred to as output type). Must be one of the + * self::TYPE_… constants. + */ + public const OPT_FORMAT = 'geoformat'; + + /** + * Boolean option specifying if negative coordinates should have minus signs, e.g. "-1°, -2°" + * (false) or cardinal directions, e.g. "1° S, 2° W" (true). Default is false. + */ + public const OPT_DIRECTIONAL = 'directional'; + + /** + * Option for the separator character between latitude and longitude. Defaults to a comma. + */ + public const OPT_SEPARATOR_SYMBOL = 'separator'; + + /** + * Option specifying the amount and position of space characters in the output. Must be an array + * containing zero or more of the self::OPT_SPACE_… flags. + */ + public const OPT_SPACING_LEVEL = 'spacing'; + + /** + * Option specifying the precision in fractional degrees. Must be a number or numeric string. + */ + public const OPT_PRECISION = 'precision'; + + private const DEFAULT_PRECISION = 1 / 3600; + + public function __construct( FormatterOptions $options = null ) { + parent::__construct( $options ); + + $this->defaultOption( self::OPT_NORTH_SYMBOL, 'N' ); + $this->defaultOption( self::OPT_EAST_SYMBOL, 'E' ); + $this->defaultOption( self::OPT_SOUTH_SYMBOL, 'S' ); + $this->defaultOption( self::OPT_WEST_SYMBOL, 'W' ); + + $this->defaultOption( self::OPT_DEGREE_SYMBOL, '°' ); + $this->defaultOption( self::OPT_MINUTE_SYMBOL, "'" ); + $this->defaultOption( self::OPT_SECOND_SYMBOL, '"' ); + + $this->defaultOption( self::OPT_FORMAT, self::TYPE_FLOAT ); + $this->defaultOption( self::OPT_DIRECTIONAL, false ); + + $this->defaultOption( self::OPT_SEPARATOR_SYMBOL, ',' ); + $this->defaultOption( self::OPT_SPACING_LEVEL, [ + self::OPT_SPACE_LATLONG, + self::OPT_SPACE_DIRECTION, + self::OPT_SPACE_COORDPARTS, + ] ); + $this->defaultOption( self::OPT_PRECISION, 0 ); + } + + /** + * @see ValueFormatter::format + * + * Calls formatLatLongValue() using OPT_PRECISION for the $precision parameter. + * + * @param LatLongValue $value + * + * @return string Plain text + * @throws InvalidArgumentException + */ + public function format( $value ): string { + if ( !( $value instanceof LatLongValue ) ) { + throw new InvalidArgumentException( 'Data value type mismatch. Expected a LatLongValue.' ); + } + + return $this->formatLatLongValue( $value, $this->getPrecisionFromOptions() ); + } + + private function getPrecisionFromOptions(): float { + $precision = $this->options->getOption( self::OPT_PRECISION ); + + if ( is_string( $precision ) ) { + return (float)$precision; + } + + if ( is_float( $precision ) || is_int( $precision ) ) { + return $precision; + } + + return self::DEFAULT_PRECISION; + } + + /** + * Formats a LatLongValue with the desired precision. + * + * @since 0.5 + * + * @param LatLongValue $value + * @param float|int $precision The desired precision, given as fractional degrees. + * + * @return string Plain text + * @throws InvalidArgumentException + */ + public function formatLatLongValue( LatLongValue $value, ?float $precision ): string { + if ( $precision <= 0 || !is_finite( $precision ) ) { + $precision = self::DEFAULT_PRECISION; + } + + $formatted = implode( + $this->getOption( self::OPT_SEPARATOR_SYMBOL ) . $this->getSpacing( self::OPT_SPACE_LATLONG ), + [ + $this->formatLatitude( $value->getLatitude(), $precision ), + $this->formatLongitude( $value->getLongitude(), $precision ) + ] + ); + + return $formatted; + } + + /** + * @param string $spacingLevel One of the self::OPT_SPACE_… constants + * + * @return string + */ + private function getSpacing( string $spacingLevel ): string { + if ( in_array( $spacingLevel, $this->getOption( self::OPT_SPACING_LEVEL ) ) ) { + return ' '; + } + return ''; + } + + private function formatLatitude( float $latitude, float $precision ): string { + return $this->makeDirectionalIfNeeded( + $this->formatCoordinate( $latitude, $precision ), + $this->options->getOption( self::OPT_NORTH_SYMBOL ), + $this->options->getOption( self::OPT_SOUTH_SYMBOL ) + ); + } + + private function formatLongitude( float $longitude, float $precision ): string { + return $this->makeDirectionalIfNeeded( + $this->formatCoordinate( $longitude, $precision ), + $this->options->getOption( self::OPT_EAST_SYMBOL ), + $this->options->getOption( self::OPT_WEST_SYMBOL ) + ); + } + + private function makeDirectionalIfNeeded( string $coordinate, string $positiveSymbol, + string $negativeSymbol ): string { + + if ( $this->options->getOption( self::OPT_DIRECTIONAL ) ) { + return $this->makeDirectional( $coordinate, $positiveSymbol, $negativeSymbol ); + } + + return $coordinate; + } + + private function makeDirectional( string $coordinate, string $positiveSymbol, + string $negativeSymbol ): string { + + $isNegative = substr( $coordinate, 0, 1 ) === '-'; + + if ( $isNegative ) { + $coordinate = substr( $coordinate, 1 ); + } + + $symbol = $isNegative ? $negativeSymbol : $positiveSymbol; + + return $coordinate . $this->getSpacing( self::OPT_SPACE_DIRECTION ) . $symbol; + } + + private function formatCoordinate( float $degrees, float $precision ): string { + // Remove insignificant detail + $degrees = $this->roundDegrees( $degrees, $precision ); + $format = $this->getOption( self::OPT_FORMAT ); + + if ( $format === self::TYPE_FLOAT ) { + return $this->getInFloatFormat( $degrees ); + } + + if ( $format !== self::TYPE_DD ) { + if ( $precision >= 1 - 1 / 60 && $precision < 1 ) { + $precision = 1; + } elseif ( $precision >= 1 / 60 - 1 / 3600 && $precision < 1 / 60 ) { + $precision = 1 / 60; + } + } + + if ( $format === self::TYPE_DD || $precision >= 1 ) { + return $this->getInDecimalDegreeFormat( $degrees, $precision ); + } + if ( $format === self::TYPE_DM || $precision >= 1 / 60 ) { + return $this->getInDecimalMinuteFormat( $degrees, $precision ); + } + if ( $format === self::TYPE_DMS ) { + return $this->getInDegreeMinuteSecondFormat( $degrees, $precision ); + } + + throw new InvalidArgumentException( 'Invalid coordinate format specified in the options' ); + } + + private function roundDegrees( float $degrees, float $precision ): float { + $sign = $degrees > 0 ? 1 : -1; + $reduced = round( abs( $degrees ) / $precision ); + $expanded = $reduced * $precision; + + return $sign * $expanded; + } + + private function getInFloatFormat( float $floatDegrees ): string { + $stringDegrees = (string)$floatDegrees; + + if ( $stringDegrees === '-0' ) { + return '0'; + } + + return $stringDegrees; + } + + private function getInDecimalDegreeFormat( float $floatDegrees, float $precision ): string { + $degreeDigits = $this->getSignificantDigits( 1, $precision ); + $stringDegrees = $this->formatNumber( $floatDegrees, $degreeDigits ); + + return $stringDegrees . $this->options->getOption( self::OPT_DEGREE_SYMBOL ); + } + + private function getInDegreeMinuteSecondFormat( float $floatDegrees, float $precision ): string { + $isNegative = $floatDegrees < 0; + $secondDigits = $this->getSignificantDigits( 3600, $precision ); + + $seconds = round( abs( $floatDegrees ) * 3600, max( 0, $secondDigits ) ); + $minutes = (int)( $seconds / 60 ); + $degrees = (int)( $minutes / 60 ); + + $seconds -= $minutes * 60; + $minutes -= $degrees * 60; + + $space = $this->getSpacing( self::OPT_SPACE_COORDPARTS ); + $result = $this->formatNumber( $degrees ) + . $this->options->getOption( self::OPT_DEGREE_SYMBOL ) + . $space + . $this->formatNumber( $minutes ) + . $this->options->getOption( self::OPT_MINUTE_SYMBOL ) + . $space + . $this->formatNumber( $seconds, $secondDigits ) + . $this->options->getOption( self::OPT_SECOND_SYMBOL ); + + if ( $isNegative && ( $degrees + $minutes + $seconds ) > 0 ) { + $result = '-' . $result; + } + + return $result; + } + + private function getInDecimalMinuteFormat( float $floatDegrees, float $precision ): string { + $isNegative = $floatDegrees < 0; + $minuteDigits = $this->getSignificantDigits( 60, $precision ); + + $minutes = round( abs( $floatDegrees ) * 60, max( 0, $minuteDigits ) ); + $degrees = (int)( $minutes / 60 ); + + $minutes -= $degrees * 60; + + $space = $this->getSpacing( self::OPT_SPACE_COORDPARTS ); + $result = $this->formatNumber( $degrees ) + . $this->options->getOption( self::OPT_DEGREE_SYMBOL ) + . $space + . $this->formatNumber( $minutes, $minuteDigits ) + . $this->options->getOption( self::OPT_MINUTE_SYMBOL ); + + if ( $isNegative && ( $degrees + $minutes ) > 0 ) { + $result = '-' . $result; + } + + return $result; + } + + /** + * @param float|int $unitsPerDegree The number of target units per degree + * (60 for minutes, 3600 for seconds) + * @param float|int $degreePrecision + * + * @return int The number of digits to show after the decimal point + * (resp. before, if the result is negative). + */ + private function getSignificantDigits( float $unitsPerDegree, float $degreePrecision ): int { + return (int)ceil( -log10( $unitsPerDegree * $degreePrecision ) ); + } + + /** + * @param float $number + * @param int $digits The number of digits after the decimal point. + * + * @return string + */ + private function formatNumber( float $number, int $digits = 0 ): string { + // TODO: use NumberLocalizer + return sprintf( '%.' . ( $digits > 0 ? $digits : 0 ) . 'F', $number ); + } + +} diff --git a/www/wiki/vendor/data-values/geo/src/GlobeMath.php b/www/wiki/vendor/data-values/geo/src/GlobeMath.php new file mode 100644 index 00000000..984368b8 --- /dev/null +++ b/www/wiki/vendor/data-values/geo/src/GlobeMath.php @@ -0,0 +1,116 @@ +<?php + +declare( strict_types = 1 ); + +namespace DataValues\Geo; + +use DataValues\Geo\Values\GlobeCoordinateValue; +use DataValues\Geo\Values\LatLongValue; + +/** + * Logical and mathematical helper functions for normalizations and calculations with + * GlobeCoordinateValue objects. + * + * @since 0.2 + * + * @license GPL-2.0-or-later + * @author Thiemo Kreuz + */ +class GlobeMath { + + /** + * @todo Move this constant next to GlobeCoordinateValue::GLOBE_EARTH? + */ + public const GLOBE_MOON = 'http://www.wikidata.org/entity/Q405'; + + /** + * @param string|null $globe IRI of a globe. + * + * @return string Normalized IRI, defaults to 'http://www.wikidata.org/entity/Q2'. + */ + public function normalizeGlobe( ?string $globe ) { + if ( !is_string( $globe ) || $globe === '' ) { + return GlobeCoordinateValue::GLOBE_EARTH; + } + + return $globe; + } + + /** + * Normalizes latitude to [-90°..+90°]. Normalizes longitude to [-180°..+180°[ on Earth and + * Moon and to [0°..+360°[ on all other globes. + * @see http://planetarynames.wr.usgs.gov/TargetCoordinates + * + * @param GlobeCoordinateValue $value + * + * @return GlobeCoordinateValue + */ + public function normalizeGlobeCoordinate( GlobeCoordinateValue $value ): GlobeCoordinateValue { + return new GlobeCoordinateValue( + $this->normalizeGlobeLatLong( $value->getLatLong(), $value->getGlobe() ), + $value->getPrecision(), + $value->getGlobe() + ); + } + + /** + * @param LatLongValue $value + * @param string|null $globe + * + * @return LatLongValue + */ + public function normalizeGlobeLatLong( LatLongValue $value, string $globe = null ): LatLongValue { + switch ( $this->normalizeGlobe( $globe ) ) { + case GlobeCoordinateValue::GLOBE_EARTH: + case self::GLOBE_MOON: + $minimumLongitude = -180; + break; + default: + $minimumLongitude = 0; + } + + return $this->normalizeLatLong( $value, $minimumLongitude ); + } + + /** + * @param LatLongValue $value + * @param float $minimumLongitude + * + * @return LatLongValue + */ + public function normalizeLatLong( LatLongValue $value, float $minimumLongitude = -180.0 ): LatLongValue { + $lat = $value->getLatitude(); + $lon = $value->getLongitude(); + + // Normalize to [-180°..+180°[ on Earth/Moon, [0°..+360°[ on other globes. + if ( $lon >= $minimumLongitude + 360 ) { + $lon -= 360; + } elseif ( $lon < $minimumLongitude ) { + $lon += 360; + } + + if ( $lat >= 270 ) { + // Same side of the globe, on the southern hemisphere. + $lat -= 360; + } elseif ( $lat <= -270 ) { + // Same side of the globe, on the northern hemisphere. + $lat += 360; + } elseif ( $lat > 90 ) { + // Other side of the globe + $lat = 180 - $lat; + $lon += $lon - 180 >= $minimumLongitude ? -180 : 180; + } elseif ( $lat < -90 ) { + // Other side of the globe + $lat = -180 - $lat; + $lon += $lon - 180 >= $minimumLongitude ? -180 : 180; + } + + // North/south pole + if ( abs( $lat ) === 90.0 ) { + $lon = 0; + } + + return new LatLongValue( $lat, $lon ); + } + +} diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/DdCoordinateParser.php b/www/wiki/vendor/data-values/geo/src/Parsers/DdCoordinateParser.php new file mode 100644 index 00000000..94b46335 --- /dev/null +++ b/www/wiki/vendor/data-values/geo/src/Parsers/DdCoordinateParser.php @@ -0,0 +1,226 @@ +<?php + +declare( strict_types = 1 ); + +namespace DataValues\Geo\Parsers; + +use DataValues\Geo\Values\LatLongValue; +use ValueParsers\ParseException; +use ValueParsers\ParserOptions; + +/** + * Parser for geographical coordinates in Decimal Degree notation. + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + * @author H. Snater < mediawiki@snater.com > + */ +class DdCoordinateParser extends LatLongParserBase { + + /** + * The symbol representing degrees. + * @since 0.1 + */ + public const OPT_DEGREE_SYMBOL = 'degree'; + + /** + * @param ParserOptions|null $options + */ + public function __construct( ParserOptions $options = null ) { + $options = $options ?: new ParserOptions(); + $options->defaultOption( self::OPT_DEGREE_SYMBOL, '°' ); + + parent::__construct( $options ); + + $this->defaultDelimiters = [ $this->getOption( self::OPT_DEGREE_SYMBOL ) ]; + } + + /** + * @see LatLongParserBase::getParsedCoordinate + * + * @param string $coordinateSegment + * + * @return float + */ + protected function getParsedCoordinate( string $coordinateSegment ): float { + $coordinateSegment = $this->resolveDirection( $coordinateSegment ); + return $this->parseCoordinate( $coordinateSegment ); + } + + /** + * @see LatLongParserBase::areValidCoordinates + * + * @param string[] $normalizedCoordinateSegments + * + * @return bool + */ + protected function areValidCoordinates( array $normalizedCoordinateSegments ): bool { + // TODO: Implement localized decimal separator. + $baseRegExp = '\d{1,3}(\.\d{1,20})?' . $this->getOption( self::OPT_DEGREE_SYMBOL ); + + // Cache whether the coordinates are specified in directional format (a mixture of + // directional and non-directional is regarded invalid). + $directional = false; + + $match = false; + + foreach ( $normalizedCoordinateSegments as $i => $segment ) { + $direction = '(' + . $this->getOption( self::OPT_NORTH_SYMBOL ) . '|' + . $this->getOption( self::OPT_SOUTH_SYMBOL ) . ')'; + + if ( $i === 1 ) { + $direction = '(' + . $this->getOption( self::OPT_EAST_SYMBOL ) . '|' + . $this->getOption( self::OPT_WEST_SYMBOL ) . ')'; + } + + $match = preg_match( + '/^(' . $baseRegExp . $direction . '|' . $direction . $baseRegExp . ')$/i', + $segment + ); + + if ( $directional ) { + // Directionality is only set after parsing latitude: When the latitude is + // is directional, the longitude needs to be as well. Therefore we break here since + // checking for directionality is the only check needed for longitude. + break; + } elseif ( $match ) { + // Latitude is directional, no need to check for non-directionality. + $directional = true; + continue; + } + + $match = preg_match( '/^(-)?' . $baseRegExp . '$/i', $segment ); + + if ( !$match ) { + // Does neither match directional nor non-directional. + break; + } + } + + return ( 1 === $match ); + } + + /** + * @see ValueParser::parse + * + * @param string $value + * + * @throws ParseException + * @return LatLongValue + */ + public function parse( $value ): LatLongValue { + if ( !is_string( $value ) ) { + throw new ParseException( 'Not a string' ); + } + + return parent::parse( $this->getNormalizedNotation( $value ) ); + } + + /** + * Returns a normalized version of the coordinate string. + * + * @param string $coordinates + * + * @return string + */ + protected function getNormalizedNotation( string $coordinates ): string { + $coordinates = str_replace( + [ '°', '°' ], + $this->getOption( self::OPT_DEGREE_SYMBOL ), $coordinates + ); + + $coordinates = $this->removeInvalidChars( $coordinates ); + + return $coordinates; + } + + /** + * Returns a string with whitespace, control characters and characters with ASCII values above + * 126 removed. + * + * @see LatLongParserBase::removeInvalidChars + * + * @param string $string + * + * @return string + */ + protected function removeInvalidChars( string $string ): string { + return str_replace( ' ', '', parent::removeInvalidChars( $string ) ); + } + + /** + * Converts a coordinate segment to float representation. + * + * @param string $coordinateSegment + * + * @return float + */ + protected function parseCoordinate( string $coordinateSegment ): float { + return (float)str_replace( + $this->getOption( self::OPT_DEGREE_SYMBOL ), + '', + $coordinateSegment + ); + } + + /** + * @see LatLongParserBase::splitString + * + * @param string $normalizedCoordinateString + * + * @return string[] + */ + protected function splitString( string $normalizedCoordinateString ): array { + $separator = $this->getOption( self::OPT_SEPARATOR_SYMBOL ); + + $normalizedCoordinateSegments = explode( $separator, $normalizedCoordinateString ); + + if ( count( $normalizedCoordinateSegments ) !== 2 ) { + // Separator not present within the string, trying to figure out the segments by + // splitting after the first direction character or degree symbol: + $delimiters = $this->defaultDelimiters; + + $ns = [ + $this->getOption( self::OPT_NORTH_SYMBOL ), + $this->getOption( self::OPT_SOUTH_SYMBOL ) + ]; + + $ew = [ + $this->getOption( self::OPT_EAST_SYMBOL ), + $this->getOption( self::OPT_WEST_SYMBOL ) + ]; + + foreach ( $ns as $delimiter ) { + if ( mb_strpos( $normalizedCoordinateString, $delimiter ) === 0 ) { + // String starts with "north" or "west" symbol: Separation needs to be done + // before the "east" or "west" symbol. + $delimiters = array_merge( $ew, $delimiters ); + break; + } + } + + if ( count( $delimiters ) !== count( $this->defaultDelimiters ) + 2 ) { + $delimiters = array_merge( $ns, $delimiters ); + } + + foreach ( $delimiters as $delimiter ) { + $delimiterPos = mb_strpos( $normalizedCoordinateString, $delimiter ); + if ( $delimiterPos !== false ) { + $adjustPos = ( in_array( $delimiter, $ew ) ) ? 0 : mb_strlen( $delimiter ); + $normalizedCoordinateSegments = [ + mb_substr( $normalizedCoordinateString, 0, $delimiterPos + $adjustPos ), + mb_substr( $normalizedCoordinateString, $delimiterPos + $adjustPos ) + ]; + break; + } + } + } + + return $normalizedCoordinateSegments; + } + +} diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/DmCoordinateParser.php b/www/wiki/vendor/data-values/geo/src/Parsers/DmCoordinateParser.php new file mode 100644 index 00000000..0dee3115 --- /dev/null +++ b/www/wiki/vendor/data-values/geo/src/Parsers/DmCoordinateParser.php @@ -0,0 +1,167 @@ +<?php + +declare( strict_types = 1 ); + +namespace DataValues\Geo\Parsers; + +use ValueParsers\ParseException; +use ValueParsers\ParserOptions; + +/** + * Parser for geographical coordinates in Decimal Minute notation. + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + * @author H. Snater < mediawiki@snater.com > + */ +class DmCoordinateParser extends DdCoordinateParser { + + public const FORMAT_NAME = 'dm-coordinate'; + + /** + * The symbols representing minutes. + * @since 0.1 + */ + public const OPT_MINUTE_SYMBOL = 'minute'; + + /** + * @param ParserOptions|null $options + */ + public function __construct( ParserOptions $options = null ) { + $options = $options ?: new ParserOptions(); + $options->defaultOption( self::OPT_MINUTE_SYMBOL, "'" ); + + parent::__construct( $options ); + + $this->defaultDelimiters = [ $this->getOption( self::OPT_MINUTE_SYMBOL ) ]; + } + + /** + * @see LatLongParserBase::areValidCoordinates + * + * @param string[] $normalizedCoordinateSegments + * + * @return bool + */ + protected function areValidCoordinates( array $normalizedCoordinateSegments ): bool { + // At least one coordinate segment needs to have minutes specified. + $regExpStrict = '\d{1,3}' + . preg_quote( $this->getOption( self::OPT_DEGREE_SYMBOL ) ) + // TODO: Implement localized decimal separator. + . '(\d{1,2}(\.\d{1,20})?' + . preg_quote( $this->getOption( self::OPT_MINUTE_SYMBOL ) ) + . ')'; + $regExpLoose = $regExpStrict . '?'; + + // Cache whether minutes have been detected within the coordinate: + $detectedMinute = false; + + // Cache whether the coordinates are specified in directional format (a mixture of + // directional and non-directional is regarded invalid). + $directional = false; + + foreach ( $normalizedCoordinateSegments as $i => $segment ) { + $direction = '(' + . $this->getOption( self::OPT_NORTH_SYMBOL ) . '|' + . $this->getOption( self::OPT_SOUTH_SYMBOL ) . ')'; + + if ( $i === 1 ) { + $direction = '(' + . $this->getOption( self::OPT_EAST_SYMBOL ) . '|' + . $this->getOption( self::OPT_WEST_SYMBOL ) . ')'; + } + + $match = preg_match( + '/^(' . $regExpStrict . $direction . '|' . $direction . $regExpStrict . ')$/i', + $segment + ); + + if ( $match ) { + $detectedMinute = true; + } else { + $match = preg_match( + '/^(' . $regExpLoose . $direction . '|' . $direction . $regExpLoose . ')$/i', + $segment + ); + } + + if ( $match ) { + $directional = true; + } elseif ( !$directional ) { + $match = preg_match( '/^(-)?' . $regExpStrict . '$/i', $segment ); + + if ( $match ) { + $detectedMinute = true; + } else { + $match = preg_match( '/^(-)?' . $regExpLoose . '$/i', $segment ); + } + } + + if ( !$match ) { + return false; + } + } + + return $detectedMinute; + } + + /** + * @see DdCoordinateParser::getNormalizedNotation + * + * @param string $coordinates + * + * @return string + */ + protected function getNormalizedNotation( string $coordinates ): string { + $minute = $this->getOption( self::OPT_MINUTE_SYMBOL ); + + $coordinates = str_replace( [ '′', '′', '´', '′' ], $minute, $coordinates ); + + $coordinates = parent::getNormalizedNotation( $coordinates ); + + $coordinates = $this->removeInvalidChars( $coordinates ); + + return $coordinates; + } + + /** + * @see DdCoordinateParser::parseCoordinate + * + * @param string $coordinateSegment + * + * @return float + */ + protected function parseCoordinate( string $coordinateSegment ): float { + $isNegative = substr( $coordinateSegment, 0, 1 ) === '-'; + + if ( $isNegative ) { + $coordinateSegment = substr( $coordinateSegment, 1 ); + } + + $degreeSymbol = $this->getOption( self::OPT_DEGREE_SYMBOL ); + $exploded = explode( $degreeSymbol, $coordinateSegment ); + + if ( count( $exploded ) !== 2 ) { + throw new ParseException( + 'Unable to explode coordinate segment by degree symbol (' . $degreeSymbol . ')', + $coordinateSegment, + self::FORMAT_NAME + ); + } + + list( $degrees, $minutes ) = $exploded; + + $minutes = substr( $minutes, 0, -1 ); + + $coordinateSegment = $degrees + $minutes / 60; + + if ( $isNegative ) { + $coordinateSegment *= -1; + } + + return (float)$coordinateSegment; + } + +} diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/DmsCoordinateParser.php b/www/wiki/vendor/data-values/geo/src/Parsers/DmsCoordinateParser.php new file mode 100644 index 00000000..c6fc079a --- /dev/null +++ b/www/wiki/vendor/data-values/geo/src/Parsers/DmsCoordinateParser.php @@ -0,0 +1,198 @@ +<?php + +declare( strict_types = 1 ); + +namespace DataValues\Geo\Parsers; + +use ValueParsers\ParseException; +use ValueParsers\ParserOptions; + +/** + * Parser for geographical coordinates in Degree Minute Second notation. + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + * @author H. Snater < mediawiki@snater.com > + */ +class DmsCoordinateParser extends DmCoordinateParser { + + public const FORMAT_NAME = 'dms-coordinate'; + + /** + * The symbol representing seconds. + * @since 0.1 + */ + public const OPT_SECOND_SYMBOL = 'second'; + + /** + * @param ParserOptions|null $options + */ + public function __construct( ParserOptions $options = null ) { + $options = $options ?: new ParserOptions(); + $options->defaultOption( self::OPT_SECOND_SYMBOL, '"' ); + + parent::__construct( $options ); + + $this->defaultDelimiters = [ $this->getOption( self::OPT_SECOND_SYMBOL ) ]; + } + + /** + * @see LatLongParserBase::areValidCoordinates + * + * @param string[] $normalizedCoordinateSegments + * + * @return bool + */ + protected function areValidCoordinates( array $normalizedCoordinateSegments ): bool { + // At least one coordinate segment needs to have seconds specified (which additionally + // requires minutes to be specified). + $regExpLoose = '(\d{1,3}' + . preg_quote( $this->getOption( self::OPT_DEGREE_SYMBOL ) ) + . ')(\d{1,2}' + . preg_quote( $this->getOption( self::OPT_MINUTE_SYMBOL ) ) + . ')?((\d{1,2}' + . preg_quote( $this->getOption( self::OPT_SECOND_SYMBOL ) ) + // TODO: Implement localized decimal separator. + . ')?|(\d{1,2}\.\d{1,20}' + . preg_quote( $this->getOption( self::OPT_SECOND_SYMBOL ) ) + . ')?)'; + $regExpStrict = str_replace( '?', '', $regExpLoose ); + + // Cache whether seconds have been detected within the coordinate: + $detectedSecond = false; + + // Cache whether the coordinates are specified in directional format (a mixture of + // directional and non-directional is regarded invalid). + $directional = false; + + foreach ( $normalizedCoordinateSegments as $i => $segment ) { + $direction = '(' + . $this->getOption( self::OPT_NORTH_SYMBOL ) . '|' + . $this->getOption( self::OPT_SOUTH_SYMBOL ) . ')'; + + if ( $i === 1 ) { + $direction = '(' + . $this->getOption( self::OPT_EAST_SYMBOL ) . '|' + . $this->getOption( self::OPT_WEST_SYMBOL ) . ')'; + } + + $match = preg_match( + '/^(' . $regExpStrict . $direction . '|' . $direction . $regExpStrict . ')$/i', + $segment + ); + + if ( $match ) { + $detectedSecond = true; + } else { + $match = preg_match( + '/^(' . $regExpLoose . $direction . '|' . $direction . $regExpLoose . ')$/i', + $segment + ); + } + + if ( $match ) { + $directional = true; + } elseif ( !$directional ) { + $match = preg_match( '/^(-)?' . $regExpStrict . '$/i', $segment ); + + if ( $match ) { + $detectedSecond = true; + } else { + $match = preg_match( '/^(-)?' . $regExpLoose . '$/i', $segment ); + } + } + + if ( !$match ) { + return false; + } + } + + return $detectedSecond; + } + + /** + * @see DdCoordinateParser::getNormalizedNotation + * + * @param string $coordinates + * + * @return string + */ + protected function getNormalizedNotation( string $coordinates ): string { + $second = $this->getOption( self::OPT_SECOND_SYMBOL ); + $minute = $this->getOption( self::OPT_MINUTE_SYMBOL ); + + $coordinates = str_replace( + [ '″', '″', $minute . $minute, '´´', '′′', '″' ], + $second, + $coordinates + ); + $coordinates = str_replace( [ '´', '´' ], $second, $coordinates ); + + $coordinates = parent::getNormalizedNotation( $coordinates ); + + $coordinates = $this->removeInvalidChars( $coordinates ); + + return $coordinates; + } + + /** + * @see DdCoordinateParser::parseCoordinate + * + * @param string $coordinateSegment + * + * @return float + */ + protected function parseCoordinate( string $coordinateSegment ): float { + $isNegative = mb_substr( $coordinateSegment, 0, 1 ) === '-'; + + if ( $isNegative ) { + $coordinateSegment = mb_substr( $coordinateSegment, 1 ); + } + + $degreeSymbol = $this->getOption( self::OPT_DEGREE_SYMBOL ); + $degreePosition = mb_strpos( $coordinateSegment, $degreeSymbol ); + + if ( $degreePosition === false ) { + throw new ParseException( + 'Did not find degree symbol (' . $degreeSymbol . ')', + $coordinateSegment, + self::FORMAT_NAME + ); + } + + $degrees = (float)mb_substr( $coordinateSegment, 0, $degreePosition ); + + $minutePosition = mb_strpos( $coordinateSegment, $this->getOption( self::OPT_MINUTE_SYMBOL ) ); + + if ( $minutePosition === false ) { + $minutes = 0; + } else { + $degSignLength = mb_strlen( $this->getOption( self::OPT_DEGREE_SYMBOL ) ); + $minuteLength = $minutePosition - $degreePosition - $degSignLength; + $minutes = (float)mb_substr( $coordinateSegment, $degreePosition + $degSignLength, $minuteLength ); + } + + $secondPosition = mb_strpos( $coordinateSegment, $this->getOption( self::OPT_SECOND_SYMBOL ) ); + + if ( $secondPosition === false ) { + $seconds = 0; + } else { + $seconds = (float)mb_substr( + $coordinateSegment, + ( $minutePosition === false ? $degreePosition : $minutePosition ) + 1, + -1 + ); + } + + $coordinateSegment = $degrees + ( $minutes + $seconds / 60 ) / 60; + + if ( $isNegative ) { + $coordinateSegment *= -1; + } + + return (float)$coordinateSegment; + } + +} diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/FloatCoordinateParser.php b/www/wiki/vendor/data-values/geo/src/Parsers/FloatCoordinateParser.php new file mode 100644 index 00000000..3b57bb44 --- /dev/null +++ b/www/wiki/vendor/data-values/geo/src/Parsers/FloatCoordinateParser.php @@ -0,0 +1,136 @@ +<?php + +declare( strict_types = 1 ); + +namespace DataValues\Geo\Parsers; + +use ValueParsers\ParseException; + +/** + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + * @author H. Snater < mediawiki@snater.com > + */ +class FloatCoordinateParser extends LatLongParserBase { + + public const FORMAT_NAME = 'float-coordinate'; + + /** + * @see LatLongParserBase::getParsedCoordinate + * + * @param string $coordinateSegment + * + * @return float + */ + protected function getParsedCoordinate( string $coordinateSegment ): float { + return (float)$this->resolveDirection( str_replace( ' ', '', $coordinateSegment ) ); + } + + /** + * @see LatLongParserBase::areValidCoordinates + * + * @param string[] $normalizedCoordinateSegments + * + * @return bool + */ + protected function areValidCoordinates( array $normalizedCoordinateSegments ): bool { + // TODO: Implement localized decimal separator. + $baseRegExp = '\d{1,3}(\.\d{1,20})?'; + + // Cache whether the coordinates are specified in directional format (a mixture of + // directional and non-directional is regarded invalid). + $directional = false; + + $match = false; + + foreach ( $normalizedCoordinateSegments as $i => $segment ) { + $segment = str_replace( ' ', '', $segment ); + + $direction = '(' + . $this->getOption( self::OPT_NORTH_SYMBOL ) . '|' + . $this->getOption( self::OPT_SOUTH_SYMBOL ) . ')'; + + if ( $i === 1 ) { + $direction = '(' + . $this->getOption( self::OPT_EAST_SYMBOL ) . '|' + . $this->getOption( self::OPT_WEST_SYMBOL ) . ')'; + } + + $match = preg_match( + '/^(' . $baseRegExp . $direction . '|' . $direction . $baseRegExp . ')$/i', + $segment + ); + + if ( $directional && !$match ) { + // Latitude is directional, longitude not. + break; + } elseif ( $match ) { + continue; + } + + $match = preg_match( '/^(-)?' . $baseRegExp . '$/i', $segment ); + + if ( !$match ) { + // Does neither match directional nor non-directional. + break; + } + } + + return ( 1 === $match ); + } + + /** + * @see LatLongParserBase::splitString + * + * @param string $normalizedCoordinateString + * + * @throws ParseException if unable to split input string into two segments + * @return string[] + */ + protected function splitString( string $normalizedCoordinateString ): array { + $separator = $this->getOption( self::OPT_SEPARATOR_SYMBOL ); + + $normalizedCoordinateSegments = explode( $separator, $normalizedCoordinateString ); + + if ( count( $normalizedCoordinateSegments ) !== 2 ) { + // Separator not present within the string, trying to figure out the segments by + // splitting at the the first SPACE after the first direction character or digit: + $numberRegEx = '-?\d{1,3}(\.\d{1,20})?'; + + $ns = '(' + . $this->getOption( self::OPT_NORTH_SYMBOL ) . '|' + . $this->getOption( self::OPT_SOUTH_SYMBOL ) .')'; + + $latitudeRegEx = '(' . $ns . '\s*)?' . $numberRegEx . '(\s*' . $ns . ')?'; + + $ew = '(' + . $this->getOption( self::OPT_EAST_SYMBOL ) . '|' + . $this->getOption( self::OPT_WEST_SYMBOL ) .')'; + + $longitudeRegEx = '(' . $ew . '\s*)?' . $numberRegEx . '(\s*' . $ew . ')?'; + + $match = preg_match( + '/^(' . $latitudeRegEx . ') (' . $longitudeRegEx . ')$/i', + $normalizedCoordinateString, + $matches + ); + + if ( $match ) { + $normalizedCoordinateSegments = [ $matches[1], $matches[7] ]; + } + } + + if ( count( $normalizedCoordinateSegments ) !== 2 ) { + throw new ParseException( + 'Unable to split input into two coordinate segments', + $normalizedCoordinateString, + self::FORMAT_NAME + ); + } + + return $normalizedCoordinateSegments; + } + +} diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/GlobeCoordinateParser.php b/www/wiki/vendor/data-values/geo/src/Parsers/GlobeCoordinateParser.php new file mode 100644 index 00000000..15c1503d --- /dev/null +++ b/www/wiki/vendor/data-values/geo/src/Parsers/GlobeCoordinateParser.php @@ -0,0 +1,138 @@ +<?php + +declare( strict_types = 1 ); + +namespace DataValues\Geo\Parsers; + +use DataValues\Geo\Values\GlobeCoordinateValue; +use DataValues\Geo\Values\LatLongValue; +use ValueParsers\ParseException; +use ValueParsers\ParserOptions; +use ValueParsers\ValueParser; + +/** + * Extends the LatLongParser by adding precision detection support. + * + * The object that gets constructed is a GlobeCoordinateValue rather then a LatLongValue. + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + * @author H. Snater < mediawiki@snater.com > + * @author Thiemo Kreuz + */ +class GlobeCoordinateParser implements ValueParser { + + public const FORMAT_NAME = 'globe-coordinate'; + + /** + * Option specifying the globe. Should be a string containing a Wikidata concept URI. Defaults + * to Earth. + */ + public const OPT_GLOBE = 'globe'; + + private $options; + + public function __construct( ParserOptions $options = null ) { + $this->options = $options ?: new ParserOptions(); + + $this->options->defaultOption( ValueParser::OPT_LANG, 'en' ); + $this->options->defaultOption( self::OPT_GLOBE, 'http://www.wikidata.org/entity/Q2' ); + } + + /** + * @see StringValueParser::stringParse + * + * @param string $value + * + * @throws ParseException + * @return GlobeCoordinateValue + */ + public function parse( $value ): GlobeCoordinateValue { + foreach ( $this->getParsers() as $precisionDetector => $parser ) { + try { + $latLong = $parser->parse( $value ); + + return new GlobeCoordinateValue( + new LatLongValue( + $latLong->getLatitude(), + $latLong->getLongitude() + ), + $this->detectPrecision( $latLong, $precisionDetector ), + $this->options->getOption( self::OPT_GLOBE ) + ); + } catch ( ParseException $parseException ) { + continue; + } + } + + throw new ParseException( + 'The format of the coordinate could not be determined.', + $value, + self::FORMAT_NAME + ); + } + + private function detectPrecision( LatLongValue $latLong, string $precisionDetector ): float { + if ( $this->options->hasOption( 'precision' ) ) { + return $this->options->getOption( 'precision' ); + } + + return min( + call_user_func( [ $this, $precisionDetector ], $latLong->getLatitude() ), + call_user_func( [ $this, $precisionDetector ], $latLong->getLongitude() ) + ); + } + + /** + * @return ValueParser[] + */ + private function getParsers(): array { + $parsers = []; + + $parsers['detectFloatPrecision'] = new FloatCoordinateParser( $this->options ); + $parsers['detectDmsPrecision'] = new DmsCoordinateParser( $this->options ); + $parsers['detectDmPrecision'] = new DmCoordinateParser( $this->options ); + $parsers['detectDdPrecision'] = new DdCoordinateParser( $this->options ); + + return $parsers; + } + + private function detectDdPrecision( float $degree ): float { + return $this->detectFloatPrecision( $degree ); + } + + private function detectDmPrecision( float $degree ): float { + $minutes = $degree * 60; + $split = explode( '.', (string)round( $minutes, 6 ) ); + + if ( isset( $split[1] ) ) { + return $this->detectDmsPrecision( $degree ); + } + + return 1 / 60; + } + + private function detectDmsPrecision( float $degree ): float { + $seconds = $degree * 3600; + $split = explode( '.', (string)round( $seconds, 4 ) ); + + if ( isset( $split[1] ) ) { + return pow( 10, -strlen( $split[1] ) ) / 3600; + } + + return 1 / 3600; + } + + private function detectFloatPrecision( float $degree ): float { + $split = explode( '.', (string)round( $degree, 8 ) ); + + if ( isset( $split[1] ) ) { + return pow( 10, -strlen( $split[1] ) ); + } + + return 1; + } + +} diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/LatLongParser.php b/www/wiki/vendor/data-values/geo/src/Parsers/LatLongParser.php new file mode 100644 index 00000000..b83129b1 --- /dev/null +++ b/www/wiki/vendor/data-values/geo/src/Parsers/LatLongParser.php @@ -0,0 +1,108 @@ +<?php + +declare( strict_types = 1 ); + +namespace DataValues\Geo\Parsers; + +use DataValues\Geo\Values\LatLongValue; +use ValueParsers\ParseException; +use ValueParsers\ParserOptions; +use ValueParsers\ValueParser; + +/** + * ValueParser that parses the string representation of a geographical coordinate. + * + * The resulting objects are of type @see LatLongValue. + * + * Supports the following notations: + * - Degree minute second + * - Decimal degrees + * - Decimal minutes + * - Float + * + * And for all these notations direction can be indicated either with + * + and - or with N/E/S/W, the later depending on the set options. + * + * The delimiter between latitude and longitude can be set in the options. + * So can the symbols used for degrees, minutes and seconds. + * + * Some code in this class has been borrowed from the + * MapsCoordinateParser class of the Maps extension for MediaWiki. + * + * @since 0.1, name changed in 2.0 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class LatLongParser implements ValueParser { + + public const TYPE_FLOAT = 'float'; + public const TYPE_DMS = 'dms'; + public const TYPE_DM = 'dm'; + public const TYPE_DD = 'dd'; + + /** + * The symbols representing the different directions for usage in directional notation. + */ + public const OPT_NORTH_SYMBOL = 'north'; + public const OPT_EAST_SYMBOL = 'east'; + public const OPT_SOUTH_SYMBOL = 'south'; + public const OPT_WEST_SYMBOL = 'west'; + + /** + * The symbols representing degrees, minutes and seconds. + */ + public const OPT_DEGREE_SYMBOL = 'degree'; + public const OPT_MINUTE_SYMBOL = 'minute'; + public const OPT_SECOND_SYMBOL = 'second'; + + /** + * The symbol to use as separator between latitude and longitude. + */ + public const OPT_SEPARATOR_SYMBOL = 'separator'; + + /** + * @var ParserOptions + */ + private $options; + + public function __construct( ParserOptions $options = null ) { + $this->options = $options ?: new ParserOptions(); + $this->options->defaultOption( ValueParser::OPT_LANG, 'en' ); + } + + /** + * @see ValueParser::parse + * + * @param string $value + * + * @throws ParseException + * @return LatLongValue + */ + public function parse( $value ): LatLongValue { + foreach ( $this->getParsers() as $parser ) { + try { + return $parser->parse( $value ); + } catch ( ParseException $ex ) { + continue; + } + } + + throw new ParseException( 'The format of the coordinate could not be determined. Parsing failed.' ); + } + + /** + * @return LatLongParserBase[] + */ + private function getParsers(): array { + $parsers = []; + + $parsers[] = new FloatCoordinateParser( $this->options ); + $parsers[] = new DmsCoordinateParser( $this->options ); + $parsers[] = new DmCoordinateParser( $this->options ); + $parsers[] = new DdCoordinateParser( $this->options ); + + return $parsers; + } + +} diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/LatLongParserBase.php b/www/wiki/vendor/data-values/geo/src/Parsers/LatLongParserBase.php new file mode 100644 index 00000000..258f9e92 --- /dev/null +++ b/www/wiki/vendor/data-values/geo/src/Parsers/LatLongParserBase.php @@ -0,0 +1,248 @@ +<?php + +declare( strict_types = 1 ); + +namespace DataValues\Geo\Parsers; + +use DataValues\Geo\Values\LatLongValue; +use ValueParsers\ParseException; +use ValueParsers\ParserOptions; +use ValueParsers\ValueParser; + +/** + * @since 0.1, renamed in 2.0 + * + * @license GPL-2.0-or-later + * @author H. Snater < mediawiki@snater.com > + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +abstract class LatLongParserBase implements ValueParser { + + public const FORMAT_NAME = 'geo-coordinate'; + + /** + * The symbols representing the different directions for usage in directional notation. + */ + public const OPT_NORTH_SYMBOL = 'north'; + public const OPT_EAST_SYMBOL = 'east'; + public const OPT_SOUTH_SYMBOL = 'south'; + public const OPT_WEST_SYMBOL = 'west'; + + /** + * The symbol to use as separator between latitude and longitude. + */ + public const OPT_SEPARATOR_SYMBOL = 'separator'; + + /** + * Delimiters used to split a coordinate string when unable to split by using the separator. + * @var string[] + */ + protected $defaultDelimiters; + + /** + * @var ParserOptions + */ + private $options; + + public function __construct( ParserOptions $options = null ) { + $this->options = $options ?: new ParserOptions(); + + $this->options->defaultOption( ValueParser::OPT_LANG, 'en' ); + + $this->options->defaultOption( self::OPT_NORTH_SYMBOL, 'N' ); + $this->options->defaultOption( self::OPT_EAST_SYMBOL, 'E' ); + $this->options->defaultOption( self::OPT_SOUTH_SYMBOL, 'S' ); + $this->options->defaultOption( self::OPT_WEST_SYMBOL, 'W' ); + + $this->options->defaultOption( self::OPT_SEPARATOR_SYMBOL, ',' ); + } + + /** + * Parses a single coordinate segment (either latitude or longitude) and returns it as a float. + * + * @param string $coordinateSegment + * + * @throws ParseException + * @return float + */ + abstract protected function getParsedCoordinate( string $coordinateSegment ): float; + + /** + * Returns whether a coordinate split into its two segments is in the representation expected by + * this parser. + * + * @param string[] $normalizedCoordinateSegments + * + * @return bool + */ + abstract protected function areValidCoordinates( array $normalizedCoordinateSegments ): bool; + + /** + * @see ValueParser::parse + * + * @param string $value + * + * @throws ParseException + * @return LatLongValue + */ + public function parse( $value ): LatLongValue { + if ( !is_string( $value ) ) { + throw new ParseException( 'Not a string' ); + } + + $rawValue = $value; + + $value = $this->removeInvalidChars( $value ); + + $normalizedCoordinateSegments = $this->splitString( $value ); + + if ( !$this->areValidCoordinates( $normalizedCoordinateSegments ) ) { + throw new ParseException( 'Not a valid geographical coordinate', $rawValue, static::FORMAT_NAME ); + } + + list( $latitude, $longitude ) = $normalizedCoordinateSegments; + + return new LatLongValue( + $this->getParsedCoordinate( $latitude ), + $this->getParsedCoordinate( $longitude ) + ); + } + + /** + * Returns a string trimmed and with control characters and characters with ASCII values above + * 126 removed. SPACE characters within the string are not removed to retain the option to split + * the string using that character. + * + * @param string $string + * + * @return string + */ + protected function removeInvalidChars( string $string ): string { + $filtered = []; + + foreach ( str_split( $string ) as $character ) { + $asciiValue = ord( $character ); + + if ( + ( $asciiValue >= 32 && $asciiValue < 127 ) + || $asciiValue == 194 + || $asciiValue == 176 + ) { + $filtered[] = $character; + } + } + + return trim( implode( '', $filtered ) ); + } + + /** + * Splits a string into two strings using the separator specified in the options. If the string + * could not be split using the separator, the method will try to split the string by analyzing + * the used symbols. If the string could not be split into two parts, an empty array is + * returned. + * + * @param string $normalizedCoordinateString + * + * @throws ParseException if unable to split input string into two segments + * @return string[] + */ + protected function splitString( string $normalizedCoordinateString ): array { + $separator = $this->getOption( self::OPT_SEPARATOR_SYMBOL ); + + $normalizedCoordinateSegments = explode( $separator, $normalizedCoordinateString ); + + if ( count( $normalizedCoordinateSegments ) !== 2 ) { + // Separator not present within the string, trying to figure out the segments by + // splitting after the first direction character or degree symbol: + $delimiters = $this->defaultDelimiters; + + $ns = [ + $this->getOption( self::OPT_NORTH_SYMBOL ), + $this->getOption( self::OPT_SOUTH_SYMBOL ) + ]; + + $ew = [ + $this->getOption( self::OPT_EAST_SYMBOL ), + $this->getOption( self::OPT_WEST_SYMBOL ) + ]; + + foreach ( $ns as $delimiter ) { + if ( mb_strpos( $normalizedCoordinateString, $delimiter ) === 0 ) { + // String starts with "north" or "west" symbol: Separation needs to be done + // before the "east" or "west" symbol. + $delimiters = array_merge( $ew, $delimiters ); + break; + } + } + + if ( count( $delimiters ) !== count( $this->defaultDelimiters ) + 2 ) { + $delimiters = array_merge( $ns, $delimiters ); + } + + foreach ( $delimiters as $delimiter ) { + $delimiterPos = mb_strpos( $normalizedCoordinateString, $delimiter ); + if ( $delimiterPos !== false ) { + $adjustPos = ( in_array( $delimiter, $ew ) ) ? 0 : mb_strlen( $delimiter ); + $normalizedCoordinateSegments = [ + mb_substr( $normalizedCoordinateString, 0, $delimiterPos + $adjustPos ), + mb_substr( $normalizedCoordinateString, $delimiterPos + $adjustPos ) + ]; + break; + } + } + } + + if ( count( $normalizedCoordinateSegments ) !== 2 ) { + throw new ParseException( __CLASS__ . ': Unable to split string ' + . $normalizedCoordinateString . ' into two coordinate segments' ); + } + + return $normalizedCoordinateSegments; + } + + /** + * Turns directional notation (N/E/S/W) of a single coordinate into non-directional notation + * (+/-). + * This method assumes there are no preceding or tailing spaces. + * + * @param string $coordinateSegment + * + * @return string + */ + protected function resolveDirection( string $coordinateSegment ): string { + $n = $this->getOption( self::OPT_NORTH_SYMBOL ); + $e = $this->getOption( self::OPT_EAST_SYMBOL ); + $s = $this->getOption( self::OPT_SOUTH_SYMBOL ); + $w = $this->getOption( self::OPT_WEST_SYMBOL ); + + // If there is a direction indicator, remove it, and prepend a minus sign for south and west + // directions. If there is no direction indicator, the coordinate is already non-directional + // and no work is required. + foreach ( [ $n, $e, $s, $w ] as $direction ) { + // The coordinate segment may either start or end with a direction symbol. + preg_match( + '/^(' . $direction . '|)([^' . $direction . ']+)(' . $direction . '|)$/i', + $coordinateSegment, + $matches + ); + + if ( $matches[1] !== '' || $matches[3] !== '' ) { + $coordinateSegment = $matches[2]; + + if ( in_array( $direction, [ $s, $w ] ) ) { + $coordinateSegment = '-' . $coordinateSegment; + } + + return $coordinateSegment; + } + } + + // Coordinate segment does not include a direction symbol. + return $coordinateSegment; + } + + protected function getOption( string $optionName ) { + return $this->options->getOption( $optionName ); + } + +} diff --git a/www/wiki/vendor/data-values/geo/src/Values/GlobeCoordinateValue.php b/www/wiki/vendor/data-values/geo/src/Values/GlobeCoordinateValue.php new file mode 100644 index 00000000..d5fd581f --- /dev/null +++ b/www/wiki/vendor/data-values/geo/src/Values/GlobeCoordinateValue.php @@ -0,0 +1,220 @@ +<?php + +declare( strict_types = 1 ); + +namespace DataValues\Geo\Values; + +use DataValues\DataValue; +use DataValues\IllegalValueException; +use InvalidArgumentException; + +/** + * Value Object representing a latitude-longitude pair with a certain precision on a certain globe. + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + * @author Thiemo Kreuz + */ +class GlobeCoordinateValue implements DataValue { + + private $latLong; + + /** + * @var float|null + */ + private $precision; + + /** + * IRI of the globe on which the location resides. + * + * @var string + */ + private $globe; + + /** + * Wikidata concept URI for the Earth. Used as default value when no other globe was specified. + */ + public const GLOBE_EARTH = 'http://www.wikidata.org/entity/Q2'; + + /** + * @param LatLongValue $latLong + * @param float|int|null $precision in degrees, e.g. 0.01. + * @param string|null $globe IRI, defaults to 'http://www.wikidata.org/entity/Q2'. + * + * @throws IllegalValueException + */ + public function __construct( LatLongValue $latLong, float $precision = null, string $globe = null ) { + $this->assertIsPrecision( $precision ); + + if ( $globe === null ) { + $globe = self::GLOBE_EARTH; + } elseif ( $globe === '' ) { + throw new IllegalValueException( '$globe must be a non-empty string or null' ); + } + + $this->latLong = $latLong; + $this->precision = $precision; + $this->globe = $globe; + } + + private function assertIsPrecision( ?float $precision ) { + if ( is_float( $precision ) && ( $precision < -360 || $precision > 360 ) ) { + throw new IllegalValueException( '$precision needs to be between -360 and 360' ); + } + } + + public function getLatLong(): LatLongValue { + return $this->latLong; + } + + /** + * Returns the precision of the coordinate in degrees, e.g. 0.01. + */ + public function getPrecision(): ?float { + return $this->precision; + } + + /** + * Returns the IRI of the globe on which the location resides. + */ + public function getGlobe(): string { + return $this->globe; + } + + public function getLatitude(): float { + return $this->latLong->getLatitude(); + } + + public function getLongitude(): float { + return $this->latLong->getLongitude(); + } + + /** + * @see \Comparable::equals + */ + public function equals( $target ): bool { + return $target instanceof self + && $this->latLong->equals( $target->latLong ) + && $this->precision === $target->precision + && $this->globe === $target->globe; + } + + public function getCopy(): self { + return new self( + $this->latLong, + $this->precision, + $this->globe + ); + } + + /** + * @see Hashable::getHash + * + * @since 2.0 + */ + public function getHash(): string { + return md5( + $this->latLong->getLatitude() . '|' + . $this->latLong->getLongitude() . '|' + . $this->precision . '|' + . $this->globe + ); + } + + /** + * @see Serializable::serialize + * + * @return string + */ + public function serialize(): string { + return json_encode( array_values( $this->getArrayValue() ) ); + } + + /** + * @see Serializable::unserialize + * + * @param string $value + * + * @throws InvalidArgumentException + */ + public function unserialize( $value ) { + list( $latitude, $longitude, $altitude, $precision, $globe ) = json_decode( $value ); + $this->__construct( new LatLongValue( $latitude, $longitude ), $precision, $globe ); + } + + /** + * @see DataValue::getType + */ + public static function getType(): string { + return 'globecoordinate'; + } + + /** + * @see DataValue::getSortKey + */ + public function getSortKey(): float { + return $this->getLatitude(); + } + + /** + * @see DataValue::getValue + */ + public function getValue(): self { + return $this; + } + + /** + * @see DataValue::getArrayValue + */ + public function getArrayValue(): array { + return [ + 'latitude' => $this->latLong->getLatitude(), + 'longitude' => $this->latLong->getLongitude(), + + // The altitude field is no longer used in this class. + // It is kept here for compatibility reasons. + 'altitude' => null, + + 'precision' => $this->precision, + 'globe' => $this->globe, + ]; + } + + public function toArray(): array { + return [ + 'value' => $this->getArrayValue(), + 'type' => $this->getType(), + ]; + } + + /** + * Constructs a new instance from the provided array. Round-trips with @see getArrayValue. + * + * @throws InvalidArgumentException + */ + public static function newFromArray( $data ): self { + if ( !is_array( $data ) ) { + throw new IllegalValueException( 'array expected' ); + } + + if ( !array_key_exists( 'latitude', $data ) ) { + throw new IllegalValueException( 'latitude field required' ); + } + + if ( !array_key_exists( 'longitude', $data ) ) { + throw new IllegalValueException( 'longitude field required' ); + } + + return new static( + new LatLongValue( + $data['latitude'], + $data['longitude'] + ), + ( isset( $data['precision'] ) ) ? $data['precision'] : null, + ( isset( $data['globe'] ) ) ? $data['globe'] : null + ); + } + +} diff --git a/www/wiki/vendor/data-values/geo/src/Values/LatLongValue.php b/www/wiki/vendor/data-values/geo/src/Values/LatLongValue.php new file mode 100644 index 00000000..e3a23c6c --- /dev/null +++ b/www/wiki/vendor/data-values/geo/src/Values/LatLongValue.php @@ -0,0 +1,162 @@ +<?php + +declare( strict_types = 1 ); + +namespace DataValues\Geo\Values; + +use DataValues\DataValue; +use DataValues\IllegalValueException; +use InvalidArgumentException; + +/** + * Value Object representing a geographical point. + * + * Latitude is specified in degrees within the range [-360, 360]. + * Longitude is specified in degrees within the range [-360, 360]. + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class LatLongValue implements DataValue { + + private $latitude; + private $longitude; + + /** + * @param float|int $latitude Latitude in degrees within the range [-360, 360] + * @param float|int $longitude Longitude in degrees within the range [-360, 360] + * + * @throws InvalidArgumentException + */ + public function __construct( float $latitude, float $longitude ) { + $this->assertIsLatitude( $latitude ); + $this->assertIsLongitude( $longitude ); + + $this->latitude = $latitude; + $this->longitude = $longitude; + } + + private function assertIsLatitude( float $latitude ) { + if ( $latitude < -360 || $latitude > 360 ) { + throw new InvalidArgumentException( 'Latitude needs to be between -360 and 360' ); + } + } + + private function assertIsLongitude( float $longitude ) { + if ( $longitude < -360 || $longitude > 360 ) { + throw new InvalidArgumentException( 'Longitude needs to be between -360 and 360' ); + } + } + + public function getLatitude(): float { + return $this->latitude; + } + + public function getLongitude(): float { + return $this->longitude; + } + + /** + * @see \Comparable::equals + */ + public function equals( $target ): bool { + return $target instanceof self + && $this->latitude === $target->latitude + && $this->longitude === $target->longitude; + } + + /** + * @see \Hashable::getHash + */ + public function getHash(): string { + return md5( serialize( $this ) ); + } + + public function getCopy(): self { + return new self( $this->latitude, $this->longitude ); + } + + /** + * @see Serializable::serialize + * + * @return string + */ + public function serialize(): string { + $data = [ + $this->latitude, + $this->longitude + ]; + + return implode( '|', $data ); + } + + /** + * @see Serializable::unserialize + * + * @param string $value + * + * @throws InvalidArgumentException + */ + public function unserialize( $value ) { + $data = explode( '|', $value, 2 ); + + if ( count( $data ) < 2 ) { + throw new InvalidArgumentException( 'Invalid serialization provided in ' . __METHOD__ ); + } + + $this->__construct( (float)$data[0], (float)$data[1] ); + } + + public static function getType(): string { + return 'geocoordinate'; + } + + public function getSortKey(): float { + return $this->latitude; + } + + public function getValue(): self { + return $this; + } + + /** + * @return float[] + */ + public function getArrayValue(): array { + return [ + 'latitude' => $this->latitude, + 'longitude' => $this->longitude + ]; + } + + /** + * Constructs a new instance from the provided array. Round-trips with @see getArrayValue. + * + * @throws InvalidArgumentException + */ + public static function newFromArray( $data ): self { + if ( !is_array( $data ) ) { + throw new IllegalValueException( 'array expected' ); + } + + if ( !array_key_exists( 'latitude', $data ) ) { + throw new IllegalValueException( 'latitude field required' ); + } + + if ( !array_key_exists( 'longitude', $data ) ) { + throw new IllegalValueException( 'longitude field required' ); + } + + return new static( $data['latitude'], $data['longitude'] ); + } + + public function toArray(): array { + return [ + 'value' => $this->getArrayValue(), + 'type' => $this->getType(), + ]; + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/COPYING b/www/wiki/vendor/data-values/interfaces/COPYING new file mode 100644 index 00000000..ebba08a4 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/COPYING @@ -0,0 +1,347 @@ +The license text below "----" applies to all files within this distribution, other +than those that are in a directory which contains files named "LICENSE" or +"COPYING", or a subdirectory thereof. For those files, the license text contained in +said file overrides any license information contained in directories of smaller depth. +Alternative licenses are typically used for software that is provided by external +parties, and merely packaged with this software for convenience. +---- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/www/wiki/vendor/data-values/interfaces/Interfaces.php b/www/wiki/vendor/data-values/interfaces/Interfaces.php new file mode 100644 index 00000000..d3495021 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/Interfaces.php @@ -0,0 +1,18 @@ +<?php + +/** + * Entry point of the DataValues Interfaces library. + * + * @since 0.1 + * @codeCoverageIgnore + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ + +if ( defined( 'DATAVALUES_INTERFACES_VERSION' ) ) { + // Do not initialize more than once. + return 1; +} + +define( 'DATAVALUES_INTERFACES_VERSION', '0.2.5' ); diff --git a/www/wiki/vendor/data-values/interfaces/README.md b/www/wiki/vendor/data-values/interfaces/README.md new file mode 100644 index 00000000..96d5789e --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/README.md @@ -0,0 +1,119 @@ +# DataValues Interfaces + +DataValues Interfaces is a small PHP library that defines a set of interfaces for parsers, +formatters and validators. + +It is part of the [DataValues set of libraries](https://github.com/DataValues). + +[![Build Status](https://secure.travis-ci.org/DataValues/Interfaces.png?branch=master)](http://travis-ci.org/DataValues/Interfaces) +[![Code Coverage](https://scrutinizer-ci.com/g/DataValues/Interfaces/badges/coverage.png?s=6432d29bf3fed068995e66093ad52e053099a916)](https://scrutinizer-ci.com/g/DataValues/Interfaces/) +[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/DataValues/Interfaces/badges/quality-score.png?s=da1bb6ea09762d9e3a143e473cdefa712db46804)](https://scrutinizer-ci.com/g/DataValues/Interfaces/) + +On [Packagist](https://packagist.org/packages/data-values/interfaces): +[![Latest Stable Version](https://poser.pugx.org/data-values/interfaces/version.png)](https://packagist.org/packages/data-values/interfaces) +[![Download count](https://poser.pugx.org/data-values/interfaces/d/total.png)](https://packagist.org/packages/data-values/interfaces) + +## Requirements + +* PHP 5.5 or later + +## Installation + +You can use [Composer](http://getcomposer.org/) to download and install +this package as well as its dependencies. Alternatively you can simply clone +the git repository and take care of loading yourself. + +### Composer + +To add this package as a local, per-project dependency to your project, simply add a +dependency on `data-values/interfaces` to your project's `composer.json` file. +Here is a minimal example of a `composer.json` file that just defines a dependency on +DataValues Interfaces 0.2: + + { + "require": { + "data-values/interfaces": "0.2.*" + } + } + +### Manual + +Get the DataValues Interfaces code, either via git, or some other means. Also get all dependencies. +You can find a list of the dependencies in the "require" section of the composer.json file. +Load all dependencies and the load the DataValues Interfaces library by including its entry point: +Interfaces.php. + +## Tests + +This library comes with a set up PHPUnit tests that cover all non-trivial code. You can run these +tests using the PHPUnit configuration file found in the root directory. The tests can also be run +via TravisCI, as a TravisCI configuration file is also provided in the root directory. + +## Authors + +DataValues Interfaces has been written by [Jeroen De Dauw](https://www.mediawiki.org/wiki/User:Jeroen_De_Dauw), +as [Wikimedia Germany](https://wikimedia.de) employee for the [Wikidata project](https://wikidata.org/). + +## Release notes + +### 0.2.5 (2017-08-09) + +* Removed MediaWiki extension credits registration + +### 0.2.4 (2017-08-02) + +* Fixed `ValueFormatterTestBase` not being installable via Composer. + +### 0.2.3 (2017-08-02) + +* Updated minimal required PHP version from 5.3 to 5.5.9. +* Minor fixes to code documentation. +* Added PHPCS support. + +### 0.2.2 (2016-07-15) + +* Fixed `ValueFormatterTestBase` not doing strict string comparisons. + +### 0.2.1 (2016-01-13) + +* Fixed an issue when using this component with HHVM 1.11.0 (see #21). + +### 0.2.0 (2015-08-11) + +* Dropped deprecated `ErrorObject`, use `Error` instead +* Dropped deprecated `ResultObject`, use `Result` instead +* Dropped deprecated constant `DataValuesInterfaces_VERSION`, use `DATAVALUES_INTERFACES_VERSION` instead +* Dropped `ValueFormatterTestBase::getFormatterClass` +* Made `ValueFormatterTestBase::getInstance` abstract +* The options in `ValueFormatterTestBase::getInstance` are now optional + +### 0.1.5 (2015-02-14) + +* The options in the `ValueFormatterBase` constructor are now optional +* The MediaWiki extension registration now includes the license + +### 0.1.4 (2014-04-14) + +* Added rawValue and expectedFormat arguments to `ValueParsers\ParseException` + +### 0.1.3 (2014-03-31) + +* Added `ValueFormatters\FormattingException` + +### 0.1.2 (2013-11-22) + +* Improved autoloading code +* Fixed link in MediaWiki credits +* Renamed entry point from DataValuesInterfaces.php to Interfaces.php + +### 0.1.0 (2013-11-16) + +Initial release with these features: + +* `ValueFormatters\ValueFormatter` interface +* `ValueParsers\ValueParser` interface +* `ValueValidators\ValueValidator` interface + +## Links + +* [DataValues Interfaces on Packagist](https://packagist.org/packages/data-values/interfaces) diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormatterOptions.php b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormatterOptions.php new file mode 100644 index 00000000..133f01e1 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormatterOptions.php @@ -0,0 +1,123 @@ +<?php + +namespace ValueFormatters; + +use InvalidArgumentException; +use OutOfBoundsException; +use RuntimeException; + +/** + * Object holding options for a formatter. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +final class FormatterOptions { + + /** + * @since 0.1 + * + * @var array + */ + protected $options; + + /** + * @since 0.1 + * + * @param array $options + * + * @throws InvalidArgumentException + */ + public function __construct( array $options = [] ) { + foreach ( array_keys( $options ) as $option ) { + if ( !is_string( $option ) ) { + throw new InvalidArgumentException( 'Option names need to be strings' ); + } + } + + $this->options = $options; + } + + /** + * Sets the value of the specified option. + * + * @since 0.1 + * + * @param string $option + * @param mixed $value + * + * @throws InvalidArgumentException + */ + public function setOption( $option, $value ) { + if ( !is_string( $option ) ) { + throw new InvalidArgumentException( 'Option name needs to be a string' ); + } + + $this->options[$option] = $value; + } + + /** + * Returns the value of the specified option. If the option is not set, + * an InvalidArgumentException is thrown. + * + * @since 0.1 + * + * @param string $option + * + * @throws OutOfBoundsException + * @return mixed + */ + public function getOption( $option ) { + if ( !array_key_exists( $option, $this->options ) ) { + throw new OutOfBoundsException( "Option '$option' has not been set so cannot be obtained" ); + } + + return $this->options[$option]; + } + + /** + * Returns if the specified option is set or not. + * + * @since 0.1 + * + * @param string $option + * + * @return bool + */ + public function hasOption( $option ) { + return array_key_exists( $option, $this->options ); + } + + /** + * Sets the value of an option to the provided default in case the option is not set yet. + * + * @since 0.1 + * + * @param string $option + * @param mixed $default + */ + public function defaultOption( $option, $default ) { + if ( !$this->hasOption( $option ) ) { + $this->setOption( $option, $default ); + } + } + + /** + * Requires an option to be set. + * If it's not set, a RuntimeException is thrown. + * + * @since 0.1 + * + * @param string $option + * + * @throws RuntimeException + */ + public function requireOption( $option ) { + if ( !$this->hasOption( $option ) ) { + throw new RuntimeException( 'Required option"' . $option . '" is not set' ); + } + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormattingException.php b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormattingException.php new file mode 100644 index 00000000..afda7227 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormattingException.php @@ -0,0 +1,15 @@ +<?php + +namespace ValueFormatters; + +use RuntimeException; + +/** + * @since 0.1.3 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class FormattingException extends RuntimeException { + +} diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatter.php b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatter.php new file mode 100644 index 00000000..909b3145 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatter.php @@ -0,0 +1,33 @@ +<?php + +namespace ValueFormatters; + +/** + * Interface for value formatters, typically (but not limited to) expecting a DataValue object and + * returning a string. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +interface ValueFormatter { + + /** + * Identifier for the option that holds the code of the language in which the formatter should + * operate. + * @since 0.1 + */ + const OPT_LANG = 'lang'; + + /** + * @since 0.1 + * + * @param mixed $value + * + * @return mixed + * @throws FormattingException + */ + public function format( $value ); + +} diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatterBase.php b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatterBase.php new file mode 100644 index 00000000..3fd7ca2e --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatterBase.php @@ -0,0 +1,67 @@ +<?php + +namespace ValueFormatters; + +/** + * Base class for ValueFormatters. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +abstract class ValueFormatterBase implements ValueFormatter { + + /** + * @since 0.1 + * + * @var FormatterOptions + */ + protected $options; + + /** + * @since 0.1 + * + * @param FormatterOptions|null $options + */ + public function __construct( FormatterOptions $options = null ) { + $this->options = $options ?: new FormatterOptions(); + + $this->options->defaultOption( ValueFormatter::OPT_LANG, 'en' ); + } + + /** + * Shortcut to $this->options->getOption. + * + * @since 0.1 + * + * @param string $option + * + * @return mixed + */ + final protected function getOption( $option ) { + return $this->options->getOption( $option ); + } + + /** + * Shortcut to $this->options->requireOption. + * + * @param string $option + */ + final protected function requireOption( $option ) { + $this->options->requireOption( $option ); + } + + /** + * Shortcut to $this->options->defaultOption. + * + * @since 0.1 + * + * @param string $option + * @param mixed $default + */ + final protected function defaultOption( $option, $default ) { + $this->options->defaultOption( $option, $default ); + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParseException.php b/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParseException.php new file mode 100644 index 00000000..151d9a57 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParseException.php @@ -0,0 +1,67 @@ +<?php + +namespace ValueParsers; + +use RuntimeException; + +/** + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class ParseException extends RuntimeException { + + /** + * @var string|null + */ + private $expectedFormat; + + /** + * @var string|null + */ + private $rawValue; + + /** + * @param string $message A plain english message describing the error + * @param string|null $rawValue The raw value that failed to be parsed. + * @param string|null $expectedFormat An identifier for the format the raw value + * did not match + * + * @since 0.1.4 + */ + public function __construct( $message, $rawValue = null, $expectedFormat = null ) { + parent::__construct( $message ); + $this->expectedFormat = $expectedFormat; + $this->rawValue = $rawValue; + } + + /** + * An identifier for the format the raw value did not match. + * + * This does not necessarily specify the exact format the throwing parser accepts. + * For example, a PositiveFloatParser might throw a ParseException with the + * expected format 'float' if the value does not even parse as a float, while + * in fact the parser would only accept positive floats. However, if the user + * enters a negative float, the parser must throw with a more specific format, + * i. e. 'positive-float'. + * + * @since 0.1.4 + */ + public function getExpectedFormat() { + return $this->expectedFormat; + } + + /** + * The raw value which was not parsable. + * + * This is not necessarily the value an user entered, but the rawest value + * that's available at the throwing site. + * + * @since 0.1.4 + */ + public function getRawValue() { + return $this->rawValue; + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParserOptions.php b/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParserOptions.php new file mode 100644 index 00000000..d06413f1 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParserOptions.php @@ -0,0 +1,122 @@ +<?php + +namespace ValueParsers; + +use InvalidArgumentException; +use RuntimeException; + +/** + * Object holding options for a parser. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +final class ParserOptions { + + /** + * @since 0.1 + * + * @var array + */ + protected $options; + + /** + * @since 0.1 + * + * @param array $options + * + * @throws InvalidArgumentException + */ + public function __construct( array $options = [] ) { + foreach ( array_keys( $options ) as $option ) { + if ( !is_string( $option ) ) { + throw new InvalidArgumentException( 'Option names need to be strings.' ); + } + } + + $this->options = $options; + } + + /** + * Sets the value of the specified option. + * + * @since 0.1 + * + * @param string $option + * @param mixed $value + * + * @throws InvalidArgumentException + */ + public function setOption( $option, $value ) { + if ( !is_string( $option ) ) { + throw new InvalidArgumentException( 'Option name needs to be a string.' ); + } + + $this->options[$option] = $value; + } + + /** + * Returns the value of the specified option. If the option is not set, + * an InvalidArgumentException is thrown. + * + * @since 0.1 + * + * @param string $option + * + * @throws InvalidArgumentException + * @return mixed + */ + public function getOption( $option ) { + if ( !array_key_exists( $option, $this->options ) ) { + throw new InvalidArgumentException(); + } + + return $this->options[$option]; + } + + /** + * Returns if the specified option is set or not. + * + * @since 0.1 + * + * @param string $option + * + * @return bool + */ + public function hasOption( $option ) { + return array_key_exists( $option, $this->options ); + } + + /** + * Sets the value of an option to the provided default in case the option is not set yet. + * + * @since 0.1 + * + * @param string $option + * @param mixed $default + */ + public function defaultOption( $option, $default ) { + if ( !$this->hasOption( $option ) ) { + $this->setOption( $option, $default ); + } + } + + /** + * Requires an option to be set. + * If it's not set, a RuntimeException is thrown. + * + * @since 0.1 + * + * @param string $option + * + * @throws RuntimeException + */ + public function requireOption( $option ) { + if ( !$this->hasOption( $option ) ) { + throw new RuntimeException( 'Required option "' . $option . '" is not set.' ); + } + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ValueParser.php b/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ValueParser.php new file mode 100644 index 00000000..c2027461 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ValueParser.php @@ -0,0 +1,32 @@ +<?php + +namespace ValueParsers; + +/** + * Interface for value parsers, typically (but not limited to) expecting a string and returning a + * DataValue object. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +interface ValueParser { + + /** + * Identifier for the option that holds the code of the language in which the parser should + * operate. + * @since 0.1 + */ + const OPT_LANG = 'lang'; + + /** + * @since 0.1 + * + * @param mixed $value + * + * @return mixed + */ + public function parse( $value ); + +} diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueValidators/Error.php b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/Error.php new file mode 100644 index 00000000..a368e5e0 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/Error.php @@ -0,0 +1,97 @@ +<?php + +namespace ValueValidators; + +/** + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class Error { + + const SEVERITY_ERROR = 9; + const SEVERITY_WARNING = 4; + + protected $text; + protected $severity; + protected $property; + + protected $code; + protected $params; + + /** + * @since 0.1 + * + * @param string $text + * @param string|null $property + * @param string $code + * @param array $params + * + * @return self + */ + public static function newError( $text = '', $property = null, $code = 'invalid', array $params = [] ) { + return new static( $text, self::SEVERITY_ERROR, $property, $code, $params ); + } + + /** + * @since 0.1 + * + * @param string $text + * @param integer $severity + * @param string|null $property + * @param string $code + * @param array $params + */ + protected function __construct( $text, $severity, $property, $code, array $params ) { + $this->text = $text; + $this->severity = $severity; + $this->property = $property; + $this->code = $code; + $this->params = $params; + } + + /** + * @since 0.1 + * + * @return string + */ + public function getText() { + return $this->text; + } + + /** + * @since 0.1 + * + * @return integer, element of the ValueValidatorError::SEVERITY_ enum + */ + public function getSeverity() { + return $this->severity; + } + + /** + * Returns the property of the value for which the error occurred, or null if it occurred for the value itself. + * + * @since 0.1 + * + * @return string|null + */ + public function getProperty() { + return $this->property; + } + + /** + * @return array + */ + public function getParameters() { + return $this->params; + } + + /** + * @return string + */ + public function getCode() { + return $this->code; + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueValidators/Result.php b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/Result.php new file mode 100644 index 00000000..3f7225b8 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/Result.php @@ -0,0 +1,114 @@ +<?php + +namespace ValueValidators; + +/** + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class Result { + + /** + * @since 0.1 + * + * @var bool + */ + protected $isValid; + + /** + * @since 0.1 + * + * @var Error[] + */ + protected $errors = []; + + /** + * @since 0.1 + * + * @return self + */ + public static function newSuccess() { + return new static( true ); + } + + /** + * @since 0.1 + * + * @param Error[] $errors + * + * @return self + */ + public static function newError( array $errors ) { + return new static( false, $errors ); + } + + /** + * Returns a result that represents the combination of the two given results. + * In particular, this means: + * + * If $a->getErrors() is empty and $a->isValid() is true, $b is returned. + * If $b->getErrors() is empty and $b->isValid() is true, $a is returned. + * + * Otherwise, a new Result is constructed that contains + * all errors from $a and $b, and is considered valid + * if both $a and $b were valid. + * + * @since 0.1 + * + * @param self $a + * @param self $b + * + * @return self + */ + public static function merge( self $a, self $b ) { + $aErrors = $a->getErrors(); + $bErrors = $b->getErrors(); + + if ( $a->isValid() && empty( $aErrors ) ) { + return $b; + } elseif ( $b->isValid() && empty( $bErrors ) ) { + return $a; + } else { + $errors = array_merge( $aErrors, $bErrors ); + $valid = ( $a->isValid() && $b->isValid() ); + + return new self( $valid, $errors ); + } + } + + /** + * @since 0.1 + * + * @param bool $isValid + * @param Error[] $errors + */ + protected function __construct( $isValid, array $errors = [] ) { + $this->isValid = $isValid; + $this->errors = $errors; + } + + /** + * Returns if the value was found to be valid or not. + * + * @since 0.1 + * + * @return bool + */ + public function isValid() { + return $this->isValid; + } + + /** + * Returns an array with the errors that occurred during validation. + * + * @since 0.1 + * + * @return Error[] + */ + public function getErrors() { + return $this->errors; + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidator.php b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidator.php new file mode 100644 index 00000000..ce0d1aaa --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidator.php @@ -0,0 +1,35 @@ +<?php + +namespace ValueValidators; + +/** + * Interface for value validators. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +interface ValueValidator { + + /** + * Parses a value. + * + * @since 0.1 + * + * @param mixed $value The value to validate + * + * @return Result + */ + public function validate( $value ); + + /** + * Takes an associative array with options and sets those known to the ValueValidator. + * + * @since 0.1 + * + * @param array $options + */ + public function setOptions( array $options ); + +} diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidatorObject.php b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidatorObject.php new file mode 100644 index 00000000..e38bd5c6 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidatorObject.php @@ -0,0 +1,215 @@ +<?php + +namespace ValueValidators; + +/** + * ValueValidator that holds base validation functions for any type of object. + * + * @since 0.1 + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +abstract class ValueValidatorObject implements ValueValidator { + + /** + * A list of allowed values. This means the parameters value(s) must be in the list + * during validation. False for no restriction. + * + * @since 0.1 + * + * @var array|false + */ + protected $allowedValues = false; + + /** + * A list of prohibited values. This means the parameters value(s) must + * not be in the list during validation. False for no restriction. + * + * @since 0.1 + * + * @var array|false + */ + protected $prohibitedValues = false; + + /** + * @since 0.1 + * + * @var array + */ + protected $options = []; + + /** + * @since 0.1 + * + * @var Error[] + */ + protected $errors = []; + + /** + * @see ValueValidator::validate + * + * @param mixed $value + * + * @return Result + */ + final public function validate( $value ) { + $this->errors = []; + + if ( $this->enableWhitelistRestrictions() ) { + $this->valueIsAllowed( $value ); + } + + $this->doValidation( $value ); + + if ( $this->errors === [] ) { + return Result::newSuccess(); + } else { + return Result::newError( $this->errors ); + } + } + + /** + * Checks the value against the allowed values and prohibited values lists in case they are set. + * + * @since 0.1 + * + * @param mixed $value + */ + protected function valueIsAllowed( $value ) { + if ( $this->allowedValues !== false && !in_array( $value, $this->allowedValues, true ) ) { + $this->addErrorMessage( 'Value not in whitelist' ); + } + + if ( $this->prohibitedValues !== false && in_array( $value, $this->prohibitedValues, true ) ) { + $this->addErrorMessage( 'Value in blacklist' ); + } + } + + /** + * @see ValueValidator::validate + * + * @since 0.1 + * + * @param mixed $value + */ + abstract public function doValidation( $value ); + + /** + * Sets the parameter definition values contained in the provided array. + * @see ParamDefinition::setArrayValues + * + * @param array $param + */ + public function setOptions( array $param ) { + if ( $this->enableWhitelistRestrictions() ) { + if ( array_key_exists( 'values', $param ) ) { + $this->allowedValues = $param['values']; + } + + if ( array_key_exists( 'excluding', $param ) ) { + $this->prohibitedValues = $param['excluding']; + } + } + + $this->options = $param; + } + + /** + * Registers an error message. + * + * @since 0.1 + * + * @param string $errorMessage + */ + protected function addErrorMessage( $errorMessage ) { + $this->addError( Error::newError( $errorMessage ) ); + } + + /** + * Registers an error. + * + * @since 0.1 + * + * @param Error $error + */ + protected function addError( Error $error ) { + $this->errors[] = $error; + } + + /** + * Registers a list of errors. + * + * @since 0.1 + * + * @param Error[] $errors + */ + protected function addErrors( array $errors ) { + $this->errors = array_merge( $this->errors, $errors ); + } + + /** + * Runs the value through the provided ValueValidator and registers the errors. + * Options of $this can be mapped to those of the passed ValueValidator using + * the $optionMap parameter in which keys are source names and values are target + * names. + * + * @since 0.1 + * + * @param mixed $value + * @param ValueValidator $validator + * @param string|null $property + * @param array $optionMap + */ + protected function runSubValidator( + $value, + ValueValidator $validator, + $property = null, + array $optionMap = [] + ) { + if ( $optionMap !== [] ) { + $options = []; + + foreach ( $optionMap as $source => $target ) { + if ( array_key_exists( $source, $this->options ) ) { + $options[$target] = $this->options[$source]; + } + } + + $validator->setOptions( $options ); + } + + /** + * @var Error $error + */ + foreach ( $validator->validate( $value )->getErrors() as $error ) { + $this->addError( Error::newError( $error->getText(), $property ) ); + } + } + + /** + * If the "values" and "excluding" arguments should be held into account. + * + * @since 0.1 + * + * @return bool + */ + protected function enableWhitelistRestrictions() { + return true; + } + + /** + * Returns the allowed values. + * + * TODO: think about how to access set options in general and if we want to have + * whitelist and baclklist values in the validator objects to begin with. + * + * @since 0.1 + * + * @return array|bool false + */ + public function getWhitelistedValues() { + return $this->allowedValues; + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/FormatterOptionsTest.php b/www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/FormatterOptionsTest.php new file mode 100644 index 00000000..f611149d --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/FormatterOptionsTest.php @@ -0,0 +1,191 @@ +<?php + +namespace ValueFormatters\Test; + +use ValueFormatters\FormatterOptions; + +/** + * @covers ValueFormatters\FormatterOptions + * + * @group ValueFormatters + * @group DataValueExtensions + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class FormatterOptionsTest extends \PHPUnit_Framework_TestCase { + + public function testConstructor() { + $options = [ + 'foo' => 42, + 'bar' => 4.2, + 'baz' => [ 'o_O', false, null, '42' => 42, [] ] + ]; + + $formatterOptions = new FormatterOptions( $options ); + + foreach ( $options as $option => $value ) { + $this->assertSame( + serialize( $value ), + serialize( $formatterOptions->getOption( $option ) ), + 'Option should be set properly' + ); + } + + $this->assertFalse( $formatterOptions->hasOption( 'ohi' ) ); + } + + public function testConstructorFail() { + $options = [ + 'foo' => 42, + 'bar' => 4.2, + 42 => [ 'o_O', false, null, '42' => 42, [] ] + ]; + + $this->setExpectedException( 'Exception' ); + + new FormatterOptions( $options ); + } + + public function setOptionProvider() { + $argLists = []; + + $formatterOptions = new FormatterOptions(); + + $argLists[] = [ $formatterOptions, 'foo', 42 ]; + $argLists[] = [ $formatterOptions, 'bar', 42 ]; + $argLists[] = [ $formatterOptions, 'foo', 'foo' ]; + $argLists[] = [ $formatterOptions, 'foo', null ]; + + return $argLists; + } + + /** + * @dataProvider setOptionProvider + */ + public function testSetAndGetOption( FormatterOptions $options, $option, $value ) { + $options->setOption( $option, $value ); + + $this->assertEquals( + $value, + $options->getOption( $option ), + 'Setting an option should work' + ); + } + + public function testHashOption() { + $options = [ + 'foo' => 42, + 'bar' => 4.2, + 'baz' => [ 'o_O', false, null, '42' => 42, [] ] + ]; + + $formatterOptions = new FormatterOptions( $options ); + + foreach ( array_keys( $options ) as $option ) { + $this->assertTrue( $formatterOptions->hasOption( $option ) ); + } + + $this->assertFalse( $formatterOptions->hasOption( 'ohi' ) ); + $this->assertFalse( $formatterOptions->hasOption( 'Foo' ) ); + } + + public function testSetOption() { + $formatterOptions = new FormatterOptions( [ 'foo' => 'bar' ] ); + + $values = [ + [ 'foo', 'baz' ], + [ 'foo', 'bar' ], + [ 'onoez', '' ], + [ 'hax', 'zor' ], + [ 'nyan', 9001 ], + [ 'cat', 4.2 ], + [ 'spam', [ '~=[,,_,,]:3' ] ], + ]; + + foreach ( $values as $value ) { + $formatterOptions->setOption( $value[0], $value[1] ); + $this->assertSame( $value[1], $formatterOptions->getOption( $value[0] ) ); + } + } + + /** + * @dataProvider nonExistingOptionsProvider + */ + public function testGetOption( $nonExistingOption ) { + $this->assertTrue( true ); + $formatterOptions = new FormatterOptions( [ 'foo' => 'bar' ] ); + + $this->setExpectedException( 'OutOfBoundsException' ); + + $formatterOptions->getOption( $nonExistingOption ); + } + + public function nonExistingOptionsProvider() { + $argLists = []; + + $argLists[] = [ 'bar' ]; + $argLists[] = [ 'Foo' ]; + $argLists[] = [ 'FOO' ]; + $argLists[] = [ 'spam' ]; + $argLists[] = [ 'onoez' ]; + + return $argLists; + } + + public function testRequireOption() { + $options = [ + 'foo' => 42, + 'bar' => 4.2, + 'baz' => [ 'o_O', false, null, '42' => 42, [] ] + ]; + + $formatterOptions = new FormatterOptions( $options ); + + foreach ( array_keys( $options ) as $option ) { + $formatterOptions->requireOption( $option ); + } + + $this->setExpectedException( 'Exception' ); + + $formatterOptions->requireOption( 'Foo' ); + } + + public function testDefaultOption() { + $options = [ + 'foo' => 42, + 'bar' => 4.2, + 'baz' => [ 'o_O', false, null, '42' => 42, [] ] + ]; + + $formatterOptions = new FormatterOptions( $options ); + + foreach ( $options as $option => $value ) { + $formatterOptions->defaultOption( $option, 9001 ); + + $this->assertSame( + serialize( $value ), + serialize( $formatterOptions->getOption( $option ) ), + 'Defaulting a set option should not affect its value' + ); + } + + $defaults = [ + 'N' => 42, + 'y' => 4.2, + 'a' => false, + 'n' => [ '42' => 42, [ '' ] ] + ]; + + foreach ( $defaults as $option => $value ) { + $formatterOptions->defaultOption( $option, $value ); + + $this->assertSame( + serialize( $value ), + serialize( $formatterOptions->getOption( $option ) ), + 'Defaulting a not set option should affect its value' + ); + } + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/ValueFormatterTestBase.php b/www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/ValueFormatterTestBase.php new file mode 100644 index 00000000..6252b7b2 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/ValueFormatterTestBase.php @@ -0,0 +1,62 @@ +<?php + +namespace ValueFormatters\Test; + +use ValueFormatters\FormatterOptions; +use ValueFormatters\ValueFormatter; + +/** + * Base for unit tests for ValueFormatter implementing classes. + * + * @since 0.1 + * + * @group ValueFormatters + * @group DataValueExtensions + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +abstract class ValueFormatterTestBase extends \PHPUnit_Framework_TestCase { + + /** + * Returns a list with valid inputs and their associated formatting output. + * + * @since 0.1 + * + * @return array[] + */ + abstract public function validProvider(); + + /** + * @since 0.1 + * + * @param FormatterOptions|null $options + * + * @return ValueFormatter + */ + abstract protected function getInstance( FormatterOptions $options = null ); + + /** + * @dataProvider validProvider + * + * @since 0.1 + * + * @param mixed $value + * @param mixed $expected + * @param FormatterOptions|null $options + * @param ValueFormatter|null $formatter + */ + public function testValidFormat( + $value, + $expected, + FormatterOptions $options = null, + ValueFormatter $formatter = null + ) { + if ( $formatter === null ) { + $formatter = $this->getInstance( $options ); + } + + $this->assertSame( $expected, $formatter->format( $value ) ); + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/tests/ValueParsers/ParserOptionsTest.php b/www/wiki/vendor/data-values/interfaces/tests/ValueParsers/ParserOptionsTest.php new file mode 100644 index 00000000..8a97ecb7 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/tests/ValueParsers/ParserOptionsTest.php @@ -0,0 +1,191 @@ +<?php + +namespace ValueParsers\Test; + +use ValueParsers\ParserOptions; + +/** + * @covers ValueParsers\ParserOptions + * + * @group ValueParsers + * @group DataValueExtensions + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class ParserOptionsTest extends \PHPUnit_Framework_TestCase { + + public function testConstructor() { + $options = [ + 'foo' => 42, + 'bar' => 4.2, + 'baz' => [ 'o_O', false, null, '42' => 42, [] ] + ]; + + $parserOptions = new ParserOptions( $options ); + + foreach ( $options as $option => $value ) { + $this->assertSame( + serialize( $value ), + serialize( $parserOptions->getOption( $option ) ), + 'Option should be set properly' + ); + } + + $this->assertFalse( $parserOptions->hasOption( 'ohi' ) ); + } + + public function testConstructorFail() { + $options = [ + 'foo' => 42, + 'bar' => 4.2, + 42 => [ 'o_O', false, null, '42' => 42, [] ] + ]; + + $this->setExpectedException( 'Exception' ); + + new ParserOptions( $options ); + } + + public function setOptionProvider() { + $argLists = []; + + $parserOptions = new ParserOptions(); + + $argLists[] = [ $parserOptions, 'foo', 42 ]; + $argLists[] = [ $parserOptions, 'bar', 42 ]; + $argLists[] = [ $parserOptions, 'foo', 'foo' ]; + $argLists[] = [ $parserOptions, 'foo', null ]; + + return $argLists; + } + + /** + * @dataProvider setOptionProvider + */ + public function testSetAndGetOption( ParserOptions $options, $option, $value ) { + $options->setOption( $option, $value ); + + $this->assertEquals( + $value, + $options->getOption( $option ), + 'Setting an option should work' + ); + } + + public function testHashOption() { + $options = [ + 'foo' => 42, + 'bar' => 4.2, + 'baz' => [ 'o_O', false, null, '42' => 42, [] ] + ]; + + $parserOptions = new ParserOptions( $options ); + + foreach ( array_keys( $options ) as $option ) { + $this->assertTrue( $parserOptions->hasOption( $option ) ); + } + + $this->assertFalse( $parserOptions->hasOption( 'ohi' ) ); + $this->assertFalse( $parserOptions->hasOption( 'Foo' ) ); + } + + public function testSetOption() { + $parserOptions = new ParserOptions( [ 'foo' => 'bar' ] ); + + $values = [ + [ 'foo', 'baz' ], + [ 'foo', 'bar' ], + [ 'onoez', '' ], + [ 'hax', 'zor' ], + [ 'nyan', 9001 ], + [ 'cat', 4.2 ], + [ 'spam', [ '~=[,,_,,]:3' ] ], + ]; + + foreach ( $values as $value ) { + $parserOptions->setOption( $value[0], $value[1] ); + $this->assertSame( $value[1], $parserOptions->getOption( $value[0] ) ); + } + } + + /** + * @dataProvider nonExistingOptionsProvider + */ + public function testGetOption( $nonExistingOption ) { + $this->assertTrue( true ); + $formatterOptions = new ParserOptions( [ 'foo' => 'bar' ] ); + + $this->setExpectedException( 'InvalidArgumentException' ); + + $formatterOptions->getOption( $nonExistingOption ); + } + + public function nonExistingOptionsProvider() { + $argLists = []; + + $argLists[] = [ 'bar' ]; + $argLists[] = [ 'Foo' ]; + $argLists[] = [ 'FOO' ]; + $argLists[] = [ 'spam' ]; + $argLists[] = [ 'onoez' ]; + + return $argLists; + } + + public function testRequireOption() { + $options = [ + 'foo' => 42, + 'bar' => 4.2, + 'baz' => [ 'o_O', false, null, '42' => 42, [] ] + ]; + + $parserOptions = new ParserOptions( $options ); + + foreach ( array_keys( $options ) as $option ) { + $parserOptions->requireOption( $option ); + } + + $this->setExpectedException( 'Exception' ); + + $parserOptions->requireOption( 'Foo' ); + } + + public function testDefaultOption() { + $options = [ + 'foo' => 42, + 'bar' => 4.2, + 'baz' => [ 'o_O', false, null, '42' => 42, [] ] + ]; + + $parserOptions = new ParserOptions( $options ); + + foreach ( $options as $option => $value ) { + $parserOptions->defaultOption( $option, 9001 ); + + $this->assertSame( + serialize( $value ), + serialize( $parserOptions->getOption( $option ) ), + 'Defaulting a set option should not affect its value' + ); + } + + $defaults = [ + 'N' => 42, + 'y' => 4.2, + 'a' => false, + 'n' => [ '42' => 42, [ '' ] ] + ]; + + foreach ( $defaults as $option => $value ) { + $parserOptions->defaultOption( $option, $value ); + + $this->assertSame( + serialize( $value ), + serialize( $parserOptions->getOption( $option ) ), + 'Defaulting a not set option should affect its value' + ); + } + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ErrorTest.php b/www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ErrorTest.php new file mode 100644 index 00000000..d5ba9fbd --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ErrorTest.php @@ -0,0 +1,72 @@ +<?php + +namespace ValueValidators\Test; + +use ValueValidators\Error; + +/** + * @covers ValueValidators\Error + * + * @group ValueValidators + * @group DataValueExtensions + * + * @license GPL-2.0+ + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class ErrorTest extends \PHPUnit_Framework_TestCase { + + public function newErrorProvider() { + $argLists = []; + + $argLists[] = []; + + $argLists[] = [ '' ]; + $argLists[] = [ 'foo' ]; + $argLists[] = [ ' foo bar baz.' ]; + + $argLists[] = [ ' foo bar ', null ]; + $argLists[] = [ ' foo bar ', 'length' ]; + + $argLists[] = [ ' foo bar ', null, 'something-went-wrong' ]; + $argLists[] = [ ' foo bar ', null, 'something-went-wrong', [ 'foo', 'bar' ] ]; + + return $argLists; + } + + /** + * @dataProvider newErrorProvider + */ + public function testNewError() { + $args = func_get_args(); + + $error = call_user_func_array( [ Error::class, 'newError' ], $args ); + + /** + * @var Error $error + */ + $this->assertInstanceOf( 'ValueValidators\Error', $error ); + + $this->assertInternalType( 'string', $error->getText() ); + $this->assertInternalType( 'integer', $error->getSeverity() ); + $this->assertTrue( is_string( $error->getProperty() ) || is_null( $error->getProperty() ) ); + $this->assertInternalType( 'string', $error->getCode() ); + $this->assertInternalType( 'array', $error->getParameters() ); + + if ( count( $args ) > 0 ) { + $this->assertSame( $args[0], $error->getText() ); + } + + if ( count( $args ) > 1 ) { + $this->assertSame( $args[1], $error->getProperty() ); + } + + if ( count( $args ) > 2 ) { + $this->assertSame( $args[2], $error->getCode() ); + } + + if ( count( $args ) > 3 ) { + $this->assertSame( $args[3], $error->getParameters() ); + } + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ResultTest.php b/www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ResultTest.php new file mode 100644 index 00000000..69e5a72d --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ResultTest.php @@ -0,0 +1,84 @@ +<?php + +namespace ValueValidators\Test; + +use ValueValidators\Error; +use ValueValidators\Result; + +/** + * @covers ValueValidators\Result + * + * @group ValueValidators + * @group DataValueExtensions + * + * @license GPL-2.0+ + * @author Daniel Kinzler + */ +class ResultTest extends \PHPUnit_Framework_TestCase { + + public function testNewSuccess() { + $result = Result::newSuccess(); + + $this->assertTrue( $result->isValid() ); + $this->assertEmpty( $result->getErrors() ); + } + + public function testNewError() { + $result = Result::newError( [ + Error::newError( 'foo' ), + Error::newError( 'bar' ), + ] ); + + $this->assertFalse( $result->isValid() ); + $this->assertCount( 2, $result->getErrors() ); + } + + public static function provideMerge() { + $errors = [ + Error::newError( 'foo' ), + Error::newError( 'bar' ), + ]; + + return [ + [ + Result::newSuccess(), + Result::newSuccess(), + true, + 0, + 'success + success' + ], + [ + Result::newSuccess(), + Result::newError( $errors ), + false, + 2, + 'success + error' + ], + [ + Result::newSuccess(), + Result::newError( $errors ), + false, + 2, + 'error + success' + ], + [ + Result::newError( $errors ), + Result::newError( $errors ), + false, + 4, + 'error + error' + ], + ]; + } + + /** + * @dataProvider provideMerge + */ + public function testMerge( $a, $b, $expectedValid, $expectedErrorCount, $message ) { + $result = Result::merge( $a, $b ); + + $this->assertSame( $expectedValid, $result->isValid(), $message ); + $this->assertCount( $expectedErrorCount, $result->getErrors(), $message ); + } + +} diff --git a/www/wiki/vendor/data-values/interfaces/tests/bootstrap.php b/www/wiki/vendor/data-values/interfaces/tests/bootstrap.php new file mode 100644 index 00000000..ac82d460 --- /dev/null +++ b/www/wiki/vendor/data-values/interfaces/tests/bootstrap.php @@ -0,0 +1,14 @@ +<?php + +if ( PHP_SAPI !== 'cli' ) { + die( 'Not an entry point' ); +} + +error_reporting( E_ALL | E_STRICT ); +ini_set( 'display_errors', 1 ); + +if ( !is_readable( __DIR__ . '/../vendor/autoload.php' ) ) { + die( 'You need to install this package with Composer before you can run the tests' ); +} + +require_once __DIR__ . '/../vendor/autoload.php'; diff --git a/www/wiki/vendor/data-values/validators/.gitignore b/www/wiki/vendor/data-values/validators/.gitignore new file mode 100644 index 00000000..577795cb --- /dev/null +++ b/www/wiki/vendor/data-values/validators/.gitignore @@ -0,0 +1,12 @@ +*~ +*.kate-swp +*.swp + +!.* + +.idea/ +build/ +vendor/ + +composer.phar +composer.lock
\ No newline at end of file diff --git a/www/wiki/vendor/data-values/validators/.phpcs.xml b/www/wiki/vendor/data-values/validators/.phpcs.xml new file mode 100644 index 00000000..1ee8fc09 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/.phpcs.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<ruleset> + <rule ref="./vendor/wikibase/wikibase-codesniffer/Wikibase"> + <exclude name="Generic.Arrays.DisallowLongArraySyntax" /> + </rule> + + <rule ref="Generic.Files.LineLength"> + <properties> + <property name="lineLimit" value="106" /> + </properties> + </rule> + + <file>.</file> +</ruleset> diff --git a/www/wiki/vendor/data-values/validators/.scrutinizer.yml b/www/wiki/vendor/data-values/validators/.scrutinizer.yml new file mode 100644 index 00000000..d3e813a4 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/.scrutinizer.yml @@ -0,0 +1,18 @@ +build: true +inherit: true + +tools: + external_code_coverage: true + php_code_coverage: true + php_code_sniffer: true + php_cpd: true + php_cs_fixer: true + php_loc: true + php_mess_detector: true + php_pdepend: true + php_analyzer: true + sensiolabs_security_checker: true + +filter: + excluded_paths: + - 'vendor/*' diff --git a/www/wiki/vendor/data-values/validators/.travis.yml b/www/wiki/vendor/data-values/validators/.travis.yml new file mode 100644 index 00000000..8ca18641 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/.travis.yml @@ -0,0 +1,27 @@ +language: php + +dist: trusty + +php: + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - 7.2 + - hhvm + +before_script: + - composer install --prefer-source + +script: + - composer test + +after_success: + - if [[ "`phpenv version-name`" != "7.1" ]]; then exit 0; fi + - phpunit --coverage-clover coverage.clover + - wget https://scrutinizer-ci.com/ocular.phar + - php ocular.phar code-coverage:upload --format=php-clover coverage.clover + +cache: + directories: + - $HOME/.composer/cache diff --git a/www/wiki/vendor/data-values/validators/COPYING b/www/wiki/vendor/data-values/validators/COPYING new file mode 100644 index 00000000..ebba08a4 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/COPYING @@ -0,0 +1,347 @@ +The license text below "----" applies to all files within this distribution, other +than those that are in a directory which contains files named "LICENSE" or +"COPYING", or a subdirectory thereof. For those files, the license text contained in +said file overrides any license information contained in directories of smaller depth. +Alternative licenses are typically used for software that is provided by external +parties, and merely packaged with this software for convenience. +---- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/www/wiki/vendor/data-values/validators/README.md b/www/wiki/vendor/data-values/validators/README.md new file mode 100644 index 00000000..3efdedf4 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/README.md @@ -0,0 +1,84 @@ +# DataValues Validators + +DataValues Validators is a small library that contains common ValueValidator implementations. + +It is part of the [DataValues set of libraries](https://github.com/DataValues). + +[![Build Status](https://secure.travis-ci.org/DataValues/Validators.png?branch=master)](http://travis-ci.org/DataValues/Validators) +[![Code Coverage](https://scrutinizer-ci.com/g/DataValues/Validators/badges/coverage.png?s=677e53b2fab73a0bfad4aabe3f229f2f9d287a00)](https://scrutinizer-ci.com/g/DataValues/Validators/) +[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/DataValues/Validators/badges/quality-score.png?s=6e5e7ac8557b7177926e89e39387e73f0bf87fe3)](https://scrutinizer-ci.com/g/DataValues/Validators/) + +On [Packagist](https://packagist.org/packages/data-values/validators): +[![Latest Stable Version](https://poser.pugx.org/data-values/validators/version.png)](https://packagist.org/packages/data-values/validators) +[![Download count](https://poser.pugx.org/data-values/validators/d/total.png)](https://packagist.org/packages/data-values/validators) + +## Installation + +The recommended way to use this library is via [Composer](http://getcomposer.org/). + +### Composer + +To add this package as a local, per-project dependency to your project, simply add a +dependency on `data-values/validators` to your project's `composer.json` file. +Here is a minimal example of a `composer.json` file that just defines a dependency on +version 1.0 of this package: + + { + "require": { + "data-values/validators": "1.0.*" + } + } + +### Manual + +Get the code of this package, either via git, or some other means. Also get all dependencies. +You can find a list of the dependencies in the "require" section of the composer.json file. +Then take care of autoloading the classes defined in the src directory. + +## Tests + +This library comes with a set up PHPUnit tests that cover all non-trivial code. You can run these +tests using the PHPUnit configuration file found in the root directory. The tests can also be run +via TravisCI, as a TravisCI configuration file is also provided in the root directory. + +## Authors + +DataValues Validators has been written by the Wikidata team, as [Wikimedia Germany](https://wikimedia.de) +employees for the [Wikidata project](https://wikidata.org/). + +It is based upon and contains a lot of code written by [Jeroen De Dauw](https://github.com/JeroenDeDauw) +for the [Maps](https://github.com/JeroenDeDauw/Maps) and +[Semantic MediaWiki](https://semantic-mediawiki.org/) projects. + +## Release notes + +### 0.1.3 (2018-08-02) + +* Made component installable with DataValues 2.x +* Removed MediaWiki integration + +### 0.1.2 (2014-10-09) + +* Made component installable with DataValues 1.x + +### 0.1.1 (2014-03-27) + +* Changed autoloading from PSR-0 to PSR-4 +* Added tests for DimensionValidator + +### 0.1.0 (2013-11-17) + +Initial release with these features: + +* DimensionValidator +* ListValidator +* NullValidator +* RangeValidator +* StringValidator +* TitleValidator + +## Links + +* [DataValues Validators on Packagist](https://packagist.org/packages/data-values/validators) +* [DataValues Validators on TravisCI](https://travis-ci.org/DataValues/Validators) +* [DataValues Validators on ScrutinizerCI](https://scrutinizer-ci.com/g/DataValues/Validators/) diff --git a/www/wiki/vendor/data-values/validators/composer.json b/www/wiki/vendor/data-values/validators/composer.json new file mode 100644 index 00000000..0f9ddf2c --- /dev/null +++ b/www/wiki/vendor/data-values/validators/composer.json @@ -0,0 +1,54 @@ +{ + "name": "data-values/validators", + "type": "library", + "description": "Common ValueValidator implementations", + "keywords": [ + "datavalues", + "wikidata", + "validators", + "validation" + ], + "homepage": "https://github.com/DataValues/Validators", + "license": "GPL-2.0-or-later", + "authors": [ + { + "name": "Jeroen De Dauw", + "email": "jeroendedauw@gmail.com", + "homepage": "http://jeroendedauw.com", + "role": "Developer" + }, + { + "name": "The Wikidata team", + "role": "Developer" + } + ], + "support": { + "irc": "irc://irc.freenode.net/wikidata" + }, + "require": { + "php": ">=5.5.9", + "data-values/data-values": "^2.1.1|~1.0|~0.1", + "data-values/interfaces": "~0.2.0|~0.1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35", + "wikibase/wikibase-codesniffer": "0.4.0" + }, + "autoload": { + "psr-4": { + "ValueValidators\\": "src" + } + }, + "extra": { + "branch-alias": { + "dev-master": "0.1.x-dev" + } + }, + "scripts": { + "test": [ + "composer validate --no-interaction", + "phpcs -p -s", + "phpunit" + ] + } +} diff --git a/www/wiki/vendor/data-values/validators/phpunit.xml.dist b/www/wiki/vendor/data-values/validators/phpunit.xml.dist new file mode 100644 index 00000000..7978f7e0 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/phpunit.xml.dist @@ -0,0 +1,25 @@ +<phpunit backupGlobals="false" + backupStaticAttributes="false" + bootstrap="tests/bootstrap.php" + cacheTokens="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + stopOnError="false" + stopOnFailure="false" + stopOnIncomplete="false" + stopOnSkipped="false" + strict="true" + verbose="true"> + <testsuites> + <testsuite name="DataValuesValidators"> + <directory>tests</directory> + </testsuite> + </testsuites> + <filter> + <whitelist addUncoveredFilesFromWhitelist="true"> + <directory suffix=".php">src</directory> + </whitelist> + </filter> +</phpunit> diff --git a/www/wiki/vendor/data-values/validators/src/DimensionValidator.php b/www/wiki/vendor/data-values/validators/src/DimensionValidator.php new file mode 100644 index 00000000..9d7c3ac6 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/src/DimensionValidator.php @@ -0,0 +1,267 @@ +<?php + +namespace ValueValidators; + +use Exception; + +/** + * ValueValidator that validates a dimension value. + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class DimensionValidator extends ValueValidatorObject { + + /** + * @since 0.1 + * + * @var boolean + */ + protected $allowAuto = false; + + /** + * @since 0.1 + * + * @var array + */ + protected $allowedUnits = array( 'px', '' ); + + /** + * @since 0.1 + * + * @var integer + */ + protected $minPercentage = 0; + + /** + * @since 0.1 + * + * @var integer + */ + protected $maxPercentage = 100; + + /** + * @since 0.1 + * + * @var string + */ + protected $defaultUnit = 'px'; + + /** + * Lower bound of the range (included). Either a number or false, for no lower limit. + * + * @since 0.1 + * + * @var false|int|float + */ + protected $lowerBound = false; + + /** + * Upper bound of the range (included). Either a number or false, for no upper limit. + * + * @since 0.1 + * + * @var false|int|float + */ + protected $upperBound = false; + + /** + * Sets the lower bound (included). + * + * @since 0.1 + * + * @param $lowerBound false|int|float + */ + public function setLowerBound( $lowerBound ) { + $this->lowerBound = $lowerBound; + } + + /** + * Sets the upper bound (included). + * + * @since 0.1 + * + * @param $upperBound false|int|float + */ + public function setUpperBound( $upperBound ) { + $this->upperBound = $upperBound; + } + + /** + * Requires the value to be in the specified range. + * + * @since 0.1 + * + * @param $lowerBound false|int|float + * @param $upperBound false|int|float + */ + public function setRange( $lowerBound, $upperBound ) { + $this->lowerBound = $lowerBound; + $this->upperBound = $upperBound; + } + + /** + * @see ValueValidatorObject::doValidation + * + * @since 0.1 + * + * @param mixed $value + */ + public function doValidation( $value ) { + if ( !is_string( $value ) && !is_int( $value ) && !is_float( $value ) ) { + $this->addErrorMessage( 'Dimension is not a string, float or int' ); + return; + } + + if ( !is_string( $value ) ) { + $value = (string)$value; + } + + if ( $value === 'auto' ) { + if ( !$this->allowAuto ) { + $this->addErrorMessage( 'Dimension value cannot be auto' ); + } + return; + } + + if ( !preg_match( '/^\d+(\.\d+)?(' . implode( '|', $this->allowedUnits ) . ')\z/', $value ) ) { + $this->addErrorMessage( 'Not a valid dimension value' ); + return; + } + + if ( strpos( $value, '%' ) !== false ) { + $upperBound = $this->maxPercentage; + $lowerBound = $this->minPercentage; + } else { + $upperBound = $this->upperBound; + $lowerBound = $this->lowerBound; + } + + $value = (float)preg_replace( '/\D+/', '', $value ); + + $rangeValidator = new RangeValidator(); + $rangeValidator->setRange( $lowerBound, $upperBound ); + + $this->runSubValidator( $value, $rangeValidator ); + } + + /** + * If 'auto' should be seen as a valid value. + * + * @since 0.1 + * + * @param boolean $allowAuto + */ + public function setAllowAuto( $allowAuto ) { + $this->allowAuto = $allowAuto; + } + + /** + * Set the upper bound for the value in case it's a percentage. + * + * @since 0.1 + * + * @param integer $maxPercentage + */ + public function setMaxPercentage( $maxPercentage ) { + $this->maxPercentage = $maxPercentage; + } + + /** + * Set the lower bound for the value in case it's a percentage. + * + * @since 0.1 + * + * @param integer $minPercentage + */ + public function setMinPercentage( $minPercentage ) { + $this->minPercentage = $minPercentage; + } + + /** + * Sets the default unit, ie the one that will be assumed when the empty unit is provided. + * + * @since 0.1 + * + * @param string $defaultUnit + */ + public function setDefaultUnit( $defaultUnit ) { + $this->defaultUnit = $defaultUnit; + } + + /** + * Sets the allowed units. + * + * @since 0.1 + * + * @param array $units + */ + public function setAllowedUnits( array $units = array( 'px', 'em', 'ex', '%', '' ) ) { + $this->allowedUnits = $units; + } + + /** + * Returns the allowed units. + * + * @since 0.1 + * + * @return string[] + */ + public function getAllowedUnits() { + return $this->allowedUnits; + } + + /** + * Returns the default unit. + * + * @since 0.1 + * + * @return string + */ + public function getDefaultUnit() { + return $this->defaultUnit; + } + + /** + * @see ValueValidator::setOptions + * + * @since 0.1 + * + * @param array $options + * @throws Exception + */ + public function setOptions( array $options ) { + parent::setOptions( $options ); + + if ( array_key_exists( 'allowauto', $options ) ) { + $this->setAllowAuto( $options['allowauto'] ); + } + + if ( array_key_exists( 'maxpercentage', $options ) ) { + $this->setMaxPercentage( $options['maxpercentage'] ); + } + + if ( array_key_exists( 'minpercentage', $options ) ) { + $this->setMinPercentage( $options['minpercentage'] ); + } + + if ( array_key_exists( 'units', $options ) ) { + $this->setAllowedUnits( $options['units'] ); + } + + if ( array_key_exists( 'defaultunit', $options ) ) { + $this->setDefaultUnit( $options['defaultunit'] ); + } + + if ( array_key_exists( 'lowerbound', $options ) ) { + $this->setLowerBound( $options['lowerbound'] ); + } + + if ( array_key_exists( 'upperbound', $options ) ) { + $this->setUpperBound( $options['upperbound'] ); + } + } + +} diff --git a/www/wiki/vendor/data-values/validators/src/ListValidator.php b/www/wiki/vendor/data-values/validators/src/ListValidator.php new file mode 100644 index 00000000..fde8d776 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/src/ListValidator.php @@ -0,0 +1,63 @@ +<?php + +namespace ValueValidators; + +use Exception; + +/** + * ValueValidator that validates a list of values. + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + * @author Thiemo Kreuz + */ +class ListValidator extends ValueValidatorObject { + + /** + * @see ValueValidatorObject::doValidation + * + * @since 0.1 + * + * @param array $value + * + * @throws Exception + */ + public function doValidation( $value ) { + if ( !is_array( $value ) ) { + $this->addErrorMessage( 'Not an array' ); + return; + } + + $options = array(); + + if ( array_key_exists( 'elementcount', $this->options ) ) { + $options['range'] = $this->options['elementcount']; + } + + if ( array_key_exists( 'minelements', $this->options ) ) { + $options['lowerbound'] = $this->options['minelements']; + } + + if ( array_key_exists( 'maxelements', $this->options ) ) { + $options['upperbound'] = $this->options['maxelements']; + } + + $validator = new RangeValidator(); + $validator->setOptions( $options ); + $this->runSubValidator( count( $value ), $validator, 'length' ); + } + + /** + * @see ValueValidatorObject::enableWhitelistRestrictions + * + * @since 0.1 + * + * @return bool + */ + protected function enableWhitelistRestrictions() { + return false; + } + +} diff --git a/www/wiki/vendor/data-values/validators/src/NullValidator.php b/www/wiki/vendor/data-values/validators/src/NullValidator.php new file mode 100644 index 00000000..514775e8 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/src/NullValidator.php @@ -0,0 +1,41 @@ +<?php + +namespace ValueValidators; + +/** + * ValueValidator does a null validation (ie everything passes). + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + * + * @codeCoverageIgnore + */ +class NullValidator implements ValueValidator { + + /** + * @see ValueValidator::validate + * + * @since 0.1 + * + * @param mixed $value + * + * @return Result Always successfull. + */ + public function validate( $value ) { + return Result::newSuccess(); + } + + /** + * @see ValueValidator::setOptions + * + * @since 0.1 + * + * @param array $options + */ + public function setOptions( array $options ) { + // No op + } + +} diff --git a/www/wiki/vendor/data-values/validators/src/RangeValidator.php b/www/wiki/vendor/data-values/validators/src/RangeValidator.php new file mode 100644 index 00000000..2166ad67 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/src/RangeValidator.php @@ -0,0 +1,166 @@ +<?php + +namespace ValueValidators; + +use Exception; + +/** + * ValueValidator that validates if a numeric value is within a certain range. + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class RangeValidator extends ValueValidatorObject { + + /** + * Lower bound of the range (included). Either a number or false, for no lower limit. + * + * @since 0.1 + * + * @var false|int|float + */ + protected $lowerBound = false; + + /** + * Upper bound of the range (included). Either a number or false, for no upper limit. + * + * @since 0.1 + * + * @var false|int|float + */ + protected $upperBound = false; + + /** + * Sets the lower bound (included). + * + * @since 0.1 + * + * @param $lowerBound false|int|float + */ + public function setLowerBound( $lowerBound ) { + $this->lowerBound = $lowerBound; + } + + /** + * Sets the upper bound (included). + * + * @since 0.1 + * + * @param $upperBound false|int|float + */ + public function setUpperBound( $upperBound ) { + $this->upperBound = $upperBound; + } + + /** + * Requires the value to be in the specified range. + * + * @since 0.1 + * + * @param $lowerBound false|int|float + * @param $upperBound false|int|float + */ + public function setRange( $lowerBound, $upperBound ) { + $this->lowerBound = $lowerBound; + $this->upperBound = $upperBound; + } + + /** + * Requires the value to be within the range of a point. + * Bounds are included, ie 6 will be valid for point 4 within range 2. + * + * @since 0.1 + * + * @param int|float $point + * @param int|float $range + */ + public function setWithinRange( $point, $range ) { + $this->lowerBound = $point - $range; + $this->upperBound = $point + $range; + } + + /** + * @see ValueValidatorObject::doValidation + * + * @since 0.1 + * + * @param mixed $value + */ + public function doValidation( $value ) { + if ( !true ) { + // TODO: type check + $this->addErrorMessage( 'Not a numeric value - cannot check the range' ); + return; + } + + $this->validateBounds( $value ); + } + + /** + * Validates the parameters value and returns the result. + * + * @since 0.1 + * + * @param $value mixed + * @param float|null|false $upperBound + * @param float|null|false $lowerBound + * + * @return boolean + */ + protected function validateBounds( $value, $upperBound = null, $lowerBound = null ) { + $upperBound = is_null( $upperBound ) ? $this->upperBound : $upperBound; + $lowerBound = is_null( $lowerBound ) ? $this->lowerBound : $lowerBound; + + $smallEnough = $upperBound === false || $value <= $upperBound; + $bigEnough = $lowerBound === false || $value >= $lowerBound; + + if ( !$smallEnough ) { + $this->addErrorMessage( 'Value exceeding upper bound' ); + } + + if ( !$bigEnough ) { + $this->addErrorMessage( 'Value exceeding lower bound' ); + } + + return $smallEnough && $bigEnough; + } + + /** + * @see ValueValidator::setOptions + * + * @since 0.1 + * + * @param array $options + * @throws Exception + */ + public function setOptions( array $options ) { + parent::setOptions( $options ); + + if ( array_key_exists( 'range', $options ) ) { + if ( is_array( $options['range'] ) && count( $options['range'] ) == 2 ) { + $this->setRange( $options['range'][0], $options['range'][1] ); + } else { + throw new Exception( 'The range argument must be an array with two elements' ); + } + } + + if ( array_key_exists( 'withinrange', $options ) ) { + if ( is_array( $options['withinrange'] ) && count( $options['withinrange'] ) == 2 ) { + $this->setWithinRange( $options['withinrange'][0], $options['withinrange'][1] ); + } else { + throw new Exception( 'The withinrange argument must be an array with two elements' ); + } + } + + if ( array_key_exists( 'lowerbound', $options ) ) { + $this->setLowerBound( $options['lowerbound'] ); + } + + if ( array_key_exists( 'upperbound', $options ) ) { + $this->setUpperBound( $options['upperbound'] ); + } + } + +} diff --git a/www/wiki/vendor/data-values/validators/src/StringValidator.php b/www/wiki/vendor/data-values/validators/src/StringValidator.php new file mode 100644 index 00000000..37304ea0 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/src/StringValidator.php @@ -0,0 +1,65 @@ +<?php + +namespace ValueValidators; + +use Exception; + +/** + * ValueValidator that validates a string value. + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class StringValidator extends ValueValidatorObject { + + /** + * @see ValueValidatorObject::doValidation + * + * @since 0.1 + * + * @param string $value + * + * @throws Exception + */ + public function doValidation( $value ) { + if ( !is_string( $value ) ) { + $this->addErrorMessage( 'Not a string' ); // TODO + return; + } + + $lowerBound = false; + $upperBound = false; + + if ( array_key_exists( 'length', $this->options ) ) { + $lowerBound = $this->options['length']; + $upperBound = $this->options['length']; + } else { + if ( array_key_exists( 'minlength', $this->options ) ) { + $lowerBound = $this->options['minlength']; + } + + if ( array_key_exists( 'maxlength', $this->options ) ) { + $upperBound = $this->options['maxlength']; + } + } + + if ( $lowerBound !== false || $upperBound !== false ) { + $rangeValidator = new RangeValidator(); + $rangeValidator->setRange( $lowerBound, $upperBound ); + $this->runSubValidator( strlen( $value ), $rangeValidator, 'length' ); + } + + if ( array_key_exists( 'regex', $this->options ) ) { + $match = preg_match( $this->options['regex'], $value ); + + if ( $match === false ) { + throw new Exception( 'The regex argument must be a valid Perl regular expression.' ); + } elseif ( $match === 0 ) { + $this->addErrorMessage( 'String does not match the regular expression ' . $this->options['regex'] ); + } + } + } + +} diff --git a/www/wiki/vendor/data-values/validators/src/TitleValidator.php b/www/wiki/vendor/data-values/validators/src/TitleValidator.php new file mode 100644 index 00000000..3459d68d --- /dev/null +++ b/www/wiki/vendor/data-values/validators/src/TitleValidator.php @@ -0,0 +1,63 @@ +<?php + +namespace ValueValidators; + +use Title; + +/** + * ValueValidator that validates a Title object. + * + * @since 0.1 + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class TitleValidator extends ValueValidatorObject { + + /** + * @since 0.1 + * + * @var bool + */ + protected $hasToExist = true; + + /** + * @since 0.1 + * + * @param bool $hasToExist + */ + public function setHasToExist( $hasToExist ) { + $this->hasToExist = $hasToExist; + } + + /** + * @see ValueValidatorObject::doValidation + * + * @since 0.1 + * + * @param Title $value + */ + public function doValidation( $value ) { + if ( !( $value instanceof Title ) ) { + $this->addErrorMessage( 'Not a title' ); + } elseif ( $this->hasToExist && !$value->exists() ) { + $this->addErrorMessage( 'Title does not exist' ); + } + } + + /** + * @see ValueValidator::setOptions + * + * @since 0.1 + * + * @param array $options + */ + public function setOptions( array $options ) { + parent::setOptions( $options ); + + if ( array_key_exists( 'hastoexist', $options ) ) { + $this->setHasToExist( $options['hastoexist'] ); + } + } + +} diff --git a/www/wiki/vendor/data-values/validators/tests/ValueValidators/DimensionValidatorTest.php b/www/wiki/vendor/data-values/validators/tests/ValueValidators/DimensionValidatorTest.php new file mode 100644 index 00000000..7254ddd0 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/tests/ValueValidators/DimensionValidatorTest.php @@ -0,0 +1,108 @@ +<?php + +namespace ValueValidators\Tests; + +use PHPUnit\Framework\TestCase; +use ValueValidators\DimensionValidator; + +/** + * @covers ValueValidators\DimensionValidator + * + * @group ValueValidators + * @group DataValueExtensions + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class DimensionValidatorTest extends TestCase { + + /** + * @var DimensionValidator + */ + private $validator; + + protected function setUp() { + $this->validator = new DimensionValidator(); + } + + public function testWhenAutoIsNotAllowed_autoIsNotValid() { + $this->validator->setAllowAuto( false ); + $this->assertIsNotValid( 'auto' ); + } + + private function assertIsNotValid( $value ) { + $this->assertFalse( $this->validator->validate( $value )->isValid() ); + } + + public function testWhenAutoIsAllowed_autoIsValid() { + $this->validator->setAllowAuto( true ); + $this->assertIsValid( 'auto' ); + } + + private function assertIsValid( $value ) { + $this->assertTrue( $this->validator->validate( $value )->isValid() ); + } + + public function testUsingDefaultSettings_pxIsAllowed() { + $this->assertIsValid( '100px' ); + } + + public function testUsingDefaultSettings_NoUnitIsAllowed() { + $this->assertIsValid( '100' ); + } + + public function testUsingDefaultSettings_trailingNewlineIsInvalid() { + $this->assertIsNotValid( "100\n" ); + } + + public function testGivenUpperBound_valueUnderIsValid() { + $this->validator->setUpperBound( 100 ); + $this->assertIsValid( '99' ); + } + + public function testGivenUpperBound_valueEqualIsValid() { + $this->validator->setUpperBound( 100 ); + $this->assertIsValid( '100' ); + } + + public function testGivenUpperBound_valueOverIsInvalid() { + $this->validator->setUpperBound( 100 ); + $this->assertIsNotValid( '101' ); + } + + public function testUsingDefaultSettings_percentageIsNotValid() { + $this->assertIsNotValid( '50%' ); + } + + public function testWhenPercentageInUnitList_percentageValid() { + $this->validator->setAllowedUnits( array( 'px', '%' ) ); + $this->assertIsValid( '50%' ); + } + + public function testGivenLowerPercentageBound_valueOverIsValid() { + $this->validator->setAllowedUnits( array( '%' ) ); + $this->validator->setMinPercentage( 50 ); + $this->assertIsValid( '51%' ); + } + + public function testGivenLowerPercentageBound_valueEqualIsValid() { + $this->validator->setAllowedUnits( array( '%' ) ); + $this->validator->setMinPercentage( 50 ); + $this->assertIsValid( '50%' ); + } + + public function testGivenLowerPercentageBound_valueUnderIsNotValid() { + $this->validator->setAllowedUnits( array( '%' ) ); + $this->validator->setMinPercentage( 50 ); + $this->assertIsNotValid( '49%' ); + } + + public function testInvalidValuesAreInvalid() { + $this->assertIsNotValid( '' ); + $this->assertIsNotValid( 'a' ); + $this->assertIsNotValid( '1a' ); + $this->assertIsNotValid( '1px2' ); + $this->assertIsNotValid( 'a1px' ); + } + +} diff --git a/www/wiki/vendor/data-values/validators/tests/ValueValidators/ListValidatorTest.php b/www/wiki/vendor/data-values/validators/tests/ValueValidators/ListValidatorTest.php new file mode 100644 index 00000000..5a07f07f --- /dev/null +++ b/www/wiki/vendor/data-values/validators/tests/ValueValidators/ListValidatorTest.php @@ -0,0 +1,220 @@ +<?php + +namespace ValueValidators\Tests; + +use PHPUnit\Framework\TestCase; +use ValueValidators\Error; +use ValueValidators\ListValidator; + +/** + * @covers ValueValidators\ListValidator + * + * @group ValueValidators + * @group DataValueExtensions + * + * @license GPL-2.0-or-later + * @author Thiemo Kreuz + */ +class ListValidatorTest extends TestCase { + + /** + * @dataProvider invalidRangeProvider + */ + public function testInvalidRange( $range ) { + $validator = new ListValidator(); + $validator->setOptions( [ 'elementcount' => $range ] ); + $this->setExpectedException( 'Exception' ); + $validator->validate( [] ); + } + + public function invalidRangeProvider() { + return [ + [ null ], + [ 0 ], + [ '' ], + [ [] ], + [ [ 0 ] ], + [ [ 0, 0, 0 ] ], + ]; + } + + /** + * @dataProvider valueProvider + */ + public function testValidate( $value, array $options, $expectedErrors ) { + $validator = new ListValidator(); + $validator->setOptions( $options ); + $result = $validator->validate( $value ); + + if ( !is_array( $expectedErrors ) ) { + $expectedErrors = [ $expectedErrors ]; + } + + $this->assertEquals( $expectedErrors, $result->getErrors() ); + } + + public function valueProvider() { + return [ + [ + 'value' => null, + 'options' => [], + 'expectedErrors' => Error::newError( 'Not an array' ) + ], + [ + 'value' => 0, + 'options' => [], + 'expectedErrors' => Error::newError( 'Not an array' ) + ], + [ + 'value' => '', + 'options' => [], + 'expectedErrors' => Error::newError( 'Not an array' ) + ], + [ + 'value' => [], + 'options' => [], + 'expectedErrors' => [] + ], + [ + 'value' => [ 1 ], + 'options' => [], + 'expectedErrors' => [] + ], + + // Lower bound only + [ + 'value' => [], + 'options' => [ 'minelements' => null ], + 'expectedErrors' => [] + ], + [ + 'value' => [], + 'options' => [ 'minelements' => 0 ], + 'expectedErrors' => [] + ], + [ + 'value' => [], + 'options' => [ 'minelements' => 1 ], + 'expectedErrors' => Error::newError( 'Value exceeding lower bound', 'length' ) + ], + [ + 'value' => [ 1 ], + 'options' => [ 'minelements' => 1 ], + 'expectedErrors' => [] + ], + + // Upper bound only + [ + 'value' => [], + 'options' => [ 'maxelements' => null ], + 'expectedErrors' => [] + ], + [ + 'value' => [], + 'options' => [ 'maxelements' => 0 ], + 'expectedErrors' => [] + ], + [ + 'value' => [ 1 ], + 'options' => [ 'maxelements' => 0 ], + 'expectedErrors' => Error::newError( 'Value exceeding upper bound', 'length' ) + ], + [ + 'value' => [ 1 ], + 'options' => [ 'maxelements' => 1 ], + 'expectedErrors' => [] + ], + + // Lower and upper bound + [ + 'value' => [], + 'options' => [ 'elementcount' => [ 0, 0 ] ], + 'expectedErrors' => [] + ], + [ + 'value' => [ 1 ], + 'options' => [ 'elementcount' => [ 2, 2 ] ], + 'expectedErrors' => Error::newError( 'Value exceeding lower bound', 'length' ) + ], + [ + 'value' => [ 1, 2 ], + 'options' => [ 'elementcount' => [ 2, 2 ] ], + 'expectedErrors' => [] + ], + [ + 'value' => [ 1 ], + 'options' => [ 'elementcount' => [ 0, 0 ] ], + 'expectedErrors' => Error::newError( 'Value exceeding upper bound', 'length' ) + ], + [ + 'value' => [], + 'options' => [ 'elementcount' => [ 0, 0 ] ], + 'expectedErrors' => [] + ], + [ + 'value' => [], + 'options' => [ 'elementcount' => [ 2, 0 ] ], + 'expectedErrors' => Error::newError( 'Value exceeding lower bound', 'length' ) + ], + [ + 'value' => [ 1, 2 ], + 'options' => [ 'elementcount' => [ 2, 0 ] ], + 'expectedErrors' => Error::newError( 'Value exceeding upper bound', 'length' ) + ], + [ + 'value' => [ 1 ], + 'options' => [ 'elementcount' => [ 2, 0 ] ], + 'expectedErrors' => [ + Error::newError( 'Value exceeding upper bound', 'length' ), + Error::newError( 'Value exceeding lower bound', 'length' ), + ] + ], + [ + 'value' => [ 1 ], + 'options' => [ 'minelements' => 2, 'maxelements' => 0 ], + 'expectedErrors' => [ + Error::newError( 'Value exceeding upper bound', 'length' ), + Error::newError( 'Value exceeding lower bound', 'length' ), + ] + ], + + // Conflicting options + [ + 'value' => [], + 'options' => [ 'elementcount' => [ 1, 1 ], 'minelements' => null ], + 'expectedErrors' => [] + ], + [ + 'value' => [], + 'options' => [ 'elementcount' => [ 1, 1 ], 'minelements' => false ], + 'expectedErrors' => [] + ], + [ + 'value' => [], + 'options' => [ 'elementcount' => [ 1, 1 ], 'minelements' => 0 ], + 'expectedErrors' => [] + ], + [ + 'value' => [], + 'options' => [ 'minelements' => 0, 'elementcount' => [ 1, 1 ] ], + 'expectedErrors' => [] + ], + [ + 'value' => [ 1 ], + 'options' => [ 'elementcount' => [ 0, 0 ], 'maxelements' => false ], + 'expectedErrors' => [] + ], + [ + 'value' => [ 1 ], + 'options' => [ 'elementcount' => [ 0, 0 ], 'maxelements' => 1 ], + 'expectedErrors' => [] + ], + [ + 'value' => [ 1 ], + 'options' => [ 'maxelements' => 1, 'elementcount' => [ 0, 0 ] ], + 'expectedErrors' => [] + ], + ]; + } + +} diff --git a/www/wiki/vendor/data-values/validators/tests/ValueValidators/RangeValidatorTest.php b/www/wiki/vendor/data-values/validators/tests/ValueValidators/RangeValidatorTest.php new file mode 100644 index 00000000..c2301fec --- /dev/null +++ b/www/wiki/vendor/data-values/validators/tests/ValueValidators/RangeValidatorTest.php @@ -0,0 +1,68 @@ +<?php + +namespace ValueValidators\Tests; + +use PHPUnit\Framework\TestCase; +use ValueValidators\RangeValidator; + +/** + * @covers ValueValidators\RangeValidator + * + * @group ValueValidators + * @group DataValueExtensions + * + * @license GPL-2.0-or-later + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +class RangeValidatorTest extends TestCase { + + /** + * @dataProvider withinBoundsProvider + */ + public function testNumberWithinRange_WhenSetWithSetRange( $number, $lowerBound, $upperBound ) { + $rangeValidator = new RangeValidator(); + $rangeValidator->setRange( $lowerBound, $upperBound ); + + $this->assertTrue( $rangeValidator->validate( $number )->isValid() ); + } + + public function withinBoundsProvider() { + return array( + array( 0, 0, 0 ), + array( 5, 0, 9 ), + array( -5, -9, 0 ), + array( 0, -5, 5 ), + ); + } + + /** + * @dataProvider withinBoundsProvider + */ + public function testNumberWithinRange_WhenSetWithIndividualSetters( $number, $lowerBound, $upperBound ) { + $rangeValidator = new RangeValidator(); + $rangeValidator->setLowerBound( $lowerBound ); + $rangeValidator->setUpperBound( $upperBound ); + + $this->assertTrue( $rangeValidator->validate( $number )->isValid() ); + } + + /** + * @dataProvider outsideBoundsProvider + */ + public function testNumberOutsideRange_WhenSetWithSetRange( $number, $lowerBound, $upperBound ) { + $rangeValidator = new RangeValidator(); + $rangeValidator->setRange( $lowerBound, $upperBound ); + + $this->assertFalse( $rangeValidator->validate( $number )->isValid() ); + } + + public function outsideBoundsProvider() { + return array( + array( 0, 1, 1 ), + array( -1, 0, 9 ), + array( 100, -200, 99 ), + array( -42, -41, 99 ), + ); + } + +} diff --git a/www/wiki/vendor/data-values/validators/tests/ValueValidators/StringValidatorTest.php b/www/wiki/vendor/data-values/validators/tests/ValueValidators/StringValidatorTest.php new file mode 100644 index 00000000..a2d2fe2e --- /dev/null +++ b/www/wiki/vendor/data-values/validators/tests/ValueValidators/StringValidatorTest.php @@ -0,0 +1,99 @@ +<?php + +namespace ValueValidators\Tests; + +use PHPUnit\Framework\TestCase; +use ValueValidators\Error; +use ValueValidators\StringValidator; + +/** + * @covers ValueValidators\StringValidator + * + * @group ValueValidators + * @group DataValueExtensions + * + * @license GPL-2.0-or-later + * @author Thiemo Kreuz + */ +class StringValidatorTest extends TestCase { + + /** + * @dataProvider stringProvider + */ + public function testValidate( $value, array $options, $expectedError ) { + $validator = new StringValidator(); + $validator->setOptions( $options ); + $result = $validator->validate( $value ); + + $this->assertEquals( + $expectedError === null ? [] : [ $expectedError ], + $result->getErrors() + ); + } + + public function stringProvider() { + return [ + [ + 'value' => null, + 'options' => [], + 'expectedErrors' => Error::newError( 'Not a string' ) + ], + [ + 'value' => '', + 'options' => [], + 'expectedErrors' => null + ], + [ + 'value' => '', + 'options' => [ 'length' => 1 ], + 'expectedErrors' => Error::newError( 'Value exceeding lower bound', 'length' ) + ], + [ + 'value' => '1', + 'options' => [ 'length' => 1 ], + 'expectedErrors' => null + ], + [ + 'value' => '1', + 'options' => [ 'length' => 0 ], + 'expectedErrors' => Error::newError( 'Value exceeding upper bound', 'length' ) + ], + [ + 'value' => '', + 'options' => [ 'length' => 0 ], + 'expectedErrors' => null + ], + [ + 'value' => '', + 'options' => [ 'minlength' => 1 ], + 'expectedErrors' => Error::newError( 'Value exceeding lower bound', 'length' ) + ], + [ + 'value' => '1', + 'options' => [ 'minlength' => 1 ], + 'expectedErrors' => null + ], + [ + 'value' => '1', + 'options' => [ 'maxlength' => 0 ], + 'expectedErrors' => Error::newError( 'Value exceeding upper bound', 'length' ) + ], + [ + 'value' => '', + 'options' => [ 'maxlength' => 0 ], + 'expectedErrors' => null + ], + [ + 'value' => '1', + 'options' => [ 'regex' => '/^$/' ], + 'expectedErrors' => Error::newError( 'String does not match the regular expression /^$/' ) + ], + [ + 'value' => '', + 'options' => [ 'regex' => '/^$/' ], + 'expectedErrors' => null + ], + ]; + } + +} diff --git a/www/wiki/vendor/data-values/validators/tests/ValueValidators/TitleValidatorTest.php b/www/wiki/vendor/data-values/validators/tests/ValueValidators/TitleValidatorTest.php new file mode 100644 index 00000000..24c21c17 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/tests/ValueValidators/TitleValidatorTest.php @@ -0,0 +1,62 @@ +<?php + +namespace ValueValidators\Tests; + +use PHPUnit\Framework\TestCase; +use ValueValidators\Error; +use ValueValidators\TitleValidator; + +/** + * @covers ValueValidators\TitleValidator + * + * @group ValueValidators + * @group DataValueExtensions + * + * @license GPL-2.0-or-later + * @author Thiemo Kreuz + */ +class TitleValidatorTest extends TestCase { + + /** + * @dataProvider titleProvider + */ + public function testValidate( $value, $hasToExist, $expectedError ) { + $validator = new TitleValidator(); + $validator->setOptions( [ 'hastoexist' => $hasToExist ] ); + $result = $validator->validate( $value ); + + $this->assertEquals( + $expectedError === null ? [] : [ $expectedError ], + $result->getErrors() + ); + } + + public function titleProvider() { + $title = $this->getMockBuilder( 'Title' ) + ->disableOriginalConstructor() + ->setMethods( [ 'exists' ] ) + ->getMock(); + $title->expects( $this->any() ) + ->method( 'exists' ) + ->will( $this->returnValue( false ) ); + + return [ + [ + 'value' => null, + 'hasToExist' => false, + 'expectedErrors' => Error::newError( 'Not a title' ) + ], + [ + 'value' => $title, + 'hasToExist' => false, + 'expectedErrors' => null + ], + [ + 'value' => $title, + 'hasToExist' => true, + 'expectedErrors' => Error::newError( 'Title does not exist' ) + ], + ]; + } + +} diff --git a/www/wiki/vendor/data-values/validators/tests/bootstrap.php b/www/wiki/vendor/data-values/validators/tests/bootstrap.php new file mode 100644 index 00000000..ac82d460 --- /dev/null +++ b/www/wiki/vendor/data-values/validators/tests/bootstrap.php @@ -0,0 +1,14 @@ +<?php + +if ( PHP_SAPI !== 'cli' ) { + die( 'Not an entry point' ); +} + +error_reporting( E_ALL | E_STRICT ); +ini_set( 'display_errors', 1 ); + +if ( !is_readable( __DIR__ . '/../vendor/autoload.php' ) ) { + die( 'You need to install this package with Composer before you can run the tests' ); +} + +require_once __DIR__ . '/../vendor/autoload.php'; |