diff options
author | Yaco <franco@reevo.org> | 2021-10-19 20:42:50 -0300 |
---|---|---|
committer | Yaco <franco@reevo.org> | 2021-10-19 20:42:50 -0300 |
commit | 1dc109c979d7788e8811b4eecfb8bfdf3b6ea6e2 (patch) | |
tree | 21d2a3bd6706af9eeb3e9d1def5a6ab8d8a67e93 | |
parent | 8c201ace3699b4928daf41eb7b4cdcb4565c6f3b (diff) |
adds reevotech scripts
353 files changed, 33365 insertions, 1554 deletions
diff --git a/bin/bkp/bkp_wiki.sh b/bin/bkp/bkp_wiki.sh index c9aef4a4..7591d212 100755 --- a/bin/bkp/bkp_wiki.sh +++ b/bin/bkp/bkp_wiki.sh @@ -6,14 +6,26 @@ # EN: This file is part of: reevo-web (http://git.reevo.org/reevo/reevo-web) # ---- -cd /srv/reevo-2020/bin/bkp/ +cd /srv/reevotech -RUTA=`cat ../../etc/global_config.php | grep '^$REEVO_PATH' | cut -d '"' -f 2` -DOMINIO=`cat $RUTA/etc/global_config.php | grep '^$REEVO_URL' | cut -d '"' -f 2` -USER=`cat $RUTA/etc/global_config.php | grep '^$REEVO_DB_USER' | cut -d '"' -f 2` -PASSWORD=`cat $RUTA/etc/global_config.php | grep '^$REEVO_DB_PASS' | cut -d '"' -f 2` +if [ -z $1 ]; +then + echo "You must specify the deployment codename" + exit +fi -DB=`cat $RUTA/etc/global_config.php | grep '^$REEVO_DB_WIKI' | cut -d '"' -f 2` +DEPLOY=$1 +DEPLOYFILE=`ls ./etc | grep $DEPLOY` + +echo $DEPLOY +read +cd /srv/reevotech/bin/bkp/ +RUTA=`cat ../../etc/global_config-$DEPLOY.php | grep '^$REEVO_PATH' | cut -d '"' -f 2` +DOMINIO=`cat $RUTA/etc/global_config-$DEPLOY.php | grep '^$REEVO_URL' | cut -d '"' -f 2` +USER=`cat $RUTA/etc/global_config-$DEPLOY.php | grep '^$REEVO_DB_USER' | cut -d '"' -f 2` +PASSWORD=`cat $RUTA/etc/global_config-$DEPLOY.php | grep '^$REEVO_DB_PASS' | cut -d '"' -f 2` + +DB=`cat $RUTA/etc/global_config-$DEPLOY.php | grep '^$REEVO_DB_WIKI' | cut -d '"' -f 2` TIMESTAMP=`date +%Y-%m-%d-%H:%M:%S` echo "" diff --git a/bin/reevotech/CompletaGeoPorDireccion.sh b/bin/reevotech/CompletaGeoPorDireccion.sh new file mode 100755 index 00000000..6950e2dc --- /dev/null +++ b/bin/reevotech/CompletaGeoPorDireccion.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Este script lo usamos para actualizar los datos de geolocalizcion ubicacion de experiencia a partir de los campos que contienen la direcciΓ³n postal... Usamos OSM nominatim: `https://nominatim.org/release-docs/develop/api/Search/` +# +# Se puede usar como: IFS=$(echo -en "\n\b") && for i in `php ../ListarPaginas.php Plantilla:Experiencia`; do ./CompletaGeoPorDireccion.sh "$i"; done +DEPLOY="$1" +EXP="$2" +DATA=`php PropiedadObtener.php -d="$DEPLOY" -t="$EXP" -p="ecoversity:place-street" -p="ecoversity:place-city" -p="ecoversity:place-state" -p="ecoversity:place-country" > /tmp/x && sed 's/ /+/g' /tmp/x | sed ':a;N;$!ba;s/\n/,/g'` +echo "https://nominatim.openstreetmap.org/search.php?format=json&addressdetails=1&q=$DATA" + +if [ -z "$DATA" ] +then + echo "\$DATA is empty, exiting...." + exit +else + echo "\$DATA is NOT empty" +fi + + + +curl -s "https://nominatim.openstreetmap.org/search.php?format=json&addressdetails=1&q=$DATA" > /tmp/json + +cat /tmp/json | jq '.[0]' + +LAT=`cat /tmp/json | jq '.[0] | .lat' | sed 's/"//g'` +LON=`cat /tmp/json | jq '.[0] | .lon' | sed 's/"//g'` + +echo "Lat: $LAT" +echo "Lon: $LON" + +if [ $LAT != "null" ]; then + php PropiedadActualizar.php -d="$DEPLOY" -t="$EXP" -f="true" -p="ecoversity:place|$LAT, $LON" + sed -i "/$EXP/d" todos.log + echo $EXP >> correctos.log +else + echo "I was unable to get a coordinate, logging to revisar.log" + sed -i "/$EXP/d" todos.log + echo $EXP >> revisar.log +fi diff --git a/bin/reevotech/CreateSemanticObject.sh b/bin/reevotech/CreateSemanticObject.sh new file mode 100644 index 00000000..87dc64a9 --- /dev/null +++ b/bin/reevotech/CreateSemanticObject.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +echo "This script is used to create a Semantic Object defined in a specific Deployment" +echo "" diff --git a/bin/reevotech/ListarPaginas.php b/bin/reevotech/ListarPaginas.php new file mode 100644 index 00000000..96a4d6ef --- /dev/null +++ b/bin/reevotech/ListarPaginas.php @@ -0,0 +1,66 @@ +<?php +# ---- +# Copyright (C) 2013-2020 - Reevo Project (http://reevo.org) +# License: Affero GPL version 3 - http://www.gnu.org/licenses/agpl.html +# ES: Este script recibe el nombre de una Plantilla o CategorΓa y lista todas las paginas que lo usan. +# Se usa con: php ListarPaginas.php "CategorΓa:Experiencia" +# ---- + + +// error_reporting(0); +// Load all the stuff +require_once( __DIR__ . '/vendor/autoload.php' ); +require_once( __DIR__ .'/../../etc/global_config.php' ); + +// Log in to a wiki +$api = new \Mediawiki\Api\MediawikiApi( $wgServer .'/api.php' ); +$api->login( new \Mediawiki\Api\ApiUser( $REEVO_WIKI_API_USER, $REEVO_WIKI_API_PASS ) ); +$services = new \Mediawiki\Api\MediawikiFactory( $api ); + +// Obtengo el nombre del template como parΓ‘metro +if ($argv[1]) { + + $pageListGetter = $services->newPageListGetter(); + $tipo = explode(':',$argv[1]); + switch ($tipo[0]) { + case 'Categoria': + $examplePages = $pageListGetter->getPageListFromCategoryName( $argv[1] ); + break; + case 'Plantilla': + $examplePages = $pageListGetter->getPageListFromPageTransclusions( $argv[1] ); + break; + default: + echo "No reconozco el tipo de objeto que estas intentando listar (debe ser CategorΓa o Plantilla)\n\n"; + exit(); + } + $array = accessProtected($examplePages,'pages'); + foreach ( $array as $exPage ) { + $pagename = $exPage->getTitle()->getText(); + echo "$pagename \n"; + } +} else { + echo "Hay que indicar una plantilla como parametro \n"; +} + +function accessProtected($obj, $prop) { + $reflection = new ReflectionClass($obj); + $property = $reflection->getProperty($prop); + $property->setAccessible(true); + return $property->getValue($obj); +} + + + + + +// print_r($examplePages); + +// $myArray = json_decode(json_encode($examplePages), true); +// print_r($examplePages->getPageList()); + + + + + + +?> diff --git a/bin/reevotech/PropiedadActualizar.php b/bin/reevotech/PropiedadActualizar.php new file mode 100644 index 00000000..6e0fb829 --- /dev/null +++ b/bin/reevotech/PropiedadActualizar.php @@ -0,0 +1,128 @@ +<?php +# ---- +# Copyright (C) 2013-2020 - Reevo Project (http://reevo.org) +# License: Affero GPL version 3 - http://www.gnu.org/licenses/agpl.html +# ES: Este script recibe el nombre de una pagina e intenta agregar o actualizar las propiedades especΓficadas de las mismas con el valor dado. +# Algo como: php PropiedadActualizar.php -t=Experiencia:Summerhill -f=true -p="experiencia:descripcion|Algo" -p="experiencia:lugar-pais|AR" +# ---- + +$opciones = getopt('d:t:p:f:'); + +if ($opciones['d']) { + $deployment = $opciones['d']; +} else { + echo "Es necesario que definas el nombre del deployment con -d='ecoversities'\n"; + exit; +} + +// error_reporting(0); +// Load all the stuff +require_once( __DIR__ . '/vendor/autoload.php' ); +require_once( __DIR__ .'/../../etc/global_config-'.$deployment.'.php' ); + +// Log in to a wiki +$api = new \Mediawiki\Api\MediawikiApi( $wgServer .'/api.php' ); +$api->login( new \Mediawiki\Api\ApiUser( $REEVO_WIKI_API_USER, $REEVO_WIKI_API_PASS ) ); +$services = new \Mediawiki\Api\MediawikiFactory( $api ); +echo "Deployment URL: $wgServer \n"; + + +if ($opciones['t']) { + if ($opciones['p']) { + $title = $opciones['t']; + if (is_string($opciones['p'])) { + $prop[] = $opciones['p']; + } else { + $prop = $opciones['p']; + } + foreach ($prop as $key => $value) { + $p = explode('|', $value); + $propiedades[$p[0]] = $p[1]; + } + $result = ActualizarPropiedades($title, $propiedades, $opciones, $services); + echo "\nSe actualizΓ³ correctamente la pΓ‘gina $result ($wgServer/$result)\n\n\n"; + } else { + echo "Es necesario que definas al menos una propiedad para agregar o modificar con -p='propiedad|valor'\n"; + } +} else { + echo "Es necesario que definas el nombe de la pagina a editar con -t='Pagina'\n"; +} + +// Obtengo el nombre de la pΓ‘gina como parΓ‘metro + +function ActualizarPropiedades($title, $propiedades, $opciones, $services) { + + $page = $services->newPageGetter()->getFromTitle( $title ); + $pagecontent = $page->getRevisions()->getLatest(); + if (!$pagecontent) { + echo "\n**** ERROR: No existe una pΓ‘gina con el nombre '$title'\n\n\n"; + exit(); + } else { + echo "\n**** PROCESANDO: '$title' ****\n"; + } + + $pagecontent = $page->getRevisions()->getLatest()->getContent()->getData(); + + $template = preg_grep('/^\{{(.*(?<!}}))$/', explode("\n", $pagecontent)); + $template_pos = array_key_first($template); + $templatefin = preg_grep('/^\}}(.*)$/', explode("\n", $pagecontent)); + $templatefin_pos = array_key_first($templatefin); + + + $extracto = preg_grep('/^\|/', explode("\n", $pagecontent)); + foreach ($extracto as $key => $value) { + $data = str_replace('|','',$value); + $data_limpia = explode('=', $data, 2); + $propiedades_previas[$data_limpia[0]] = $data_limpia[1]; + } + + + // Verifico que tengo que hacer + if ($opciones['f'] == 'true') { + echo "\nVoy a actulizar y/o agregar las siguientes propiedades: \n"; + $propiedades_actualizables = array_intersect_key($propiedades,$propiedades_previas); + print_r($propiedades_actualizables); + $propiedades_final = array_replace($propiedades_previas, $propiedades); + } else { + echo "\nNo se van a reemplazar los valores de propiedades existentes. Agrega '-f=true' para hacerlo. Propiedadedes existentes con sus valores actuales: \n"; + $propiedades_actualizables = array_intersect_key($propiedades, $propiedades_previas); + print_r($propiedades_actualizables); + + echo "\nPropiedades antes no definidas que voy a agregar: \n"; + $propiedades_nuevas = array_diff_key($propiedades,$propiedades_previas); + print_r($propiedades_nuevas); + $propiedades_final = array_replace($propiedades_previas, $propiedades_nuevas); + } + + // Construyo un array con el formato del template original + $propiedades_final_array[] = $template[$template_pos]; + foreach ($propiedades_final as $key => $value) { + $propiedades_final_array[] = '|'.$key.'='.$value; + } + $propiedades_final_array[] = $templatefin[$templatefin_pos]; + + // Hago un array con el contenido de toda la pagina y reemplazo el template viejo por el nuevo + $contenido_array = explode("\n", $pagecontent); + $templatefin_pos = $templatefin_pos + 1; + array_splice($contenido_array, $template_pos, $templatefin_pos,$propiedades_final_array); + + $contenido_final = implode("\n", $contenido_array); + + $newContent = new \Mediawiki\DataModel\Content( $contenido_final ); + $pagetitle = new \Mediawiki\DataModel\Title( $title ); + $identifier = new \Mediawiki\DataModel\PageIdentifier( $pagetitle ); + $revision = new \Mediawiki\DataModel\Revision( $newContent, $identifier ); + $services->newRevisionSaver()->save( $revision ); + + return $title; + +} + +function accessProtected($obj, $prop) { + $reflection = new ReflectionClass($obj); + $property = $reflection->getProperty($prop); + $property->setAccessible(true); + return $property->getValue($obj); +} + +?> diff --git a/bin/reevotech/PropiedadObtener.php b/bin/reevotech/PropiedadObtener.php new file mode 100644 index 00000000..938c7d92 --- /dev/null +++ b/bin/reevotech/PropiedadObtener.php @@ -0,0 +1,91 @@ +<?php +# ---- +# Copyright (C) 2013-2020 - Reevo Project (http://reevo.org) +# License: Affero GPL version 3 - http://www.gnu.org/licenses/agpl.html +# ES: Este script recibe el nombre de una pagina e intenta obtener el valor las propiedades especΓficas. +# Algo como: php PropiedadObtener.php -d="Deployment" -t="Experiencia:Summerhill" -p="experiencia:lugar" -p="experiencia:lugar-pais" +# ---- + +$opciones = getopt('d:t:p:f:'); + +if ($opciones['d']) { + $deployment = $opciones['d']; +} else { + echo "Es necesario que definas el nombre del deployment con -d='ecoversities'\n"; + exit; +} + +// error_reporting(0); +// Load all the stuff +require_once( __DIR__ . '/vendor/autoload.php' ); +require_once( __DIR__ .'/../../etc/global_config-'.$deployment.'.php' ); +#echo "Deployment URL: $wgServer \n"; + +// Log in to a wiki +$api = new \Mediawiki\Api\MediawikiApi( $wgServer .'/api.php' ); +$api->login( new \Mediawiki\Api\ApiUser( $REEVO_WIKI_API_USER, $REEVO_WIKI_API_PASS ) ); +$services = new \Mediawiki\Api\MediawikiFactory( $api ); + + + +if ($opciones['t']) { + if ($opciones['p']) { + $title = $opciones['t']; + if (is_string($opciones['p'])) { + $prop[] = $opciones['p']; + } else { + $prop = $opciones['p']; + } + foreach ($prop as $key => $value) { + // $p = explode('|', $value); + $propiedades[$value] = ''; + } + $result = ObtenerPropiedades($title, $propiedades, $opciones, $services); + } else { + echo "Es necesario que definas al menos una propiedad para obtener con -p='propiedad|valor'\n"; + exit; + } +} else { + echo "Es necesario que definas el nombe de la pagina a revisar con -t='Pagina'\n"; + exit; +} + +// Obtengo el nombre de la pΓ‘gina como parΓ‘metro + +function ObtenerPropiedades($title, $propiedades, $opciones, $services) { + + $page = $services->newPageGetter()->getFromTitle( $title ); + $pagecontent = $page->getRevisions()->getLatest(); + if (!$pagecontent) { + echo "\n**** ERROR: No existe una pΓ‘gina con el nombre '$title'\n\n\n"; + exit(); + } else { + // echo "\n**** PROCESANDO: '$title' ****\n"; + } + + $pagecontent = $page->getRevisions()->getLatest()->getContent()->getData(); + + // armo un array con las propiedades de SMW + $extracto = preg_grep('/^\|/', explode("\n", $pagecontent)); + foreach ($extracto as $key => $value) { + $data = str_replace('|','',$value); + $data_limpia = explode('=', $data); + $propiedades_previas[$data_limpia[0]] = $data_limpia[1]; + } + + foreach ($propiedades as $key => $value) { + if (array_key_exists($key, $propiedades_previas)) { + echo "$propiedades_previas[$key]\n"; + } + } + +} + +function accessProtected($obj, $prop) { + $reflection = new ReflectionClass($obj); + $property = $reflection->getProperty($prop); + $property->setAccessible(true); + return $property->getValue($obj); +} + +?> diff --git a/bin/reevotech/PullPages.sh b/bin/reevotech/PullPages.sh new file mode 100755 index 00000000..e479e39e --- /dev/null +++ b/bin/reevotech/PullPages.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Use: ./bin/reevotech/PullPages.sh ecoversities Help + +if [ $# -eq 0 ] + then + echo "Missing parameters. Use: ./bin/reevotech/PullPages.sh ecoversities Help" + exit +fi + +cd /srv/reevotech + +DEPLOY=$1 +DEPLOYFILE=`ls ./etc | grep $DEPLOY` +NS=$2 +DOMAIN=`cat ./etc/$DEPLOYFILE | grep 'REEVO_URL =' | cut -d'"' -f 2` + +# echo $DEPLOY +# echo $DEPLOYFILE +# echo $DOMAIN + +cd ./www/wiki/deployments/$DEPLOY + +if [[ -d pages_tmp/$NS ]] +then + echo "" + cd pages_tmp/$NS + git pull + cd ../../ +else + git clone -c remote.origin.namespaces="$NS" mediawiki::http://$DOMAIN pages_tmp/$NS +fi + +cp -rf pages_tmp/$NS pages +rm -rf pages/$NS/.git diff --git a/bin/reevotech/PutPages.sh b/bin/reevotech/PutPages.sh new file mode 100755 index 00000000..831a8616 --- /dev/null +++ b/bin/reevotech/PutPages.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Use: ./bin/reevotech/PutPages.sh ecoversities Property + +if [ $# -eq 0 ] + then + echo "Missing parameters. Use: ./bin/reevotech/PutPages.sh ecoversities Help" + exit +fi + + +cd /srv/reevotech + +DEPLOY=$1 +NS=$2 + +cd /srv/reevotech/www/wiki/maintenance/ + + +php importTextFiles.php --conf ../LocalSettings-$DEPLOY.php -s "Updated using PutPages.sh" --overwrite "../deployments/$DEPLOY/pages/$NS/*" diff --git a/bin/reevotech/test.php b/bin/reevotech/test.php new file mode 100644 index 00000000..4bb78902 --- /dev/null +++ b/bin/reevotech/test.php @@ -0,0 +1,44 @@ +<?php + +// Load all the stuff +require_once( __DIR__ . '/vendor/autoload.php' ); + +// Log in to a wiki +$api = new \Mediawiki\Api\MediawikiApi( 'http://source.ecoversities.test/api.php' ); +$api->login( new \Mediawiki\Api\ApiUser( 'Yaco', 'yaco2234' ) ); +$services = new \Mediawiki\Api\MediawikiFactory( $api ); + +// Get a page +$page = $services->newPageGetter()->getFromTitle( 'Portada' ); + +print_r("$page", TRUE); +// +// // Edit a page +// $content = new \Mediawiki\DataModel\Content( 'New Text' ); +// $revision = new \Mediawiki\DataModel\Revision( $content, $page->getPageIdentifier() ); +// $services->newRevisionSaver()->save( $revision ); +// +// // Move a page +// $services->newPageMover()->move( +// $services->newPageGetter()->getFromTitle( 'FooBar' ), +// new Title( 'FooBar' ) +// ); +// +// // Delete a page +// $services->newPageDeleter()->delete( +// $services->newPageGetter()->getFromTitle( 'DeleteMe!' ), +// array( 'reason' => 'Reason for Deletion' ) +// ); +// +// // Create a new page +// $newContent = new \Mediawiki\DataModel\Content( 'Hello World' ); +// $title = new \Mediawiki\DataModel\Title( 'New Page' ); +// $identifier = new \Mediawiki\DataModel\PageIdentifier( $title ); +// $revision = new \Mediawiki\DataModel\Revision( $newContent, $identifier ); +// $services->newRevisionSaver()->save( $revision ); +// +// // List all pages in a category +// $pages = $services->newPageListGetter()->getPageListFromCategoryName( 'Category:Cat name' ); + + +?> diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/.gitignore b/bin/reevotech/vendor/addwiki/mediawiki-api-base/.gitignore new file mode 100644 index 00000000..9c16bff2 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/.gitignore @@ -0,0 +1,6 @@ +.idea +vendor +composer.lock +test.php +docs/_build +phpunit.xml diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/.phan/config.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/.phan/config.php new file mode 100644 index 00000000..28c1f4ad --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/.phan/config.php @@ -0,0 +1,40 @@ +<?php + +/** + * This configuration will be read and overlaid on top of the + * default configuration. Command line arguments will be applied + * after this file is read. + */ +return [ + + /** + * A list of directories that should be parsed for class and + * method information. After excluding the directories + * defined in exclude_analysis_directory_list, the remaining + * files will be statically analyzed for errors. + * + * Thus, both first-party and third-party code being used by + * your application should be included in this list. + */ + 'directory_list' => [ + 'src', + 'vendor', + ], + + /** + * A directory list that defines files that will be excluded + * from static analysis, but whose class and method + * information should be included. + * + * Generally, you'll want to include the directories for + * third-party code (such as "vendor/") in this list. + * + * n.b.: If you'd like to parse but not analyze 3rd + * party code, directories containing that code + * should be added to the `directory_list` as + * to `exclude_analysis_directory_list`. + */ + "exclude_analysis_directory_list" => [ + 'vendor/' + ], +]; diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/.scrutinizer.yml b/bin/reevotech/vendor/addwiki/mediawiki-api-base/.scrutinizer.yml new file mode 100644 index 00000000..ffc976e3 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/.scrutinizer.yml @@ -0,0 +1,13 @@ +inherit: true + +tools: + 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 + external_code_coverage: + timeout: 300
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/.travis.yml b/bin/reevotech/vendor/addwiki/mediawiki-api-base/.travis.yml new file mode 100644 index 00000000..cb3e7641 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/.travis.yml @@ -0,0 +1,61 @@ +language: php + +php: + - hhvm + - 5.5 + - 5.6 + - 7.0 + - 7.1 + +env: + - MW=master + +matrix: + include: + - php: 7.1 + env: MW=REL1_28 + - php: 7.1 + env: MW=REL1_27 + - php: 7.1 + env: MW=REL1_26 + - php: 7.1 + env: MW=REL1_25 + - php: 7.1 + env: MW=REL1_24 + allow_failures: + - env: MW=REL1_24 + +addons: + mariadb: '10.0' + +before_install: + - bash ./build/travis/install-mediawiki.sh + +install: + - travis_retry composer install + +before_script: + - bash ./build/travis/run-webserver.sh + - export ADDWIKI_MW_API='http://localhost:8080/w/api.php' + - export ADDWIKI_MW_USER='CIUser' + - export ADDWIKI_MW_PASSWORD='CIPass' + +script: + - composer lint + - composer phpcs + - composer phpunit-coverage + +after_success: + - travis_retry wget https://scrutinizer-ci.com/ocular.phar + - php ocular.phar code-coverage:upload --format=php-clover coverage.clover + +cache: + directories: + - $HOME/.composer/cache + +notifications: + irc: + channels: + - "chat.freenode.net##add" + on_success: change + on_failure: always diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/LICENSE.md b/bin/reevotech/vendor/addwiki/mediawiki-api-base/LICENSE.md new file mode 100644 index 00000000..0671f06a --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/LICENSE.md @@ -0,0 +1,264 @@ +The GNU General Public License, Version 2, June 1991 (GPLv2) +============================================================ + +> 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 Library 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. + + +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. diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/README.md b/bin/reevotech/vendor/addwiki/mediawiki-api-base/README.md new file mode 100644 index 00000000..ea2a7d4b --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/README.md @@ -0,0 +1,16 @@ +# mediawiki-api-base + +[](https://travis-ci.org/addwiki/mediawiki-api-base) +[](https://scrutinizer-ci.com/g/addwiki/mediawiki-api-base/?branch=master) +[](https://scrutinizer-ci.com/g/addwiki/mediawiki-api-base/?branch=master) +[](https://www.versioneye.com/php/addwiki:mediawiki-api-base) + +[](https://php-eye.com/package/addwiki/mediawiki-api-base) + +[](https://packagist.org/packages/addwiki/mediawiki-api-base) +[](https://packagist.org/packages/addwiki/mediawiki-api-base) +[](https://www.versioneye.com/php/addwiki:mediawiki-api-base/references) + +Issue tracker: https://phabricator.wikimedia.org/project/profile/1490/ + +Documentation: https://addwiki.readthedocs.io
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/RELEASENOTES.md b/bin/reevotech/vendor/addwiki/mediawiki-api-base/RELEASENOTES.md new file mode 100644 index 00000000..a84b19cc --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/RELEASENOTES.md @@ -0,0 +1,95 @@ +These are the release notes for the [mediawiki-api-base](README.md) library. + +## Version 2.4.0 (2 November 2017) +* New MultipartRequest class added. PR [#38](https://github.com/addwiki/mediawiki-api-base/pull/38). + +## Version 2.3.1 (3 May 2017) +* Don't fail on libxml errors if the RSD URL can still be found. PR [#35](https://github.com/addwiki/mediawiki-api-base/pull/35), Fixes [T163527](https://phabricator.wikimedia.org/T163527). + +## Version 2.3.0 (27 April 2017) + +* All guzzle configuration settings can now be overridden in `ClientFactory`. [#27](https://github.com/addwiki/mediawiki-api-base/pull/27) +* Requests that fail due to maxlag will be automatically retried. [#28](https://github.com/addwiki/mediawiki-api-base/pull/28). Fixes [T143193](https://phabricator.wikimedia.org/T143193). +* Added `MediawikiApi::getApiUrl`. [#24](https://github.com/addwiki/mediawiki-api-base/pull/24) +* Debugging infomation now logged when login fails. [#26](https://github.com/addwiki/mediawiki-api-base/pull/26) +* UsageException messages now include the error code and result the API returned. [#31](https://github.com/addwiki/mediawiki-api-base/pull/31) +* Both formatversion=2 and old style API results supported [#33](https://github.com/addwiki/mediawiki-api-base/pull/33) +* Fix [MediawikiApi::newFromPage() fails on non-XML HTML](https://phabricator.wikimedia.org/T163527). [#34](https://github.com/addwiki/mediawiki-api-base/pull/34) +* Various CI improvements. + +## Version 2.2.1 (3 August 2016) + +* Cast SimpleXMLElements attributes as string in `MediawikiApi::newFromPage()` + +## Version 2.2.0 (18 January 2016) + +* Added `MediawikiApiInterface`, now implemented by `MediawikiApi` +* Added `ApiRequester`, now implemented by `MediawikiApi` +* Added `AsyncApiRequester`, now implemented by `MediawikiApi` +* The constructor of `MediawikiApi` was made package public + +## Version 2.1.0 (29 December 2015) + +* Retry throttled actions that return a failed-save code and anti-abuse message +* Added delay between retried requests +* Added and used `Guzzle/ClientFactory` + +## Version 2.0.0 (18 December 2015) + +* Added `MediawikiApi::newFromApiEndpoint` and `MediawikiApi::newFromPage` +* MediawikiApi constructor access marked as private (please use static factory methods) +* Added async methods to MediawikiApi `getRequestAsync` & `postRequestAsync` +* Requires "guzzlehttp/guzzle": "~6.0" ( From "guzzle/guzzle": "~5.2" ) +* Requires "guzzlehttp/promises": "~1.0" + +## Version 1.1.1 (20 July 2016) + +* Issue with README fixed + +## Version 1.1.0 (5 September 2015) + +* Requests that encounter a connection exception are now retried +* Requests that result in non blocking mediawiki api error codes are now retried (ratelimited, readonly, internal_api_error_DBQueryError) +* MediawikiApi now implements PSR-3 LoggerAwareInterface +* MediawikiSession now implements PSR-3 LoggerAwareInterface +* MediawikiApi no longer raises PHP warnings, instead it logs warnings + +## Version 1.0.0 (23 August 2015) + +* Added `FluentRequest` object +* Requires "guzzlehttp/retry-subscriber": "~2.0" + +## Version 0.3 (1 June 2015) + +* UsageExceptions can now contain the full api result array +* No longer uses addwiki/guzzle-mediawiki-client +* Now using "guzzlehttp/guzzle": "~5.0" ( From "guzzle/guzzle": "~3.2" ) +* Added getHeaders method to Request interface +* ApiUser now accepts a domain + +## Version 0.2 (13 January 2015) + +### Compatibility changes + +* Session objects now use action=query&meta=tokens to get tokens when possible. +NOTE: [Token names have changed between versions](//www.mediawiki.org/wiki/API:Tokens) + +### Deprecations + +* MediawikiApi getAction and postAction methods have been deprecated in favour of getRequest and postRequest + +### New features + +* If warnings are present in API results E_USER_WARNING errors are triggered +* The Request interface and SimpleRequest class have been added +* MediawikiApi now has a getRequest and postRequest method +* MediawikiApi now has a getVersion method +* Unsuccessful logins now throw a UsageException with extra details + +## Version 0.1.2 (25 May 2014) + +* Fix issue where API tokens were not returned + +## Version 0.1 (12 May 2014) + +* Initial release after split from mediawiki-api lib diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/build/travis/install-mediawiki.sh b/bin/reevotech/vendor/addwiki/mediawiki-api-base/build/travis/install-mediawiki.sh new file mode 100644 index 00000000..59d29ba4 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/build/travis/install-mediawiki.sh @@ -0,0 +1,29 @@ +#! /bin/bash + +set -x + +originalDirectory=$(pwd) + +if [[ $TRAVIS_PHP_VERSION == *"hhvm"* ]] +then + PHPINI=/etc/hhvm/php.ini + echo "hhvm.enable_zend_compat = true" >> $PHPINI +fi + +mkdir ./../web +cd ./../web + +wget https://github.com/wikimedia/mediawiki/archive/$MW.tar.gz +tar -zxf $MW.tar.gz +mv mediawiki-$MW w +ln -s ./w ./wiki + +cd w + +composer self-update +composer install + +mysql -e 'CREATE DATABASE mediawiki;' +php maintenance/install.php --dbtype mysql --dbuser root --dbname mediawiki --dbpath $(pwd) --pass CIPass TravisWiki CIUser + +cd $originalDirectory diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/build/travis/run-webserver.sh b/bin/reevotech/vendor/addwiki/mediawiki-api-base/build/travis/run-webserver.sh new file mode 100644 index 00000000..2412031c --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/build/travis/run-webserver.sh @@ -0,0 +1,25 @@ +#! /bin/bash + +set -x + +# HHVM doesn't have a built in web server +# We can't guarantee any single PHP version is always installed on Travis hosts +# So list the versions and try to pick the latest PHP version +# Also the web server on 7.1 seems to have issues, so don't use that? +if [[ $TRAVIS_PHP_VERSION == *"hhvm"* ]] || [[ $TRAVIS_PHP_VERSION == *"7.1"* ]] +then + WEBSERVERPHPVERSION=`phpenv versions | grep -v system | grep -v hhvm | grep -v 7.1 | tail -n 1 | xargs` + phpenv global $WEBSERVERPHPVERSION + php --version +fi + +# Run a web server for MediaWiki and wait until it is up +nohup php -S 0.0.0.0:8080 -t ./../web > /dev/null 2>&1 & +until curl -s localhost:8080; do true; done > /dev/null 2>&1 + +# Switch back to the actual php version requested for this build if needed +if [ -v $WEBSERVERPHPVERSION ] +then + phpenv global $TRAVIS_PHP_VERSION + php --version +fi diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/composer.json b/bin/reevotech/vendor/addwiki/mediawiki-api-base/composer.json new file mode 100644 index 00000000..c83fca09 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/composer.json @@ -0,0 +1,52 @@ +{ + "name": "addwiki/mediawiki-api-base", + "type": "library", + "description": "A basic Mediawiki api base library", + "keywords": ["Mediawiki"], + "license": "GPL-2.0+", + "authors": [ + { "name": "Addshore" } + ], + "require": { + "php": ">=5.5", + "guzzlehttp/guzzle": "~6.0", + "guzzlehttp/promises": "~1.0", + "psr/log": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.0|~5.3.0", + "jakub-onderka/php-parallel-lint": "0.9.2", + "mediawiki/mediawiki-codesniffer": "^13.0" + }, + "suggest": { + "etsy/phan": "Allows running static analysis on the package (requires PHP 7+)" + }, + "scripts": { + "lint": "parallel-lint . --exclude vendor", + "phpunit": "phpunit", + "phpunit-unit": "phpunit --testsuite unit", + "phpunit-integration": "phpunit --testsuite integration", + "phpunit-coverage": "phpunit --coverage-clover=coverage.clover", + "phpcs": "phpcs -ps", + "test": [ + "@lint", + "@phpcs", + "@phpunit" + ] + }, + "autoload": { + "psr-4": { + "Mediawiki\\Api\\": "src/" + } + }, + "autoload-dev": { + "files": [ + "tests/Integration/TestEnvironment.php" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "2.4.x-dev" + } + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/Makefile b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/Makefile new file mode 100644 index 00000000..54002b3b --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/Makefile @@ -0,0 +1,225 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " applehelp to make an Apple Help Book" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " epub3 to make an epub3" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " coverage to run coverage check of the documentation (if enabled)" + @echo " dummy to check syntax errors of document sources" + +.PHONY: clean +clean: + rm -rf $(BUILDDIR)/* + +.PHONY: html +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +.PHONY: dirhtml +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +.PHONY: singlehtml +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +.PHONY: pickle +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +.PHONY: json +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +.PHONY: htmlhelp +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +.PHONY: qthelp +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/mediawiki-api-base.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/mediawiki-api-base.qhc" + +.PHONY: applehelp +applehelp: + $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp + @echo + @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." + @echo "N.B. You won't be able to view it unless you put it in" \ + "~/Library/Documentation/Help or install it in your application" \ + "bundle." + +.PHONY: devhelp +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/mediawiki-api-base" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/mediawiki-api-base" + @echo "# devhelp" + +.PHONY: epub +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +.PHONY: epub3 +epub3: + $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 + @echo + @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." + +.PHONY: latex +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +.PHONY: latexpdf +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: latexpdfja +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: text +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +.PHONY: man +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +.PHONY: texinfo +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +.PHONY: info +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +.PHONY: gettext +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +.PHONY: changes +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +.PHONY: linkcheck +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +.PHONY: doctest +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +.PHONY: coverage +coverage: + $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage + @echo "Testing of coverage in the sources finished, look at the " \ + "results in $(BUILDDIR)/coverage/python.txt." + +.PHONY: xml +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +.PHONY: pseudoxml +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." + +.PHONY: dummy +dummy: + $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy + @echo + @echo "Build finished. Dummy builder generates no files." diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/conf.py b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/conf.py new file mode 100644 index 00000000..cb3ce592 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/conf.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +import sys, os +from sphinx.highlighting import lexers +from pygments.lexers.web import PhpLexer + +lexers['php'] = PhpLexer(startinline=True, linenos=1) +lexers['php-annotations'] = PhpLexer(startinline=True, linenos=1) +primary_domain = 'php' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'mediawiki-api-base' +copyright = '2016, addwiki' +author = 'addwiki' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '2.2' +# The full version, including alpha/beta/rc tags. +release = '2.2.1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'default' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Output file base name for HTML help builder. +htmlhelp_basename = 'mediawiki-api-basedoc' diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/index.rst b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/index.rst new file mode 100644 index 00000000..ac4860ce --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/index.rst @@ -0,0 +1,17 @@ +Welcome to mediawiki-api-base's documentation! +============================================== + +.. toctree:: + :maxdepth: 3 + + overview + quickstart + multipart + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/make.bat b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/make.bat new file mode 100644 index 00000000..7ce5e397 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/make.bat @@ -0,0 +1,281 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^<target^>` where ^<target^> is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. epub3 to make an epub3 + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + echo. coverage to run coverage check of the documentation if enabled + echo. dummy to check syntax errors of document sources + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +REM Check if sphinx-build is available and fallback to Python version if any +%SPHINXBUILD% 1>NUL 2>NUL +if errorlevel 9009 goto sphinx_python +goto sphinx_ok + +:sphinx_python + +set SPHINXBUILD=python -m sphinx.__init__ +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +:sphinx_ok + + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\mediawiki-api-base.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\mediawiki-api-base.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "epub3" ( + %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3 + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub3 file is in %BUILDDIR%/epub3. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "coverage" ( + %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage + if errorlevel 1 exit /b 1 + echo. + echo.Testing of coverage in the sources finished, look at the ^ +results in %BUILDDIR%/coverage/python.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +if "%1" == "dummy" ( + %SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. Dummy builder generates no files. + goto end +) + +:end diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/multipart.rst b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/multipart.rst new file mode 100644 index 00000000..1b438c71 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/multipart.rst @@ -0,0 +1,28 @@ +================== +Multipart requests +================== + +The MultipartRequest class can be used if you need a FluentRequest that has more parameters to be set on individual parts of a multipart request. + +The name is a slight misnomer, because either of the other two Request classes (SimpleRequest and FluentRequest) +will also end up being multipart requests if you pass any parameters of type Resource_. + +.. _Resource: http://php.net/manual/en/resource.php + +To use a MultipartRequest you must first set the main parameters, and then you can add additional "multipart parameters" to any of the parameters you've set. +(You will get an Exception if you try to set a multipart parameter for a main parameter that doesn't exist yet.) + +For example, to add a ``Content-Disposition`` header to a parameter named ``param1``:: + + $contentDisposition = 'form-data; name="param1"; filename="a_filename.png"'; + $request = MultipartRequest::factory() + ->setParams( [ 'param1' => 'Lorem ipsum' ] ) + ->setAction( 'actionname' ) + ->setMultipartParams( [ + 'param1' => [ + 'headers' => [ 'Content-Disposition' => $contentDisposition ], + ], + ] ); + $response = $api->postRequest( $request ); + +(For details of creating the ``$api`` object in this example, see :ref:`quickstart`.) diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/overview.rst b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/overview.rst new file mode 100644 index 00000000..0e83549d --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/overview.rst @@ -0,0 +1,129 @@ +======== +Overview +======== + +addwiki/mediawiki-api-base is a PHP HTTP client wrapped around guzzle that makes it easy to interest with a mediawiki installation. + +#. Uses PSR-3 interfaces for logging +#. Handles Mediawiki login, sessions, cookies and tokens +#. Handles response errors by throwing catchable UsageExceptions +#. Retries failed requests where possible +#. Allows Async requests + +Requirements +======================== + +#. PHP 5.5.0 +#. Guzzle HTTP library ~6.0 + +.. _installation: + +Installation +======================== + +The recommended way to install this library is with +`Composer <http://getcomposer.org>`_. Composer is a dependency management tool +for PHP that allows you to declare the dependencies your project needs and +installs them into your project. + +.. code-block:: bash + + # Install Composer + curl -sS https://getcomposer.org/installer | php + +You can add addwiki/mediawiki-api-base as a dependency using the composer.phar CLI: + +.. code-block:: bash + + php composer.phar require addwiki/mediawiki-api-base:~2.0 + +Alternatively, you can specify addwiki/mediawiki-api-base as a dependency in your project's +existing composer.json file: + +.. code-block:: js + + { + "require": { + "addwiki/mediawiki-api-base": "~2.0" + } + } + +After installing, you need to require Composer's autoloader: + +.. code-block:: php + + require 'vendor/autoload.php'; + +You can find out more on how to install Composer, configure autoloading, and +other best-practices for defining dependencies at `getcomposer.org <http://getcomposer.org>`_. + + +Bleeding edge +-------------------------- + +During your development, you can keep up with the latest changes on the master +branch by setting the version requirement for addwiki/mediawiki-api-base to ``~2.0@dev``. + +.. code-block:: js + + { + "require": { + "addwiki/mediawiki-api-base": "~2.0@dev" + } + } + + +License +=================== + +Licensed using the `GPL-2.0+ <https://opensource.org/licenses/GPL-2.0>`_. + + 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. + + +Contributing +======================== + +Running the tests +----------------- + +In order to contribute, you'll need to checkout the source from GitHub and +install the dependencies using Composer: + +.. code-block:: bash + + git clone https://github.com/addwiki/mediawiki-api-base.git + cd mediawiki-api-base + curl -s http://getcomposer.org/installer | php + ./composer.phar install --dev + +The library is tested with a combination of linters and phpunit. Run all of the tests as follows: + +.. code-block:: bash + + ./composer.phar test + +You can choose to run each part of the whole test suite individually using the following commands: + +.. code-block:: bash + + # Run the linting only + ./composer.phar lint + # Run phpunit only + ./composer.phar phpunit + # Run only the phpunit unit tests + ./composer.phar phpunit-unit + # Run only the phpunit integration tests + ./composer.phar phpunit-integration
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/quickstart.rst b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/quickstart.rst new file mode 100644 index 00000000..5db0601f --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/docs/quickstart.rst @@ -0,0 +1,87 @@ +.. _quickstart: + +========== +Quickstart +========== + +This page provides a quick introduction to this library and introductory examples. +If you have not already installed the library head over to the :ref:`installation` +page. + +Getting an API object +---------------------------------- + +You can get an api object by simply passing the api endpoint: + +.. code-block:: php + + use \Mediawiki\Api\MediawikiApi; + + $api = MediawikiApi::newFromApiEndpoint( 'https://en.wikipedia.org/w/api.php' ); + +You can even just pass a page: + +.. code-block:: php + + use \Mediawiki\Api\MediawikiApi; + + $api = MediawikiApi::newFromPage( 'https://en.wikipedia.org/wiki/Berlin' ); + +Logging in and out +---------------------------------- + +.. code-block:: php + + use \MediawikiApi\Api\ApiUser; + + $api->login( new ApiUser( 'username', 'password' ) ); + $api->logout(); + +Making request objects +---------------------------------- + +The library provides two different way of constructing requests. + +.. code-block:: php + + use Mediawiki\Api\SimpleRequest; + use Mediawiki\Api\FluentRequest; + + $purgeRequest = new SimpleRequest( 'purge', array( 'titles' => 'Berlin' ) ); + // or + $purgeRequest = FluentRequest::factory()->setAction( 'purge' )->setParam( 'titles', 'Berlin' ) ); + +Sending requests +---------------------------------- + +.. code-block:: php + + $api->postRequest( $purgeRequest ); + + $queryResponse = $api->getRequest( FluentRequest::factory()->setAction( 'query' )->setParam( 'meta', 'siteinfo' ) ); + + try{ + $api->postRequest( new SimpleRequest( 'FooBarBaz' ) ); + } + catch ( UsageException $e ) { + echo "The api returned an error!"; + } + + +Making async requests +---------------------------------- + +.. code-block:: php + + // Initiate each request but do not block + $requestPromises = array( + 'Page1' => $api->postRequestAsync( FluentRequest::factory()->setAction( 'purge' )->setParam( 'titles', 'Page1' ) ), + 'Page2' => $api->postRequestAsync( FluentRequest::factory()->setAction( 'purge' )->setParam( 'titles', 'Page2' ) ), + 'Page3' => $api->postRequestAsync( FluentRequest::factory()->setAction( 'purge' )->setParam( 'titles', 'Page3' ) ), + ); + + // Wait on all of the requests to complete. + $results = GuzzleHttp\Promise\unwrap( $requestPromises ); + + // You can access each result using the key provided to the unwrap function. + print_r( $results['Page1'], $results['Page2'], $results['Page3'] ) diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/phpcs.xml b/bin/reevotech/vendor/addwiki/mediawiki-api-base/phpcs.xml new file mode 100755 index 00000000..c4ca4081 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/phpcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<ruleset name="MediaWiki"> + <rule ref="vendor/mediawiki/mediawiki-codesniffer/MediaWiki"/> + <file>.</file> + <exclude-pattern>vendor/</exclude-pattern> +</ruleset> diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/phpunit.xml.dist b/bin/reevotech/vendor/addwiki/mediawiki-api-base/phpunit.xml.dist new file mode 100644 index 00000000..a5874032 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/phpunit.xml.dist @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<phpunit colors="true"> + <testsuites> + <testsuite name="unit"> + <directory suffix="Test.php">./tests/Unit</directory> + </testsuite> + <testsuite name="integration"> + <directory suffix="Test.php">./tests/Integration</directory> + </testsuite> + </testsuites> + <filter> + <whitelist addUncoveredFilesFromWhitelist="true"> + <directory suffix=".php">./src</directory> + </whitelist> + </filter> +</phpunit>
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/ApiRequester.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/ApiRequester.php new file mode 100644 index 00000000..cc3c8bcf --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/ApiRequester.php @@ -0,0 +1,31 @@ +<?php + +namespace Mediawiki\Api; + +/** + * @since 2.2 + * @licence GNU GPL v2+ + * @author Addshore + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +interface ApiRequester { + + /** + * @since 2.2 + * + * @param Request $request The GET request to send. + * + * @return mixed Normally an array + */ + public function getRequest( Request $request ); + + /** + * @since 2.2 + * + * @param Request $request The POST request to send. + * + * @return mixed Normally an array + */ + public function postRequest( Request $request ); + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/ApiUser.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/ApiUser.php new file mode 100644 index 00000000..b2f59153 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/ApiUser.php @@ -0,0 +1,90 @@ +<?php + +namespace Mediawiki\Api; + +use InvalidArgumentException; + +/** + * @since 0.1 + * + * @author Addshore + * @author RobinR1 + * @author Bene + * + * Represents a user that can log in to the api + */ +class ApiUser { + + /** + * @var string + */ + private $password; + + /** + * @var string + */ + private $username; + + /** + * @var string + */ + private $domain; + + /** + * @param string $username The username. + * @param string $password The user's password. + * @param string|null $domain The domain (for authentication systems that support domains). + * + * @throws \InvalidArgumentException + */ + public function __construct( $username, $password, $domain = null ) { + $domainIsStringOrNull = ( is_string( $domain ) || is_null( $domain ) ); + if ( !is_string( $username ) || !is_string( $password ) || !$domainIsStringOrNull ) { + throw new InvalidArgumentException( 'Username, Password and Domain must all be strings' ); + } + if ( empty( $username ) || empty( $password ) ) { + throw new InvalidArgumentException( 'Username and Password are not allowed to be empty' ); + } + $this->username = $username; + $this->password = $password; + $this->domain = $domain; + } + + /** + * @since 0.1 + * @return string + */ + public function getUsername() { + return $this->username; + } + + /** + * @since 0.1 + * @return string + */ + public function getPassword() { + return $this->password; + } + + /** + * @since 0.1 + * @return string + */ + public function getDomain() { + return $this->domain; + } + + /** + * @since 0.1 + * @param mixed $other Another ApiUser object to compare with. + * + * @return bool + */ + public function equals( $other ) { + return $other instanceof self + && $this->username == $other->getUsername() + && $this->password == $other->getPassword() + && $this->domain == $other->getDomain(); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/AsyncApiRequester.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/AsyncApiRequester.php new file mode 100644 index 00000000..6190ac7e --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/AsyncApiRequester.php @@ -0,0 +1,37 @@ +<?php + +namespace Mediawiki\Api; + +use GuzzleHttp\Promise\PromiseInterface; + +/** + * @since 2.2 + * @licence GNU GPL v2+ + * @author Addshore + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +interface AsyncApiRequester { + + /** + * @since 2.2 + * + * @param Request $request The GET request to send. + * + * @return PromiseInterface + * Normally promising an array, though can be mixed (json_decode result) + * Can throw UsageExceptions or RejectionExceptions + */ + public function getRequestAsync( Request $request ); + + /** + * @since 2.2 + * + * @param Request $request The POST request to send. + * + * @return PromiseInterface + * Normally promising an array, though can be mixed (json_decode result) + * Can throw UsageExceptions or RejectionExceptions + */ + public function postRequestAsync( Request $request ); + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/FluentRequest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/FluentRequest.php new file mode 100644 index 00000000..0d10553b --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/FluentRequest.php @@ -0,0 +1,118 @@ +<?php + +namespace Mediawiki\Api; + +/** + * @since 1.0 + * + * @author Addshore + */ +class FluentRequest implements Request { + + /** + * @var array + */ + private $params = []; + + /** + * @var array + */ + private $headers = []; + + /** + * @since 1.0 + * + * @return array + */ + public function getParams() { + return $this->params; + } + + /** + * @since 1.0 + * + * @return array + */ + public function getHeaders() { + return $this->headers; + } + + /** + * @since 1.0 + * + * @return static + */ + public static function factory() { + return new static(); + } + + /** + * @since 1.0 + * + * @param string $action The action name. + * + * @return $this + */ + public function setAction( $action ) { + $this->setParam( 'action', $action ); + return $this; + } + + /** + * Totally overwrite any previously set params + * + * @since 1.0 + * + * @param array $params New parameters. + * + * @return $this + */ + public function setParams( array $params ) { + $this->params = $params; + return $this; + } + + /** + * Totally overwrite any previously set params + * + * @since 1.0 + * + * @param array $params Additional parameters. + * + * @return $this + */ + public function addParams( array $params ) { + $this->params = array_merge( $this->params, $params ); + return $this; + } + + /** + * Set a single parameter. + * + * @since 1.0 + * + * @param string $param The parameter name. + * @param string $value The parameter value. + * + * @return $this + */ + public function setParam( $param, $value ) { + $this->params[$param] = $value; + return $this; + } + + /** + * Totally overwrite any previously set HTTP headers. + * + * @since 1.0 + * + * @param array $headers New headers. + * + * @return $this + */ + public function setHeaders( $headers ) { + $this->headers = $headers; + return $this; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/Guzzle/ClientFactory.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/Guzzle/ClientFactory.php new file mode 100644 index 00000000..704a1660 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/Guzzle/ClientFactory.php @@ -0,0 +1,96 @@ +<?php + +namespace Mediawiki\Api\Guzzle; + +use GuzzleHttp\Client; +use GuzzleHttp\Handler\CurlHandler; +use GuzzleHttp\HandlerStack; +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; + +/** + * @since 2.1 + * + * @author Addshore + */ +class ClientFactory implements LoggerAwareInterface { + + private $client; + private $logger; + private $config; + + /** + * @since 2.1 + * + * @param array $config All configuration settings supported by Guzzle, and these: + * middleware => array of extra middleware to pass to guzzle + * user-agent => string default user agent to use for requests + */ + public function __construct( array $config = [] ) { + $this->logger = new NullLogger(); + $this->config = $config; + } + + /** + * @since 2.1 + * + * @return Client + */ + public function getClient() { + if ( $this->client === null ) { + $this->client = $this->newClient(); + } + return $this->client; + } + + /** + * @return Client + */ + private function newClient() { + $this->config += [ + 'cookies' => true, + 'headers' => [], + 'middleware' => [], + ]; + + if ( !array_key_exists( 'User-Agent', $this->config['headers'] ) ) { + if ( array_key_exists( 'user-agent', $this->config ) ) { + $this->config['headers']['User-Agent'] = $this->config['user-agent']; + } else { + $this->config['headers']['User-Agent'] = 'Addwiki - mediawiki-api-base'; + } + } + unset( $this->config['user-agent'] ); + + if ( !array_key_exists( 'handler', $this->config ) ) { + $this->config['handler'] = HandlerStack::create( new CurlHandler() ); + } + + $middlewareFactory = new MiddlewareFactory(); + $middlewareFactory->setLogger( $this->logger ); + + $this->config['middleware'][] = $middlewareFactory->retry(); + + foreach ( $this->config['middleware'] as $name => $middleware ) { + $this->config['handler']->push( $middleware ); + } + unset( $this->config['middleware'] ); + + return new Client( $this->config ); + } + + /** + * Sets a logger instance on the object + * + * @since 2.1 + * + * @param LoggerInterface $logger The new Logger object. + * + * @return null + */ + public function setLogger( LoggerInterface $logger ) { + $this->logger = $logger; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/Guzzle/MiddlewareFactory.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/Guzzle/MiddlewareFactory.php new file mode 100644 index 00000000..9e03c02f --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/Guzzle/MiddlewareFactory.php @@ -0,0 +1,158 @@ +<?php + +namespace Mediawiki\Api\Guzzle; + +use GuzzleHttp\Exception\ConnectException; +use GuzzleHttp\Exception\RequestException; +use GuzzleHttp\Middleware; +use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Psr7\Response; +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; + +/** + * @access private + * + * @author Addshore + */ +class MiddlewareFactory implements LoggerAwareInterface { + + /** + * @var LoggerInterface + */ + private $logger; + + public function __construct() { + $this->logger = new NullLogger(); + } + + /** + * @param LoggerInterface $logger The new Logger object. + */ + public function setLogger( LoggerInterface $logger ) { + $this->logger = $logger; + } + + /** + * @access private + * + * @param bool $delay default to true, can be false to speed up tests + * + * @return callable + */ + public function retry( $delay = true ) { + if ( $delay ) { + return Middleware::retry( $this->newRetryDecider(), $this->getRetryDelay() ); + } else { + return Middleware::retry( $this->newRetryDecider() ); + } + } + + /** + * Returns a method that takes the number of retries and returns the number of miliseconds + * to wait + * + * @return callable + */ + private function getRetryDelay() { + return function ( $numberOfRetries, Response $response = null ) { + // The $response argument is only passed as of Guzzle 6.2.2. + if ( $response !== null ) { + // Retry-After may be a number of seconds or an absolute date (RFC 7231, + // section 7.1.3). + $retryAfter = $response->getHeaderLine( 'Retry-After' ); + + if ( is_numeric( $retryAfter ) ) { + return 1000 * $retryAfter; + } + + if ( $retryAfter ) { + $seconds = strtotime( $retryAfter ) - time(); + return 1000 * max( 1, $seconds ); + } + } + + return 1000 * $numberOfRetries; + }; + } + + /** + * @return callable + */ + private function newRetryDecider() { + return function ( + $retries, + Request $request, + Response $response = null, + RequestException $exception = null + ) { + // Don't retry if we have run out of retries + if ( $retries >= 5 ) { + return false; + } + + $shouldRetry = false; + + // Retry connection exceptions + if ( $exception instanceof ConnectException ) { + $shouldRetry = true; + } + + if ( $response ) { + $data = json_decode( $response->getBody(), true ); + + // Retry on server errors + if ( $response->getStatusCode() >= 500 ) { + $shouldRetry = true; + } + + foreach ( $response->getHeader( 'Mediawiki-Api-Error' ) as $mediawikiApiErrorHeader ) { + if ( + // Retry if the API explicitly tells us to: + // https://www.mediawiki.org/wiki/Manual:Maxlag_parameter + $response->getHeaderLine( 'Retry-After' ) + || + // Retry if we have a response with an API error worth retrying + in_array( + $mediawikiApiErrorHeader, + [ + 'ratelimited', + 'maxlag', + 'readonly', + 'internal_api_error_DBQueryError', + ] + ) + || + // Or if we have been stopped from saving as an 'anti-abuse measure' + // Note: this tries to match "actionthrottledtext" i18n messagae for mediawiki + ( + $mediawikiApiErrorHeader == 'failed-save' && + strstr( $data['error']['info'], 'anti-abuse measure' ) + ) + ) { + $shouldRetry = true; + } + + } + } + + // Log if we are retrying + if ( $shouldRetry ) { + $this->logger->warning( + sprintf( + 'Retrying %s %s %s/5, %s', + $request->getMethod(), + $request->getUri(), + $retries + 1, + $response ? 'status code: ' . $response->getStatusCode() : + $exception->getMessage() + ) + ); + } + + return $shouldRetry; + }; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/MediawikiApi.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/MediawikiApi.php new file mode 100644 index 00000000..0c6c4fe3 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/MediawikiApi.php @@ -0,0 +1,507 @@ +<?php + +namespace Mediawiki\Api; + +use DOMDocument; +use DOMXPath; +use GuzzleHttp\Client; +use GuzzleHttp\ClientInterface; +use GuzzleHttp\Exception\RequestException; +use GuzzleHttp\Promise\PromiseInterface; +use InvalidArgumentException; +use Mediawiki\Api\Guzzle\ClientFactory; +use Psr\Http\Message\ResponseInterface; +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Psr\Log\LogLevel; +use Psr\Log\NullLogger; +use SimpleXMLElement; + +/** + * Main class for this library + * + * @since 0.1 + * + * @author Addshore + */ +class MediawikiApi implements MediawikiApiInterface, LoggerAwareInterface { + + /** + * @var ClientInterface|null Should be accessed through getClient + */ + private $client = null; + + /** + * @var bool|string + */ + private $isLoggedIn; + + /** + * @var MediawikiSession + */ + private $session; + + /** + * @var string + */ + private $version; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var string + */ + private $apiUrl; + + /** + * @since 2.0 + * + * @param string $apiEndpoint e.g. https://en.wikipedia.org/w/api.php + * + * @return self returns a MediawikiApi instance using $apiEndpoint + */ + public static function newFromApiEndpoint( $apiEndpoint ) { + return new self( $apiEndpoint ); + } + + /** + * Create a new MediawikiApi object from a URL to any page in a MediaWiki website. + * + * @since 2.0 + * @see https://en.wikipedia.org/wiki/Really_Simple_Discovery + * + * @param string $url e.g. https://en.wikipedia.org OR https://de.wikipedia.org/wiki/Berlin + * @return self returns a MediawikiApi instance using the apiEndpoint provided by the RSD + * file accessible on all Mediawiki pages + * @throws RsdException If the RSD URL could not be found in the page's HTML. + */ + public static function newFromPage( $url ) { + // Set up HTTP client and HTML document. + $tempClient = new Client( [ 'headers' => [ 'User-Agent' => 'addwiki-mediawiki-client' ] ] ); + $pageHtml = $tempClient->get( $url )->getBody(); + $pageDoc = new DOMDocument(); + + // Try to load the HTML (turn off errors temporarily; most don't matter, and if they do get + // in the way of finding the API URL, will be reported in the RsdException below). + $internalErrors = libxml_use_internal_errors( true ); + $pageDoc->loadHTML( $pageHtml ); + $libXmlErrors = libxml_get_errors(); + libxml_use_internal_errors( $internalErrors ); + + // Extract the RSD link. + $xpath = 'head/link[@type="application/rsd+xml"][@href]'; + $link = ( new DOMXpath( $pageDoc ) )->query( $xpath ); + if ( $link->length === 0 ) { + // Format libxml errors for display. + $libXmlErrorStr = array_reduce( $libXmlErrors, function ( $prevErr, $err ) { + return $prevErr . ', ' . $err->message . ' (line '.$err->line . ')'; + } ); + if ( $libXmlErrorStr ) { + $libXmlErrorStr = "In addition, libxml had the following errors: $libXmlErrorStr"; + } + throw new RsdException( "Unable to find RSD URL in page: $url $libXmlErrorStr" ); + } + $rsdUrl = $link->item( 0 )->attributes->getnamedItem( 'href' )->nodeValue; + + // Then get the RSD XML, and return the API link. + $rsdXml = new SimpleXMLElement( $tempClient->get( $rsdUrl )->getBody() ); + return self::newFromApiEndpoint( (string)$rsdXml->service->apis->api->attributes()->apiLink ); + } + + /** + * @param string $apiUrl The API Url + * @param ClientInterface|null $client Guzzle Client + * @param MediawikiSession|null $session Inject a custom session here + */ + public function __construct( $apiUrl, ClientInterface $client = null, + MediawikiSession $session = null ) { + if ( !is_string( $apiUrl ) ) { + throw new InvalidArgumentException( '$apiUrl must be a string' ); + } + if ( $session === null ) { + $session = new MediawikiSession( $this ); + } + + $this->apiUrl = $apiUrl; + $this->client = $client; + $this->session = $session; + + $this->logger = new NullLogger(); + } + + /** + * Get the API URL (the URL to which API requests are sent, usually ending in api.php). + * This is useful if you've created this object via MediawikiApi::newFromPage(). + * + * @since 2.3 + * + * @return string The API URL. + */ + public function getApiUrl() { + return $this->apiUrl; + } + + /** + * @return ClientInterface + */ + private function getClient() { + if ( $this->client === null ) { + $clientFactory = new ClientFactory(); + $clientFactory->setLogger( $this->logger ); + $this->client = $clientFactory->getClient(); + } + return $this->client; + } + + /** + * Sets a logger instance on the object + * + * @since 1.1 + * + * @param LoggerInterface $logger The new Logger object. + * + * @return null + */ + public function setLogger( LoggerInterface $logger ) { + $this->logger = $logger; + $this->session->setLogger( $logger ); + } + + /** + * @since 2.0 + * + * @param Request $request The GET request to send. + * + * @return PromiseInterface + * Normally promising an array, though can be mixed (json_decode result) + * Can throw UsageExceptions or RejectionExceptions + */ + public function getRequestAsync( Request $request ) { + $promise = $this->getClient()->requestAsync( + 'GET', + $this->apiUrl, + $this->getClientRequestOptions( $request, 'query' ) + ); + + return $promise->then( function ( ResponseInterface $response ) { + return call_user_func( [ $this, 'decodeResponse' ], $response ); + } ); + } + + /** + * @since 2.0 + * + * @param Request $request The POST request to send. + * + * @return PromiseInterface + * Normally promising an array, though can be mixed (json_decode result) + * Can throw UsageExceptions or RejectionExceptions + */ + public function postRequestAsync( Request $request ) { + $promise = $this->getClient()->requestAsync( + 'POST', + $this->apiUrl, + $this->getClientRequestOptions( $request, $this->getPostRequestEncoding( $request ) ) + ); + + return $promise->then( function ( ResponseInterface $response ) { + return call_user_func( [ $this, 'decodeResponse' ], $response ); + } ); + } + + /** + * @since 0.2 + * + * @param Request $request The GET request to send. + * + * @return mixed Normally an array + */ + public function getRequest( Request $request ) { + $response = $this->getClient()->request( + 'GET', + $this->apiUrl, + $this->getClientRequestOptions( $request, 'query' ) + ); + + return $this->decodeResponse( $response ); + } + + /** + * @since 0.2 + * + * @param Request $request The POST request to send. + * + * @return mixed Normally an array + */ + public function postRequest( Request $request ) { + $response = $this->getClient()->request( + 'POST', + $this->apiUrl, + $this->getClientRequestOptions( $request, $this->getPostRequestEncoding( $request ) ) + ); + + return $this->decodeResponse( $response ); + } + + /** + * @param ResponseInterface $response + * + * @return mixed + * @throws UsageException + */ + private function decodeResponse( ResponseInterface $response ) { + $resultArray = json_decode( $response->getBody(), true ); + + $this->logWarnings( $resultArray ); + $this->throwUsageExceptions( $resultArray ); + + return $resultArray; + } + + /** + * @param Request $request + * + * @return string + */ + private function getPostRequestEncoding( Request $request ) { + if ( $request instanceof MultipartRequest ) { + return 'multipart'; + } + foreach ( $request->getParams() as $value ) { + if ( is_resource( $value ) ) { + return 'multipart'; + } + } + return 'form_params'; + } + + /** + * @param Request $request + * @param string $paramsKey either 'query' or 'multipart' + * + * @throws RequestException + * + * @return array as needed by ClientInterface::get and ClientInterface::post + */ + private function getClientRequestOptions( Request $request, $paramsKey ) { + $params = array_merge( $request->getParams(), [ 'format' => 'json' ] ); + if ( $paramsKey === 'multipart' ) { + $params = $this->encodeMultipartParams( $request, $params ); + } + + return [ + $paramsKey => $params, + 'headers' => array_merge( $this->getDefaultHeaders(), $request->getHeaders() ), + ]; + } + + /** + * Turn the normal key-value array of request parameters into a multipart array where each + * parameter is a new array with a 'name' and 'contents' elements (and optionally more, if the + * request is a MultipartRequest). + * + * @param Request $request The request to which the parameters belong. + * @param string[] $params The existing parameters. Not the same as $request->getParams(). + * + * @return array + */ + private function encodeMultipartParams( Request $request, $params ) { + // See if there are any multipart parameters in this request. + $multipartParams = ( $request instanceof MultipartRequest ) + ? $request->getMultipartParams() + : []; + return array_map( + function ( $name, $value ) use ( $multipartParams ) { + $partParams = [ + 'name' => $name, + 'contents' => $value, + ]; + if ( isset( $multipartParams[ $name ] ) ) { + // If extra parameters have been set for this part, use them. + $partParams = array_merge( $multipartParams[ $name ], $partParams ); + } + return $partParams; + }, + array_keys( $params ), + $params + ); + } + + /** + * @return array + */ + private function getDefaultHeaders() { + return [ + 'User-Agent' => $this->getUserAgent(), + ]; + } + + private function getUserAgent() { + $loggedIn = $this->isLoggedin(); + if ( $loggedIn ) { + return 'addwiki-mediawiki-client/' . $loggedIn; + } + return 'addwiki-mediawiki-client'; + } + + /** + * @param $result + */ + private function logWarnings( $result ) { + if ( is_array( $result ) && array_key_exists( 'warnings', $result ) ) { + foreach ( $result['warnings'] as $module => $warningData ) { + // Accomodate both formatversion=2 and old-style API results + $logPrefix = $module . ': '; + if ( isset( $warningData['*'] ) ) { + $this->logger->warning( $logPrefix . $warningData['*'], [ 'data' => $warningData ] ); + } else { + $this->logger->warning( $logPrefix . $warningData['warnings'], [ 'data' => $warningData ] ); + } + } + } + } + + /** + * @param array $result + * + * @throws UsageException + */ + private function throwUsageExceptions( $result ) { + if ( is_array( $result ) && array_key_exists( 'error', $result ) ) { + throw new UsageException( + $result['error']['code'], + $result['error']['info'], + $result + ); + } + } + + /** + * @since 0.1 + * + * @return bool|string false or the name of the current user + */ + public function isLoggedin() { + return $this->isLoggedIn; + } + + /** + * @since 0.1 + * + * @param ApiUser $apiUser The ApiUser to log in as. + * + * @throws UsageException + * @return bool success + */ + public function login( ApiUser $apiUser ) { + $this->logger->log( LogLevel::DEBUG, 'Logging in' ); + $credentials = $this->getLoginParams( $apiUser ); + $result = $this->postRequest( new SimpleRequest( 'login', $credentials ) ); + if ( $result['login']['result'] == "NeedToken" ) { + $params = array_merge( [ 'lgtoken' => $result['login']['token'] ], $credentials ); + $result = $this->postRequest( new SimpleRequest( 'login', $params ) ); + } + if ( $result['login']['result'] == "Success" ) { + $this->isLoggedIn = $apiUser->getUsername(); + return true; + } + + $this->isLoggedIn = false; + $this->logger->log( LogLevel::DEBUG, 'Login failed.', $result ); + $this->throwLoginUsageException( $result ); + return false; + } + + /** + * @param ApiUser $apiUser + * + * @return string[] + */ + private function getLoginParams( ApiUser $apiUser ) { + $params = [ + 'lgname' => $apiUser->getUsername(), + 'lgpassword' => $apiUser->getPassword(), + ]; + + if ( !is_null( $apiUser->getDomain() ) ) { + $params['lgdomain'] = $apiUser->getDomain(); + } + return $params; + } + + /** + * @param array $result + * + * @throws UsageException + */ + private function throwLoginUsageException( $result ) { + $loginResult = $result['login']['result']; + + throw new UsageException( + 'login-' . $loginResult, + array_key_exists( 'reason', $result['login'] ) + ? $result['login']['reason'] + : 'No Reason given', + $result + ); + } + + /** + * @since 0.1 + * + * @return bool success + */ + public function logout() { + $this->logger->log( LogLevel::DEBUG, 'Logging out' ); + $result = $this->postRequest( new SimpleRequest( 'logout' ) ); + if ( $result === [] ) { + $this->isLoggedIn = false; + $this->clearTokens(); + return true; + } + return false; + } + + /** + * @since 0.1 + * + * @param string $type The token type to get. + * + * @return string + */ + public function getToken( $type = 'csrf' ) { + return $this->session->getToken( $type ); + } + + /** + * Clear all tokens stored by the API. + * + * @since 0.1 + */ + public function clearTokens() { + $this->session->clearTokens(); + } + + /** + * @return string + */ + public function getVersion() { + if ( !isset( $this->version ) ) { + $result = $this->getRequest( new SimpleRequest( 'query', [ + 'meta' => 'siteinfo', + 'continue' => '', + ] ) ); + preg_match( + '/\d+(?:\.\d+)+/', + $result['query']['general']['generator'], + $versionParts + ); + $this->version = $versionParts[0]; + } + return $this->version; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/MediawikiApiInterface.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/MediawikiApiInterface.php new file mode 100644 index 00000000..83580676 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/MediawikiApiInterface.php @@ -0,0 +1,60 @@ +<?php + +namespace Mediawiki\Api; + +/** + * @since 2.2 + * @licence GNU GPL v2+ + * @author Addshore + * @author Jeroen De Dauw < jeroendedauw@gmail.com > + */ +interface MediawikiApiInterface extends ApiRequester, AsyncApiRequester { + + /** + * @since 2.2 + * + * @return bool|string false or the name of the current user + */ + public function isLoggedin(); + + /** + * @since 2.2 + * + * @param ApiUser $apiUser The ApiUser to log in as. + * + * @throws UsageException + * @return bool success + */ + public function login( ApiUser $apiUser ); + + /** + * @since 2.2 + * + * @return bool success + */ + public function logout(); + + /** + * @since 2.2 + * + * @param string $type The type of token to get. + * + * @return string + */ + public function getToken( $type = 'csrf' ); + + /** + * @since 2.2 + * + * Clears all tokens stored by the api + */ + public function clearTokens(); + + /** + * @since 2.2 + * + * @return string + */ + public function getVersion(); + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/MediawikiSession.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/MediawikiSession.php new file mode 100644 index 00000000..c430695c --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/MediawikiSession.php @@ -0,0 +1,168 @@ +<?php + +namespace Mediawiki\Api; + +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Psr\Log\LogLevel; +use Psr\Log\NullLogger; + +/** + * @since 0.1 + * + * @author Addshore + */ +class MediawikiSession implements LoggerAwareInterface { + + /** + * @var array + */ + private $tokens = []; + + /** + * @var MediawikiApi + */ + private $api; + + /** + * @var bool if this session is running against mediawiki version pre 1.25 + */ + private $usePre125TokensModule = false; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param MediawikiApi $api The API object to use for this session. + */ + public function __construct( MediawikiApi $api ) { + $this->api = $api; + $this->logger = new NullLogger(); + } + + /** + * Sets a logger instance on the object + * + * @since 1.1 + * + * @param LoggerInterface $logger The new Logger object. + * + * @return null + */ + public function setLogger( LoggerInterface $logger ) { + $this->logger = $logger; + } + + /** + * Tries to get the specified token from the API + * + * @since 0.1 + * + * @param string $type The type of token to get. + * + * @return string + */ + public function getToken( $type = 'csrf' ) { + // If we don't already have the token that we want + if ( !array_key_exists( $type, $this->tokens ) ) { + $this->logger->log( LogLevel::DEBUG, 'Getting fresh token', [ 'type' => $type ] ); + + // If we know that we don't have the new module mw<1.25 + if ( $this->usePre125TokensModule ) { + return $this->reallyGetPre125Token( $type ); + } else { + return $this->reallyGetToken( $type ); + } + + } + + return $this->tokens[$type]; + } + + private function reallyGetPre125Token( $type ) { + // Suppress deprecation warning + $result = @$this->api->postRequest( // @codingStandardsIgnoreLine + new SimpleRequest( 'tokens', [ 'type' => $this->getOldTokenType( $type ) ] ) + ); + $this->tokens[$type] = array_pop( $result['tokens'] ); + + return $this->tokens[$type]; + } + + private function reallyGetToken( $type ) { + // We suppress errors on this call so the user doesn't get get a warning that isn't their fault. + $result = @$this->api->postRequest( // @codingStandardsIgnoreLine + new SimpleRequest( 'query', [ + 'meta' => 'tokens', + 'type' => $this->getNewTokenType( $type ), + 'continue' => '', + ] ) + ); + // If mw<1.25 (no new module) + $metaWarning = "Unrecognized value for parameter 'meta': tokens"; + if ( isset( $result['warnings']['query']['*'] ) + && false !== strpos( $result['warnings']['query']['*'], $metaWarning ) ) { + $this->usePre125TokensModule = true; + $this->logger->log( LogLevel::DEBUG, 'Falling back to pre 1.25 token system' ); + $this->tokens[$type] = $this->reallyGetPre125Token( $type ); + } else { + $this->tokens[$type] = array_pop( $result['query']['tokens'] ); + } + + return $this->tokens[$type]; + } + + /** + * Tries to guess a new token type from an old token type + * + * @param string $type + * + * @return string + */ + private function getNewTokenType( $type ) { + switch ( $type ) { + case 'edit': + case 'delete': + case 'protect': + case 'move': + case 'block': + case 'unblock': + case 'email': + case 'import': + case 'options': + return 'csrf'; + } + // Return the same type, don't know what to do with this.. + return $type; + } + + /** + * Tries to guess an old token type from a new token type + * + * @param $type + * + * @return string + */ + private function getOldTokenType( $type ) { + switch ( $type ) { + // Guess that we want an edit token, this may not always work as we might be trying to + // use it for something else... + case 'csrf': + return 'edit'; + } + return $type; + } + + /** + * Clears all tokens stored by the api + * + * @since 0.2 + */ + public function clearTokens() { + $this->logger->log( LogLevel::DEBUG, 'Clearing session tokens', [ 'tokens' => $this->tokens ] ); + $this->tokens = []; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/MultipartRequest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/MultipartRequest.php new file mode 100644 index 00000000..8d3fbdf4 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/MultipartRequest.php @@ -0,0 +1,77 @@ +<?php + +namespace Mediawiki\Api; + +use Exception; + +/** + * A MultipartRequest is the same as a FluentRequest with additional support for setting request + * parameters (both normal parameters and headers) on multipart requests. + * + * @link http://docs.guzzlephp.org/en/stable/request-options.html#multipart + * + * @since 2.4.0 + */ +class MultipartRequest extends FluentRequest { + + /** @var mixed[] */ + protected $multipartParams = []; + + /** + * Check the structure of a multipart parameter array. + * + * @param mixed[] $params The multipart parameters to check. + * + * @throws Exception + */ + protected function checkMultipartParams( $params ) { + foreach ( $params as $key => $val ) { + if ( !is_array( $val ) ) { + throw new Exception( "Parameter '$key' must be an array." ); + } + if ( !in_array( $key, array_keys( $this->getParams() ) ) ) { + throw new Exception( "Parameter '$key' is not already set on this request." ); + } + } + } + + /** + * Set all multipart parameters, replacing all existing ones. + * + * Each key of the array passed in here must be the name of a parameter already set on this + * request object. + * + * @param mixed[] $params The multipart parameters to use. + * @return $this + */ + public function setMultipartParams( $params ) { + $this->checkMultipartParams( $params ); + $this->multipartParams = $params; + return $this; + } + + /** + * Add extra multipart parameters. + * + * Each key of the array passed in here must be the name of a parameter already set on this + * request object. + * + * @param mixed[] $params The multipart parameters to add to any already present. + * + * @return $this + */ + public function addMultipartParams( $params ) { + $this->checkMultipartParams( $params ); + $this->multipartParams = array_merge( $this->multipartParams, $params ); + return $this; + } + + /** + * Get all multipart request parameters. + * + * @return mixed[] + */ + public function getMultipartParams() { + return $this->multipartParams; + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/Request.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/Request.php new file mode 100644 index 00000000..0daace2a --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/Request.php @@ -0,0 +1,30 @@ +<?php + +namespace Mediawiki\Api; + +/** + * @since 0.2 + * + * @author Addshore + */ +interface Request { + + /** + * @since 0.2 + * + * @return array + */ + public function getParams(); + + /** + * Associative array of headers to add to the request. + * Each key is the name of a header, and each value is a string or array of strings representing + * the header field values. + * + * @since 0.3 + * + * @return array + */ + public function getHeaders(); + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/RsdException.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/RsdException.php new file mode 100644 index 00000000..b304f574 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/RsdException.php @@ -0,0 +1,12 @@ +<?php + +namespace Mediawiki\Api; + +use Exception; + +/** + * An exception raised when an issue is encountered with Really Simple Discovery. + * @see https://en.wikipedia.org/wiki/Really_Simple_Discovery + */ +class RsdException extends Exception { +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/SimpleRequest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/SimpleRequest.php new file mode 100644 index 00000000..1e33348d --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/SimpleRequest.php @@ -0,0 +1,61 @@ +<?php + +namespace Mediawiki\Api; + +use InvalidArgumentException; + +/** + * Please consider using a FluentRequest object + * + * @since 0.2 + * + * @author Addshore + */ +class SimpleRequest implements Request { + + /** + * @var string + */ + private $action; + + /** + * @var array + */ + private $params; + + /** + * @var array + */ + private $headers; + + /** + * @param string $action The API action. + * @param array $params The parameters for the action. + * @param array $headers Any extra HTTP headers to send. + * + * @throws InvalidArgumentException + */ + public function __construct( $action, array $params = [], array $headers = [] ) { + if ( !is_string( $action ) ) { + throw new InvalidArgumentException( '$action must be string' ); + } + $this->action = $action; + $this->params = $params; + $this->headers = $headers; + } + + /** + * @return string[] + */ + public function getParams() { + return array_merge( [ 'action' => $this->action ], $this->params ); + } + + /** + * @return string[] + */ + public function getHeaders() { + return $this->headers; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/UsageException.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/UsageException.php new file mode 100644 index 00000000..77148f1b --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/src/UsageException.php @@ -0,0 +1,75 @@ +<?php + +namespace Mediawiki\Api; + +use Exception; + +/** + * Class representing a Mediawiki Api UsageException + * + * @since 0.1 + * + * @author Addshore + */ +class UsageException extends Exception { + + /** + * @var string + */ + private $apiCode; + + /** + * @var array + */ + private $result; + + /** + * @var string + */ + private $rawMessage; + + /** + * @since 0.1 + * + * @param string $apiCode The API error code. + * @param string $message The API error message. + * @param array $result the result the exception was generated from + */ + public function __construct( $apiCode = '', $message = '', $result = [] ) { + $this->apiCode = $apiCode; + $this->result = $result; + $this->rawMessage = $message; + $message = 'Code: ' . $apiCode . PHP_EOL . + 'Message: ' . $message . PHP_EOL . + 'Result: ' . json_encode( $result ); + parent::__construct( $message, 0, null ); + } + + /** + * @since 0.1 + * + * @return string + */ + public function getApiCode() { + return $this->apiCode; + } + + /** + * @since 0.3 + * + * @return array + */ + public function getApiResult() { + return $this->result; + } + + /** + * @since 2.3.0 + * + * @return string + */ + public function getRawMessage() { + return $this->rawMessage; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Integration/MediawikiApiTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Integration/MediawikiApiTest.php new file mode 100644 index 00000000..da6683e4 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Integration/MediawikiApiTest.php @@ -0,0 +1,103 @@ +<?php + +namespace Mediawiki\Api\Test\Integration; + +use Mediawiki\Api\MediawikiApi; +use Mediawiki\Api\SimpleRequest; + +/** + * @author Addshore + */ +class MediawikiApiTest extends \PHPUnit_Framework_TestCase { + + /** + * @covers Mediawiki\Api\MediawikiApi::newFromPage + */ + public function testNewFromPage() { + $api = MediawikiApi::newFromPage( TestEnvironment::newInstance()->getPageUrl() ); + $this->assertInstanceOf( 'Mediawiki\Api\MediawikiApi', $api ); + } + + /** + * @covers Mediawiki\Api\MediawikiApi::newFromPage + * @expectedException Mediawiki\Api\RsdException + * @expectedExceptionMessageRegExp |Unable to find RSD URL in page.*| + */ + public function testNewFromPageInvalidHtml() { + // This could be any URL that doesn't contain the RSD link, but the README URL + // is a test-accessible one that doesn't return 404. + $nonWikiPage = str_replace( 'api.php', 'README', TestEnvironment::newInstance()->getApiUrl() ); + MediawikiApi::newFromPage( $nonWikiPage ); + } + + /** + * Duplicate element IDs break DOMDocument::loadHTML + * @see https://phabricator.wikimedia.org/T163527#3219833 + * @covers Mediawiki\Api\MediawikiApi::newFromPage + */ + public function testNewFromPageWithDuplicateId() { + $testPageName = __METHOD__; + $testEnv = TestEnvironment::newInstance(); + $wikiPageUrl = str_replace( 'api.php', "index.php?title=$testPageName", $testEnv->getApiUrl() ); + + // Test with no duplicate IDs. + $testEnv->savePage( $testPageName, '<p id="unique-id"></p>' ); + $api1 = MediawikiApi::newFromPage( $wikiPageUrl ); + $this->assertInstanceOf( MediawikiApi::class, $api1 ); + + // Test with duplicate ID. + $wikiText = '<p id="duplicated-id"></p><div id="duplicated-id"></div>'; + $testEnv->savePage( $testPageName, $wikiText ); + $api2 = MediawikiApi::newFromPage( $wikiPageUrl ); + $this->assertInstanceOf( MediawikiApi::class, $api2 ); + } + + /** + * @covers Mediawiki\Api\MediawikiApi::getRequest + * @covers Mediawiki\Api\MediawikiApi::getClientRequestOptions + * @covers Mediawiki\Api\MediawikiApi::decodeResponse + * @covers Mediawiki\Api\MediawikiApi::getClient + */ + public function testQueryGetResponse() { + $api = TestEnvironment::newInstance()->getApi(); + $response = $api->getRequest( new SimpleRequest( 'query' ) ); + $this->assertInternalType( 'array', $response ); + } + + /** + * @covers Mediawiki\Api\MediawikiApi::getRequestAsync + * @covers Mediawiki\Api\MediawikiApi::getClientRequestOptions + * @covers Mediawiki\Api\MediawikiApi::decodeResponse + * @covers Mediawiki\Api\MediawikiApi::getClient + */ + public function testQueryGetResponseAsync() { + $api = TestEnvironment::newInstance()->getApi(); + $response = $api->getRequestAsync( new SimpleRequest( 'query' ) ); + $this->assertInternalType( 'array', $response->wait() ); + } + + /** + * @covers Mediawiki\Api\MediawikiApi::postRequest + * @covers Mediawiki\Api\MediawikiApi::getClientRequestOptions + * @covers Mediawiki\Api\MediawikiApi::decodeResponse + * @covers Mediawiki\Api\MediawikiApi::getClient + */ + public function testQueryPostResponse() { + $api = TestEnvironment::newInstance()->getApi(); + $response = $api->postRequest( new SimpleRequest( 'query' ) ); + $this->assertInternalType( 'array', $response ); + } + + /** + * @covers Mediawiki\Api\MediawikiApi::postRequestAsync + * @covers Mediawiki\Api\MediawikiApi::getClientRequestOptions + * @covers Mediawiki\Api\MediawikiApi::decodeResponse + * @covers Mediawiki\Api\MediawikiApi::getClient + */ + public function testQueryPostResponseAsync() { + $api = TestEnvironment::newInstance()->getApi(); + $response = $api->postRequestAsync( new SimpleRequest( 'query' ) ); + $this->assertInternalType( 'array', $response->wait() ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Integration/TestEnvironment.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Integration/TestEnvironment.php new file mode 100644 index 00000000..cb781508 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Integration/TestEnvironment.php @@ -0,0 +1,92 @@ +<?php + +namespace Mediawiki\Api\Test\Integration; + +use Exception; +use Mediawiki\Api\MediawikiApi; +use Mediawiki\Api\SimpleRequest; + +/** + * @author Addshore + */ +class TestEnvironment { + + /** + * Get a new TestEnvironment. + * This is identical to calling self::__construct() but is useful for fluent construction. + * + * @return TestEnvironment + */ + public static function newInstance() { + return new self(); + } + + /** @var MediawikiApi */ + private $api; + + /** @var string */ + private $apiUrl; + + /** @var string */ + private $pageUrl; + + /** + * Set up the test environment by creating a new API object pointing to a + * MediaWiki installation on localhost (or elsewhere as specified by the + * ADDWIKI_MW_API environment variable). + * + * @throws Exception If the ADDWIKI_MW_API environment variable does not end in 'api.php' + */ + public function __construct() { + $apiUrl = getenv( 'ADDWIKI_MW_API' ); + + if ( substr( $apiUrl, -7 ) !== 'api.php' ) { + $msg = "URL incorrect: $apiUrl" + ." (Set the ADDWIKI_MW_API environment variable correctly)"; + throw new Exception( $msg ); + } + + $this->apiUrl = $apiUrl; + $this->pageUrl = str_replace( 'api.php', 'index.php?title=Special:SpecialPages', $apiUrl ); + $this->api = MediawikiApi::newFromApiEndpoint( $this->apiUrl ); + } + + /** + * Get the url of the api to test against, based on the MEDIAWIKI_API_URL environment variable. + * @return string + */ + public function getApiUrl() { + return $this->apiUrl; + } + + /** + * Get the url of a page on the wiki to test against, based on the api url. + * @return string + */ + public function getPageUrl() { + return $this->pageUrl; + } + + /** + * Get the MediawikiApi to test against + * @return MediawikiApi + */ + public function getApi() { + return $this->api; + } + + /** + * Save a wiki page. + * @param string $title The title of the page. + * @param string $content The complete page text to save. + */ + public function savePage( $title, $content ) { + $params = [ + 'title' => $title, + 'text' => $content, + 'md5' => md5( $content ), + 'token' => $this->api->getToken(), + ]; + $this->api->postRequest( new SimpleRequest( 'edit', $params ) ); + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Integration/TokenHandlingTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Integration/TokenHandlingTest.php new file mode 100644 index 00000000..68ec52be --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Integration/TokenHandlingTest.php @@ -0,0 +1,28 @@ +<?php + +namespace Mediawiki\Api\Test\Integration; + +/** + * @author Addshore + */ +class TokenHandlingTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideTokenTypes + * + * @covers Mediawiki\Api\MediawikiApi::getToken + * @covers Mediawiki\Api\MediawikiSession::getToken + */ + public function testGetAnonUserToken() { + $api = TestEnvironment::newInstance()->getApi(); + $this->assertEquals( '+\\', $api->getToken() ); + } + + public function provideTokenTypes() { + return [ + [ 'csrf' ], + [ 'edit' ], + ]; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/ApiUserTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/ApiUserTest.php new file mode 100644 index 00000000..7e0da7ca --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/ApiUserTest.php @@ -0,0 +1,71 @@ +<?php + +namespace Mediawiki\Api\Test\Unit; + +use Mediawiki\Api\ApiUser; + +/** + * @author Addshore + * + * @covers Mediawiki\Api\ApiUser + */ +class ApiUserTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $user, $pass, $domain = null ) { + $apiUser = new ApiUser( $user, $pass, $domain ); + $this->assertSame( $user, $apiUser->getUsername() ); + $this->assertSame( $pass, $apiUser->getPassword() ); + $this->assertSame( $domain, $apiUser->getDomain() ); + } + + public function provideValidConstruction() { + return [ + [ 'user', 'pass' ], + [ 'user', 'pass', 'domain' ], + ]; + } + + /** + * @dataProvider provideInvalidConstruction + */ + public function testInvalidConstruction( $user, $pass, $domain = null ) { + $this->setExpectedException( 'InvalidArgumentException' ); + new ApiUser( $user, $pass, $domain ); + } + + public function provideInvalidConstruction() { + return [ + [ 'user', '' ], + [ '', 'pass' ], + [ '', '' ], + [ 'user', [] ], + [ 'user', 455667 ], + [ 34567, 'pass' ], + [ [], 'pass' ], + [ 'user', 'pass', [] ], + ]; + } + + /** + * @dataProvider provideTestEquals + */ + public function testEquals( ApiUser $user1, ApiUser $user2, $shouldEqual ) { + $this->assertSame( $shouldEqual, $user1->equals( $user2 ) ); + $this->assertSame( $shouldEqual, $user2->equals( $user1 ) ); + } + + public function provideTestEquals() { + return [ + [ new ApiUser( 'usera', 'passa' ), new ApiUser( 'usera', 'passa' ), true ], + [ new ApiUser( 'usera', 'passa', 'domain' ), new ApiUser( 'usera', 'passa', 'domain' ), true ], + [ new ApiUser( 'DIFF', 'passa' ), new ApiUser( 'usera', 'passa' ), false ], + [ new ApiUser( 'usera', 'DIFF' ), new ApiUser( 'usera', 'passa' ), false ], + [ new ApiUser( 'usera', 'passa' ), new ApiUser( 'DIFF', 'passa' ), false ], + [ new ApiUser( 'usera', 'passa' ), new ApiUser( 'usera', 'DIFF' ), false ], + ]; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/FluentRequestTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/FluentRequestTest.php new file mode 100644 index 00000000..93af921e --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/FluentRequestTest.php @@ -0,0 +1,69 @@ +<?php + +namespace Mediawiki\Api\Test\Unit; + +use Mediawiki\Api\FluentRequest; +use PHPUnit_Framework_TestCase; + +/** + * @author Addshore + * + * @covers Mediawiki\Api\FluentRequest + */ +class FluentRequestTest extends PHPUnit_Framework_TestCase { + + public function testFactory() { + $this->assertInstanceOf( 'Mediawiki\Api\FluentRequest', FluentRequest::factory() ); + } + + public function testConstructionDefaults() { + $request = new FluentRequest(); + + $this->assertEquals( [], $request->getParams() ); + $this->assertEquals( [], $request->getHeaders() ); + } + + public function testSetParams() { + $request = new FluentRequest(); + + $params = [ 'foo', 'bar' ]; + $request->setParams( $params ); + + $this->assertEquals( $params, $request->getParams() ); + } + + public function testSetParam() { + $request = new FluentRequest(); + + $request->setParam( 'paramName', 'fooValue' ); + + $this->assertEquals( [ 'paramName' => 'fooValue' ], $request->getParams() ); + } + + public function testAddParams() { + $request = new FluentRequest(); + + $params = [ 'a' => 'foo', 'b' => 'bar' ]; + $request->addParams( $params ); + + $this->assertEquals( $params, $request->getParams() ); + } + + public function testSetHeaders() { + $request = new FluentRequest(); + + $params = [ 'foo', 'bar' ]; + $request->setHeaders( $params ); + + $this->assertEquals( $params, $request->getHeaders() ); + } + + public function testSetAction() { + $request = new FluentRequest(); + + $request->setAction( 'fooAction' ); + + $this->assertEquals( [ 'action' => 'fooAction' ], $request->getParams() ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/Guzzle/ClientFactoryTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/Guzzle/ClientFactoryTest.php new file mode 100644 index 00000000..d84d0333 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/Guzzle/ClientFactoryTest.php @@ -0,0 +1,91 @@ +<?php + +namespace Mediawiki\Api\Test\Unit\Guzzle; + +use GuzzleHttp\HandlerStack; +use Mediawiki\Api\Guzzle\ClientFactory; +use Psr\Http\Message\RequestInterface; + +/** + * @author Christian Schmidt + * + * @covers Mediawiki\Api\Guzzle\ClientFactory + */ +class ClientFactoryTest extends \PHPUnit_Framework_TestCase { + + public function testNoConfig() { + $clientFactory = new ClientFactory(); + + $client = $clientFactory->getClient(); + + $this->assertSame( $client, $clientFactory->getClient() ); + + $config = $client->getConfig(); + $this->assertEquals( $config['headers']['User-Agent'], 'Addwiki - mediawiki-api-base' ); + + $this->assertFalse( empty( $config['cookies'] ) ); + } + + public function testUserAgent() { + $clientFactory = new ClientFactory( [ 'user-agent' => 'Foobar' ] ); + + $client = $clientFactory->getClient(); + + $this->assertNull( $client->getConfig( 'user-agent' ) ); + + $config = $client->getConfig(); + $this->assertEquals( $config['headers']['User-Agent'], 'Foobar' ); + } + + public function testHeaders() { + $clientFactory = new ClientFactory( [ + 'headers' => [ + 'User-Agent' => 'Foobar', + 'X-Foo' => 'Bar', + ] + ] ); + + $client = $clientFactory->getClient(); + + $headers = $client->getConfig( 'headers' ); + $this->assertCount( 2, $headers ); + $this->assertEquals( $headers['User-Agent'], 'Foobar' ); + $this->assertEquals( $headers['X-Foo'], 'Bar' ); + } + + public function testHandler() { + $handler = HandlerStack::create(); + + $clientFactory = new ClientFactory( [ 'handler' => $handler ] ); + + $client = $clientFactory->getClient(); + + $this->assertSame( $handler, $client->getConfig( 'handler' ) ); + } + + public function testMiddleware() { + $invoked = false; + $middleware = function () use ( &$invoked ) { + return function () use ( &$invoked ) { + $invoked = true; + }; + }; + + $clientFactory = new ClientFactory( [ 'middleware' => [ $middleware ] ] ); + + $client = $clientFactory->getClient(); + + $this->assertNull( $client->getConfig( 'middleware' ) ); + + $request = $this->getMockBuilder( RequestInterface::class )->getMock(); + + $handler = $client->getConfig( 'handler' ); + $handler->remove( 'http_errors' ); + $handler->remove( 'allow_redirects' ); + $handler->remove( 'cookies' ); + $handler->remove( 'prepare_body' ); + $handler( $request, [] ); + + $this->assertTrue( $invoked ); + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/Guzzle/MiddlewareFactoryTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/Guzzle/MiddlewareFactoryTest.php new file mode 100644 index 00000000..1cf7270a --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/Guzzle/MiddlewareFactoryTest.php @@ -0,0 +1,214 @@ +<?php + +namespace Mediawiki\Api\Test\Unit\Guzzle; + +use GuzzleHttp\Client; +use GuzzleHttp\Exception\ConnectException; +use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Psr7\Response; +use Mediawiki\Api\Guzzle\MiddlewareFactory; + +/** + * @author Addshore + * + * @todo test interaction with logger + * + * @covers Mediawiki\Api\Guzzle\MiddlewareFactory + */ +class MiddlewareFactoryTest extends \PHPUnit_Framework_TestCase { + + public function testRetriesConnectException() { + $queue = [ + new ConnectException( 'Error 1', new Request( 'GET', 'test' ) ), + new Response( 200, [ 'X-Foo' => 'Bar' ] ), + ]; + + $client = $this->getClient( $queue, $delays ); + $response = $client->request( 'GET', '/' ); + + $this->assertEquals( 200, $response->getStatusCode() ); + $this->assertEquals( [ 1000 ], $delays ); + } + + public function testRetries500Errors() { + $queue = [ + new Response( 500 ), + new Response( 200 ), + ]; + + $client = $this->getClient( $queue, $delays ); + $response = $client->request( 'GET', '/' ); + + $this->assertEquals( 200, $response->getStatusCode() ); + $this->assertEquals( [ 1000 ], $delays ); + } + + public function testRetriesSomeMediawikiApiErrorHeaders() { + $queue = [ + new Response( 200, [ 'mediawiki-api-error' => 'ratelimited' ] ), + new Response( 200, [ 'mediawiki-api-error' => 'maxlag' ] ), + new Response( 200, [ 'mediawiki-api-error' => 'readonly' ] ), + new Response( 200, [ 'mediawiki-api-error' => 'internal_api_error_DBQueryError' ] ), + new Response( 200, [ 'mediawiki-api-error' => 'DoNotRetryThisHeader' ] ), + ]; + + $client = $this->getClient( $queue, $delays ); + $response = $client->request( 'GET', '/' ); + + $this->assertEquals( 200, $response->getStatusCode() ); + $this->assertEquals( + [ 'DoNotRetryThisHeader' ], + $response->getHeader( 'mediawiki-api-error' ) + ); + $this->assertEquals( [ 1000, 2000, 3000, 4000 ], $delays ); + } + + public function testRetryAntiAbuseMeasure() { + $antiAbusejson = json_encode( + [ + 'error' => [ + 'info' => 'anti-abuse measure' + ] + ] + ); + + $queue = [ + new Response( 200, [ 'mediawiki-api-error' => 'failed-save' ], $antiAbusejson ), + new Response( 200, [ 'mediawiki-api-error' => 'DoNotRetryThisHeader' ] ), + ]; + + $client = $this->getClient( $queue, $delays ); + $response = $client->request( 'GET', '/' ); + + $this->assertEquals( 200, $response->getStatusCode() ); + $this->assertEquals( 'DoNotRetryThisHeader', $response->getHeaderLine( 'mediawiki-api-error' ) ); + } + + public function testRetryLimit() { + $queue = [ + new ConnectException( 'Error 1', new Request( 'GET', 'test' ) ), + new ConnectException( 'Error 2', new Request( 'GET', 'test' ) ), + new ConnectException( 'Error 3', new Request( 'GET', 'test' ) ), + new ConnectException( 'Error 4', new Request( 'GET', 'test' ) ), + new ConnectException( 'Error 5', new Request( 'GET', 'test' ) ), + new ConnectException( 'Error 6', new Request( 'GET', 'test' ) ), + new Response( 200 ), + ]; + + $client = $this->getClient( $queue ); + + $this->setExpectedException( + 'GuzzleHttp\Exception\ConnectException', + 'Error 6' + ); + + $client->request( 'GET', '/' ); + } + + public function testConnectExceptionRetryDelay() { + $queue = [ + new ConnectException( '+1 second delay', new Request( 'GET', 'test' ) ), + new ConnectException( '+2 second delay', new Request( 'GET', 'test' ) ), + new Response( 200 ), + ]; + + $client = $this->getClient( $queue, $delays ); + $response = $client->request( 'GET', '/' ); + + $this->assertEquals( 200, $response->getStatusCode() ); + $this->assertEquals( [ 1000, 2000 ], $delays ); + } + + public function testServerErrorRetryDelay() { + $queue = [ + new Response( 500 ), + new Response( 503 ), + new Response( 200 ), + ]; + + $client = $this->getClient( $queue, $delays ); + $response = $client->request( 'GET', '/' ); + + $this->assertEquals( 200, $response->getStatusCode() ); + $this->assertEquals( [ 1000, 2000 ], $delays ); + } + + public function testRelativeRetryDelayHeaderRetryDelay() { + $queue = [ + new Response( 200, [ 'mediawiki-api-error' => 'maxlag', 'retry-after' => 10 ] ), + new Response( 200 ), + ]; + + $this->getClient( $queue, $delays )->request( 'GET', '/' ); + + $this->assertEquals( [ 10000 ], $delays ); + } + + public function testAbsoluteRetryDelayHeaderRetryDelay() { + $queue = [ + new Response( + 200, + [ + 'mediawiki-api-error' => 'maxlag', + 'retry-after' => gmdate( DATE_RFC1123, time() + 600 ), + ] + ), + new Response( 200 ), + ]; + + $client = $this->getClient( $queue, $delays ); + $response = $client->request( 'GET', '/' ); + + $this->assertEquals( 200, $response->getStatusCode() ); + $this->assertCount( 1, $delays ); + // Allow 5 second delay while running this test. + $this->assertGreaterThan( 600000 - 5000, $delays[0] ); + } + + public function testPastRetryDelayHeaderRetryDelay() { + $queue = [ + new Response( + 200, + [ + 'mediawiki-api-error' => 'maxlag', + 'retry-after' => 'Fri, 31 Dec 1999 23:59:59 GMT', + ] + ), + new Response( 200 ), + ]; + + $client = $this->getClient( $queue, $delays ); + $response = $client->request( 'GET', '/' ); + + $this->assertEquals( 200, $response->getStatusCode() ); + $this->assertEquals( [ 1000 ], $delays ); + } + + private function getClient( array $queue, &$delays = null ) { + $mock = new MockHandler( $queue ); + + $handler = HandlerStack::create( $mock ); + + $middlewareFactory = new MiddlewareFactory(); + $handler->push( $middlewareFactory->retry() ); + + $delayMocker = $this->getDelayMocker( $delays ); + $handler->push( $delayMocker ); + + return new Client( [ 'handler' => $handler ] ); + } + + private function getDelayMocker( &$delays ) { + return function ( callable $handler ) use ( &$delays ) { + return function ( $request, array $options ) use ( $handler, &$delays ) { + if ( isset( $options['delay'] ) ) { + $delays[] = $options['delay']; + unset( $options['delay'] ); + } + return $handler( $request, $options ); + }; + }; + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/MediawikiApiTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/MediawikiApiTest.php new file mode 100644 index 00000000..a55f6739 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/MediawikiApiTest.php @@ -0,0 +1,296 @@ +<?php + +namespace Mediawiki\Api\Test\Unit; + +use Mediawiki\Api\ApiUser; +use Mediawiki\Api\MediawikiApi; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\Api\UsageException; +use PHPUnit_Framework_TestCase; +use stdClass; + +/** + * @author Addshore + * + * @covers Mediawiki\Api\MediawikiApi + */ +class MediawikiApiTest extends PHPUnit_Framework_TestCase { + + public function provideValidConstruction() { + return [ + [ 'localhost' ], + [ 'http://en.wikipedia.org/w/api.php' ], + [ '127.0.0.1/foo/bar/wwwwwwwww/api.php' ], + ]; + } + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $apiLocation ) { + new MediawikiApi( $apiLocation ); + $this->assertTrue( true ); + } + + public function provideInvalidConstruction() { + return [ + [ null ], + [ 12345678 ], + [ [] ], + [ new stdClass() ], + ]; + } + + /** + * @dataProvider provideInvalidConstruction + */ + public function testInvalidConstruction( $apiLocation ) { + $this->setExpectedException( 'InvalidArgumentException' ); + new MediawikiApi( $apiLocation ); + } + + private function getMockClient() { + return $this->getMock( 'GuzzleHttp\ClientInterface' ); + } + + private function getMockResponse( $responseValue ) { + $mock = $this->getMock( 'Psr\Http\Message\ResponseInterface' ); + $mock->expects( $this->any() ) + ->method( 'getBody' ) + ->will( $this->returnValue( json_encode( $responseValue ) ) ); + return $mock; + } + + private function getExpectedRequestOpts( $params, $paramsLocation ) { + return [ + $paramsLocation => array_merge( $params, [ 'format' => 'json' ] ), + 'headers' => [ 'User-Agent' => 'addwiki-mediawiki-client' ], + ]; + } + + public function testGetRequestThrowsUsageExceptionOnError() { + $client = $this->getMockClient(); + $client->expects( $this->once() ) + ->method( 'request' ) + ->will( $this->returnValue( + $this->getMockResponse( [ 'error' => [ + 'code' => 'imacode', + 'info' => 'imamsg', + ] ] ) + ) ); + $api = new MediawikiApi( '', $client ); + + try{ + $api->getRequest( new SimpleRequest( 'foo' ) ); + $this->fail( 'No Usage Exception Thrown' ); + } + catch ( UsageException $e ) { + $this->assertEquals( 'imacode', $e->getApiCode() ); + $this->assertEquals( 'imamsg', $e->getRawMessage() ); + } + } + + public function testPostRequestThrowsUsageExceptionOnError() { + $client = $this->getMockClient(); + $client->expects( $this->once() ) + ->method( 'request' ) + ->will( $this->returnValue( + $this->getMockResponse( [ 'error' => [ + 'code' => 'imacode', + 'info' => 'imamsg', + ] ] ) + ) ); + $api = new MediawikiApi( '', $client ); + + try{ + $api->postRequest( new SimpleRequest( 'foo' ) ); + $this->fail( 'No Usage Exception Thrown' ); + } + catch ( UsageException $e ) { + $this->assertSame( 'imacode', $e->getApiCode() ); + $this->assertSame( 'imamsg', $e->getRawMessage() ); + } + } + + /** + * @dataProvider provideActionsParamsResults + */ + public function testGetActionReturnsResult( $expectedResult, $action, $params = [] ) { + $client = $this->getMockClient(); + $params = array_merge( [ 'action' => $action ], $params ); + $client->expects( $this->once() ) + ->method( 'request' ) + ->with( 'GET', null, $this->getExpectedRequestOpts( $params, 'query' ) ) + ->will( $this->returnValue( $this->getMockResponse( $expectedResult ) ) ); + $api = new MediawikiApi( '', $client ); + + $result = $api->getRequest( new SimpleRequest( $action, $params ) ); + + $this->assertEquals( $expectedResult, $result ); + } + + /** + * @dataProvider provideActionsParamsResults + */ + public function testPostActionReturnsResult( $expectedResult, $action, $params = [] ) { + $client = $this->getMockClient(); + $params = array_merge( [ 'action' => $action ], $params ); + $client->expects( $this->once() ) + ->method( 'request' ) + ->with( 'POST', null, $this->getExpectedRequestOpts( $params, 'form_params' ) ) + ->will( $this->returnValue( $this->getMockResponse( $expectedResult ) ) ); + $api = new MediawikiApi( '', $client ); + + $result = $api->postRequest( new SimpleRequest( $action, $params ) ); + + $this->assertEquals( $expectedResult, $result ); + } + + private function getNullFilePointer() { + if ( !file_exists( '/dev/null' ) ) { + // windows + return fopen( 'NUL', 'r' ); + } + return fopen( '/dev/null', 'r' ); + } + + public function testPostActionWithFileReturnsResult() { + $dummyFile = $this->getNullFilePointer(); + $params = [ + 'filename' => 'foo.jpg', + 'file' => $dummyFile, + ]; + $client = $this->getMockClient(); + $client->expects( $this->once() )->method( 'request' )->with( + 'POST', + null, + [ + 'multipart' => [ + [ 'name' => 'action', 'contents' => 'upload' ], + [ 'name' => 'filename', 'contents' => 'foo.jpg' ], + [ 'name' => 'file', 'contents' => $dummyFile ], + [ 'name' => 'format', 'contents' => 'json' ], + ], + 'headers' => [ 'User-Agent' => 'addwiki-mediawiki-client' ], + ] + )->will( $this->returnValue( $this->getMockResponse( [ 'success ' => 1 ] ) ) ); + $api = new MediawikiApi( '', $client ); + + $result = $api->postRequest( new SimpleRequest( 'upload', $params ) ); + + $this->assertEquals( [ 'success ' => 1 ], $result ); + } + + public function provideActionsParamsResults() { + return [ + [ [ 'key' => 'value' ], 'logout' ], + [ [ 'key' => 'value' ], 'logout', [ 'param1' => 'v1' ] ], + [ [ 'key' => 'value', 'key2' => 1212, [] ], 'logout' ], + ]; + } + + public function testGoodLoginSequence() { + $client = $this->getMockClient(); + $user = new ApiUser( 'U1', 'P1' ); + $eq1 = [ + 'action' => 'login', + 'lgname' => 'U1', + 'lgpassword' => 'P1', + ]; + $client->expects( $this->at( 0 ) ) + ->method( 'request' ) + ->with( 'POST', null, $this->getExpectedRequestOpts( $eq1, 'form_params' ) ) + ->will( $this->returnValue( $this->getMockResponse( [ 'login' => [ + 'result' => 'NeedToken', + 'token' => 'IamLoginTK', + ] ] ) ) ); + $params = array_merge( $eq1, [ 'lgtoken' => 'IamLoginTK' ] ); + $response = $this->getMockResponse( [ 'login' => [ 'result' => 'Success' ] ] ); + $client->expects( $this->at( 1 ) ) + ->method( 'request' ) + ->with( 'POST', null, $this->getExpectedRequestOpts( $params, 'form_params' ) ) + ->will( $this->returnValue( $response ) ); + $api = new MediawikiApi( '', $client ); + + $this->assertTrue( $api->login( $user ) ); + $this->assertSame( 'U1', $api->isLoggedin() ); + } + + public function testBadLoginSequence() { + $client = $this->getMockClient(); + $user = new ApiUser( 'U1', 'P1' ); + $eq1 = [ + 'action' => 'login', + 'lgname' => 'U1', + 'lgpassword' => 'P1', + ]; + $client->expects( $this->at( 0 ) ) + ->method( 'request' ) + ->with( 'POST', null, $this->getExpectedRequestOpts( $eq1, 'form_params' ) ) + ->will( $this->returnValue( $this->getMockResponse( [ 'login' => [ + 'result' => 'NeedToken', + 'token' => 'IamLoginTK', + ] ] ) ) ); + $params = array_merge( $eq1, [ 'lgtoken' => 'IamLoginTK' ] ); + $response = $this->getMockResponse( [ 'login' => [ 'result' => 'BADTOKENorsmthin' ] ] ); + $client->expects( $this->at( 1 ) ) + ->method( 'request' ) + ->with( 'POST', null, $this->getExpectedRequestOpts( $params, 'form_params' ) ) + ->will( $this->returnValue( $response ) ); + $api = new MediawikiApi( '', $client ); + + $this->setExpectedException( 'Mediawiki\Api\UsageException' ); + $api->login( $user ); + } + + public function testLogout() { + $client = $this->getMockClient(); + $client->expects( $this->at( 0 ) ) + ->method( 'request' ) + ->with( 'POST', null, $this->getExpectedRequestOpts( [ 'action' => 'logout' ], 'form_params' ) ) + ->will( $this->returnValue( $this->getMockResponse( [] ) ) ); + $api = new MediawikiApi( '', $client ); + + $this->assertTrue( $api->logout() ); + } + + public function testLogoutOnFailure() { + $client = $this->getMockClient(); + $client->expects( $this->at( 0 ) ) + ->method( 'request' ) + ->with( 'POST', null, $this->getExpectedRequestOpts( [ 'action' => 'logout' ], 'form_params' ) ) + ->will( $this->returnValue( $this->getMockResponse( null ) ) ); + $api = new MediawikiApi( '', $client ); + + $this->assertFalse( $api->logout() ); + } + + /** + * @dataProvider provideVersions + */ + public function testGetVersion( $apiValue, $expectedVersion ) { + $client = $this->getMockClient(); + $params = [ 'action' => 'query', 'meta' => 'siteinfo', 'continue' => '' ]; + $client->expects( $this->exactly( 1 ) ) + ->method( 'request' ) + ->with( 'GET', null, $this->getExpectedRequestOpts( $params, 'query' ) ) + ->will( $this->returnValue( $this->getMockResponse( [ + 'query' => [ + 'general' => [ + 'generator' => $apiValue, + ], + ], + ] ) ) ); + $api = new MediawikiApi( '', $client ); + $this->assertEquals( $expectedVersion, $api->getVersion() ); + } + + public function provideVersions() { + return [ + [ 'MediaWiki 1.25wmf13', '1.25' ], + [ 'MediaWiki 1.24.1', '1.24.1' ], + [ 'MediaWiki 1.19', '1.19' ], + [ 'MediaWiki 1.0.0', '1.0.0' ], + ]; + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/MediawikiSessionTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/MediawikiSessionTest.php new file mode 100644 index 00000000..667a526f --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/MediawikiSessionTest.php @@ -0,0 +1,95 @@ +<?php + +namespace Mediawiki\Api\Test\Unit; + +use Mediawiki\Api\MediawikiApi; +use Mediawiki\Api\MediawikiSession; +use PHPUnit_Framework_MockObject_MockObject; +use PHPUnit_Framework_TestCase; + +/** + * @author Addshore + * + * @covers Mediawiki\Api\MediawikiSession + */ +class MediawikiSessionTest extends PHPUnit_Framework_TestCase { + + /** + * @return PHPUnit_Framework_MockObject_MockObject|MediawikiApi + */ + private function getMockApi() { + return $this->getMockBuilder( '\Mediawiki\Api\MediawikiApi' ) + ->disableOriginalConstructor() + ->getMock(); + } + + public function testConstruction() { + $session = new MediawikiSession( $this->getMockApi() ); + $this->assertInstanceOf( '\Mediawiki\Api\MediawikiSession', $session ); + } + + /** + * @dataProvider provideTokenTypes + */ + public function testGetToken( $tokenType ) { + $mockApi = $this->getMockApi(); + $mockApi->expects( $this->exactly( 2 ) ) + ->method( 'postRequest' ) + ->with( $this->isInstanceOf( '\Mediawiki\Api\SimpleRequest' ) ) + ->will( $this->returnValue( [ + 'query' => [ + 'tokens' => [ + $tokenType => 'TKN-' . $tokenType, + ] + ] + ] ) ); + + $session = new MediawikiSession( $mockApi ); + + // Although we make 2 calls to the method we assert the tokens method about is only called once + $this->assertEquals( 'TKN-' . $tokenType, $session->getToken() ); + $this->assertEquals( 'TKN-' . $tokenType, $session->getToken() ); + // Then clearing the tokens and calling again should make a second call! + $session->clearTokens(); + $this->assertEquals( 'TKN-' . $tokenType, $session->getToken() ); + } + + /** + * @dataProvider provideTokenTypes + */ + public function testGetTokenPre125( $tokenType ) { + $mockApi = $this->getMockApi(); + $mockApi->expects( $this->at( 0 ) ) + ->method( 'postRequest' ) + ->with( $this->isInstanceOf( '\Mediawiki\Api\SimpleRequest' ) ) + ->will( $this->returnValue( [ + 'warnings' => [ + 'query' => [ + '*' => "Unrecognized value for parameter 'meta': tokens", + ] + ] + ] ) ); + $mockApi->expects( $this->at( 1 ) ) + ->method( 'postRequest' ) + ->with( $this->isInstanceOf( '\Mediawiki\Api\SimpleRequest' ) ) + ->will( $this->returnValue( [ + 'tokens' => [ + $tokenType => 'TKN-' . $tokenType, + ] + ] ) ); + + $session = new MediawikiSession( $mockApi ); + + // Although we make 2 calls to the method we assert the tokens method about is only called once + $this->assertSame( 'TKN-' . $tokenType, $session->getToken() ); + $this->assertSame( 'TKN-' . $tokenType, $session->getToken() ); + } + + public function provideTokenTypes() { + return [ + [ 'csrf' ], + [ 'edit' ], + ]; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/MultipartRequestTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/MultipartRequestTest.php new file mode 100644 index 00000000..993c29e8 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/MultipartRequestTest.php @@ -0,0 +1,44 @@ +<?php + +namespace Mediawiki\Api\Test\Unit; + +use Exception; +use Mediawiki\Api\MultipartRequest; +use PHPUnit_Framework_TestCase; + +class MultipartRequestTest extends PHPUnit_Framework_TestCase { + + public function testBasics() { + $request = new MultipartRequest(); + $this->assertEquals( [], $request->getMultipartParams() ); + + // One parameter. + $request->setParam( 'testparam', 'value' ); + $request->addMultipartParams( [ 'testparam' => [ 'lorem' => 'ipsum' ] ] ); + $this->assertEquals( + [ 'testparam' => [ 'lorem' => 'ipsum' ] ], + $request->getMultipartParams() + ); + + // Another parameter. + $request->setParam( 'testparam2', 'value' ); + $request->addMultipartParams( [ 'testparam2' => [ 'lorem2' => 'ipsum2' ] ] ); + $this->assertEquals( + [ + 'testparam' => [ 'lorem' => 'ipsum' ], + 'testparam2' => [ 'lorem2' => 'ipsum2' ], + ], + $request->getMultipartParams() + ); + } + + /** + * You are not allowed to set multipart parameters on a parameter that doesn't exist. + * @expectedException Exception + * @expectedExceptionMessage Parameter 'testparam' is not already set on this request. + */ + public function testParamNotYetSet() { + $request = new MultipartRequest(); + $request->addMultipartParams( [ 'testparam' => [] ] ); + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/SimpleRequestTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/SimpleRequestTest.php new file mode 100644 index 00000000..df979992 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/SimpleRequestTest.php @@ -0,0 +1,49 @@ +<?php + +namespace Mediawiki\Api\Test\Unit; + +use Mediawiki\Api\SimpleRequest; +use PHPUnit_Framework_TestCase; + +/** + * @author Addshore + * + * @covers Mediawiki\Api\SimpleRequest + */ +class SimpleRequestTest extends PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $action, $params, $expected, $headers = [] ) { + $request = new SimpleRequest( $action, $params, $headers ); + $this->assertEquals( $expected, $request->getParams() ); + $this->assertEquals( $headers, $request->getHeaders() ); + } + + public function provideValidConstruction() { + return [ + [ 'action', [], [ 'action' => 'action' ] ], + [ '1123', [], [ 'action' => '1123' ] ], + [ 'a', [ 'b' => 'c' ], [ 'action' => 'a', 'b' => 'c' ] ], + [ 'a', [ 'b' => 'c', 'd' => 'e' ], [ 'action' => 'a', 'b' => 'c', 'd' => 'e' ] ], + [ 'a', [ 'b' => 'c|d|e|f' ], [ 'action' => 'a', 'b' => 'c|d|e|f' ] ], + [ 'foo', [], [ 'action' => 'foo' ] ,[ 'foo' => 'bar' ] ], + ]; + } + + /** + * @dataProvider provideInvalidConstruction + */ + public function testInvalidConstruction( $action, $params ) { + $this->setExpectedException( 'InvalidArgumentException' ); + new SimpleRequest( $action, $params ); + } + + public function provideInvalidConstruction() { + return [ + [ [], [] ], + ]; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/UsageExceptionTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/UsageExceptionTest.php new file mode 100644 index 00000000..2b7d6072 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api-base/tests/Unit/UsageExceptionTest.php @@ -0,0 +1,39 @@ +<?php + +namespace Mediawiki\Api\Test\Unit; + +use Mediawiki\Api\UsageException; +use PHPUnit_Framework_TestCase; + +/** + * @author Addshore + * + * @covers Mediawiki\Api\UsageException + */ +class UsageExceptionTest extends PHPUnit_Framework_TestCase { + + public function testUsageExceptionWithNoParams() { + $e = new UsageException(); + $this->assertSame( + 'Code: ' . PHP_EOL . + 'Message: ' . PHP_EOL . + 'Result: []', + $e->getMessage() + ); + $this->assertSame( '', $e->getApiCode() ); + $this->assertEquals( [], $e->getApiResult() ); + } + + public function testUsageExceptionWithParams() { + $e = new UsageException( 'imacode', 'imamsg', [ 'foo' => 'bar' ] ); + $this->assertSame( 'imacode', $e->getApiCode() ); + $this->assertSame( + 'Code: imacode' . PHP_EOL . + 'Message: imamsg' . PHP_EOL . + 'Result: {"foo":"bar"}', + $e->getMessage() + ); + $this->assertEquals( [ 'foo' => 'bar' ], $e->getApiResult() ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/.gitignore b/bin/reevotech/vendor/addwiki/mediawiki-api/.gitignore new file mode 100644 index 00000000..2bd8a05e --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/.gitignore @@ -0,0 +1,9 @@ +.idea +vendor +composer.lock +test.php +phpunit.xml +nbproject +docs/_build +log + diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/.scrutinizer.yml b/bin/reevotech/vendor/addwiki/mediawiki-api/.scrutinizer.yml new file mode 100644 index 00000000..ffc976e3 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/.scrutinizer.yml @@ -0,0 +1,13 @@ +inherit: true + +tools: + 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 + external_code_coverage: + timeout: 300
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/.travis.yml b/bin/reevotech/vendor/addwiki/mediawiki-api/.travis.yml new file mode 100644 index 00000000..26793151 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/.travis.yml @@ -0,0 +1,52 @@ +language: php + +php: + - 5.5 + - 5.6 + - 7.0 + +env: + matrix: + - TEST_SUITE=unit + # All the currently-supported versions from https://www.mediawiki.org/wiki/Version_lifecycle + - TEST_SUITE=integration MEDIAWIKI_VERSION=1.26.4 + - TEST_SUITE=integration MEDIAWIKI_VERSION=1.27.3 + - TEST_SUITE=integration MEDIAWIKI_VERSION=1.28.2 + - TEST_SUITE=integration MEDIAWIKI_VERSION=1.29.1 + global: + - MEDIAWIKI_API_URL='http://127.0.0.1:8081/api.php' + +matrix: + include: + - php: hhvm + env: TEST_SUITE=unit + before_install: + install: + - composer install + - php: 7.1 + env: TEST_SUITE=unit + before_install: + install: + - composer install + +before_install: + - bin/install-mediawiki.sh + +install: + - php -S 127.0.0.1:8081 -t build/mediawiki >/dev/null 2>&1 & + - composer install + +script: + - $TRAVIS_BUILD_DIR/vendor/bin/phpunit --coverage-clover=$TRAVIS_BUILD_DIR/coverage.clover $TRAVIS_BUILD_DIR/tests/$TEST_SUITE + - $TRAVIS_BUILD_DIR/vendor/bin/phpcs + +after_script: + - wget https://scrutinizer-ci.com/ocular.phar + - php ocular.phar code-coverage:upload --format=php-clover $TRAVIS_BUILD_DIR/coverage.clover + +notifications: + irc: + channels: + - "chat.freenode.net##add" + on_success: change + on_failure: always diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/LICENSE.md b/bin/reevotech/vendor/addwiki/mediawiki-api/LICENSE.md new file mode 100644 index 00000000..0671f06a --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/LICENSE.md @@ -0,0 +1,264 @@ +The GNU General Public License, Version 2, June 1991 (GPLv2) +============================================================ + +> 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 Library 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. + + +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. diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/README.md b/bin/reevotech/vendor/addwiki/mediawiki-api/README.md new file mode 100644 index 00000000..325958fc --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/README.md @@ -0,0 +1,74 @@ +mediawiki-api +================== +[](https://travis-ci.org/addwiki/mediawiki-api) +[](https://scrutinizer-ci.com/g/addwiki/mediawiki-api/) +[](https://scrutinizer-ci.com/g/addwiki/mediawiki-api/) +[](https://www.versioneye.com/user/projects/54b92f798d55087422000030) + +On Packagist: +[](https://packagist.org/packages/addwiki/mediawiki-api) +[](https://packagist.org/packages/addwiki/mediawiki-api) + +Issue tracker: https://phabricator.wikimedia.org/project/profile/1490/ + +## Installation + +Use composer to install the library and all its dependencies: + + composer require "addwiki/mediawiki-api:~0.7.0" + +## Example Usage + +```php +// Load all the stuff +require_once( __DIR__ . '/vendor/autoload.php' ); + +// Log in to a wiki +$api = new \Mediawiki\Api\MediawikiApi( 'http://localhost/w/api.php' ); +$api->login( new \Mediawiki\Api\ApiUser( 'username', 'password' ) ); +$services = new \Mediawiki\Api\MediawikiFactory( $api ); + +// Get a page +$page = $services->newPageGetter()->getFromTitle( 'Foo' ); + +// Edit a page +$content = new \Mediawiki\DataModel\Content( 'New Text' ); +$revision = new \Mediawiki\DataModel\Revision( $content, $page->getPageIdentifier() ); +$services->newRevisionSaver()->save( $revision ); + +// Move a page +$services->newPageMover()->move( + $services->newPageGetter()->getFromTitle( 'FooBar' ), + new Title( 'FooBar' ) +); + +// Delete a page +$services->newPageDeleter()->delete( + $services->newPageGetter()->getFromTitle( 'DeleteMe!' ), + array( 'reason' => 'Reason for Deletion' ) +); + +// Create a new page +$newContent = new \Mediawiki\DataModel\Content( 'Hello World' ); +$title = new \Mediawiki\DataModel\Title( 'New Page' ); +$identifier = new \Mediawiki\DataModel\PageIdentifier( $title ); +$revision = new \Mediawiki\DataModel\Revision( $newContent, $identifier ); +$services->newRevisionSaver()->save( $revision ); + +// List all pages in a category +$pages = $services->newPageListGetter()->getPageListFromCategoryName( 'Category:Cat name' ); +``` + +## Running the integration tests + +To run the integration tests, you need to have a running MediaWiki instance. The tests will create pages and categories without using a user account so it's best if you use a test instance. Furthermore you need to turn off rate limiting by adding the line + + $wgGroupPermissions['*']['noratelimit'] = true; + +to the `LocalSettings.php` of your MediaWiki. + +By default, the tests will use the URL `http://localhost/w/api.php` as the API endpoint. If you have a different URL (e.g. `http://localhost:8080/w/api.php`), you need to configure the URL as an environemnt variable before running the tests. Example: + + export MEDIAWIKI_API_URL='http://localhost:8080/w/api.php' + +**Warning:** Running the integration tests can take a long time to complete. diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/RELEASENOTES.md b/bin/reevotech/vendor/addwiki/mediawiki-api/RELEASENOTES.md new file mode 100644 index 00000000..8d8bb9a1 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/RELEASENOTES.md @@ -0,0 +1,111 @@ +Release Notes +============= + +These are the release notes for [mediawiki-api](http://addwiki.readthedocs.io/projects/mediawiki-api/). + +## Version 0.7.2 (20th November 2017) + +* New parent class for all API service classes, + with protected access on `Service::$api` to make it easier to subclass any services. +* File uploading improved, with the option of [chunked uploading](https://www.mediawiki.org/wiki/API:Upload#Chunked_uploading). +* Various fixes and improvements to the testing set-up and coding standards. + +## Version 0.7.1 (8th March 2017) + +* Fixed dependancy on addwiki/mediawiki-datamodel + +## Version 0.7 (March 2017) + +* Documentation! This package now has a + [dedicated documentation website](https://addwiki.readthedocs.io/projects/mediawiki-api/). +* A new NamespaceGetter service with which you can get all namespaces, + or a single namespace by localised name, alias, or canonical name + ([#39](https://github.com/addwiki/mediawiki-api/pull/39), [#41](https://github.com/addwiki/mediawiki-api/pull/41)). +* A new CategoryTraverser service for descending (all levels of) category trees + and either retrieving all pages or performing some action on each page. +* A new method to PagePurger for purging multiple pages at once ([#36](https://github.com/addwiki/mediawiki-api/pull/36)). +* All methods of the PageListGetter now continue their queries where the first request doesn't retrieve the whole result set + ([#31](https://github.com/addwiki/mediawiki-api/pull/31)). +* Bug [#40](https://github.com/addwiki/mediawiki-api/pull/40) fixed with `RevisionSaver::save()` overwriting EditInfo if null. +* Integration tests: more documentation about how to run integration tests locally, + and the tests are running on Travis CI. +* Lots of fixes to coding-standards and in-code documentation. + +## Version 0.6 (3 August 2016) + +* Adds newParser method to factory +* Use the new API continuation mode +* Fix ignored bot assertion in EditInfo + +## Version 0.5.1 (7 September 2015) + +* Adds ApiGenerator interface +* Adds AnonymousGenerator implementation of Generator +* Adds FluentGenerator implementation of Generator + +## Version 0.5 (4 September 2015) + +####Breaks + +* LogListGetter now requires mediawiki verison 1.25 or above +* PageListGetter now requires mediawiki verison 1.25 or above +* Removed ALL Options objects + +####Additions + +* Introduces RevisionUndoer service +* Introduces UserCreator service +* Introduces FileUploader service +* Introduces ImageRotator service + +####Libs + +* Using mediawiki-api-base 1.0 +* Using mediawiki-datamodel 0.6 + +## Version 0.4 (13 January 2015) + +* Issue#8 PageListGetter methods now construct pages with a Title object rather than string +* Page(Deleter|ListGetter|Mover|Protector|Restorer), User(Blocker|RightsChanger) service methods now require an *Options object rather than a selection of parameters. +* Implemented PageListGetter::getRandom + +## Version 0.3 (2014-06-24) + +* Removes NewEditInfo and NewRevision +* Moved basic api functionality to a separate base lib (mediawiki-api-base) +* Repos renamed to Getters +* PageGetter, RevisionSaver and UserGetter moved to the Service Namespace +* Introduces MediawikiFactory +* Introduces PageDeleter service +* Introduces PageListGetter service +* Introduces PageProtector service +* Introduces PagePurger service +* Introduces RevisionDeleter service +* Introduces RevisionPatroller service +* Introduces RevisionRollbacker service +* Introduces UserBlocker service +* Introduces UserRightsChanger service +* Introduces PageRestorer service +* Introduces RevisionRestorer service +* Correctly handle non existent users in UserGetter + + +## Version 0.2 (2014-02-23) + +* Altered everything for changed in mediawiki-datamodel +* Removed Edit << action class +* Introduces NewEditInfo and NewRevision + + +## Version 0.1 (2014-02-23) + +Initial release with the following features: + +* MediawikiApi +* ApiUser +* MediawikiSession +* UsageExceptions +* PageRepo +* UserRepo +* EditSaver +* Edit << action diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/bin/install-mediawiki.sh b/bin/reevotech/vendor/addwiki/mediawiki-api/bin/install-mediawiki.sh new file mode 100755 index 00000000..030830ad --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/bin/install-mediawiki.sh @@ -0,0 +1,55 @@ +#!/bin/bash +## +## This script installs MediaWiki to ./build/mediawiki (relative to the directory from which it's called). +## + +## Check inputs. +if [ -z $MEDIAWIKI_VERSION ]; then + echo "You must specify the MEDIAWIKI_VERSION environment variable" + exit 0 +fi + +## Set some paths. +BUILDDIR=$(cd $(dirname "$0"); pwd -P)"/../build" +if [ ! -d $BUILDDIR ]; then + mkdir "$BUILDDIR" +fi +INSTALLDIR="$BUILDDIR/mediawiki" +if [ -d "$INSTALLDIR" ]; then + rm -r "$INSTALLDIR" +fi +echo "Installing MediaWiki $MEDIAWIKI_VERSION to $INSTALLDIR" + +## Get the required version, and unpack it to `./build/mediawiki`. +if [ ! -s "$BUILDDIR/$MEDIAWIKI_VERSION.tar.gz" ]; then + wget --directory-prefix="$BUILDDIR" "https://github.com/wikimedia/mediawiki/archive/$MEDIAWIKI_VERSION.tar.gz" +fi +cd "$BUILDDIR" +echo "Unpacking" +tar -zxf "$MEDIAWIKI_VERSION.tar.gz" +mv "mediawiki-$MEDIAWIKI_VERSION" $INSTALLDIR + +## Install MediaWiki. +cd "$INSTALLDIR" +WIKIDB="test_wiki1" +echo "Creating database as MySQL root user" +PASSARG="" +if [ -n "$DBPASS" ]; then + PASSARG="-p$DBPASS" +fi +mysql "$PASSARG" -uroot -e "DROP DATABASE IF EXISTS $WIKIDB" +mysql "$PASSARG" -uroot -e "CREATE DATABASE $WIKIDB" +echo "Updating dependencies (Composer)" +composer install +echo "Installing TestWiki1 wiki" +php maintenance/install.php --dbtype mysql --dbuser "root" --dbpass "$DBPASS" --dbname $WIKIDB --scriptpath "" --pass admin123 TestWiki1 admin + +# Add some extra configuration to LocalSettings.php +cat << 'EOF' >> "$INSTALLDIR/LocalSettings.php" +$wgEnableUploads = true; +$wgShowExceptionDetails = true; +$wgCacheDirectory = __DIR__."/images/tmp"; +$wgServer = "http://127.0.0.1:8081"; +$wgUsePathInfo = false; +$wgJobRunRate = 200; +EOF diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/composer.json b/bin/reevotech/vendor/addwiki/mediawiki-api/composer.json new file mode 100644 index 00000000..f49a19ca --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/composer.json @@ -0,0 +1,44 @@ +{ + "name": "addwiki/mediawiki-api", + "type": "library", + "description": "A MediaWiki API library", + "keywords": ["Mediawiki"], + "license": "GPL-2.0+", + "authors": [ + { + "name": "Addshore" + } + ], + "require": { + "addwiki/mediawiki-api-base": "~2.4", + "addwiki/mediawiki-datamodel": "~0.7.0" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "^0.9.2", + "mediawiki/mediawiki-codesniffer": "^13.0", + "phpunit/phpunit": "~4.8", + "monolog/monolog": "^1.23" + }, + "autoload": { + "psr-4": { + "Mediawiki\\Api\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Mediawiki\\Api\\Test\\": ["tests/integration", "tests/unit"] + } + }, + "extra": { + "branch-alias": { + "dev-master": "0.7.x-dev" + } + }, + "scripts": { + "fix": "phpcbf", + "test": [ + "parallel-lint . --exclude vendor", + "phpcs -ps" + ] + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/docs/Makefile b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/Makefile new file mode 100644 index 00000000..46208266 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/Makefile @@ -0,0 +1,225 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " applehelp to make an Apple Help Book" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " epub3 to make an epub3" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " coverage to run coverage check of the documentation (if enabled)" + @echo " dummy to check syntax errors of document sources" + +.PHONY: clean +clean: + rm -rf $(BUILDDIR)/* + +.PHONY: html +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +.PHONY: dirhtml +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +.PHONY: singlehtml +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +.PHONY: pickle +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +.PHONY: json +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +.PHONY: htmlhelp +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +.PHONY: qthelp +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/mediawiki-api.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/mediawiki-api.qhc" + +.PHONY: applehelp +applehelp: + $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp + @echo + @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." + @echo "N.B. You won't be able to view it unless you put it in" \ + "~/Library/Documentation/Help or install it in your application" \ + "bundle." + +.PHONY: devhelp +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/mediawiki-api" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/mediawiki-api" + @echo "# devhelp" + +.PHONY: epub +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +.PHONY: epub3 +epub3: + $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 + @echo + @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." + +.PHONY: latex +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +.PHONY: latexpdf +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: latexpdfja +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: text +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +.PHONY: man +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +.PHONY: texinfo +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +.PHONY: info +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +.PHONY: gettext +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +.PHONY: changes +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +.PHONY: linkcheck +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +.PHONY: doctest +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +.PHONY: coverage +coverage: + $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage + @echo "Testing of coverage in the sources finished, look at the " \ + "results in $(BUILDDIR)/coverage/python.txt." + +.PHONY: xml +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +.PHONY: pseudoxml +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." + +.PHONY: dummy +dummy: + $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy + @echo + @echo "Build finished. Dummy builder generates no files." diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/docs/category_traverser.rst b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/category_traverser.rst new file mode 100644 index 00000000..497398e8 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/category_traverser.rst @@ -0,0 +1,28 @@ +Category Traversal +================== + +The CategoryTraverser class is used to start at one Category page in a wiki's category hierarchy +and descend through that category's children, grandchildren, and so on. +The basic output of this is a Pages object containing all the pages in the category tree. +It is also possible to register callbacks that will be called +for every subcategory or other page (i.e. anything not a category). + +Basic usage +----------- + +To get all pages in a category or any of its subcategories. + +.. code-block:: php + :linenos: + + // Construct the API. + $api = new \Mediawiki\Api\MediawikiApi( 'http://localhost/w/api.php' ); + $services = new \Mediawiki\Api\MediawikiFactory( $api ); + $categoryTraverser = $services->newCategoryTraverser(); + + // Get the root category. + $rootCatIdent = new PageIdentifier( new Title( 'Category:Categories' ) ); + $rootCat = $this->factory->newPageGetter()->getFromPageIdentifier( $pageIdentifier ); + + // Get all pages. + $allPages = $categoryTraverser->descend( $rootCat ); diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/docs/conf.py b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/conf.py new file mode 100644 index 00000000..3310f585 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/conf.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +import sys, os +from sphinx.highlighting import lexers +from pygments.lexers.web import PhpLexer + +lexers['php'] = PhpLexer(startinline=True, linenos=1) +lexers['php-annotations'] = PhpLexer(startinline=True, linenos=1) +primary_domain = 'php' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'mediawiki-api' +copyright = '2016, addwiki' +author = 'addwiki' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.6' +# The full version, including alpha/beta/rc tags. +release = '0.6' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'default' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Output file base name for HTML help builder. +htmlhelp_basename = 'mediawiki-apidoc' diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/docs/contributing.rst b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/contributing.rst new file mode 100644 index 00000000..c2cd2813 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/contributing.rst @@ -0,0 +1,44 @@ +Contributing +============ + +We welcome all contributions, be they code, documentation, or even just ideas about how to make this package better! + +The best way to get started is to browse the `#addwiki board on Phabricator`_ +and either work on one of the tasks already there or create a new one with details of what you want to work on. + +.. _Addwiki board on Phabricator: https://phabricator.wikimedia.org/tag/addwiki/ + +Get the code +------------ + +The code is `hosted on GitHub`_. Clone the repository with:: + + $ git clone https://github.com/addwiki/mediawiki-api.git + +.. _hosted on GitHub: https://github.com/addwiki/mediawiki-api + +Run the tests +------------- + +After cloning the repository and updating the dependencies with Composer, +you should be able to run all **unit** tests with:: + + ./vendor/bin/phpunit ./tests/unit + +To run the **integration** tests you need to set up a local MediaWiki installation +(including with a ``admin`` administrator user with password ``admin123``) +and tell ``phpunit`` where to find it. + +1. Copy ``./phpunit.xml.dist`` to ``./phpunit.xml`` and add the following section:: + + <php> + <env name="MEDIAWIKI_API_URL" value="http://localhost/path/to/your/wiki/api.php" /> + </php> + +2. Create and promote a new user:: + + $ php mediawiki/maintenance/createAndPromote.php --sysop WikiSysop wiki123sysop + +Now all integration tests can be run with:: + + ./vendor/bin/phpunit ./tests/integration diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/docs/file_uploader.rst b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/file_uploader.rst new file mode 100755 index 00000000..9f8b534f --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/file_uploader.rst @@ -0,0 +1,28 @@ +Uploading files +=============== + +Basic usage +----------- + +To upload a single, small-sized file: + +.. code-block:: php + :linenos: + + // Construct the API. + $api = new \Mediawiki\Api\MediawikiApi( 'http://localhost/w/api.php' ); + $services = new \Mediawiki\Api\MediawikiFactory( $api ); + $fileUploader = $services->newFileUploader(); + + // Upload the file. + $fileUploader->upload( 'The_file.png', '/full/path/to/the_file.png' ); + +If you need to work with larger files, you can switch to chunked uploading: + +.. code-block:: php + :linenos: + + // Upload the file in 10 MB chunks. + $fileUploader = $services->newFileUploader(); + $fileUploader->setChunkSize( 1024 * 1024 * 10 ); + $fileUploader->upload( 'The_file.png', '/full/path/to/the_file.png' ); diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/docs/index.rst b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/index.rst new file mode 100644 index 00000000..558107b3 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/index.rst @@ -0,0 +1,25 @@ +Documentation for addwiki/mediawiki-api +======================================= + +Welcome to the documentation for the ``addwiki/mediawiki-api`` package! +This is part of the Addwiki_ family of PHP packages. + +.. _Addwiki: http://addwiki.readthedocs.io/ + +Quick links: + +* This documentation: http://addwiki.readthedocs.io/projects/mediawiki-api/ +* Source code: https://github.com/addwiki/mediawiki-api/ +* Issue tracker: https://phabricator.wikimedia.org/project/profile/1490/ + +Contents +-------- + +.. toctree:: + :maxdepth: 2 + + page_list_getter.rst + category_traverser.rst + namespace_getter.rst + file_uploader.rst + contributing.rst diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/docs/make.bat b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/make.bat new file mode 100644 index 00000000..a5507331 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/make.bat @@ -0,0 +1,281 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^<target^>` where ^<target^> is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. epub3 to make an epub3 + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + echo. coverage to run coverage check of the documentation if enabled + echo. dummy to check syntax errors of document sources + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +REM Check if sphinx-build is available and fallback to Python version if any +%SPHINXBUILD% 1>NUL 2>NUL +if errorlevel 9009 goto sphinx_python +goto sphinx_ok + +:sphinx_python + +set SPHINXBUILD=python -m sphinx.__init__ +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +:sphinx_ok + + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\mediawiki-api.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\mediawiki-api.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "epub3" ( + %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3 + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub3 file is in %BUILDDIR%/epub3. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "coverage" ( + %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage + if errorlevel 1 exit /b 1 + echo. + echo.Testing of coverage in the sources finished, look at the ^ +results in %BUILDDIR%/coverage/python.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +if "%1" == "dummy" ( + %SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. Dummy builder generates no files. + goto end +) + +:end diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/docs/namespace_getter.rst b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/namespace_getter.rst new file mode 100644 index 00000000..c362833f --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/namespace_getter.rst @@ -0,0 +1,54 @@ +Getting Namespaces +================== + +The Name Space Getter allows you to search for namespaces and their aliases and to list all namespaces of a wiki. + +To use it, first get a new NamespaceGetter object from the factory: + +.. code-block:: php + + $api = new \Mediawiki\Api\MediawikiApi( 'http://localhost/w/api.php' ); + $services = new \Mediawiki\Api\MediawikiFactory( $api ); + $namespaceGetter = $services->newNamespaceGetter(); + + +Looking for a namespace +----------------------- + +If you've got a page name like ``File:awesome_cats.jpg`` and want to know its namespace ID and possible localized names +and aliases, use the following code: + +.. code-block:: php + + $fileNamespace = $namespaceGetter->getNamespaceByName( 'File' ); + printf( "Name in local language: %s\n", $fileNamespace->getLocalName() ); + printf( "Possible aliases: %s\n", implode( ', ', $fileNamespace->getAliases() ) ); + // ... etc + +``getNamespaceByName`` accepts the canonical name, the local name and aliases. If you want to match only the canonical +name, use ``getNamespaceByCanonicalName`` instead. + + +Getting a namespaced page +------------------------- + +If you have a page title that is not in the default namespace, you can't pass the page name string ``PageGetter`` but +must construct a ``Title`` object instead: + +.. code-block:: php + + $pageName = 'User:MalReynolds'; + $nameParts = explode( ':', $pageName, 2 ); + $namespace = $namespaceGetter->getNamespaceByName( $nameParts[0] ); + $title = new \Mediawiki\DataModel\Title( $nameParts[1], $namespace->getId() ); + $page = $services->newPageGetter()->getFromTitle( $title ); + + +Listing all namespaces +---------------------- + +.. code-block:: php + + foreach( $namespaceGetter->getNamespaces() as $namespace ) { + echo $namespace->getLocalName() . "\n"; + }
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/docs/page_list_getter.rst b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/page_list_getter.rst new file mode 100644 index 00000000..aad9f8a8 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/page_list_getter.rst @@ -0,0 +1,88 @@ +Page Lists +========== + +The Page List Getter allows you to retrieve lists of pages based on various criteria. +It takes care of continuing queries where they span multiple requests, +ensuring that you get all pages in your result set. +This means that for some lists of pages a great many requests will be sent, +and you should account for this possible performance problem when you request these lists +(e.g. by running these as a background process and caching the results). + +To use it, first get a new PageListGetter object from the factory: + +.. code-block:: php + + $api = new \Mediawiki\Api\MediawikiApi( 'http://localhost/w/api.php' ); + $services = new \Mediawiki\Api\MediawikiFactory( $api ); + $pageListGetter = $services->newPageListGetter(); + +The examples below all use this ``$pageListGetter`` object. + +All methods of the PageListGetter return ``Page`` objects; +this class is part of the `addwiki/mediawiki-datamodel`_ package, +and is documented in `that page's documentation`_. + +.. _addwiki/mediawiki-datamodel: https://packagist.org/packages/addwiki/mediawiki-datamodel +.. _that page's documentation: http://addwiki.readthedocs.io/projects/mediawiki-datamodel/ + +All pages in a category +----------------------- + +Note that the category name as provided should also include the 'Category' namespace prefix +(in the language of the wiki, or in canonical English form). + +.. code-block:: php + + $examplePages = $pageListGetter->getPageListFromCategoryName( 'Category:Example pages' ); + foreach ( $examplePages->asArray() as $exPage ) { + echo $exPage->getTitle()->getText(); + } + +Pages that transclude a template +-------------------------------- + +Although generally it is templates that are transcluded, +any page may be and so any page title can be passed to this method. + +.. code-block:: php + + $usingTestTemplate = $pageListGetter->getPageListFromPageTransclusions( 'Template:Test' ); + +Pages that link to a given page +------------------------------- + +Get the list of pages that link to a particular page. + +.. code-block:: php + + $backLinks = $pageListGetter->getFromWhatLinksHere( 'Test page' ); + +Pages with a given prefix +------------------------- + +Find pages that have a particular prefix to their title. +This can also be used to find subpages of any page. + +.. code-block:: php + + $backLinks = $pageListGetter->getFromPrefix( 'A page/' ); + +Random pages +------------ + +Get up to ten random pages at a time. +This method takes the same arguments as the API `list=random`_ query. + +.. _list=random: https://www.mediawiki.org/wiki/API:Random + +* ``rnlimit`` How many pages to get. No more than 10 (20 for bots) allowed. Default: 1. +* ``rnnamespace`` Pipe-separate list of namespace IDs. +* ``rnfilterredir`` How to filter for redirects. Possible values: ``all``, ``redirects``, ``nonredirects``. Default: ``nonredirects``. + +.. code-block:: php + + $backLinks = $pageListGetter->getRandom( [ + 'rnlimit' => 7, + 'rnnamespace' => '3|5|6', + 'rnfilterredir' => 'all', + ] ); diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/docs/page_purger.rst b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/page_purger.rst new file mode 100644 index 00000000..84cd7523 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/docs/page_purger.rst @@ -0,0 +1,34 @@ +Page Purger +=========== + +``PagePurger`` allows you to purge a single ``Page`` or multiple ``Pages``. +You can also check whether the ``Page`` or ``Pages`` have been purged successfully. + +To get started you need to create ``PagePurger`` object: + +.. code-block:: php + +$api = new \Mediawiki\Api\MediawikiApi( 'http://localhost/w/api.php' ); +$pagePurger = new \Mediawiki\Api\Service\PagePurger( $api ); + +Purge +----- + +Purge a single ``Page``. It will return a ``boolean`` that indicates if the purge operation was successful. + +Example: + +.. code-block:: php + +$page = new \Mediawiki\DataModel\Page(...); +$pagePurger->purge( $page ); + +PurgePages +---------- + +Purges every ``Page`` in the ``Pages`` object at once. It will return a new ``Pages`` object *with the purged ``Page``(s) only!* + +.. code-block:: php + +$pages = new \Mediawiki\DataModel\Pages(...); +$pagePurger->purgePages( $pages ); diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/phpcs.xml b/bin/reevotech/vendor/addwiki/mediawiki-api/phpcs.xml new file mode 100644 index 00000000..1c5b15ce --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/phpcs.xml @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<ruleset name="MediaWiki"> + <rule ref="vendor/mediawiki/mediawiki-codesniffer/MediaWiki"> + <exclude name="MediaWiki.Commenting.FunctionComment.MissingParamComment" /> + </rule> + <file>.</file> + <arg name="extensions" value="php,php5,inc"/> + <arg name="encoding" value="utf8"/> + <exclude-pattern>build/</exclude-pattern> + <exclude-pattern>vendor/</exclude-pattern> +</ruleset> diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/phpunit.xml.dist b/bin/reevotech/vendor/addwiki/mediawiki-api/phpunit.xml.dist new file mode 100755 index 00000000..f674132b --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/phpunit.xml.dist @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- convertWarningsToExceptions is false as real API calls can return un expected warnings --> +<phpunit + bootstrap="./vendor/autoload.php" + colors="true" + convertWarningsToExceptions="false" +> + <testsuites> + <testsuite> + <directory suffix="Test.php">./tests/integration</directory> + </testsuite> + <testsuite> + <directory suffix="Test.php">./tests/unit</directory> + </testsuite> + </testsuites> + <filter> + <whitelist addUncoveredFilesFromWhitelist="true"> + <directory suffix=".php">./src</directory> + </whitelist> + </filter> +</phpunit> diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/CategoryLoopException.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/CategoryLoopException.php new file mode 100644 index 00000000..9612f050 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/CategoryLoopException.php @@ -0,0 +1,32 @@ +<?php + +namespace Mediawiki\Api; + +use Mediawiki\DataModel\Pages; + +/** + * Class CategoryLoopException + * @package Mediawiki\Api + */ +class CategoryLoopException extends \Exception { + + /** @var Pages */ + protected $categoryPath; + + /** + * @param Pages $path + */ + public function setCategoryPath( Pages $path ) { + $this->categoryPath = $path; + } + + /** + * Get the path of Pages that comprise the category loop. The first item in this list is also a + * child page of the last item. + * @return Pages The set of category Pages that comprise the category loop. + */ + public function getCategoryPath() { + return $this->categoryPath; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Generator/AnonymousGenerator.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Generator/AnonymousGenerator.php new file mode 100644 index 00000000..715e3c02 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Generator/AnonymousGenerator.php @@ -0,0 +1,41 @@ +<?php + +namespace Mediawiki\Api\Generator; + +/** + * @access public + * + * @author Addshore + * + * @since 0.5.1 + */ +class AnonymousGenerator implements ApiGenerator { + + /** + * @var string + */ + private $name; + + /** + * @var array + */ + private $params; + + /** + * @param string $name + * @param array $params including 'g' prefix keys + */ + public function __construct( $name, array $params ) { + $this->name = $name; + $this->params = $params; + } + + /** + * @return array + */ + public function getParams() { + $params = $this->params; + $params['generator'] = $this->name; + return $params; + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Generator/ApiGenerator.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Generator/ApiGenerator.php new file mode 100644 index 00000000..923e98cd --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Generator/ApiGenerator.php @@ -0,0 +1,27 @@ +<?php + +namespace Mediawiki\Api\Generator; + +/** + * Interface relating to Mediawiki generators + * @see https://www.mediawiki.org/wiki/API:Query#Generators + * + * @access public + * + * @author Addshore + * + * @since 0.5.1 + */ +interface ApiGenerator { + + /** + * @since 0.5.1 + * + * Associative array of parameters including the 'generator' parameter. + * All generator param keys must have their 'g' prefixes + * + * @return string[] + */ + public function getParams(); + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Generator/FluentGenerator.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Generator/FluentGenerator.php new file mode 100644 index 00000000..108f4999 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Generator/FluentGenerator.php @@ -0,0 +1,68 @@ +<?php + +namespace Mediawiki\Api\Generator; + +/** + * @access public + * + * @author Addshore + * + * @since 0.5.1 + */ +class FluentGenerator implements ApiGenerator { + + private $name; + private $params; + + /** + * @param string $name + */ + public function __construct( $name ) { + $this->name = $name; + } + + /** + * Convenience method for using this fluidly + * + * @param string $name + * + * @return FluentGenerator + */ + public static function factory( $name ) { + return new self( $name ); + } + + /** + * @return string[] + */ + public function getParams() { + $params = $this->params; + $params['generator'] = $this->name; + return $params; + } + + /** + * @param string $key optionally with the 'g' prefix + * @param string $value + * + * @return $this + */ + public function set( $key, $value ) { + $key = $this->addKeyprefixIfNeeded( $key ); + $this->params[$key] = $value; + return $this; + } + + /** + * @param string $key + * + * @return string + */ + private function addKeyPrefixIfNeeded( $key ) { + if ( strtolower( substr( $key, 0, 1 ) ) === 'g' ) { + return $key; + } + return 'g' . $key; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/MediawikiFactory.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/MediawikiFactory.php new file mode 100644 index 00000000..fc773ce5 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/MediawikiFactory.php @@ -0,0 +1,240 @@ +<?php + +namespace Mediawiki\Api; + +use Mediawiki\Api\Service\CategoryTraverser; +use Mediawiki\Api\Service\FileUploader; +use Mediawiki\Api\Service\ImageRotator; +use Mediawiki\Api\Service\LogListGetter; +use Mediawiki\Api\Service\NamespaceGetter; +use Mediawiki\Api\Service\PageDeleter; +use Mediawiki\Api\Service\PageListGetter; +use Mediawiki\Api\Service\PageMover; +use Mediawiki\Api\Service\PageProtector; +use Mediawiki\Api\Service\PagePurger; +use Mediawiki\Api\Service\PageGetter; +use Mediawiki\Api\Service\PageRestorer; +use Mediawiki\Api\Service\PageWatcher; +use Mediawiki\Api\Service\Parser; +use Mediawiki\Api\Service\RevisionDeleter; +use Mediawiki\Api\Service\RevisionPatroller; +use Mediawiki\Api\Service\RevisionRestorer; +use Mediawiki\Api\Service\RevisionRollbacker; +use Mediawiki\Api\Service\RevisionSaver; +use Mediawiki\Api\Service\RevisionUndoer; +use Mediawiki\Api\Service\UserBlocker; +use Mediawiki\Api\Service\UserCreator; +use Mediawiki\Api\Service\UserGetter; +use Mediawiki\Api\Service\UserRightsChanger; + +/** + * @access public + * + * @author Addshore + */ +class MediawikiFactory { + + /** + * @var MediawikiApi + */ + private $api; + + /** + * @param MediawikiApi $api + */ + public function __construct( MediawikiApi $api ) { + $this->api = $api; + } + + /** + * Get a new CategoryTraverser object for this API. + * @return \Mediawiki\Api\Service\CategoryTraverser + */ + public function newCategoryTraverser() { + return new CategoryTraverser( $this->api ); + } + + /** + * @since 0.3 + * @return RevisionSaver + */ + public function newRevisionSaver() { + return new RevisionSaver( $this->api ); + } + + /** + * @since 0.5 + * @return RevisionUndoer + */ + public function newRevisionUndoer() { + return new RevisionUndoer( $this->api ); + } + + /** + * @since 0.3 + * @return PageGetter + */ + public function newPageGetter() { + return new PageGetter( $this->api ); + } + + /** + * @since 0.3 + * @return UserGetter + */ + public function newUserGetter() { + return new UserGetter( $this->api ); + } + + /** + * @since 0.3 + * @return PageDeleter + */ + public function newPageDeleter() { + return new PageDeleter( $this->api ); + } + + /** + * @since 0.3 + * @return PageMover + */ + public function newPageMover() { + return new PageMover( $this->api ); + } + + /** + * @since 0.3 + * @return PageListGetter + */ + public function newPageListGetter() { + return new PageListGetter( $this->api ); + } + + /** + * @since 0.3 + * @return PageRestorer + */ + public function newPageRestorer() { + return new PageRestorer( $this->api ); + } + + /** + * @since 0.3 + * @return PagePurger + */ + public function newPagePurger() { + return new PagePurger( $this->api ); + } + + /** + * @since 0.3 + * @return RevisionRollbacker + */ + public function newRevisionRollbacker() { + return new RevisionRollbacker( $this->api ); + } + + /** + * @since 0.3 + * @return RevisionPatroller + */ + public function newRevisionPatroller() { + return new RevisionPatroller( $this->api ); + } + + /** + * @since 0.3 + * @return PageProtector + */ + public function newPageProtector() { + return new PageProtector( $this->api ); + } + + /** + * @since 0.5 + * @return PageWatcher + */ + public function newPageWatcher() { + return new PageWatcher( $this->api ); + } + + /** + * @since 0.3 + * @return RevisionDeleter + */ + public function newRevisionDeleter() { + return new RevisionDeleter( $this->api ); + } + + /** + * @since 0.3 + * @return RevisionRestorer + */ + public function newRevisionRestorer() { + return new RevisionRestorer( $this->api ); + } + + /** + * @since 0.3 + * @return UserBlocker + */ + public function newUserBlocker() { + return new UserBlocker( $this->api ); + } + + /** + * @since 0.3 + * @return UserRightsChanger + */ + public function newUserRightsChanger() { + return new UserRightsChanger( $this->api ); + } + + /** + * @since 0.5 + * @return UserCreator + */ + public function newUserCreator() { + return new UserCreator( $this->api ); + } + + /** + * @since 0.4 + * @return LogListGetter + */ + public function newLogListGetter() { + return new LogListGetter( $this->api ); + } + + /** + * @since 0.5 + * @return FileUploader + */ + public function newFileUploader() { + return new FileUploader( $this->api ); + } + + /** + * @since 0.5 + * @return ImageRotator + */ + public function newImageRotator() { + return new ImageRotator( $this->api ); + } + + /** + * @since 0.6 + * @return Parser + */ + public function newParser() { + return new Parser( $this->api ); + } + + /** + * @since 0.7 + * @return NamespaceGetter + */ + public function newNamespaceGetter() { + return new NamespaceGetter( $this->api ); + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/CategoryTraverser.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/CategoryTraverser.php new file mode 100644 index 00000000..c82b5d69 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/CategoryTraverser.php @@ -0,0 +1,161 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\CategoryLoopException; +use Mediawiki\Api\MediawikiApi; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\Pages; + +/** + * Category traverser. + * + * Note on spelling 'descendant' (from Wiktionary): + * The adjective, "descending from a biological ancestor", may be spelt either + * with an 'a' or with an 'e' in the final syllable. However the noun descendant, + * "one who is the progeny of someone", may be spelt only with an 'a'. + */ +class CategoryTraverser extends Service { + + const CALLBACK_CATEGORY = 10; + const CALLBACK_PAGE = 20; + + /** + * @var string[] + */ + protected $namespaces; + + /** + * @var callable[] + */ + protected $callbacks; + + /** + * Used to remember the previously-visited categories when traversing. + * @var string[] + */ + protected $alreadyVisited; + + /** + * @param MediawikiApi $api The API to connect to. + */ + public function __construct( MediawikiApi $api ) { + parent::__construct( $api ); + $this->callbacks = []; + } + + /** + * Query the remote site for the list of namespaces in use, so that later we can tell what's a + * category and what's not. This populates $this->namespaces, and will not re-request on + * repeated invocations. + * @return void + */ + protected function retrieveNamespaces() { + if ( is_array( $this->namespaces ) ) { + return; + } + $params = [ 'meta' => 'siteinfo', 'siprop' => 'namespaces' ]; + $namespaces = $this->api->getRequest( new SimpleRequest( 'query', $params ) ); + if ( isset( $namespaces['query']['namespaces'] ) ) { + $this->namespaces = $namespaces['query']['namespaces']; + } + } + + /** + * Register a callback that will be called for each page or category visited during the + * traversal. + * @param int $type One of the 'CALLBACK_' constants of this class. + * @param callable $callback A callable that takes two \Mediawiki\DataModel\Page parameters. + */ + public function addCallback( $type, $callback ) { + if ( !isset( $this->callbacks[$type] ) ) { + $this->callbacks[$type] = []; + } + $this->callbacks[$type][] = $callback; + } + + /** + * Visit every descendant page of $rootCategoryName (which will be a Category + * page, because there are no desecendants of any other pages). + * @param Page $rootCat The full name of the page to start at. + * @param Page[] $currentPath Used only when recursing into this method, to track each path + * through the category hierarchy in case of loops. + * @return Pages All descendants of the given category. + * @throws CategoryLoopException If a category loop is detected. + */ + public function descend( Page $rootCat, $currentPath = null ) { + // Make sure we know the namespace IDs. + $this->retrieveNamespaces(); + + $rootCatName = $rootCat->getPageIdentifier()->getTitle()->getText(); + if ( is_null( $currentPath ) ) { + $this->alreadyVisited = []; + $currentPath = new Pages(); + } + $this->alreadyVisited[] = $rootCatName; + $currentPath->addPage( $rootCat ); + + // Start a list of child pages. + $descendants = new Pages(); + do { + $pageListGetter = new PageListGetter( $this->api ); + $members = $pageListGetter->getPageListFromCategoryName( $rootCatName ); + foreach ( $members->toArray() as $member ) { + /** @var Title */ + $memberTitle = $member->getPageIdentifier()->getTitle(); + + // See if this page is a Category page. + $isCat = false; + if ( isset( $this->namespaces[ $memberTitle->getNs() ] ) ) { + $ns = $this->namespaces[ $memberTitle->getNs() ]; + $isCat = ( isset( $ns['canonical'] ) && $ns['canonical'] === 'Category' ); + } + // If it's a category, descend into it. + if ( $isCat ) { + // If this member has already been visited on this branch of the traversal, + // throw an Exception with information about which categories form the loop. + if ( $currentPath->hasPage( $member ) ) { + $currentPath->addPage( $member ); + $loop = new CategoryLoopException(); + $loop->setCategoryPath( $currentPath ); + throw $loop; + } + // Don't go any further if we've already visited this member + // (does not indicate a loop, however; we've already caught that above). + if ( in_array( $memberTitle->getText(), $this->alreadyVisited ) ) { + continue; + } + // Call any registered callbacked, and carry on to the next branch. + $this->call( self::CALLBACK_CATEGORY, [ $member, $rootCat ] ); + $newDescendants = $this->descend( $member, $currentPath ); + $descendants->addPages( $newDescendants ); + // Re-set the path. + $currentPath = new Pages(); + } else { + // If it's a page, add it to the list and carry on. + $descendants->addPage( $member ); + $this->call( self::CALLBACK_PAGE, [ $member, $rootCat ] ); + } + } + } while ( isset( $result['continue'] ) ); + return $descendants; + } + + /** + * Call all the registered callbacks of a particular type. + * @param int $type The callback type; should match one of the 'CALLBACK_' constants. + * @param mixed[] $params The parameters to pass to the callback function. + */ + protected function call( $type, $params ) { + if ( !isset( $this->callbacks[$type] ) ) { + return; + } + foreach ( $this->callbacks[$type] as $callback ) { + if ( is_callable( $callback ) ) { + call_user_func_array( $callback, $params ); + } + } + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/FileUploader.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/FileUploader.php new file mode 100644 index 00000000..5ada5739 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/FileUploader.php @@ -0,0 +1,139 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Exception; +use Mediawiki\Api\MultipartRequest; +use Mediawiki\Api\SimpleRequest; + +/** + * @access private + * + * @author Addshore + */ +class FileUploader extends Service { + + /** @var int */ + protected $chunkSize; + + /** + * Set the chunk size used for chunked uploading. + * + * Chunked uploading is available in MediaWiki 1.20 and above, although prior to version 1.25, + * SVGs could not be uploaded via chunked uploading. + * + * @link https://www.mediawiki.org/wiki/API:Upload#Chunked_uploading + * + * @param int $chunkSize In bytes. + */ + public function setChunkSize( $chunkSize ) { + $this->chunkSize = $chunkSize; + } + + /** + * Upload a file. + * + * @param string $targetName The name to give the file on the wiki (no 'File:' prefix required). + * @param string $location Can be local path or remote URL. + * @param string $text Initial page text for new files. + * @param string $comment Upload comment. Also used as the initial page text for new files if + * text parameter not provided. + * @param string $watchlist Unconditionally add or remove the page from your watchlist, use + * preferences or do not change watch. Possible values: 'watch', 'preferences', 'nochange'. + * @param bool $ignoreWarnings Ignore any warnings. This must be set to upload a new version of + * an existing image. + * + * @return bool + */ + public function upload( + $targetName, + $location, + $text = '', + $comment = '', + $watchlist = 'preferences', + $ignoreWarnings = false + ) { + $params = [ + 'filename' => $targetName, + 'token' => $this->api->getToken(), + ]; + // Watchlist behaviour. + if ( in_array( $watchlist, [ 'watch', 'nochange' ] ) ) { + $params['watchlist'] = $watchlist; + } + // Ignore warnings? + if ( $ignoreWarnings ) { + $params['ignorewarnings'] = '1'; + } + // Page text. + if ( !empty( $text ) ) { + $params['text'] = $text; + } + // Revision comment. + if ( !empty( $comment ) ) { + $params['comment'] = $comment; + } + + if ( is_file( $location ) ) { + // Normal single-request upload. + $params['filesize'] = filesize( $location ); + $params['file'] = fopen( $location, 'r' ); + if ( is_int( $this->chunkSize ) && $this->chunkSize > 0 ) { + // Chunked upload. + $params = $this->uploadByChunks( $params ); + } + } else { + // Upload from URL. + $params['url'] = $location; + } + + $response = $this->api->postRequest( new SimpleRequest( 'upload', $params ) ); + return ( $response['upload']['result'] === 'Success' ); + } + + /** + * Upload a file by chunks and get the parameters for the final upload call. + * @param mixed[] $params The request parameters. + * @return mixed[] + * @throws Exception + */ + protected function uploadByChunks( $params ) { + // Get the file handle for looping, but don't keep it in the request parameters. + $fileHandle = $params['file']; + unset( $params['file'] ); + // Track the chunks and offset. + $chunksDone = 0; + $params['offset'] = 0; + while ( true ) { + + // 1. Make the request. + $params['chunk'] = fread( $fileHandle, $this->chunkSize ); + $contentDisposition = 'form-data; name="chunk"; filename="' . $params['filename'] . '"'; + $request = MultipartRequest::factory() + ->setParams( $params ) + ->setAction( 'upload' ) + ->setMultipartParams( [ + 'chunk' => [ 'headers' => [ 'Content-Disposition' => $contentDisposition ] ], + ] ); + $response = $this->api->postRequest( $request ); + + // 2. Deal with the response. + $chunksDone++; + $params['offset'] = ( $chunksDone * $this->chunkSize ); + if ( !isset( $response['upload']['filekey'] ) ) { + // This should never happen. Even the last response still has the filekey. + throw new Exception( 'Unable to get filekey for chunked upload' ); + } + $params['filekey'] = $response['upload']['filekey']; + if ( $response['upload']['result'] === 'Continue' ) { + // Amend parameters for next upload POST request. + $params['offset'] = $response['upload']['offset']; + } else { + // The final upload POST will be done in self::upload() + // to commit the upload out of the stash area. + unset( $params['chunk'], $params['offset'] ); + return $params; + } + } + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/ImageRotator.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/ImageRotator.php new file mode 100644 index 00000000..ba5624dc --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/ImageRotator.php @@ -0,0 +1,56 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\Api\UsageException; +use Mediawiki\DataModel\File; + +/** + * @access private + * + * @author Addshore + */ +class ImageRotator extends Service { + + /** + * NOTE: This service has not been fully tested + * + * @param File $file + * @param int $rotation Degrees to rotate image clockwise, One value: 90, 180, 270 + * + * @throws UsageException + * @return bool + */ + public function rotate( File $file, $rotation ) { + $params = [ + 'rotation' => $rotation, + 'token' => $this->api->getToken(), + ]; + + if ( !is_null( $file->getPageIdentifier()->getTitle() ) ) { + $params['titles'] = $file->getPageIdentifier()->getTitle()->getText(); + } else { + $params['pageids'] = $file->getPageIdentifier()->getId(); + } + + $result = $this->api->postRequest( new SimpleRequest( 'imagerotate', $params ) ); + + // This module sometimes gives odd errors so deal with them.. + if ( array_key_exists( 'imagerotate', $result ) ) { + $imageRotate = array_pop( $result['imagerotate'] ); + if ( array_key_exists( 'result', $imageRotate ) && + $imageRotate['result'] == 'Failure' + ) { + throw new UsageException( + 'imagerotate-Failure', + $imageRotate['errormessage'], + $result + ); + } + } + + return true; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/LogListGetter.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/LogListGetter.php new file mode 100644 index 00000000..d9394919 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/LogListGetter.php @@ -0,0 +1,83 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Log; +use Mediawiki\DataModel\LogList; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Revisions; +use Mediawiki\DataModel\Title; + +/** + * @access private + * + * @author Thomas Arrow + */ +class LogListGetter extends Service { + + /** + * @param array $extraParams + * + * @return LogList + */ + public function getLogList( array $extraParams = [] ) { + $logList = new LogList(); + + while ( true ) { + $params = [ + 'list' => 'logevents', + 'leprop' => 'title|ids|type|user|timestamp|comment|details' + ]; + + $newParams = array_merge( $extraParams, $params ); + $result = $this->api->getRequest( new SimpleRequest( 'query', $newParams ) ); + + foreach ( $result[ 'query' ]['logevents'] as $logevent ) { + $logList->addLog( + new Log( + $logevent['logid'], + $logevent['type'], + $logevent['action'], + $logevent['timestamp'], + $logevent['user'], + new Page( + new PageIdentifier( + new Title( $logevent['title'], $logevent['ns'] ), + $logevent['pageid'] + ), + new Revisions() + ), + $logevent['comment'], + $this->getLogDetailsFromEvent( $logevent ) + ) + ); + } + + return $logList; + } + } + + /** + * @param array $event + * + * @return array + */ + private function getLogDetailsFromEvent( $event ) { + $ignoreKeys = array_flip( [ + 'logid', + 'ns', + 'title', + 'pageid', + 'logpage', + 'type', + 'action', + 'user', + 'type', + 'timestamp', + 'comment' ] ); + return array_diff_key( $event, $ignoreKeys ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/NamespaceGetter.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/NamespaceGetter.php new file mode 100644 index 00000000..c3f00030 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/NamespaceGetter.php @@ -0,0 +1,108 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\NamespaceInfo; + +/** + * @access private + * + * @author gbirke + */ +class NamespaceGetter extends Service { + + /** + * Find a namespace by its canonical name + * + * @param string $canonicalName + * @return NamespaceInfo|null + */ + public function getNamespaceByCanonicalName( $canonicalName ) { + $result = $this->getNamespaceResult()['query']; + foreach ( $result['namespaces'] as $nsInfo ) { + if ( !empty( $nsInfo['canonical'] ) && $nsInfo['canonical'] === $canonicalName ) { + return $this->createNamespaceFromQuery( $nsInfo, $result['namespacealiases'] ); + } + } + return null; + } + + /** + * Find a namespace by its canonical name, local name or namespace alias + * + * @param string $name + * @return NamespaceInfo|null + */ + public function getNamespaceByName( $name ) { + $result = $this->getNamespaceResult()['query']; + foreach ( $result['namespaces'] as $nsInfo ) { + if ( ( !empty( $nsInfo['canonical'] ) && $nsInfo['canonical'] === $name ) || + $nsInfo['*'] === $name ) { + return $this->createNamespaceFromQuery( $nsInfo, $result['namespacealiases'] ); + } + } + foreach ( $result['namespacealiases'] as $alias ) { + if ( $alias['*'] === $name && !empty( $result['namespaces'][$alias['id']] ) ) { + return $this->createNamespaceFromQuery( + $result['namespaces'][$alias['id']], + $result['namespacealiases'] + ); + } + } + return null; + } + + /** + * @return NamespaceInfo[] + */ + public function getNamespaces() { + $namespaces = []; + $result = $this->getNamespaceResult()['query']; + foreach ( $result['namespaces'] as $nsInfo ) { + $namespaces[$nsInfo['id']] = $this->createNamespaceFromQuery( + $nsInfo, $result['namespacealiases'] + ); + } + return $namespaces; + } + + private function createNamespaceFromQuery( $nsInfo, $namespaceAliases ) { + return new NamespaceInfo( + $nsInfo['id'], + empty( $nsInfo['canonical'] ) ? '' : $nsInfo['canonical'], + $nsInfo['*'], + $nsInfo['case'], + empty( $nsInfo['defaultcontentmodel'] ) ? null : $nsInfo['defaultcontentmodel'], + $this->getAliases( $nsInfo['id'], $namespaceAliases ) + ); + } + + /** + * @param int $id + * @param array $namespaceAliases Alias list, as returned by the API + * @return string[] + */ + private function getAliases( $id, $namespaceAliases ) { + $aliases = []; + foreach ( $namespaceAliases as $alias ) { + if ( $alias['id'] === $id ) { + $aliases[] = $alias['*']; + } + } + return $aliases; + } + + /** + * @return array + */ + private function getNamespaceResult() { + return $this->api->getRequest( new SimpleRequest( + 'query', [ + 'meta' => 'siteinfo', + 'siprop' => 'namespaces|namespacealiases' + ] + ) ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageDeleter.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageDeleter.php new file mode 100644 index 00000000..60c43e30 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageDeleter.php @@ -0,0 +1,105 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Revision; +use Mediawiki\DataModel\Title; + +/** + * @access private + * + * @author Addshore + */ +class PageDeleter extends Service { + + /** + * @since 0.2 + * + * @param Page $page + * @param array $extraParams + * + * @return bool + */ + public function delete( Page $page, array $extraParams = [] ) { + $this->api->postRequest( new SimpleRequest( + 'delete', + $this->getDeleteParams( $page->getPageIdentifier(), $extraParams ) + ) ); + return true; + } + + /** + * @since 0.2 + * + * @param Revision $revision + * @param array $extraParams + * + * @return bool + */ + public function deleteFromRevision( Revision $revision, array $extraParams = [] ) { + $this->api->postRequest( new SimpleRequest( + 'delete', + $this->getDeleteParams( $revision->getPageIdentifier(), $extraParams ) + ) ); + return true; + } + + /** + * @since 0.2 + * + * @param int $pageid + * @param array $extraParams + * + * @return bool + */ + public function deleteFromPageId( $pageid, array $extraParams = [] ) { + $this->api->postRequest( new SimpleRequest( + 'delete', + $this->getDeleteParams( new PageIdentifier( null, $pageid ), $extraParams ) + ) ); + return true; + } + + /** + * @since 0.5 + * + * @param Title|string $title + * @param array $extraParams + * + * @return bool + */ + public function deleteFromPageTitle( $title, array $extraParams = [] ) { + if ( is_string( $title ) ) { + $title = new Title( $title ); + } + $this->api->postRequest( new SimpleRequest( + 'delete', + $this->getDeleteParams( new PageIdentifier( $title ), $extraParams ) + ) ); + return true; + } + + /** + * @param PageIdentifier $identifier + * @param array $extraParams + * + * @return array + */ + private function getDeleteParams( PageIdentifier $identifier, $extraParams ) { + $params = []; + + if ( !is_null( $identifier->getId() ) ) { + $params['pageid'] = $identifier->getId(); + } else { + $params['title'] = $identifier->getTitle()->getTitle(); + } + + $params['token'] = $this->api->getToken( 'delete' ); + + return array_merge( $extraParams, $params ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageGetter.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageGetter.php new file mode 100644 index 00000000..6c5c54cf --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageGetter.php @@ -0,0 +1,246 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Content; +use Mediawiki\DataModel\EditInfo; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Revision; +use Mediawiki\DataModel\Revisions; +use Mediawiki\DataModel\Title; +use RuntimeException; + +/** + * @access private + * + * @author Addshore + */ +class PageGetter extends Service { + + /** + * @since 0.2 + * + * @param int $id + * @param array $extraParams + * + * @return Page + */ + public function getFromRevisionId( $id, array $extraParams = [] ) { + $result = + $this->api->getRequest( + new SimpleRequest( + 'query', + $this->getQuery( [ 'revids' => $id ], $extraParams ) + ) + ); + + return $this->newPageFromResult( array_shift( $result['query']['pages'] ) ); + } + + /** + * @since 0.2 + * + * @param string|Title $title + * @param array $extraParams + * + * @return Page + */ + public function getFromTitle( $title, array $extraParams = [] ) { + if ( $title instanceof Title ) { + $title = $title->getTitle(); + } + $result = + $this->api->getRequest( + new SimpleRequest( + 'query', + $this->getQuery( [ 'titles' => $title ], $extraParams ) + ) + ); + + return $this->newPageFromResult( array_shift( $result['query']['pages'] ) ); + } + + /** + * @since 0.2 + * + * @param int $id + * @param array $extraParams + * + * @return Page + */ + public function getFromPageId( $id, array $extraParams = [] ) { + $result = + $this->api->getRequest( + new SimpleRequest( + 'query', + $this->getQuery( [ 'pageids' => $id ], $extraParams ) + ) + ); + + return $this->newPageFromResult( array_shift( $result['query']['pages'] ) ); + } + + /** + * @since 0.4 + * + * @param PageIdentifier $pageIdentifier + * @param array $extraParams + * + * @throws RuntimeException + * @return Page + */ + public function getFromPageIdentifier( + PageIdentifier $pageIdentifier, + array $extraParams = [] + ) { + if ( !$pageIdentifier->identifiesPage() ) { + throw new RuntimeException( '$pageIdentifier does not identify a page' ); + } + if ( !is_null( $pageIdentifier->getId() ) ) { + return $this->getFromPageId( $pageIdentifier->getId(), $extraParams ); + } else { + return $this->getFromTitle( $pageIdentifier->getTitle(), $extraParams ); + } + } + + /** + * @since 0.2 + * + * @param Page $page + * @param array $extraParams + * + * @return Page + */ + public function getFromPage( Page $page, array $extraParams = [] ) { + $result = + $this->api->getRequest( + new SimpleRequest( + 'query', + $this->getQuery( [ 'pageids' => $page->getId() ], $extraParams ) + ) + ); + $revisions = $this->getRevisionsFromResult( array_shift( $result['query']['pages'] ) ); + $revisions->addRevisions( $page->getRevisions() ); + + return new Page( + $page->getPageIdentifier(), + $revisions + ); + } + + /** + * @since 0.2 + * + * @param Revision $revision + * @param array $extraParams + * + * @return Page + */ + public function getFromRevision( Revision $revision, array $extraParams = [] ) { + $result = + $this->api->getRequest( + new SimpleRequest( + 'query', + $this->getQuery( [ 'revids' => $revision->getId() ], $extraParams ) + ) + ); + $revisions = $this->getRevisionsFromResult( array_shift( $result['query']['pages'] ) ); + $revisions->addRevision( $revision ); + + return new Page( + new PageIdentifier( + new Title( + $result['title'], + $result['ns'] + ), + $result['pageid'] + ), + $revisions + ); + } + + /** + * @param array $additionalParams + * + * @param array $extraParams + * + * @return array + */ + private function getQuery( $additionalParams, array $extraParams = [] ) { + $base = [ + 'prop' => 'revisions|info|pageprops', + 'rvprop' => 'ids|flags|timestamp|user|size|sha1|comment|content|tags', + 'inprop' => 'protection', + ]; + + return array_merge( $extraParams, $base, $additionalParams ); + } + + /** + * @param array $array + * + * @return Revisions + */ + private function getRevisionsFromResult( $array ) { + $revisions = new Revisions(); + $pageid = $array['pageid']; + foreach ( $array['revisions'] as $revision ) { + $revisions->addRevision( + new Revision( + $this->getContent( $array['contentmodel'], $revision['*'] ), + new PageIdentifier( new Title( $array['title'], $array['ns'] ), $pageid ), + $revision['revid'], + new EditInfo( + $revision['comment'], + array_key_exists( 'minor', $revision ), + array_key_exists( 'bot', $revision ) + ), + $revision['user'], + $revision['timestamp'] + ) + ); + } + + return $revisions; + } + + /** + * @param string $model + * @param string $content returned from the API + * + * @throws RuntimeException + * @return Content + */ + private function getContent( $model, $content ) { + return new Content( $content, $model ); + } + + /** + * @param array $array + * + * @return Page + */ + private function newPageFromResult( $array ) { + if ( array_key_exists( 'pageid', $array ) ) { + $pageid = $array['pageid']; + $revisions = $this->getRevisionsFromResult( $array ); + } else { + $pageid = 0; + $revisions = new Revisions(); + } + + return new Page( + new PageIdentifier( + new Title( + $array['title'], + $array['ns'] + ), + $pageid + ), + $revisions + ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageListGetter.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageListGetter.php new file mode 100644 index 00000000..6b6d0007 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageListGetter.php @@ -0,0 +1,147 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Pages; +use Mediawiki\DataModel\Title; + +/** + * @access private + * + * @author Addshore + */ +class PageListGetter extends Service { + + /** + * Get the set of pages in a given category. Extra parameters can include: + * cmtype: default 'page|subcat|file' + * cmlimit: default 10, maximum 500 (5000 for bots) + * + * @link https://www.mediawiki.org/wiki/API:Categorymembers + * @since 0.3 + * + * @param string $name + * @param array $extraParams + * + * @return Pages + */ + public function getPageListFromCategoryName( $name, array $extraParams = [] ) { + $params = array_merge( $extraParams, [ + 'list' => 'categorymembers', + 'cmtitle' => $name, + ] ); + return $this->runQuery( $params, 'cmcontinue', 'categorymembers' ); + } + + /** + * List pages that transclude a certain page. + * + * @link https://www.mediawiki.org/wiki/API:Embeddedin + * @since 0.5 + * + * @param string $pageName + * @param array $extraParams + * + * @return Pages + */ + public function getPageListFromPageTransclusions( $pageName, array $extraParams = [] ) { + $params = array_merge( $extraParams, [ + 'list' => 'embeddedin', + 'eititle' => $pageName, + ] ); + return $this->runQuery( $params, 'eicontinue', 'embeddedin' ); + } + + /** + * Get all pages that link to the given page. + * + * @link https://www.mediawiki.org/wiki/API:Linkshere + * @since 0.5 + * @uses PageListGetter::runQuery() + * + * @param string $pageName The page name + * @param string[] Any extra parameters to use: lhprop, lhnamespace, lhshow, lhlimit + * + * @return Pages + */ + public function getFromWhatLinksHere( $pageName, $extraParams = [] ) { + $params = array_merge( $extraParams, [ + 'prop' => 'info', + 'generator' => 'linkshere', + 'titles' => $pageName, + ] ); + return $this->runQuery( $params, 'glhcontinue', 'pages' ); + } + + /** + * Get all pages that have the given prefix. + * + * @link https://www.mediawiki.org/wiki/API:Allpages + * + * @param string $prefix The page title prefix. + * + * @return Pages + */ + public function getFromPrefix( $prefix ) { + $params = [ + 'list' => 'allpages', + 'apprefix' => $prefix, + ]; + return $this->runQuery( $params, 'apcontinue', 'allpages' ); + } + + /** + * Get up to 10 random pages. + * + * @link https://www.mediawiki.org/wiki/API:Random + * @uses PageListGetter::runQuery() + * + * @param array $extraParams + * + * @return Pages + */ + public function getRandom( array $extraParams = [] ) { + $params = array_merge( $extraParams, [ 'list' => 'random' ] ); + return $this->runQuery( $params, null, 'random', 'id', false ); + } + + /** + * Run a query to completion. + * + * @param string[] $params Query parameters + * @param string $contName Result subelement name for continue details + * @param string $resName Result element name for main results array + * @param string $pageIdName Result element name for page ID + * @param bool $cont Whether to continue the query, using multiple requests + * @return Pages + */ + protected function runQuery( $params, $contName, $resName, $pageIdName = 'pageid', $cont = true ) { + $pages = new Pages(); + + do { + // Set up continue parameter if it's been set already. + if ( isset( $result['continue'][$contName] ) ) { + $params[$contName] = $result['continue'][$contName]; + } + + // Run the actual query. + $result = $this->api->getRequest( new SimpleRequest( 'query', $params ) ); + if ( !array_key_exists( 'query', $result ) ) { + return $pages; + } + + // Add the results to the output page list. + foreach ( $result['query'][$resName] as $member ) { + $pageTitle = new Title( $member['title'], $member['ns'] ); + $page = new Page( new PageIdentifier( $pageTitle, $member[$pageIdName] ) ); + $pages->addPage( $page ); + } + + } while ( $cont && isset( $result['continue'] ) ); + + return $pages; + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageMover.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageMover.php new file mode 100644 index 00000000..f7eba2af --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageMover.php @@ -0,0 +1,68 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\Title; + +/** + * @access private + * + * @author Addshore + */ +class PageMover extends Service { + + /** + * @since 0.2 + * + * @param Page $page + * @param Title $target + * @param array $extraParams + * + * @return bool + */ + public function move( Page $page, Title $target, array $extraParams = [] ) { + $this->api->postRequest( + new SimpleRequest( + 'move', $this->getMoveParams( $page->getId(), $target, $extraParams ) + ) + ); + + return true; + } + + /** + * @since 0.2 + * + * @param int $pageid + * @param Title $target + * @param array $extraParams + * + * @return bool + */ + public function moveFromPageId( $pageid, Title $target, array $extraParams = [] ) { + $this->api->postRequest( + new SimpleRequest( 'move', $this->getMoveParams( $pageid, $target, $extraParams ) ) + ); + + return true; + } + + /** + * @param int $pageid + * @param Title $target + * @param array $extraParams + * + * @return array + */ + private function getMoveParams( $pageid, $target, $extraParams ) { + $params = []; + $params['fromid'] = $pageid; + $params['to'] = $target->getTitle(); + $params['token'] = $this->api->getToken( 'move' ); + + return array_merge( $extraParams, $params ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageProtector.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageProtector.php new file mode 100644 index 00000000..e3988e84 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageProtector.php @@ -0,0 +1,55 @@ +<?php + +namespace Mediawiki\Api\Service; + +use InvalidArgumentException; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; + +/** + * @access private + * + * @author Addshore + */ +class PageProtector extends Service { + + /** + * @since 0.3 + * + * @param Page $page + * @param string[] $protections where the 'key' is the action and the 'value' is the group + * @param array $extraParams + * + * @return bool + * @throws InvalidArgumentException + */ + public function protect( Page $page, $protections, array $extraParams = [] ) { + if ( !is_array( $protections ) || empty( $protections ) ) { + throw new InvalidArgumentException( + '$protections must be an array with keys and values' + ); + } + + $params = [ + 'pageid' => $page->getId(), + 'token' => $this->api->getToken( 'protect' ), + ]; + $protectionsString = ''; + foreach ( $protections as $action => $value ) { + if ( !is_string( $action ) || !is_string( $value ) ) { + throw new InvalidArgumentException( + 'All keys and elements of $protections must be strings' + ); + } + $protectionsString = $action . '=' . $value . '|'; + } + $params['protections'] = rtrim( $protectionsString, '|' ); + + $this->api->postRequest( + new SimpleRequest( 'protect', array_merge( $extraParams, $params ) ) + ); + + return true; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PagePurger.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PagePurger.php new file mode 100644 index 00000000..6f9057f1 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PagePurger.php @@ -0,0 +1,116 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\Generator\ApiGenerator; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Pages; +use Mediawiki\DataModel\Page; + +/** + * @access private + * + * @author Addshore + * @author Thomas Arrow + */ +class PagePurger extends Service { + + /** + * @since 0.3 + * + * @brief Purge a single page + * + * Purges a single page by submitting a + * 'purge' action to the mediawiki api + * with the parameter 'pageids' set to + * the singe page id + * + * @param Page $page the page that is going to be purged + * + * @return bool return true if the purge was successful + */ + public function purge( Page $page ) { + $responseArray = $this->api->postRequest( + new SimpleRequest( 'purge', [ 'pageids' => $page->getId() ] ) + ); + + // the purge response for the page + $purgeResponse = $responseArray['purge'][0]; + + return array_key_exists( 'purged', $purgeResponse ); + } + + /** + * @since 0.7 + * + * @brief Purge multiple pages + * + * Purges all the pages of the Pages object + * by submitting a 'purge' action to the mediawiki + * api with the parameter 'pageids' set to be the + * pages ids in multiple-value seperation. + * + * @param Pages $pages the pages that are going to be purged + * + * @return Pages the pages that have been purged successfully + */ + public function purgePages( Pages $pages ) { + $pagesArray = $pages->toArray(); + $pagesIds = []; + + foreach ( $pagesArray as $page ) { + array_push( $pagesIds, $page->getId() ); + } + + // convert an array to multiple-value format + // because the mediawiki api require multiple + // values to be seperated like the example + // ex: [111, 222, 333] => "111|222|333" + $pageIdsMultiple = implode( '|', $pagesIds ); + + $responseArray = $this->api->postRequest( + new SimpleRequest( 'purge', [ 'pageids' => $pageIdsMultiple ] ) + ); + + // array that will hold the successfully purged pages + $purgedPages = new Pages(); + + // for every purge result + foreach ( $responseArray['purge'] as $purgeResponse ) { + // if the purge for the page was successful + if ( array_key_exists( 'purged', $purgeResponse ) ) { + // we iterate all the input pages + foreach ( $pagesArray as $page ) { + // and if the page from the input was successfully purged + if ( $purgeResponse['title'] === $page->getTitle()->getText() ) { + // add it in the purgedPages object + $purgedPages->addPage( $page ); + + break; + } + + } + + } + + } + + return $purgedPages; + } + + /** + * @since 0.6 + * + * @param ApiGenerator $generator + * + * @return bool + */ + public function purgeGenerator( ApiGenerator $generator ) { + $this->api->postRequest( + new SimpleRequest( 'purge', $generator->getParams() ) + ); + + return true; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageRestorer.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageRestorer.php new file mode 100644 index 00000000..a422bd97 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageRestorer.php @@ -0,0 +1,76 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\Title; +use OutOfBoundsException; + +/** + * @access private + * + * @author Addshore + */ +class PageRestorer extends Service { + + /** + * @since 0.3 + * + * @param Page $page + * @param array $extraParams + * + * @return bool + */ + public function restore( Page $page, array $extraParams = [] ) { + $this->api->postRequest( + new SimpleRequest( + 'undelete', + $this->getUndeleteParams( $page->getTitle(), $extraParams ) + ) + ); + + return true; + } + + /** + * @param Title $title + * @param array $extraParams + * + * @return array + */ + private function getUndeleteParams( Title $title, $extraParams ) { + $params = []; + + $params['title'] = $title->getTitle(); + $params['token'] = $this->getUndeleteToken( $title ); + + return array_merge( $extraParams, $params ); + } + + /** + * @param Title $title + * + * @throws OutOfBoundsException + * @returns string + */ + private function getUndeleteToken( Title $title ) { + $response = $this->api->postRequest( + new SimpleRequest( + 'query', [ + 'list' => 'deletedrevs', + 'titles' => $title->getTitle(), + 'drprop' => 'token', + ] + ) + ); + if ( array_key_exists( 'token', $response['query']['deletedrevs'][0] ) ) { + return $response['query']['deletedrevs'][0]['token']; + } else { + throw new OutOfBoundsException( + 'Could not get page undelete token from list=deletedrevs query' + ); + } + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageWatcher.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageWatcher.php new file mode 100644 index 00000000..e7afab17 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/PageWatcher.php @@ -0,0 +1,37 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; + +/** + * @access private + * + * @author Addshore + */ +class PageWatcher extends Service { + + /** + * @param Page $page + * + * @return bool + */ + public function watch( Page $page ) { + $params = [ + 'token' => $this->api->getToken( 'watch' ), + ]; + if ( !is_null( $page->getPageIdentifier()->getId() ) ) { + $params['pageids'] = $page->getPageIdentifier()->getId(); + } elseif ( !is_null( $page->getPageIdentifier()->getTitle() ) ) { + $params['titles'] = $page->getPageIdentifier()->getTitle()->getTitle(); + } elseif ( !is_null( $page->getRevisions()->getLatest() ) ) { + $params['revids'] = $page->getRevisions()->getLatest()->getId(); + } + + $this->api->postRequest( new SimpleRequest( 'watch', $params ) ); + + return true; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/Parser.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/Parser.php new file mode 100644 index 00000000..da83e39e --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/Parser.php @@ -0,0 +1,47 @@ +<?php + +namespace Mediawiki\Api\Service; + +use GuzzleHttp\Promise\PromiseInterface; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\PageIdentifier; + +/** + * @access private + * + * @author Addshore + */ +class Parser extends Service { + + /** + * @param PageIdentifier $pageIdentifier + * + * @return array the parse result (raw from the api) + */ + public function parsePage( PageIdentifier $pageIdentifier ) { + return $this->parsePageAsync( $pageIdentifier )->wait(); + } + + /** + * @param PageIdentifier $pageIdentifier + * + * @return PromiseInterface of array the parse result (raw from the api) + */ + public function parsePageAsync( PageIdentifier $pageIdentifier ) { + $params = []; + if ( $pageIdentifier->getId() !== null ) { + $params['pageid'] = $pageIdentifier->getId(); + } elseif ( $pageIdentifier->getTitle() !== null ) { + $params['page'] = $pageIdentifier->getTitle()->getText(); + } else { + throw new \RuntimeException( 'No way to identify page' ); + } + + $promise = $this->api->getRequestAsync( new SimpleRequest( 'parse', $params ) ); + + return $promise->then( function ( $result ) { + return $result['parse']; + } ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionDeleter.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionDeleter.php new file mode 100644 index 00000000..b12a7278 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionDeleter.php @@ -0,0 +1,39 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Revision; + +/** + * @access private + * + * @author Addshore + */ +class RevisionDeleter extends Service { + + /** + * @since 0.5 + * + * @param Revision $revision + * + * @return bool + */ + public function delete( Revision $revision ) { + $params = [ + 'type' => 'revision', + 'hide' => 'content', + // Note: pre 1.24 this is a delete token, post it is csrf + 'token' => $this->api->getToken( 'delete' ), + 'ids' => $revision->getId(), + ]; + + $this->api->postRequest( new SimpleRequest( + 'revisiondelete', + $params + ) ); + + return true; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionPatroller.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionPatroller.php new file mode 100644 index 00000000..e642fd96 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionPatroller.php @@ -0,0 +1,47 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Revision; + +/** + * @access private + * + * @author Addshore + */ +class RevisionPatroller extends Service { + + /** + * @since 0.3 + * + * @param Revision $revision + * + * @return bool success + */ + public function patrol( Revision $revision ) { + $this->api->postRequest( new SimpleRequest( + 'patrol', [ + 'revid' => $revision->getId(), + 'token' => $this->getTokenForRevision( $revision ), + ] ) ); + return true; + } + + /** + * @param Revision $revision + * + * @returns string + */ + private function getTokenForRevision( Revision $revision ) { + $result = $this->api->postRequest( new SimpleRequest( 'query', [ + 'list' => 'recentchanges', + 'rcstart' => $revision->getTimestamp(), + 'rcend' => $revision->getTimestamp(), + 'rctoken' => 'patrol', + ] ) ); + $result = array_shift( $result['query']['recentchanges'] ); + return $result['patroltoken']; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionRestorer.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionRestorer.php new file mode 100644 index 00000000..fb82c252 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionRestorer.php @@ -0,0 +1,39 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Revision; + +/** + * @access private + * + * @author Addshore + */ +class RevisionRestorer extends Service { + + /** + * @since 0.5 + * + * @param Revision $revision + * + * @return bool + */ + public function restore( Revision $revision ) { + $params = [ + 'type' => 'revision', + 'show' => 'content', + // Note: pre 1.24 this is a delete token, post it is csrf + 'token' => $this->api->getToken( 'delete' ), + 'ids' => $revision->getId(), + ]; + + $this->api->postRequest( new SimpleRequest( + 'revisiondelete', + $params + ) ); + + return true; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionRollbacker.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionRollbacker.php new file mode 100644 index 00000000..76a2f5c7 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionRollbacker.php @@ -0,0 +1,73 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Revision; +use Mediawiki\DataModel\Title; + +/** + * @access private + * + * @author Addshore + */ +class RevisionRollbacker extends Service { + + /** + * @since 0.3 + * + * @param Revision $revision + * @param Title $title if using MW 1.24 of lower (https://gerrit.wikimedia.org/r/#/c/133063/) + * + * @return bool + */ + public function rollback( Revision $revision, Title $title = null ) { + $this->api->postRequest( + new SimpleRequest( 'rollback', $this->getRollbackParams( $revision, $title ) ) + ); + + return true; + } + + /** + * @param Revision $revision + * @param Title|null $title + * + * @return array + */ + private function getRollbackParams( Revision $revision, $title ) { + $params = []; + if ( !is_null( $title ) ) { + // This is needed prior to https://gerrit.wikimedia.org/r/#/c/133063/ + $params['title'] = $title->getTitle(); + } else { + // This will work after https://gerrit.wikimedia.org/r/#/c/133063/ + $params['pageid'] = $revision->getPageId(); + } + $params['user'] = $revision->getUser(); + $params['token'] = $this->getTokenForRevision( $revision ); + + return $params; + } + + /** + * @param Revision $revision + * + * @returns string + */ + private function getTokenForRevision( Revision $revision ) { + $result = $this->api->postRequest( + new SimpleRequest( + 'query', [ + 'prop' => 'revisions', + 'revids' => $revision->getId(), + 'rvtoken' => 'rollback', + ] + ) + ); + $result = array_shift( $result['query']['pages'] ); + + return $result['revisions'][0]['rollbacktoken']; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionSaver.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionSaver.php new file mode 100644 index 00000000..00b91ee6 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionSaver.php @@ -0,0 +1,96 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\EditInfo; +use Mediawiki\DataModel\Revision; +use RuntimeException; + +/** + * @access private + * + * @author Addshore + * @author DFelten (EditInfo fix) + */ +class RevisionSaver extends Service { + + /** + * @since 0.2 + * + * @param Revision $revision + * @param EditInfo $editInfo + * + * @return bool success + */ + public function save( Revision $revision, EditInfo $editInfo = null ) { + $editInfo = $editInfo ? $editInfo : $revision->getEditInfo(); + + $result = $this->api->postRequest( + new SimpleRequest( 'edit', $this->getEditParams( $revision, $editInfo ) ) + ); + return ( $result['edit']['result'] == 'Success' ); + } + + /** + * @param Revision $revision + * @param EditInfo $editInfo + * + * @throws RuntimeException + * @returns array + */ + private function getEditParams( Revision $revision, EditInfo $editInfo = null ) { + if ( !$revision->getPageIdentifier()->identifiesPage() ) { + throw new RuntimeException( '$revision PageIdentifier does not identify a page' ); + } + + $params = []; + + $content = $revision->getContent(); + $data = $content->getData(); + if ( !is_string( $data ) ) { + throw new RuntimeException( 'Dont know how to save content of this model.' ); + } + $params['text'] = $content->getData(); + $params['md5'] = md5( $content->getData() ); + + $timestamp = $revision->getTimestamp(); + if ( !is_null( $timestamp ) ) { + $params['basetimestamp'] = $timestamp; + } + + if ( !is_null( $revision->getPageIdentifier()->getId() ) ) { + $params['pageid'] = $revision->getPageIdentifier()->getId(); + } else { + $params['title'] = $revision->getPageIdentifier()->getTitle()->getTitle(); + } + + $params['token'] = $this->api->getToken(); + + if ( $this->api->isLoggedin() ) { + $params['assert'] = 'user'; + } + + $this->addEditInfoParams( $editInfo, $params ); + + return $params; + } + + /** + * @param null|EditInfo $editInfo + * @param array &$params + */ + private function addEditInfoParams( $editInfo, &$params ) { + if ( !is_null( $editInfo ) ) { + $params['summary'] = $editInfo->getSummary(); + if ( $editInfo->getMinor() ) { + $params['minor'] = true; + } + if ( $editInfo->getBot() ) { + $params['bot'] = true; + $params['assert'] = 'bot'; + } + } + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionUndoer.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionUndoer.php new file mode 100644 index 00000000..e411030e --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/RevisionUndoer.php @@ -0,0 +1,48 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Revision; + +/** + * @access private + * + * @author Addshore + */ +class RevisionUndoer extends Service { + + /** + * @param Revision $revision + * + * @return bool + */ + public function undo( Revision $revision ) { + $this->api->postRequest( new SimpleRequest( + 'edit', + $this->getParamsFromRevision( $revision ) + ) ); + return true; + } + + /** + * @param Revision $revision + * + * @return array + */ + private function getParamsFromRevision( Revision $revision ) { + $params = [ + 'undo' => $revision->getId(), + 'token' => $this->api->getToken(), + ]; + + if ( !is_null( $revision->getPageIdentifier()->getId() ) ) { + $params['pageid'] = $revision->getPageIdentifier()->getId(); + } else { + $params['title'] = $revision->getPageIdentifier()->getTitle()->getTitle(); + } + + return $params; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/Service.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/Service.php new file mode 100644 index 00000000..4a4b466b --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/Service.php @@ -0,0 +1,23 @@ +<?php + +namespace MediaWiki\Api\Service; + +use Mediawiki\Api\MediawikiApi; + +/** + * The base service functions that all services inherit. + * @since 0.7.2 + */ +abstract class Service { + + /** @var MediawikiApi */ + protected $api; + + /** + * @param MediawikiApi $api The API to in for this service. + */ + public function __construct( MediawikiApi $api ) { + $this->api = $api; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/UserBlocker.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/UserBlocker.php new file mode 100644 index 00000000..9cf9f421 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/UserBlocker.php @@ -0,0 +1,45 @@ +<?php + +namespace Mediawiki\Api\Service; + +use InvalidArgumentException; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\User; + +/** + * @access private + * + * @author Addshore + */ +class UserBlocker extends Service { + + /** + * @since 0.3 + * + * @param User|string $user + * @param array $extraParams + * + * @throws InvalidArgumentException + * @return bool + */ + public function block( $user, array $extraParams = [] ) { + if ( !$user instanceof User && !is_string( $user ) ) { + throw new InvalidArgumentException( '$user must be either a string or User object' ); + } + + if ( $user instanceof User ) { + $user = $user->getName(); + } + + $params = [ + 'user' => $user, + 'token' => $this->api->getToken( 'block' ), + ]; + + $params = array_merge( $extraParams, $params ); + + $this->api->postRequest( new SimpleRequest( 'block', $params ) ); + return true; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/UserCreator.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/UserCreator.php new file mode 100644 index 00000000..8d74b107 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/UserCreator.php @@ -0,0 +1,83 @@ +<?php + +namespace Mediawiki\Api\Service; + +use InvalidArgumentException; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\Api\UsageException; + +/** + * @access private + * + * @author Addshore + */ +class UserCreator extends Service { + + /** + * @param string $username + * @param string $password + * @param string|null $email + * + * @return bool + */ + public function create( $username, $password, $email = null ) { + if ( !is_string( $username ) ) { + throw new InvalidArgumentException( '$username should be a string' ); + } + if ( !is_string( $password ) ) { + throw new InvalidArgumentException( '$password should be a string' ); + } + if ( !is_string( $email ) && !is_null( $email ) ) { + throw new InvalidArgumentException( '$email should be a string or null' ); + } + + $params = [ + 'createreturnurl' => $this->api->getApiUrl(), + 'createtoken' => $this->api->getToken( 'createaccount' ), + 'username' => $username, + 'password' => $password, + 'retype' => $password, + ]; + + if ( !is_null( $email ) ) { + $params['email'] = $email; + } + + try { + $result = $this->api->postRequest( new SimpleRequest( 'createaccount', $params ) ); + return $result['createaccount']['status'] === 'PASS'; + } catch ( UsageException $exception ) { + // If the above request failed, try again in the old way. + if ( $exception->getApiCode() === 'noname' ) { + return $this->createPreOneTwentySeven( $params ); + } + throw $exception; + } + } + + /** + * Create a user in the pre 1.27 manner. + * @link https://www.mediawiki.org/wiki/API:Account_creation/pre-1.27 + * @return bool + */ + protected function createPreOneTwentySeven( $params ) { + $newParams = [ + 'name' => $params['username'], + 'password' => $params['password'], + ]; + if ( array_key_exists( 'email', $params ) ) { + $newParams['email'] = $params['email']; + } + // First get the token. + $tokenRequest = new SimpleRequest( 'createaccount', $newParams ); + $result = $this->api->postRequest( $tokenRequest ); + if ( $result['createaccount']['result'] == 'NeedToken' ) { + // Then send the token to create the account. + $newParams['token'] = $result['createaccount']['token']; + $request = new SimpleRequest( 'createaccount', $newParams ); + $result = $this->api->postRequest( $request ); + } + return ( $result['createaccount']['result'] === 'Success' ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/UserGetter.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/UserGetter.php new file mode 100644 index 00000000..d3bfbd5b --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/UserGetter.php @@ -0,0 +1,63 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\User; + +/** + * @access private + * + * @author Addshore + */ +class UserGetter extends Service { + + /** + * @param string $username + * + * @return User + */ + public function getFromUsername( $username ) { + $result = $this->api->getRequest( + new SimpleRequest( + 'query', [ + 'list' => 'users', + 'ususers' => $username, + 'usprop' => 'gender|emailable|registration|editcount|rights|implicitgroups|groups|blockinfo', + ] + ) + ); + + return $this->newUserFromListUsersResult( array_shift( $result['query']['users'] ) ); + } + + /** + * @param array $array + * + * @return User + */ + private function newUserFromListUsersResult( $array ) { + if ( array_key_exists( 'userid', $array ) ) { + return new User( + $array['name'], + $array['userid'], + $array['editcount'], + $array['registration'], + [ 'groups' => $array['groups'], 'implicitgroups' => $array['implicitgroups'] ], + $array['rights'], + $array['gender'] + ); + } else { + return new User( + $array['name'], + 0, + 0, + '', + [ 'groups' => [], 'implicitgroups' => [] ], + [], + '' + ); + } + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/UserRightsChanger.php b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/UserRightsChanger.php new file mode 100644 index 00000000..4fbea9c1 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/src/Service/UserRightsChanger.php @@ -0,0 +1,59 @@ +<?php + +namespace Mediawiki\Api\Service; + +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\User; + +/** + * @access private + * + * @author Addshore + */ +class UserRightsChanger extends Service { + + /** + * @since 0.3 + * + * @param User $user + * @param string[] $add + * @param string[] $remove + * @param array $extraParams + * + * @return bool + */ + public function change( + User $user, + $add = [], + $remove = [], + array $extraParams = [] + ) { + $result = $this->api->postRequest( + new SimpleRequest( + 'query', [ + 'list' => 'users', + 'ustoken' => 'userrights', + 'ususers' => $user->getName(), + ] + ) + ); + + $params = [ + 'user' => $user->getName(), + 'token' => $result['query']['users'][0]['userrightstoken'], + ]; + if ( !empty( $add ) ) { + $params['add'] = implode( '|', $add ); + } + if ( !empty( $remove ) ) { + $params['remove'] = implode( '|', $remove ); + } + + $this->api->postRequest( + new SimpleRequest( 'userrights', array_merge( $extraParams, $params ) ) + ); + + return true; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/fixtures/blue β³π²β₯πππΎπΈβ΄πΉβ―.png b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/fixtures/blue β³π²β₯πππΎπΈβ΄πΉβ―.png Binary files differnew file mode 100644 index 00000000..9f8efbc8 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/fixtures/blue β³π²β₯πππΎπΈβ΄πΉβ―.png diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/fixtures/namespaces.json b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/fixtures/namespaces.json new file mode 100644 index 00000000..2933692a --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/fixtures/namespaces.json @@ -0,0 +1,241 @@ +{ + "batchcomplete": "", + "query": { + "namespaces": { + "-2": { + "id": -2, + "case": "first-letter", + "canonical": "Media", + "*": "Medium" + }, + "-1": { + "id": -1, + "case": "first-letter", + "canonical": "Special", + "*": "Spezial" + }, + "0": { + "id": 0, + "case": "first-letter", + "content": "", + "*": "" + }, + "1": { + "id": 1, + "case": "first-letter", + "subpages": "", + "canonical": "Talk", + "*": "Diskussion" + }, + "2": { + "id": 2, + "case": "first-letter", + "subpages": "", + "canonical": "User", + "*": "Benutzer" + }, + "3": { + "id": 3, + "case": "first-letter", + "subpages": "", + "canonical": "User talk", + "*": "Benutzer Diskussion" + }, + "4": { + "id": 4, + "case": "first-letter", + "subpages": "", + "canonical": "Project", + "*": "Wikipedia" + }, + "5": { + "id": 5, + "case": "first-letter", + "subpages": "", + "canonical": "Project talk", + "*": "Wikipedia Diskussion" + }, + "6": { + "id": 6, + "case": "first-letter", + "canonical": "File", + "*": "Datei" + }, + "7": { + "id": 7, + "case": "first-letter", + "subpages": "", + "canonical": "File talk", + "*": "Datei Diskussion" + }, + "8": { + "id": 8, + "case": "first-letter", + "canonical": "MediaWiki", + "*": "MediaWiki" + }, + "9": { + "id": 9, + "case": "first-letter", + "subpages": "", + "canonical": "MediaWiki talk", + "*": "MediaWiki Diskussion" + }, + "10": { + "id": 10, + "case": "first-letter", + "canonical": "Template", + "*": "Vorlage" + }, + "11": { + "id": 11, + "case": "first-letter", + "subpages": "", + "canonical": "Template talk", + "*": "Vorlage Diskussion" + }, + "12": { + "id": 12, + "case": "first-letter", + "subpages": "", + "canonical": "Help", + "*": "Hilfe" + }, + "13": { + "id": 13, + "case": "first-letter", + "subpages": "", + "canonical": "Help talk", + "*": "Hilfe Diskussion" + }, + "14": { + "id": 14, + "case": "first-letter", + "subpages": "", + "canonical": "Category", + "*": "Kategorie" + }, + "15": { + "id": 15, + "case": "first-letter", + "subpages": "", + "canonical": "Category talk", + "*": "Kategorie Diskussion" + }, + "100": { + "id": 100, + "case": "first-letter", + "subpages": "", + "canonical": "Portal", + "*": "Portal" + }, + "101": { + "id": 101, + "case": "first-letter", + "subpages": "", + "canonical": "Portal Diskussion", + "*": "Portal Diskussion" + }, + "828": { + "id": 828, + "case": "first-letter", + "subpages": "", + "canonical": "Module", + "*": "Modul" + }, + "829": { + "id": 829, + "case": "first-letter", + "subpages": "", + "canonical": "Module talk", + "*": "Modul Diskussion" + }, + "2300": { + "id": 2300, + "case": "first-letter", + "canonical": "Gadget", + "*": "Gadget" + }, + "2301": { + "id": 2301, + "case": "first-letter", + "canonical": "Gadget talk", + "*": "Gadget Diskussion" + }, + "2302": { + "id": 2302, + "case": "case-sensitive", + "canonical": "Gadget definition", + "defaultcontentmodel": "GadgetDefinition", + "*": "Gadget-Definition" + }, + "2303": { + "id": 2303, + "case": "case-sensitive", + "canonical": "Gadget definition talk", + "*": "Gadget-Definition Diskussion" + }, + "2600": { + "id": 2600, + "case": "first-letter", + "canonical": "Topic", + "defaultcontentmodel": "flow-board", + "*": "Thema" + } + }, + "namespacealiases": [ + { + "id": 2, + "*": "Benutzerin" + }, + { + "id": 3, + "*": "BD" + }, + { + "id": 3, + "*": "Benutzerin Diskussion" + }, + { + "id": 4, + "*": "WP" + }, + { + "id": 5, + "*": "WD" + }, + { + "id": 6, + "*": "Bild" + }, + { + "id": 6, + "*": "Image" + }, + { + "id": 7, + "*": "Bild Diskussion" + }, + { + "id": 7, + "*": "Image talk" + }, + { + "id": 12, + "*": "H" + }, + { + "id": 13, + "*": "HD" + }, + { + "id": 100, + "*": "P" + }, + { + "id": 101, + "*": "PD" + } + ] + } +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/CategoryTraverserTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/CategoryTraverserTest.php new file mode 100644 index 00000000..7161447d --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/CategoryTraverserTest.php @@ -0,0 +1,203 @@ +<?php + +namespace Mediawiki\Api\Test; + +use Mediawiki\Api\CategoryLoopException; +use Mediawiki\Api\Service\CategoryTraverser; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Title; +use Mediawiki\DataModel\Revision; +use Mediawiki\DataModel\Content; + +class CategoryTraverserTest extends \PHPUnit_Framework_TestCase { + + /** @var TestEnvironment */ + protected $testEnvironment; + + /** @var \Mediawiki\Api\MediawikiFactory */ + protected $factory; + + /** @var \Mediawiki\Api\Service\CategoryTraverser */ + protected $traverser; + + public function setUp() { + parent::setUp(); + $this->testEnvironment = TestEnvironment::newDefault(); + $this->factory = $this->testEnvironment->getFactory(); + $this->traverser = $this->factory->newCategoryTraverser(); + } + + /** + * A convenience wrapper around a PageDeleter. + * @param string[] $titles The titles to delete. + */ + public function deletePages( $titles ) { + $deleter = $this->factory->newPageDeleter(); + foreach ( $titles as $t ) { + // @todo Properly delete? + // $deleter->deleteFromPageTitle( new Title( $t ) ); + $this->savePage( $t, '' ); + } + } + + /** + * A convenience wrapper to a RevisionSaver. + * @param string $title The title of the new page. + * @param string $content The wikitext to save to the page. + * @return Page The saved Page. + */ + protected function savePage( $title, $content ) { + $pageIdentifier = new PageIdentifier( new Title( $title ) ); + $revision = new Revision( new Content( $content ), $pageIdentifier ); + $this->factory->newRevisionSaver()->save( $revision ); + return $this->factory->newPageGetter()->getFromPageIdentifier( $pageIdentifier ); + } + + /** + * Get a list of all pages in a category or any of its descendants. + */ + public function testDescendants() { + $rootCat = $this->savePage( 'Category:Root category', '' ); + $this->savePage( 'Category:Sub category B', '[[Category:Root category]]' ); + $this->savePage( 'Category:Sub category C', '[[Category:Root category]]' ); + $this->savePage( 'Test page A1', 'Testing. [[Category:Root category]]' ); + $this->savePage( 'Test page B1', 'Testing. [[Category:Sub category B]]' ); + $this->savePage( 'Test page B2', 'Testing. [[Category:Sub category B]]' ); + $this->savePage( 'Test page C1', 'Testing. [[Category:Sub category C]]' ); + $this->testEnvironment->runJobs(); + + $callback = function ( Page $pageInfo, Page $parentCat ) { + $parentCatName = $parentCat->getPageIdentifier()->getTitle()->getText(); + $thisPageName = $pageInfo->getPageIdentifier()->getTitle()->getText(); + if ( $parentCatName === 'Category:Root category' ) { + $this->assertEquals( 'Test page A1', $thisPageName ); + } + if ( $parentCatName === 'Category:Sub category C' ) { + $this->assertEquals( 'Test page C1', $thisPageName ); + } + }; + $this->traverser->addCallback( CategoryTraverser::CALLBACK_PAGE, $callback ); + $decendants = $this->traverser->descend( $rootCat ); + $this->assertCount( 4, $decendants->toArray() ); + $this->deletePages( [ + 'Category:Root category', + 'Category:Sub category B', + 'Category:Sub category C', + 'Test page A1', + 'Test page B1', + 'Test page B2', + 'Test page C1', + ] ); + } + + /** + * Make sure there aren't duplicate results when there are multiple paths to + * the same page. + */ + public function testDescendantsWithMultiplePaths() { + $grandparent = $this->savePage( 'Category:Grandparent', '' ); + $this->savePage( 'Category:Parent 1', '[[Category:Grandparent]]' ); + $this->savePage( 'Category:Parent 2', '[[Category:Grandparent]]' ); + $this->savePage( 'Parent 1', '[[Category:Grandparent]]' ); + $this->savePage( 'Child 1', '[[Category:Parent 1]]' ); + $this->savePage( 'Child 2', '[[Category:Parent 1]]' ); + $this->savePage( 'Child 3', '[[Category:Parent 2]]' ); + $this->testEnvironment->runJobs(); + $decendants = $this->traverser->descend( $grandparent ); + $this->assertCount( 4, $decendants->toArray() ); + $this->deletePages( [ + 'Category:Grandparent', + 'Category:Parent 1', + 'Category:Parent 2', + 'Child 1', + 'Child 2', + 'Child 3', + ] ); + } + + /** + * Categories should only be traversed once. For example, in the following graph, 'C' can be + * reached as a child of 'A' or of 'B', but only the first arrival will proceed to 'D': + * + * A + * | \ + * | B + * | / + * C + * | + * D + * + */ + public function testDescendantsOnlyVisitCatsOnce() { + global $wgVisitedCats; + $wgVisitedCats = []; + $catA = $this->savePage( 'Category:A cat', '' ); + $this->savePage( 'Category:B cat', 'Testing. [[Category:A cat]]' ); + $this->savePage( 'Category:C cat', 'Testing. [[Category:A cat]][[Category:B cat]]' ); + $this->savePage( 'Category:D cat', 'Testing. [[Category:C cat]]' ); + $this->testEnvironment->runJobs(); + $callback = function ( Page $pageInfo, Page $parentCat ) { + global $wgVisitedCats; + $wgVisitedCats[] = $parentCat->getPageIdentifier()->getTitle()->getText(); + }; + $this->traverser->addCallback( CategoryTraverser::CALLBACK_CATEGORY, $callback ); + $descendants = $this->traverser->descend( $catA ); + $this->assertCount( 0, $descendants->toArray() ); + $this->assertCount( 3, $wgVisitedCats ); + $this->deletePages( [ + 'Category:A cat', + 'Category:B cat', + 'Category:C cat', + 'Category:D cat', + ] ); + } + + /** + * Category loops are caught on descent. + * + * E + * / \ + * F G + * / \ + * H I + * | + * E <-- throw an Exception when we get to this repetition + * + */ + public function testDescendIntoLoop() { + $catA = $this->savePage( 'Category:E cat', '[[Category:H cat]]' ); + $catB = $this->savePage( 'Category:F cat', '[[Category:E cat]]' ); + $catC = $this->savePage( 'Category:G cat', '[[Category:E cat]]' ); + $catD = $this->savePage( 'Category:H cat', '[[Category:F cat]]' ); + $catE = $this->savePage( 'Category:I cat', '[[Category:F cat]]' ); + $this->testEnvironment->runJobs(); + $haveCaught = false; + try { + $this->traverser->descend( $catA ); + } catch ( CategoryLoopException $ex ) { + $haveCaught = true; + $expectedCatLoop = [ + 'Category:E cat', + 'Category:F cat', + 'Category:H cat', + ]; + // Build a simplified representation of the thrown loop pages, to get around different + // revision IDs. + $actualCatLoop = []; + foreach ( $ex->getCategoryPath()->toArray() as $p ) { + $actualCatLoop[] = $p->getPageIdentifier()->getTitle()->getText(); + } + $this->assertEquals( $expectedCatLoop, $actualCatLoop ); + } + $this->assertTrue( $haveCaught ); + $this->deletePages( [ + 'Category:E cat', + 'Category:F cat', + 'Category:G cat', + 'Category:H cat', + 'Category:I cat', + ] ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/FileUploaderTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/FileUploaderTest.php new file mode 100755 index 00000000..e805ee1d --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/FileUploaderTest.php @@ -0,0 +1,75 @@ +<?php + +namespace Mediawiki\Api\Test; + +use Mediawiki\Api\ApiUser; +use Mediawiki\Api\MediawikiApi; +use Mediawiki\Api\MediawikiFactory; +use Mediawiki\Api\Service\FileUploader; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Title; +use PHPUnit_Framework_TestCase; + +/** + * Test the \Mediawiki\Api\Service\FileUploader class. + */ +class FileUploaderTest extends PHPUnit_Framework_TestCase { + + /** @var MediawikiFactory */ + protected $factory; + + /** @var FileUploader */ + protected $fileUploader; + + /** + * Create a FileUploader to use in all these tests. + */ + public function setup() { + parent::setup(); + $testEnvironment = TestEnvironment::newDefault(); + $this->factory = $testEnvironment->getFactory(); + $this->fileUploader = $this->factory->newFileUploader(); + + // Log in as the sysop user. These credentials are referenced in docs/contributing.rst. + $localApiUser = new ApiUser( 'admin', 'admin123' ); + $api = $testEnvironment->getApi(); + $api->login( $localApiUser ); + } + + public function testUpload() { + $testPagename = uniqid( 'file-uploader-test-' ) . '.png'; + $testTitle = new Title( 'File:'.$testPagename ); + + // Check that the file doesn't exist yet. + $testFile = $this->factory->newPageGetter()->getFromTitle( $testTitle ); + $this->assertEquals( 0, $testFile->getPageIdentifier()->getId() ); + + // Upload a file. + $testFilename = dirname( __DIR__ ) . '/fixtures/blue β³π²β₯πππΎπΈβ΄πΉβ―.png'; + $uploaded = $this->fileUploader->upload( $testPagename, $testFilename, 'Testing', + null, null, true ); + $this->assertTrue( $uploaded ); + + // Get the file again, and check that it exists this time. + $testFile2 = $this->factory->newPageGetter()->getFromTitle( $testTitle ); + $this->assertGreaterThan( 0, $testFile2->getPageIdentifier()->getId() ); + } + + public function testUploadByChunks() { + $testPagename = uniqid( 'file-uploader-test-' ) . '.png'; + $testTitle = new Title( 'File:'.$testPagename ); + + // Upload a 83725 byte file in 10k chunks. + $testFilename = dirname( __DIR__ ) . '/fixtures/blue β³π²β₯πππΎπΈβ΄πΉβ―.png'; + $this->fileUploader->setChunkSize( 1024 * 10 ); + $uploaded = $this->fileUploader->upload( $testPagename, $testFilename, 'Testing', + null, null, true ); + $this->assertTrue( $uploaded ); + + // Get the file again, and check that it exists this time. + $testFile2 = $this->factory->newPageGetter()->getFromTitle( $testTitle ); + $this->assertGreaterThan( 0, $testFile2->getPageIdentifier()->getId() ); + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/NamespaceGetterTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/NamespaceGetterTest.php new file mode 100644 index 00000000..eea55f9f --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/NamespaceGetterTest.php @@ -0,0 +1,86 @@ +<?php + +namespace Mediawiki\Api\Test; + +use Mediawiki\Api\MediawikiApi; +use Mediawiki\Api\Service\NamespaceGetter; +use Mediawiki\Api\SimpleRequest; +use Mediawiki\DataModel\NamespaceInfo; + +class NamespaceGetterTest extends \PHPUnit_Framework_TestCase { + public function testGetNamespaceByCanonicalNameReturnsNullIfNamespaceWasNotFound() { + $nsGetter = new NamespaceGetter( $this->getApi() ); + $this->assertNull( $nsGetter->getNamespaceByCanonicalName( 'Dummy' ) ); + } + + public function testGetNamespaceByCanonicalNameReturnsNamespaceIfNamespaceWasFound() { + $nsGetter = new NamespaceGetter( $this->getApi() ); + $expectedNamespace = new NamespaceInfo( 1, 'Talk', 'Diskussion', 'first-letter' ); + $this->assertEquals( $expectedNamespace, $nsGetter->getNamespaceByCanonicalName( 'Talk' ) ); + } + + public function testGetNamespaceByNameTriesAllNames() { + $nsGetter = new NamespaceGetter( $this->getApi() ); + $expectedNamespace = new NamespaceInfo( 1, 'Talk', 'Diskussion', 'first-letter' ); + $this->assertEquals( $expectedNamespace, $nsGetter->getNamespaceByName( 'Talk' ) ); + $this->assertEquals( $expectedNamespace, $nsGetter->getNamespaceByName( 'Diskussion' ) ); + } + + public function testGetNamespaceByNameTriesAliases() { + $nsGetter = new NamespaceGetter( $this->getApi() ); + $expectedNamespace = new NamespaceInfo( + 3, + 'User talk', + 'Benutzer Diskussion', + 'first-letter', + null, + [ 'BD', 'Benutzerin Diskussion' ] + ); + $this->assertEquals( $expectedNamespace, $nsGetter->getNamespaceByName( + 'Benutzerin Diskussion' + ) ); + $this->assertEquals( $expectedNamespace, $nsGetter->getNamespaceByName( 'BD' ) ); + } + + public function testGetNamespacesReturnsAllNamespaces() { + $nsGetter = new NamespaceGetter( $this->getApi() ); + $talkNamespace = new NamespaceInfo( 1, 'Talk', 'Diskussion', 'first-letter' ); + $gadgetNamespace = new NamespaceInfo( + 2302, + 'Gadget definition', + 'Gadget-Definition', + 'case-sensitive', + 'GadgetDefinition' + ); + $namespaces = $nsGetter->getNamespaces(); + $this->assertCount( 27, $namespaces ); + $this->assertArrayHasKey( 1, $namespaces ); + $this->assertEquals( $talkNamespace, $namespaces[1] ); + $this->assertArrayHasKey( 2302, $namespaces ); + $this->assertEquals( $gadgetNamespace, $namespaces[2302] ); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject|MediawikiApi + */ + private function getApi() { + $api = $this->getMockBuilder( MediawikiApi::class )->disableOriginalConstructor()->getMock(); + $api->expects( $this->any() ) + ->method( 'getRequest' ) + ->with( $this->getRequest() ) + ->willReturn( $this->getNamespaceFixture() ); + return $api; + } + + private function getRequest() { + return new SimpleRequest( + 'query', [ + 'meta' => 'siteinfo', + 'siprop' => 'namespaces|namespacealiases' + ] ); + } + + private function getNamespaceFixture() { + return json_decode( file_get_contents( __DIR__ . '/../fixtures/namespaces.json' ), true ); + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/PageIntegrationTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/PageIntegrationTest.php new file mode 100644 index 00000000..673eac8f --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/PageIntegrationTest.php @@ -0,0 +1,66 @@ +<?php + +namespace Mediawiki\Api\Test; + +use Mediawiki\DataModel\Content; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Revision; +use Mediawiki\DataModel\Title; +use PHPUnit_Framework_TestCase; + +/** + * @author Addshore + */ +class PageIntegrationTest extends PHPUnit_Framework_TestCase { + + /** + * @var PageIdentifier + */ + private static $localPageIdentifier; + + public static function setUpBeforeClass() { + parent::setUpBeforeClass(); + $title = new Title( 'TestPage - ' . strval( time() ) ); + self::$localPageIdentifier = new PageIdentifier( $title ); + } + + public function testCreatePage() { + $factory = TestEnvironment::newDefault()->getFactory(); + $this->assertTrue( + $factory->newRevisionSaver()->save( + new Revision( + new Content( 'testCreatePage_content' ), + self::$localPageIdentifier + ) + ), + 'Failed to Create Page ' . self::$localPageIdentifier->getTitle()->getText() + ); + } + + /** + * This is testGetPageUsingTitle as currently we only know the title + * @depends testCreatePage + */ + public function testGetPageUsingTitle() { + $factory = TestEnvironment::newDefault()->getFactory(); + $page = $factory->newPageGetter()->getFromPageIdentifier( self::$localPageIdentifier ); + $this->assertTrue( is_int( $page->getPageIdentifier()->getId() ) ); + $title = $page->getPageIdentifier()->getTitle(); + $this->assertEquals( self::$localPageIdentifier->getTitle(), $title ); + $content = $page->getRevisions()->getLatest()->getContent()->getData(); + $this->assertEquals( 'testCreatePage_content', $content ); + self::$localPageIdentifier = $page->getPageIdentifier(); + } + + /** + * @depends testGetPageUsingTitle + */ + public function testGetPageUsingId() { + $factory = TestEnvironment::newDefault()->getFactory(); + $page = $factory->newPageGetter()->getFromPageId( self::$localPageIdentifier->getId() ); + $this->assertEquals( self::$localPageIdentifier->getId(), $page->getPageIdentifier()->getId() ); + $title = $page->getPageIdentifier()->getTitle(); + $this->assertEquals( self::$localPageIdentifier->getTitle(), $title ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/PageListGetterTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/PageListGetterTest.php new file mode 100644 index 00000000..39a973a4 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/PageListGetterTest.php @@ -0,0 +1,99 @@ +<?php + +namespace Mediawiki\Api\Test; + +use Mediawiki\DataModel\Content; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Revision; +use Mediawiki\DataModel\Title; +use PHPUnit_Framework_TestCase; + +/** + * Test the \Mediawiki\Api\Service\PageListGetter class. + */ +class PageListGetterTest extends PHPUnit_Framework_TestCase { + + /** @var string */ + private $emptyCatName = 'Category:Empty category'; + + /** @var string */ + private $nonemptyCatName = 'Category:Test category'; + + /** @var \Mediawiki\Api\Service\PageListGetter */ + private $pageListGetter; + + /** + * Set up some test categories and pages. + */ + public function setUp() { + $testEnvironment = TestEnvironment::newDefault(); + $factory = $testEnvironment->getFactory(); + + // An empty category. + $emptyCat = new PageIdentifier( new Title( $this->emptyCatName ) ); + $factory->newRevisionSaver()->save( new Revision( new Content( '' ), $emptyCat ) ); + + // A non-empty category. + $testCat = new PageIdentifier( new Title( $this->nonemptyCatName ) ); + $factory->newRevisionSaver()->save( new Revision( new Content( '' ), $testCat ) ); + + // Some pages in the latter. + // (Count must exceed the default categorymember result set size of 10.) + $revisionSaver = $factory->newRevisionSaver(); + for ( $i = 1; $i <= 35; $i++ ) { + $testCat = new PageIdentifier( new Title( "Test page $i" ) ); + // Even pages link to Main Page, odd pages transclude {{test}}. + $mainPageLink = ( ( $i % 2 ) == 0 ) ? 'Go to [[Main Page]].' : 'This is a {{test}}.'; + $content = new Content( "$mainPageLink\n\n[[$this->nonemptyCatName]]" ); + $revisionSaver->save( new Revision( $content, $testCat ) ); + } + + // Run all jobs, to make sure everything is up to date. + $testEnvironment->runJobs(); + + $this->pageListGetter = $factory->newPageListGetter(); + } + + public function testGetPageListFromCategoryName() { + // The empty category. + $emptyCategory = $this->pageListGetter->getPageListFromCategoryName( $this->emptyCatName ); + $this->assertCount( 0, $emptyCategory->toArray() ); + + // The nonempty category. + $testCategory = $this->pageListGetter->getPageListFromCategoryName( $this->nonemptyCatName ); + $this->assertCount( 35, $testCategory->toArray() ); + } + + public function testGetPageListFromPageTransclusions() { + $linksHere = $this->pageListGetter->getPageListFromPageTransclusions( 'Template:Test' ); + // Only odd-numbered test pages link to the 'Test' template. + $this->assertCount( 18, $linksHere->toArray() ); + } + + public function testGetFromWhatLinksHere() { + // Every even-numbered test page links to Main Page. + $mainPageLinks = $this->pageListGetter->getFromWhatLinksHere( 'Main Page' ); + $this->assertCount( 17, $mainPageLinks->toArray() ); + + // Nothing links to 'Test page 4'. + $testPageLinks = $this->pageListGetter->getFromWhatLinksHere( 'Test page 4' ); + $this->assertCount( 0, $testPageLinks->toArray() ); + } + + public function testGetFromPrefix() { + // Pages with this prefix should be test pages 1, & 10-15; i.e. 7 of them. + $testPages = $this->pageListGetter->getFromPrefix( 'Test page 1' ); + $this->assertCount( 11, $testPages->toArray() ); + } + + public function testGetRandom() { + // Default is 1. + $randomPages1 = $this->pageListGetter->getRandom(); + $this->assertCount( 1, $randomPages1->toArray() ); + + // 8 random pages. + $randomPages2 = $this->pageListGetter->getRandom( [ 'rnlimit' => 8 ] ); + $this->assertCount( 8, $randomPages2->toArray() ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/TestEnvironment.php b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/TestEnvironment.php new file mode 100644 index 00000000..f40c0cd9 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/TestEnvironment.php @@ -0,0 +1,116 @@ +<?php + +namespace Mediawiki\Api\Test; + +use Mediawiki\Api\Guzzle\ClientFactory; +use Mediawiki\Api\MediawikiApi; +use Mediawiki\Api\MediawikiFactory; +use Mediawiki\Api\SimpleRequest; +use Monolog\Handler\StreamHandler; +use Monolog\Logger; + +/** + * @author Addshore + */ +class TestEnvironment { + + /** @var \Mediawiki\Api\MediawikiFactory */ + private $factory; + + /** @var MediawikiApi */ + protected $api; + + /** + * Get a new default test environment. + * @return TestEnvironment + */ + public static function newDefault() { + return new self(); + } + + /** + * Set up the test environment by creating a new API object pointing to a + * MediaWiki installation on localhost (or elsewhere as specified by the + * MEDIAWIKI_API_URL environment variable). + */ + public function __construct() { + $this->factory = new MediawikiFactory( $this->getApi() ); + } + + /** + * Get the MediawikiApi to test against, based on the MEDIAWIKI_API_URL environment variable. + * @return MediawikiApi + * @throws \Exception If the MEDIAWIKI_API_URL environment variable does not end in 'api.php' + */ + public function getApi() { + if ( $this->api instanceof MediawikiApi ) { + return $this->api; + } + $apiUrl = getenv( 'MEDIAWIKI_API_URL' ); + if ( empty( $apiUrl ) ) { + $apiUrl = 'http://localhost/w/api.php'; + } elseif ( substr( $apiUrl, -7 ) !== 'api.php' ) { + $msg = "URL incorrect: $apiUrl" + . " (the MEDIAWIKI_API_URL environment variable should end in 'api.php')"; + throw new \Exception( $msg ); + } + + // Log to a local file. + $logger = new Logger( 'mediawiki-api' ); + $logFile = __DIR__ . '/../../log/mediawiki-api.log'; + $logger->pushHandler( new StreamHandler( $logFile, Logger::DEBUG ) ); + + // Create and return the API object. + $this->api = new MediawikiApi( $apiUrl ); + $this->api->setLogger( $logger ); + return $this->api; + } + + /** + * Get the MediaWiki factory. + * + * @return \Mediawiki\Api\MediawikiFactory The factory instance. + */ + public function getFactory() { + return $this->factory; + } + + /** + * Run all jobs in the queue. This only works if the MediaWiki installation has $wgJobRunRate + * set to greater than zero (for test-running, you should set it to something higher than 50). + * @todo This and TestEnvironment::getJobQueueLength() should probably not live here. + * @return void + */ + public function runJobs() { + $reqestProps = [ 'meta' => 'siteinfo', 'siprop' => 'general' ]; + $siteInfoRequest = new SimpleRequest( 'query', $reqestProps ); + $out = $this->getApi()->getRequest( $siteInfoRequest ); + $mainPageUrl = $out['query']['general']['base']; + $i = 0; + while ( $this->getJobQueueLength( $this->getApi() ) > 0 ) { + $i++; + $cf = new ClientFactory(); + $cf->getClient()->get( $mainPageUrl ); + if ($i == 10) { + // Give up if we've been looping too much. This is very arbitrary. + break; + } + } + } + + /** + * Get the number of jobs currently in the queue. + * @todo This and TestEnvironment::runJobs() should probably not live here. + * @param MediawikiApi $api + * @return int + */ + public function getJobQueueLength( MediawikiApi $api ) { + $req = new SimpleRequest( 'query', [ + 'meta' => 'siteinfo', + 'siprop' => 'statistics', + ] + ); + $out = $api->getRequest( $req ); + return (int)$out['query']['statistics']['jobs']; + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/UserIntegrationTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/UserIntegrationTest.php new file mode 100644 index 00000000..29221edb --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/UserIntegrationTest.php @@ -0,0 +1,35 @@ +<?php + +namespace Mediawiki\Api\Test; + +use Mediawiki\Api\ApiUser; +use PHPUnit_Framework_TestCase; + +/** + * @author Addshore + */ +class UserIntegrationTest extends PHPUnit_Framework_TestCase { + + /** + * @var ApiUser + */ + private static $localApiUser; + + public static function setUpBeforeClass() { + parent::setUpBeforeClass(); + $strTime = strval( time() ); + self::$localApiUser = new ApiUser( 'TestUser - ' . strval( time() ), $strTime . '-pass' ); + } + + public function testCreateUser() { + $factory = TestEnvironment::newDefault()->getFactory(); + $createResult = $factory->newUserCreator()->create( + self::$localApiUser->getUsername(), + + + self::$localApiUser->getPassword() + ); + $this->assertTrue( $createResult ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/phpunit.xml.dist b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/phpunit.xml.dist new file mode 100644 index 00000000..4a0040c3 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/integration/phpunit.xml.dist @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- convertWarningsToExceptions is false as real API calls can return un expected warnings --> +<phpunit + bootstrap="../../vendor/autoload.php" + colors="true" + convertWarningsToExceptions="false" + > + <testsuites> + <testsuite name="addwiki/mediawiki-api/integration"> + <directory suffix="Test.php">.</directory> + </testsuite> + </testsuites> + <filter> + <whitelist addUncoveredFilesFromWhitelist="true"> + <directory suffix=".php">./../../src</directory> + </whitelist> + </filter> +</phpunit>
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/Generator/AnonymousGeneratorTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/Generator/AnonymousGeneratorTest.php new file mode 100644 index 00000000..67d6e450 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/Generator/AnonymousGeneratorTest.php @@ -0,0 +1,26 @@ +<?php + +namespace Mediawiki\Api\Test\Generator; + +use Mediawiki\Api\Generator\AnonymousGenerator; + +/** + * @author Addshore + * + * @covers \Mediawiki\Api\Generator\AnonymousGenerator + */ +class AnonymousGeneratorTest extends \PHPUnit_Framework_TestCase { + + public function testConstruction() { + $generator = new AnonymousGenerator( 'name', [ 'gfoo' => 'bar' ] ); + + $this->assertEquals( + [ + 'generator' => 'name', + 'gfoo' => 'bar', + ], + $generator->getParams() + ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/Generator/FluentGeneratorTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/Generator/FluentGeneratorTest.php new file mode 100644 index 00000000..bd7cb0bf --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/Generator/FluentGeneratorTest.php @@ -0,0 +1,55 @@ +<?php + +namespace Mediawiki\Api\Test\Generator; + +use Mediawiki\Api\Generator\FluentGenerator; + +/** + * @author Addshore + * + * @covers \Mediawiki\Api\Generator\FluentGenerator + */ +class FluentGeneratorTest extends \PHPUnit_Framework_TestCase { + + public function testConstructionWithNoGPrefix() { + $generator = new FluentGenerator( 'name' ); + $generator->set( 'foo', 'bar' ); + + $this->assertEquals( + [ + 'generator' => 'name', + 'gfoo' => 'bar', + ], + $generator->getParams() + ); + } + + public function testConstructionWithGPrefix() { + $generator = new FluentGenerator( 'name' ); + $generator->set( 'gfoo', 'bar' ); + + $this->assertEquals( + [ + 'generator' => 'name', + 'gfoo' => 'bar', + ], + $generator->getParams() + ); + } + + public function testFluidity() { + $generator = FluentGenerator::factory( 'name' ) + ->set( 'foo', 'bar' ) + ->set( 'gcat', 'meow' ); + + $this->assertEquals( + [ + 'generator' => 'name', + 'gfoo' => 'bar', + 'gcat' => 'meow', + ], + $generator->getParams() + ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/MediawikiFactoryTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/MediawikiFactoryTest.php new file mode 100644 index 00000000..c4ce958f --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/MediawikiFactoryTest.php @@ -0,0 +1,54 @@ +<?php + +namespace Mediawiki\Api\Test; + +use Mediawiki\Api\MediawikiFactory; + +/** + * @covers Mediawiki\Api\MediawikiFactory + * + * @author Addshore + */ +class MediawikiFactoryTest extends \PHPUnit_Framework_TestCase { + + public function getMockMediawikiApi() { + return $this->getMockBuilder( 'Mediawiki\Api\MediawikiApi' ) + ->disableOriginalConstructor() + ->getMock(); + } + + public function provideFactoryMethodsTest() { + return [ + [ 'Mediawiki\Api\Service\RevisionSaver', 'newRevisionSaver' ], + [ 'Mediawiki\Api\Service\RevisionUndoer', 'newRevisionUndoer' ], + [ 'Mediawiki\Api\Service\PageGetter', 'newPageGetter' ], + [ 'Mediawiki\Api\Service\UserGetter', 'newUserGetter' ], + [ 'Mediawiki\Api\Service\PageDeleter', 'newPageDeleter' ], + [ 'Mediawiki\Api\Service\PageMover', 'newPageMover' ], + [ 'Mediawiki\Api\Service\PageListGetter', 'newPageListGetter' ], + [ 'Mediawiki\Api\Service\PageRestorer', 'newPageRestorer' ], + [ 'Mediawiki\Api\Service\PagePurger', 'newPagePurger' ], + [ 'Mediawiki\Api\Service\RevisionRollbacker', 'newRevisionRollbacker' ], + [ 'Mediawiki\Api\Service\RevisionPatroller', 'newRevisionPatroller' ], + [ 'Mediawiki\Api\Service\PageProtector', 'newPageProtector' ], + [ 'Mediawiki\Api\Service\PageWatcher', 'newPageWatcher' ], + [ 'Mediawiki\Api\Service\RevisionDeleter', 'newRevisionDeleter' ], + [ 'Mediawiki\Api\Service\RevisionRestorer', 'newRevisionRestorer' ], + [ 'Mediawiki\Api\Service\UserBlocker', 'newUserBlocker' ], + [ 'Mediawiki\Api\Service\UserRightsChanger', 'newUserRightsChanger' ], + [ 'Mediawiki\Api\Service\UserCreator', 'newUserCreator' ], + [ 'Mediawiki\Api\Service\LogListGetter', 'newLogListGetter' ], + [ 'Mediawiki\Api\Service\FileUploader', 'newFileUploader' ], + [ 'Mediawiki\Api\Service\ImageRotator', 'newImageRotator' ], + ]; + } + + /** + * @dataProvider provideFactoryMethodsTest + */ + public function testFactoryMethod( $class, $method ) { + $factory = new MediawikiFactory( $this->getMockMediawikiApi() ); + $this->assertInstanceOf( $class, $factory->$method() ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/Service/PagePurgerTest.php b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/Service/PagePurgerTest.php new file mode 100644 index 00000000..38199c26 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/Service/PagePurgerTest.php @@ -0,0 +1,187 @@ +<?php + +namespace Mediawiki\Api\Test\Service; + +use Mediawiki\Api\MediawikiApi; +use Mediawiki\Api\Service\PagePurger; +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\Pages; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Title; +use PHPUnit_Framework_MockObject_MockObject; + +/** + * @author Addshore + * @covers Mediawiki\Api\Service\PagePurger + */ +class PagePurgerTest extends \PHPUnit_Framework_TestCase { + + private function getMockApi() { + /** @var MediawikiApi|PHPUnit_Framework_MockObject_MockObject $mock */ + $mock = $this->getMockBuilder( '\Mediawiki\Api\MediawikiApi' ) + ->disableOriginalConstructor() + ->getMock(); + return $mock; + } + + public function testValidConstruction() { + new PagePurger( $this->getMockApi() ); + $this->assertTrue( true ); + } + + public function testPurgePage() { + $api = $this->getMockApi(); + $api->expects( $this->once() ) + ->method( 'postRequest' ) + ->with( + $this->isInstanceOf( '\Mediawiki\Api\SimpleRequest' ) + ) + ->will( $this->returnValue( + [ + "batchcomplete" => "", + "purge" => [ [ "ns" => 0, "title" => "Foo", "purged" => "" ] ] + ] ) ); + + $service = new PagePurger( $api ); + + $page = new Page( + new PageIdentifier( + new Title( 'Foo', 0 ), + 123 + ) + ); + + $this->assertTrue( $service->purge( $page ) ); + } + + function testIncorrectPurgePage() { + $api = $this->getMockApi(); + $api->expects( $this->once() ) + ->method( 'postRequest' ) + ->with( + $this->isInstanceOf( '\Mediawiki\Api\SimpleRequest' ) + ) + ->will( $this->returnValue( [ + "batchcomplete" => "", + "purge" => + [ [ + "ns" => 0, + "title" => "This page really does not exist", + "missing" => "" + ] ] + ] ) ); + + $service = new PagePurger( $api ); + + $page = new Page( + new PageIdentifier( + new Title( 'Foo', 0 ), + 123 + ) + ); + + $this->assertFalse( $service->purge( $page ) ); + } + + public function testPurgePages() { + $api = $this->getMockApi(); + $api->expects( $this->once() ) + ->method( 'postRequest' ) + ->with( + $this->isInstanceOf( '\Mediawiki\Api\SimpleRequest' ) + ) + ->will( $this->returnValue( + [ + "batchcomplete" => "", + "purge" => [ + [ + "ns" => 0, + "title" => "Foo", + "purged" => "" + ], + [ + "ns" => 0, + "title" => "Bar", + "purged" => "" + ], + ] + ] + ) ); + + $service = new PagePurger( $api ); + + $pages = new Pages( [ + new Page( + new PageIdentifier( + new Title( 'Foo', 0 ), + 100 + ) + ), new Page( + new PageIdentifier( + new Title( 'Bar', 1 ), + 101 + ) + ) ] ); + + $this->assertEquals( $service->purgePages( $pages ), $pages ); + } + + function testIncorrectPurgePages() { + $api = $this->getMockApi(); + $api->expects( $this->once() ) + ->method( 'postRequest' ) + ->with( + $this->isInstanceOf( '\Mediawiki\Api\SimpleRequest' ) + ) + ->will( $this->returnValue( + [ + "batchcomplete" => "", + "purge" => [ + [ + "ns" => 0, + "title" => "Foo", + "purged" => "" + ], + [ + "ns" => 0, + "title" => "Bar", + "purged" => "" + ], + [ + "ns" => 0, + "title" => "This page really does not exist", + "missing" => "" + ], + ] + ] + ) ); + + $service = new PagePurger( $api ); + + $pages = new Pages( [ + new Page( + new PageIdentifier( + new Title( 'Foo', 0 ), + 100 + ) + ), new Page( + new PageIdentifier( + new Title( 'Bar', 1 ), + 101 + ) + ), new Page( + new PageIdentifier( + new Title( 'MissingPage', 1 ), + 103 + ) + ) ] ); + + // MissingPage is not in the pages that are returned by purgePages + $pagesArray = $pages->toArray(); + array_pop( $pagesArray ); + $result = new Pages( $pagesArray ); + + $this->assertEquals( $service->purgePages( $pages ), $result ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/phpunit.xml.dist b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/phpunit.xml.dist new file mode 100644 index 00000000..8f4cecef --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-api/tests/unit/phpunit.xml.dist @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<phpunit bootstrap="../../vendor/autoload.php" colors="true"> + <testsuites> + <testsuite name="addwiki/mediawiki-api/unit"> + <directory suffix="Test.php">.</directory> + </testsuite> + </testsuites> + <filter> + <whitelist addUncoveredFilesFromWhitelist="true"> + <directory suffix=".php">./../../src</directory> + </whitelist> + </filter> +</phpunit>
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/.gitignore b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/.gitignore new file mode 100644 index 00000000..014936d3 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/.gitignore @@ -0,0 +1,5 @@ +.idea +vendor +composer.lock +test.php +docs/_build diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/.scrutinizer.yml b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/.scrutinizer.yml new file mode 100644 index 00000000..ffc976e3 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/.scrutinizer.yml @@ -0,0 +1,13 @@ +inherit: true + +tools: + 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 + external_code_coverage: + timeout: 300
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/.travis.yml b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/.travis.yml new file mode 100644 index 00000000..a58745e1 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/.travis.yml @@ -0,0 +1,25 @@ +language: php + +php: + - hhvm + - 5.5 + - 5.6 + - 7.0 + - 7.1 + +before_script: + - composer install + +script: + - ./vendor/bin/phpunit --coverage-clover=coverage.clover + +after_script: + - wget https://scrutinizer-ci.com/ocular.phar + - php ocular.phar code-coverage:upload --format=php-clover coverage.clover + +notifications: + irc: + channels: + - "chat.freenode.net##add" + on_success: change + on_failure: always diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/LICENSE.md b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/LICENSE.md new file mode 100644 index 00000000..0671f06a --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/LICENSE.md @@ -0,0 +1,264 @@ +The GNU General Public License, Version 2, June 1991 (GPLv2) +============================================================ + +> 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 Library 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. + + +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. diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/README.md b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/README.md new file mode 100644 index 00000000..f0fdf1b1 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/README.md @@ -0,0 +1,17 @@ +mediawiki-datamodel +================== +[](https://travis-ci.org/addwiki/mediawiki-datamodel) +[](https://scrutinizer-ci.com/g/addwiki/mediawiki-datamodel/) +[](https://scrutinizer-ci.com/g/addwiki/mediawiki-datamodel/) + +On Packagist: +[](https://packagist.org/packages/addwiki/mediawiki-datamodel) +[](https://packagist.org/packages/addwiki/mediawiki-datamodel) + +Issue tracker: https://phabricator.wikimedia.org/project/profile/1490/ + +## Installation + +Use composer to install the library and all its dependencies: + + composer require "addwiki/mediawiki-datamodel:~0.7.0" diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/RELEASENOTES.md b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/RELEASENOTES.md new file mode 100644 index 00000000..08df4aab --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/RELEASENOTES.md @@ -0,0 +1,88 @@ +These are the release notes for the [mediawiki-datamodel](README.md). + +## Version 0.7.1 (10th January 2017) + +* [T184567](https://phabricator.wikimedia.org/T184567) `User` objects can now be created with a `null` `$registration`. + +## Version 0.7 (8th March 2017) + +#### New features + +* Add NamespaceInfo class + +## Version 0.6 (2015-09-04) + +#### Compatibility changes + +* Log object now takes a PageIdentifier object instead of a Page object + +#### Deprecations + +* Title::getTitle is deprecated + +#### New features + +* Implemented File class +* Implemented Redirect class +* Title::getText introduced to replace getTitle +* Log now implements JsonSerializable +* LogList now implements JsonSerializable +* Title now implements JsonSerializable +* PageIdentifier now implements JsonSerializable + +## Version 0.5 (2015-01-13) + +#### Compatibility changes + +* Revision objects now require a PageIdentifier object instead of a $pageId int +* Page objects now require a PageIdentifier objects instead of a $title and $pageId +* Content getNativeData renamed to getData +* Content constructor changed, now takes data and optional model +* Content has new method getModel in places of random constants +* Removed WikitextContent class. Content is no longer abstract. + +#### New features + +* Implemented Log class +* Implemented LogList class +* Introduce PageIdentifier class +* Page objects can be constructed without a Revisions object + +## Version 0.4 (2014-07-08) + +* Page objects now ONLY accept a Title object for $title in their constructor. +* InvalidArgumentExceptions are now thrown when objects are constructed with the wrong types. +* User objects now split up implicitgroups and regular groups, thus $groups is now array[] + + +## Version 0.3 (2014-06-24) + +#### Compatibility changes + +* Revision objects now take a Content object as $content + +#### Additions + +* Content class +* WikitextContent class +* Pages class + + +## Version 0.2 (2014-02-23) + +#### Compatibility changes + +* Revision enhanced to allow more flexibility, Constructor and public functions have changed +* contentmodel has been removed from the Page class + + +## Version 0.1 (2014-02-23) + +Initial release with the following features: + +* EditInfo +* Page +* Revision +* Revisions +* Title +* User diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/composer.json b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/composer.json new file mode 100644 index 00000000..9ac4e519 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/composer.json @@ -0,0 +1,32 @@ +{ + "name": "addwiki/mediawiki-datamodel", + "type": "library", + "description": "A Mediawiki datamodel", + "keywords": ["Mediawiki"], + "license": "GPL-2.0+", + "authors": [ + { + "name": "Addshore" + } + ], + "autoload": { + "psr-4": { + "Mediawiki\\DataModel\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Mediawiki\\DataModel\\Test\\": "tests/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "0.7.x-dev" + } + }, + "require-dev": { + "phpunit/phpunit": "~4.8.0|~5.3.0", + "jakub-onderka/php-parallel-lint": "0.9.2", + "mediawiki/mediawiki-codesniffer": "^13.0" + } +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/docs/Makefile b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/docs/Makefile new file mode 100644 index 00000000..af9b9d0b --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/docs/Makefile @@ -0,0 +1,225 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " applehelp to make an Apple Help Book" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " epub3 to make an epub3" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " coverage to run coverage check of the documentation (if enabled)" + @echo " dummy to check syntax errors of document sources" + +.PHONY: clean +clean: + rm -rf $(BUILDDIR)/* + +.PHONY: html +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +.PHONY: dirhtml +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +.PHONY: singlehtml +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +.PHONY: pickle +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +.PHONY: json +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +.PHONY: htmlhelp +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +.PHONY: qthelp +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/mediawiki-datamodel.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/mediawiki-datamodel.qhc" + +.PHONY: applehelp +applehelp: + $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp + @echo + @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." + @echo "N.B. You won't be able to view it unless you put it in" \ + "~/Library/Documentation/Help or install it in your application" \ + "bundle." + +.PHONY: devhelp +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/mediawiki-datamodel" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/mediawiki-datamodel" + @echo "# devhelp" + +.PHONY: epub +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +.PHONY: epub3 +epub3: + $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 + @echo + @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." + +.PHONY: latex +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +.PHONY: latexpdf +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: latexpdfja +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: text +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +.PHONY: man +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +.PHONY: texinfo +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +.PHONY: info +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +.PHONY: gettext +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +.PHONY: changes +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +.PHONY: linkcheck +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +.PHONY: doctest +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +.PHONY: coverage +coverage: + $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage + @echo "Testing of coverage in the sources finished, look at the " \ + "results in $(BUILDDIR)/coverage/python.txt." + +.PHONY: xml +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +.PHONY: pseudoxml +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." + +.PHONY: dummy +dummy: + $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy + @echo + @echo "Build finished. Dummy builder generates no files." diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/docs/conf.py b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/docs/conf.py new file mode 100644 index 00000000..1f465d00 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/docs/conf.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +import sys, os +from sphinx.highlighting import lexers +from pygments.lexers.web import PhpLexer + +lexers['php'] = PhpLexer(startinline=True, linenos=1) +lexers['php-annotations'] = PhpLexer(startinline=True, linenos=1) +primary_domain = 'php' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'mediawiki-datamodel' +copyright = '2016, addwiki' +author = 'addwiki' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.6' +# The full version, including alpha/beta/rc tags. +release = '0.6' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'default' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Output file base name for HTML help builder. +htmlhelp_basename = 'mediawiki-datamodeldoc' diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/docs/index.rst b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/docs/index.rst new file mode 100644 index 00000000..c862502f --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/docs/index.rst @@ -0,0 +1,22 @@ +.. mediawiki-datamodel documentation master file, created by + sphinx-quickstart on Sat Oct 1 18:15:20 2016. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to mediawiki-datamodel's documentation! +=============================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/docs/make.bat b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/docs/make.bat new file mode 100644 index 00000000..6ff153c5 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/docs/make.bat @@ -0,0 +1,281 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^<target^>` where ^<target^> is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. epub3 to make an epub3 + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + echo. coverage to run coverage check of the documentation if enabled + echo. dummy to check syntax errors of document sources + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +REM Check if sphinx-build is available and fallback to Python version if any +%SPHINXBUILD% 1>NUL 2>NUL +if errorlevel 9009 goto sphinx_python +goto sphinx_ok + +:sphinx_python + +set SPHINXBUILD=python -m sphinx.__init__ +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +:sphinx_ok + + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\mediawiki-datamodel.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\mediawiki-datamodel.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "epub3" ( + %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3 + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub3 file is in %BUILDDIR%/epub3. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "coverage" ( + %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage + if errorlevel 1 exit /b 1 + echo. + echo.Testing of coverage in the sources finished, look at the ^ +results in %BUILDDIR%/coverage/python.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +if "%1" == "dummy" ( + %SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. Dummy builder generates no files. + goto end +) + +:end diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/phpunit.xml.dist b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/phpunit.xml.dist new file mode 100644 index 00000000..d8bbce08 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/phpunit.xml.dist @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<phpunit bootstrap="./vendor/autoload.php" colors="true"> + <testsuites> + <testsuite name="addwiki/mediawiki-datamodel"> + <directory suffix="Test.php">./tests</directory> + </testsuite> + </testsuites> + <filter> + <whitelist addUncoveredFilesFromWhitelist="true"> + <directory suffix=".php">src</directory> + </whitelist> + </filter> +</phpunit>
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Content.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Content.php new file mode 100644 index 00000000..c1372d46 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Content.php @@ -0,0 +1,83 @@ +<?php + +namespace Mediawiki\DataModel; + +use LogicException; + +/** + * Class Representing the content of a revision + * @author Addshore + */ +class Content { + + /** + * @var string sha1 hash of the object content upon creation + */ + private $initialHash; + + /** + * @var mixed + */ + private $data; + + /** + * @var string|null + */ + private $model; + + /** + * Should always be called AFTER overriding constructors so a hash can be created + * + * @param mixed $data + * @param string|null $model + */ + public function __construct( $data, $model = null ) { + $this->data = $data; + $this->model = $model; + $this->initialHash = $this->getHash(); + } + + /** + * @return string + */ + public function getModel() { + return $this->model; + } + + /** + * Returns a sha1 hash of the content + * + * @throws LogicException + * @return string + */ + public function getHash() { + $data = $this->getData(); + if( is_object( $data ) ) { + if( method_exists( $data, 'getHash' ) ) { + return $data->getHash(); + } else { + return sha1( serialize( $data ) ); + } + } + if( is_string( $data ) ) { + return sha1( $data ); + } + throw new LogicException( "Cant get hash for data of type: " . gettype( $data ) ); + } + + /** + * Has the content been changed since object construction (this shouldn't happen!) + * @return bool + */ + public function hasChanged() { + return $this->initialHash !== $this->getHash(); + } + + /** + * @return mixed + */ + public function getData() { + return $this->data; + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/EditInfo.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/EditInfo.php new file mode 100644 index 00000000..b6ba7845 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/EditInfo.php @@ -0,0 +1,79 @@ +<?php + +namespace Mediawiki\DataModel; + +use InvalidArgumentException; + +/** + * Represents flags that can be used when edits are made + * @author Addshore + */ +class EditInfo { + + //minor flags + const MINOR = true; + const NOTMINOR = false; + //bot flags + const BOT = true; + const NOTBOT = false; + + /** + * @var EditInfo::MINOR|self::NOTMINOR + */ + protected $minor = false; + + /** + * @var EditInfo::BOT|self::NOTBOT + */ + protected $bot = false; + + /** + * @var string + */ + protected $summary = null; + + /** + * @param string $summary + * @param bool $minor + * @param bool $bot + * + * @throws InvalidArgumentException + */ + public function __construct( $summary = '', $minor = self::NOTMINOR, $bot = self::NOTBOT ) { + if( !is_string( $summary ) ) { + throw new InvalidArgumentException( '$summary must be a string' ); + } + if( !is_bool( $minor ) ) { + throw new InvalidArgumentException( '$minor must be a bool' ); + } + if( !is_bool( $bot ) ) { + throw new InvalidArgumentException( '$bot must be a bool' ); + } + + $this->summary = $summary; + $this->bot = $bot; + $this->minor = $minor; + } + + /** + * @return EditInfo::BOT|self::NOTBOT + */ + public function getBot() { + return $this->bot; + } + + /** + * @return EditInfo::MINOR|self::NOTMINOR + */ + public function getMinor() { + return $this->minor; + } + + /** + * @return string + */ + public function getSummary() { + return $this->summary; + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/File.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/File.php new file mode 100644 index 00000000..7851b3b8 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/File.php @@ -0,0 +1,37 @@ +<?php + +namespace Mediawiki\DataModel; + +use InvalidArgumentException; + +/** + * @author Addshore + */ +class File extends Page { + + /** + * @var string + */ + private $url; + + /** + * @param string $url + * @param PageIdentifier $pageIdentifier + * @param Revisions $revisions + */ + public function __construct( $url, PageIdentifier $pageIdentifier = null, Revisions $revisions = null ) { + parent::__construct( $pageIdentifier, $revisions ); + if( !is_string( $url ) ) { + throw new InvalidArgumentException( '$url must be a string' ); + } + $this->url = $url; + } + + /** + * @return string + */ + public function getUrl() { + return $this->url; + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Log.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Log.php new file mode 100644 index 00000000..d3e48637 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Log.php @@ -0,0 +1,171 @@ +<?php + +namespace Mediawiki\DataModel; + +use JsonSerializable; + +/** + * @since 0.5 + */ +class Log implements JsonSerializable { + + /** + * @var int + */ + private $id; + + /** + * @var string + */ + private $type; + + /** + * @var string + */ + private $action; + + /** + * @var string + */ + private $timestamp; + + /** + * @var string + */ + private $user; + + /** + * @var string + */ + private $comment; + + /** + * @var PageIdentifier + */ + private $pageIdentifier; + + /** + * @var array + */ + private $details; + + /** + * @param int $id + * @param string $type + * @param string $action + * @param string $timestamp + * @param string $user + * @param PageIdentifier $pageIdentifier + * @param string $comment + * @param array $details + */ + public function __construct( $id, $type, $action, $timestamp, $user, $pageIdentifier, $comment, $details ) { + $this->id = $id; + $this->type = $type; + $this->action = $action; + $this->timestamp = $timestamp; + $this->user = $user; + $this->pageIdentifier = $pageIdentifier; + $this->comment = $comment; + $this->details = $details; + } + + /** + * @since 0.5 + * @return string + */ + public function getUser() { + return $this->user; + } + + /** + * @since 0.5 + * @return string + */ + public function getAction() { + return $this->action; + } + + /** + * @since 0.5 + * @return string + */ + public function getComment() { + return $this->comment; + } + + /** + * @since 0.5 + * @return int + */ + public function getId() { + return $this->id; + } + + /** + * @since 0.6 + * @return PageIdentifier + */ + public function getPageIdentifier() { + return $this->pageIdentifier; + } + + /** + * @since 0.5 + * @return string + */ + public function getTimestamp() { + return $this->timestamp; + } + + /** + * @since 0.5 + * @return string + */ + public function getType() { + return $this->type; + } + + /** + * @since 0.5 + * @return array + */ + public function getDetails() { + return $this->details; + } + + /** + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + */ + public function jsonSerialize() { + return array( + 'id' => $this->id, + 'type' => $this->type, + 'action' => $this->action, + 'timestamp' => $this->timestamp, + 'user' => $this->user, + 'pageidentifier' => $this->pageIdentifier, + 'comment' => $this->comment, + 'details' => $this->details, + ); + } + + /** + * @param array $json + * + * @return self + */ + public static function jsonDeserialize( $json ) { + return new self( + $json['id'], + $json['type'], + $json['action'], + $json['timestamp'], + $json['user'], + PageIdentifier::jsonDeserialize( $json['pageidentifier'] ), + $json['comment'], + $json['details'] + ); + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/LogList.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/LogList.php new file mode 100644 index 00000000..9ce30263 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/LogList.php @@ -0,0 +1,138 @@ +<?php + +namespace Mediawiki\DataModel; + +use InvalidArgumentException; +use JsonSerializable; +use RuntimeException; + +/** + * Represents a collection of Log classes + * @author Addshore + */ +class LogList implements JsonSerializable { + + /** + * @var Log[] + */ + private $logs; + + /** + * @param Log[] $logs + */ + public function __construct( $logs = array() ) { + $this->logs = array(); + $this->addLogs( $logs ); + } + + /** + * @param Log[]|LogList $logs + * + * @throws InvalidArgumentException + */ + public function addLogs( $logs ) { + if( !is_array( $logs ) && !$logs instanceof LogList ) { + throw new InvalidArgumentException( '$logs needs to either be an array or a LogList object' ); + } + if( $logs instanceof LogList ) { + $logs = $logs->toArray(); + } + foreach( $logs as $log ) { + $this->addLog( $log ); + } + } + + /** + * @param Log $log + */ + public function addLog( Log $log ) { + $this->logs[$log->getId()] = $log; + } + + /** + * @param int $id + * + * @return bool + */ + public function hasLogWithId( $id ){ + return array_key_exists( $id, $this->logs ); + } + + /** + * @param Log $log + * + * @return bool + */ + public function hasLog( Log $log ){ + return array_key_exists( $log->getId(), $this->logs ); + } + + /** + * @return Log|null Log or null if there is no log + */ + public function getLatest() { + if( empty( $this->logs ) ) { + return null; + } + return $this->logs[ max( array_keys( $this->logs ) ) ]; + } + + /** + * @since 0.6 + * @return Log|null Log or null if there is no log + */ + public function getOldest() { + if( empty( $this->logs ) ) { + return null; + } + return $this->logs[ min( array_keys( $this->logs ) ) ]; + } + + /** + * @since 0.6 + * @return bool + */ + public function isEmpty() { + return empty( $this->logs ); + } + + /** + * @param int $id + * + * @throws RuntimeException + * @return Log + */ + public function get( $id ){ + if( $this->hasLogWithId( $id ) ){ + return $this->logs[$id]; + } + throw new RuntimeException( 'No such Log loaded in LogList object' ); + } + + /** + * @return Log[] + */ + public function toArray() { + return $this->logs; + } + + /** + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + */ + public function jsonSerialize() { + return $this->toArray(); + } + + /** + * @param array $json + * + * @return self + */ + public static function jsonDeserialize( $json ) { + $self = new LogList(); + foreach ( $json as $logJson ) { + $self->addLog( Log::jsonDeserialize( $logJson ) ); + } + return $self; + } +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/NamespaceInfo.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/NamespaceInfo.php new file mode 100644 index 00000000..451ec972 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/NamespaceInfo.php @@ -0,0 +1,131 @@ +<?php + +namespace Mediawiki\DataModel; + +/** + * Class representing metadata about a MediaWiki namespace + * + * @author gbirke + */ +class NamespaceInfo +{ + /** + * @var int + */ + private $id; + + /** + * @var string + */ + private $canonicalName; + + /** + * @var string + */ + private $localName; + + /** + * @var string + */ + private $caseHandling; + + /** + * @var string + */ + private $defaultContentModel; + + /** + * @var array + */ + private $aliases; + + /** + * NamespaceInfo constructor. + * @param int $id + * @param string $canonicalName + * @param string $localName + * @param string $caseHandling + * @param string $defaultContentModel + * @param array $aliases + * + * @throws InvalidArgumentException + */ + public function __construct( $id, $canonicalName, $localName, $caseHandling, $defaultContentModel = null, $aliases = [] ) + { + if( !is_int( $id ) ) { + throw new \InvalidArgumentException( '$id must be an integer' ); + } + if ( !is_string( $canonicalName ) ) { + throw new \InvalidArgumentException( '$canonicalName must be a string' ); + } + if ( !is_string( $localName ) ) { + throw new \InvalidArgumentException( '$localName must be a string' ); + } + if ( !is_string( $caseHandling ) ) { + throw new \InvalidArgumentException( '$caseHandling must be a string' ); + } + if ( !is_null( $defaultContentModel) && !is_string( $defaultContentModel ) ) { + throw new \InvalidArgumentException( '$canonicalName must be a string' ); + } + + if ( !is_array( $aliases ) ) { + throw new \InvalidArgumentException( '$aliases must be an array' ); + } + + $this->id = $id; + $this->canonicalName = $canonicalName; + $this->localName = $localName; + $this->caseHandling = $caseHandling; + $this->defaultContentModel = $defaultContentModel; + $this->aliases = $aliases; + } + + /** + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * @return string + */ + public function getCanonicalName() + { + return $this->canonicalName; + } + + /** + * @return string + */ + public function getLocalName() + { + return $this->localName; + } + + /** + * @return string + */ + public function getCaseHandling() + { + return $this->caseHandling; + } + + /** + * @return string + */ + public function getDefaultContentModel() + { + return $this->defaultContentModel; + } + + /** + * @return array + */ + public function getAliases() + { + return $this->aliases; + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Page.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Page.php new file mode 100644 index 00000000..c3951e85 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Page.php @@ -0,0 +1,63 @@ +<?php + +namespace Mediawiki\DataModel; + +use InvalidArgumentException; + +class Page { + + /** + * @var Revisions + */ + private $revisions; + + /** + * @var PageIdentifier + */ + private $pageIdentifier; + + /** + * @param PageIdentifier $pageIdentifier + * @param Revisions|null $revisions + * + * @throws InvalidArgumentException + */ + public function __construct( PageIdentifier $pageIdentifier = null , Revisions $revisions = null ) { + if( is_null( $revisions ) ) { + $revisions = new Revisions(); + } + $this->revisions = $revisions; + $this->pageIdentifier = $pageIdentifier; + } + + /** + * @deprecated since 0.5 + * @return int + */ + public function getId() { + return $this->pageIdentifier->getId(); + } + + /** + * @return Revisions + */ + public function getRevisions() { + return $this->revisions; + } + + /** + * @deprecated since 0.5 + * @return Title + */ + public function getTitle() { + return $this->pageIdentifier->getTitle(); + } + + /** + * @return PageIdentifier + */ + public function getPageIdentifier() { + return $this->pageIdentifier; + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/PageIdentifier.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/PageIdentifier.php new file mode 100644 index 00000000..528e3c88 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/PageIdentifier.php @@ -0,0 +1,85 @@ +<?php + +namespace Mediawiki\DataModel; + +use InvalidArgumentException; +use JsonSerializable; + +class PageIdentifier implements JsonSerializable { + + /** + * @var int|null + */ + private $id; + + /** + * @var Title|null + */ + private $title; + + /** + * @param Title|null $title + * @param int|null $id + * @throws InvalidArgumentException + */ + public function __construct( Title $title = null, $id = null ) { + if( !is_int( $id ) && !is_null( $id ) ) { + throw new InvalidArgumentException( '$id must be an int' ); + } + $this->title = $title; + $this->id = $id; + } + + /** + * @return int|null + */ + public function getId() { + return $this->id; + } + + /** + * @return Title|null + */ + public function getTitle() { + return $this->title; + } + + /** + * Does this object identify a page + * @return bool + */ + public function identifiesPage() { + if( is_null( $this->title ) && is_null( $this->id ) ) { + return false; + } + return true; + } + + /** + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + */ + public function jsonSerialize() { + $array = array(); + if ( $this->id !== null ) { + $array['id'] = $this->id; + } + if ( $this->title !== null ) { + $array['title'] = $this->title->jsonSerialize(); + } + return $array; + } + + /** + * @param array $array + * + * @returns self + */ + public static function jsonDeserialize( $array ) { + return new self( + isset( $array['title'] ) ? Title::jsonDeserialize( $array['title'] ) : null, + isset( $array['id'] ) ? $array['id'] : null + + ); + } +} +
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Pages.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Pages.php new file mode 100644 index 00000000..b8c5614c --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Pages.php @@ -0,0 +1,99 @@ +<?php + +namespace Mediawiki\DataModel; + +use InvalidArgumentException; +use RuntimeException; + +/** + * Represents a collection or Page classes + * @author Addshore + */ +class Pages { + + /** + * @var Page[] + */ + private $pages; + + /** + * @param Page[] $pages + */ + public function __construct( $pages = array() ) { + $this->pages = array(); + $this->addPages( $pages ); + } + + /** + * @param Page[]|Pages $pages + * + * @throws InvalidArgumentException + */ + public function addPages( $pages ) { + if( !is_array( $pages ) && !$pages instanceof Pages ) { + throw new InvalidArgumentException( '$pages needs to either be an array or a Pages object' ); + } + if( $pages instanceof Pages ) { + $pages = $pages->toArray(); + } + foreach( $pages as $page ) { + $this->addPage( $page ); + } + } + + /** + * @param Page $page + */ + public function addPage( Page $page ) { + $this->pages[$page->getId()] = $page; + } + + /** + * @param int $id + * + * @return bool + */ + public function hasPageWithId( $id ){ + return array_key_exists( $id, $this->pages ); + } + + /** + * @param Page $page + * + * @return bool + */ + public function hasPage( Page $page ){ + return array_key_exists( $page->getId(), $this->pages ); + } + + /** + * @return Page|null Page or null if there is no page + */ + public function getLatest() { + if( empty( $this->pages ) ) { + return null; + } + return $this->pages[ max( array_keys( $this->pages ) ) ]; + } + + + /** + * @param int $pageid + * + * @throws RuntimeException + * @return Page + */ + public function get( $pageid ){ + if( $this->hasPageWithId( $pageid ) ){ + return $this->pages[$pageid]; + } + throw new RuntimeException( 'No such page loaded in Pages object' ); + } + + /** + * @return Page[] + */ + public function toArray() { + return $this->pages; + } +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Redirect.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Redirect.php new file mode 100644 index 00000000..55b8b607 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Redirect.php @@ -0,0 +1,53 @@ +<?php + +namespace Mediawiki\DataModel; + +use JsonSerializable; + +class Redirect implements JsonSerializable { + + private $from; + private $to; + + public function __construct( Title $from, Title $to ) { + $this->from = $from; + $this->to = $to; + } + + /** + * @return Title + */ + public function getFrom() { + return $this->from; + } + + /** + * @return Title + */ + public function getTo() { + return $this->to; + } + + /** + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + */ + public function jsonSerialize() { + return array( + 'from' => $this->from->jsonSerialize(), + 'to' => $this->to->jsonSerialize(), + ); + } + + /** + * @param array $json + * + * @return self + */ + public static function jsonDeserialize( $json ) { + return new self( + Title::jsonDeserialize( $json['from'] ), + Title::jsonDeserialize( $json['to'] ) + ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Revision.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Revision.php new file mode 100644 index 00000000..09afe63f --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Revision.php @@ -0,0 +1,106 @@ +<?php + +namespace Mediawiki\DataModel; + +/** + * Representation of a version of content + * @author Addshore + */ +class Revision { + + /** + * @var int Id of the revision + */ + private $id; + + /** + * @var PageIdentifier of the page for the revision + */ + private $pageIdentifier; + + /** + * @var Content + */ + private $content; + + /** + * @var EditInfo + */ + private $editInfo; + + /** + * @var null|string + */ + private $user; + + /** + * @var null|string + */ + private $timestamp; + + /** + * @param Content $content + * @param PageIdentifier|null $pageIdentifier + * @param int|null $revId + * @param EditInfo|null $editInfo + * @param string|null $user + * @param string|null $timestamp + */ + public function __construct( Content $content, PageIdentifier $pageIdentifier = null, $revId = null, EditInfo $editInfo = null, $user = null, $timestamp = null ) { + if( is_null( $editInfo ) ) { + $editInfo = new EditInfo(); + } + if( is_null( $pageIdentifier ) ) { + $pageIdentifier = new PageIdentifier(); + } + $this->content = $content; + $this->pageIdentifier = $pageIdentifier; + $this->id = $revId; + $this->editInfo = $editInfo; + $this->user = $user; + $this->timestamp = $timestamp; + } + + /** + * @return Content + */ + public function getContent() { + return $this->content; + } + + /** + * @return EditInfo + */ + public function getEditInfo() { + return $this->editInfo; + } + + /** + * @return int|null + */ + public function getId() { + return $this->id; + } + + /** + * @return PageIdentifier|null + */ + public function getPageIdentifier() { + return $this->pageIdentifier; + } + + /** + * @return null|string + */ + public function getUser() { + return $this->user; + } + + /** + * @return null|string + */ + public function getTimestamp() { + return $this->timestamp; + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Revisions.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Revisions.php new file mode 100644 index 00000000..c6d2f436 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Revisions.php @@ -0,0 +1,102 @@ +<?php + +namespace Mediawiki\DataModel; + +use InvalidArgumentException; +use RuntimeException; + +/** + * Represents a collection or revisions + * @author Addshore + */ +class Revisions { + + /** + * @var Revision[] + */ + private $revisions; + + /** + * @param Revisions[] $revisions + */ + public function __construct( $revisions = array() ) { + $this->revisions = array(); + $this->addRevisions( $revisions ); + } + + /** + * @param Revision[]|Revisions $revisions + * + * @throws InvalidArgumentException + */ + public function addRevisions( $revisions ) { + if( !is_array( $revisions ) && !$revisions instanceof Revisions ) { + throw new InvalidArgumentException( '$revisions needs to either be an array or a Revisions object' ); + } + if( $revisions instanceof Revisions ) { + $revisions = $revisions->toArray(); + } + foreach( $revisions as $revision ) { + $this->addRevision( $revision ); + } + } + + /** + * @param Revision $revision + */ + public function addRevision( Revision $revision ) { + $this->revisions[$revision->getId()] = $revision; + } + + /** + * @param int $id + * + * @return bool + */ + public function hasRevisionWithId( $id ){ + return array_key_exists( $id, $this->revisions ); + } + + /** + * @param Revision $revision + * + * @return bool + */ + public function hasRevision( Revision $revision ){ + return array_key_exists( $revision->getId(), $this->revisions ); + } + + /** + * @return Revision|null Revision or null if there is no revision + */ + public function getLatest() { + if( empty( $this->revisions ) ) { + return null; + } + return $this->revisions[ max( array_keys( $this->revisions ) ) ]; + } + + /** + * @param int $revid + * + * @throws RuntimeException + * @throws InvalidArgumentException + * @return Revision + */ + public function get( $revid ){ + if( !is_int( $revid ) ) { + throw new InvalidArgumentException( '$revid needs to be an int' ); + } + if( $this->hasRevisionWithId( $revid ) ){ + return $this->revisions[$revid]; + } + throw new RuntimeException( 'No such revision loaded in Revisions object' ); + } + + /** + * @return Revision[] + */ + public function toArray() { + return $this->revisions; + } +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Title.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Title.php new file mode 100644 index 00000000..1fb15138 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/Title.php @@ -0,0 +1,83 @@ +<?php + +namespace Mediawiki\DataModel; + +use InvalidArgumentException; +use JsonSerializable; + +/** + * @author Addshore + */ +class Title implements JsonSerializable { + + /** + * @var string + */ + private $title; + + /** + * @var int + */ + private $ns; + + /** + * @param string $title + * @param int $ns + * + * @throws InvalidArgumentException + */ + public function __construct( $title, $ns = 0 ) { + if( !is_string( $title ) ) { + throw new InvalidArgumentException( '$title must be a string' ); + } + if( !is_int( $ns ) ) { + throw new InvalidArgumentException( '$ns must be an int' ); + } + $this->title = $title; + $this->ns = $ns; + } + + /** + * @return int + * @since 0.1 + */ + public function getNs() { + return $this->ns; + } + + /** + * @return string + * @since 0.6 + */ + public function getText() { + return $this->title; + } + + /** + * @return string + * @deprecated in 0.6 use getText (makes things look cleaner) + */ + public function getTitle() { + return $this->getText(); + } + + /** + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + */ + public function jsonSerialize() { + return array( + 'title' => $this->title, + 'ns' => $this->ns, + ); + } + + /** + * @param array $json + * + * @return self + */ + public static function jsonDeserialize( $json ) { + return new self( $json['title'], $json['ns'] ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/User.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/User.php new file mode 100644 index 00000000..fca5ddf3 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/src/User.php @@ -0,0 +1,140 @@ +<?php + +namespace Mediawiki\DataModel; + +use InvalidArgumentException; + +/** + * Represents a mediawiki user + * @author Addshore + */ +class User { + + /** + * @var string + */ + private $name; + + /** + * @var int + */ + private $id; + + /** + * @var int + */ + private $editcount; + + /** + * @var string + */ + private $registration; + + /** + * @var array + */ + private $groups; + + /** + * @var array + */ + private $rights; + + /** + * @var string + */ + private $gender; + + /** + * @param string $name + * @param int $id + * @param int $editcount + * @param string $registration + * @param array[] $groups groups grouped by type. + * Keys to use are 'groups' and 'implicitgroups' as returned by the api. + * @param array $rights + * @param string $gender + * + * @throws InvalidArgumentException + */ + public function __construct( $name, $id, $editcount, $registration, $groups, $rights, $gender ) { + if( !is_string( $name ) || empty( $name ) ) { + throw new InvalidArgumentException( '$name must be a string and can not be empty' ); + } + if( !is_int( $id ) ) { + throw new InvalidArgumentException( '$id must be an int' ); + } + if( !is_int( $editcount ) ) { + throw new InvalidArgumentException( '$editcount must be an int' ); + } + if( !is_array( $groups ) || !array_key_exists( 'groups', $groups ) || !array_key_exists( 'implicitgroups', $groups ) ) { + throw new InvalidArgumentException( '$groups must be an array or arrays with keys "groups" and "implicitgroups"' ); + } + if( !is_array( $rights ) ) { + throw new InvalidArgumentException( '$rights must be an array' ); + } + if( !is_string( $gender ) ) { + throw new InvalidArgumentException( '$gender must be a string' ); + } + + $this->editcount = $editcount; + $this->gender = $gender; + $this->groups = $groups; + $this->id = $id; + $this->name = $name; + $this->registration = $registration; + $this->rights = $rights; + } + + /** + * @return int + */ + public function getEditcount() { + return $this->editcount; + } + + /** + * @return string + */ + public function getGender() { + return $this->gender; + } + + /** + * @param string $type 'groups' or 'implicitgroups' + * + * @return array + */ + public function getGroups( $type = 'groups' ) { + return $this->groups[$type]; + } + + /** + * @return int + */ + public function getId() { + return $this->id; + } + + /** + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * @return string + */ + public function getRegistration() { + return $this->registration; + } + + /** + * @return array + */ + public function getRights() { + return $this->rights; + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/ContentTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/ContentTest.php new file mode 100644 index 00000000..e412749a --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/ContentTest.php @@ -0,0 +1,30 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\Content; +use PHPUnit_Framework_TestCase; + +class ContentTest extends PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $data, $model ) { + $content = new Content( $data, $model ); + $this->assertEquals( $data, $content->getData() ); + $this->assertEquals( $model, $content->getModel() ); + $this->assertTrue( is_string( $content->getHash() ) ); + $this->assertFalse( $content->hasChanged() ); + } + + public function provideValidConstruction() { + return array( + array( '', null ), + array( 'foo', null ), + array( new \stdClass(), null ), + ); + } + +} +
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/EditInfoTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/EditInfoTest.php new file mode 100644 index 00000000..c3128bca --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/EditInfoTest.php @@ -0,0 +1,51 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\EditInfo; +use PHPUnit_Framework_TestCase; + +/** + * @covers \Mediawiki\DataModel\EditInfo + * @author Addshore + */ +class EditInfoTest extends PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $sum, $minor, $bot ) { + $flags = new EditInfo( $sum, $minor, $bot ); + $this->assertEquals( $sum, $flags->getSummary() ); + $this->assertEquals( $minor, $flags->getMinor() ); + $this->assertEquals( $bot, $flags->getBot() ); + } + + public function provideValidConstruction() { + return array( + array( '', EditInfo::MINOR, EditInfo::BOT ), + array( '', EditInfo::MINOR, EditInfo::NOTBOT ), + array( '', EditInfo::NOTMINOR, EditInfo::BOT ), + array( '', EditInfo::NOTMINOR, EditInfo::NOTBOT ), + array( 'FOO', EditInfo::NOTMINOR, EditInfo::NOTBOT ), + ); + } + + /** + * @dataProvider provideInvalidConstruction + */ + public function testInvalidConstruction( $sum, $minor, $bot ) { + $this->setExpectedException( 'InvalidArgumentException' ); + new EditInfo( $sum, $minor, $bot ); + } + + public function provideInvalidConstruction() { + return array( + array( 1, 2, 3 ), + array( "foo", false, 3 ), + array( "foo", 3, false ), + array( array(), true, false ), + ); + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/FileTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/FileTest.php new file mode 100644 index 00000000..0da77bd1 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/FileTest.php @@ -0,0 +1,44 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\File; +use Mediawiki\DataModel\PageIdentifier; + +/** + * @covers \Mediawiki\DataModel\File + * @author Addshore + */ +class FileTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $url ) { + $file = new File( + $url, + new PageIdentifier( $this->newMockTitle(), 1 ), + $this->newMockRevisions() + ); + $this->assertEquals( $url, $file->getUrl() ); + } + + public function provideValidConstruction() { + return array( + array( 'http://upload.wikimedia.org/wikipedia/en/3/39/Journal_of_Geek_Studies_-_logo.jpg' ), + ); + } + + private function newMockTitle() { + return $this->getMockBuilder( '\Mediawiki\DataModel\Title' ) + ->disableOriginalConstructor() + ->getMock(); + } + + private function newMockRevisions() { + return $this->getMockBuilder( '\Mediawiki\DataModel\Revisions' ) + ->disableOriginalConstructor() + ->getMock(); + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/LogListTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/LogListTest.php new file mode 100644 index 00000000..1098a8a6 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/LogListTest.php @@ -0,0 +1,25 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\Log; +use Mediawiki\DataModel\LogList; +use Mediawiki\DataModel\PageIdentifier; + +/** + * @covers \Mediawiki\DataModel\LogList + * @author Addshore + */ +class LogListTest extends \PHPUnit_Framework_TestCase { + + public function testJsonRoundTrip() { + $logList = new LogList( array( + new Log( 1, 'ty', 'ac', '2014', 'Addshore', new PageIdentifier( null, 22 ), 'comment', array() ), + new Log( 2, 'ty2', 'ac2', '2015', 'Addbot', new PageIdentifier( null, 33 ), 'comment2', array() ), + ) ); + $json = $logList->jsonSerialize(); + $json = json_decode( json_encode( $json ), true ); + $this->assertEquals( $logList, LogList::jsonDeserialize( $json ) ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/NamespaceInfoTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/NamespaceInfoTest.php new file mode 100644 index 00000000..4587a8a0 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/NamespaceInfoTest.php @@ -0,0 +1,72 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\NamespaceInfo; + +/** + * @covers \Mediawiki\DataModel\NamespaceInfo + * @author gbirke + */ +class NamespaceInfoTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider provideValidConstruction + * @param int $id + * @param string $canonicalName + * @param string $localName + * @param string $caseHandling + * @param null $defaultContentModel + * @param array $aliases + */ + public function testValidConstruction($id, $canonicalName, $localName, $caseHandling, $defaultContentModel = null, + $aliases = [] ) { + $namespace = new NamespaceInfo( $id, $canonicalName, $localName, $caseHandling, $defaultContentModel, $aliases ); + $this->assertSame( $id, $namespace->getId() ); + $this->assertSame( $canonicalName, $namespace->getCanonicalName() ); + $this->assertSame( $localName, $namespace->getLocalName() ); + $this->assertSame( $caseHandling, $namespace->getCaseHandling() ); + $this->assertSame( $defaultContentModel, $namespace->getDefaultContentModel() ); + $this->assertSame( $aliases, $namespace->getAliases() ); + } + + public function provideValidConstruction() { + return array( + array( -2, 'Media', 'Media', 'first-letter' ), + array( 0, '', '', 'first-letter' ), + array( 4, 'Project', 'Wikipedia', 'first-letter' ), + array( 2302, 'Gadget definition', 'Gadget definition', 'case-sensitive', 'GadgetDefinition' ), + array( 2302, 'Gadget definition', 'Gadget definition', 'case-sensitive', 'GadgetDefinition', [ 'GD' ] ), + ); + } + + /** + * @param $id + * @param $canonicalName + * @param $localName + * @param $caseHandling + * @param null $defaultContentModel + * @param array $aliases + * + * @dataProvider provideInvalidConstruction + */ + public function testInvalidConstruction($id, $canonicalName, $localName, $caseHandling, $defaultContentModel = null, + $aliases = [] ) { + $this->setExpectedException( 'InvalidArgumentException' ); + new NamespaceInfo( $id, $canonicalName, $localName, $caseHandling, $defaultContentModel, $aliases ); + } + + public function provideInvalidConstruction() { + return array( + array( .5, 'Media', 'Media', 'first-letter' ), + array( '0', '', '', 'first-letter' ), + array( -2, null, 'Media', 'first-letter' ), + array( -2, 'Media', null, 'first-letter' ), + array( 4, 'Project', 'Wikipedia', 'first-letter', 5 ), + array( 2302, null, 'Gadget definition', 'case-sensitive', 'GadgetDefinition' ), + array( 4, 'Project', 'Wikipedia', 'first-letter', 5 ), + array( 4, 'Project', 'Wikipedia', 'first-letter', 'GadgetDefinition', 'notanalias' ), + ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/PageIdentifierTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/PageIdentifierTest.php new file mode 100644 index 00000000..42aa8412 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/PageIdentifierTest.php @@ -0,0 +1,54 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Title; + +/** + * @covers Mediawiki\DataModel\PageIdentifier + */ +class PageIdentifierTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $title, $pageid, $identifiesPage ) { + $pageIdentifier = new PageIdentifier( $title, $pageid ); + if( is_string( $title ) ) { + $this->assertEquals( new Title( $title ), $pageIdentifier->getTitle() ); + } else { + $this->assertEquals( $title, $pageIdentifier->getTitle() ); + } + $this->assertEquals( $pageid, $pageIdentifier->getId() ); + $this->assertEquals( $identifiesPage, $pageIdentifier->identifiesPage() ); + } + + public function provideValidConstruction() { + return array( + array( null, null, false ), + array( new Title( 'Foo' ), null, true ), + array( new Title( 'Foo', 2 ), null, true ), + array( null, 3, true ), + ); + } + + public function provideRoundTripObjects() { + return array( + array( new PageIdentifier( null, null ) ), + array( new PageIdentifier( null, 44 ) ), + array( new PageIdentifier( new Title( 'someTitle', 12 ), null ) ), + array( new PageIdentifier( new Title( 'someTitle', 55 ), 99 ) ), + ); + } + + /** + * @dataProvider provideRoundTripObjects + */ + public function testJsonRoundTrip( PageIdentifier $identifierObject ) { + $json = $identifierObject->jsonSerialize(); + $this->assertEquals( $identifierObject, PageIdentifier::jsonDeserialize( $json ) ); + } + +} +
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/PageTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/PageTest.php new file mode 100644 index 00000000..cbc31c8c --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/PageTest.php @@ -0,0 +1,48 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\PageIdentifier; + +/** + * @covers \Mediawiki\DataModel\Page + * @author Addshore + */ +class PageTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $pageIdentifier, $revisions ) { + $page = new Page( $pageIdentifier, $revisions ); + $this->assertEquals( $pageIdentifier, $page->getPageIdentifier() ); + if( is_null( $revisions ) ) { + $this->assertInstanceOf( 'Mediawiki\DataModel\Revisions', $page->getRevisions() ); + } else { + $this->assertEquals( $revisions, $page->getRevisions() ); + } + } + + public function provideValidConstruction() { + return array( + array( null, null ), + array( null, $this->newMockRevisions() ), + array( new PageIdentifier( $this->newMockTitle(), 1 ), $this->newMockRevisions() ), + array( new PageIdentifier( $this->newMockTitle(), 123 ), null ), + ); + } + + private function newMockTitle() { + return $this->getMockBuilder( '\Mediawiki\DataModel\Title' ) + ->disableOriginalConstructor() + ->getMock(); + } + + private function newMockRevisions() { + return $this->getMockBuilder( '\Mediawiki\DataModel\Revisions' ) + ->disableOriginalConstructor() + ->getMock(); + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/PagesTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/PagesTest.php new file mode 100644 index 00000000..0055ecc7 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/PagesTest.php @@ -0,0 +1,44 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\Page; +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Pages; + +/** + * @covers \Mediawiki\DataModel\Pages + * @author Addshore + */ +class PagesTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $input, $expected ) { + $pages = new Pages( $input ); + $this->assertEquals( $expected, $pages->toArray() ); + } + + public function provideValidConstruction() { + $mockTitle = $this->getMockBuilder( 'Mediawiki\DataModel\Title' ) + ->disableOriginalConstructor() + ->getMock(); + $mockRevisions = $this->getMockBuilder( 'Mediawiki\DataModel\Revisions' ) + ->disableOriginalConstructor() + ->getMock(); + + //todo mock these + $page1 = new Page( new PageIdentifier( $mockTitle, 1 ), $mockRevisions ); + $page2 = new Page( new PageIdentifier( $mockTitle, 2 ), $mockRevisions ); + $page4 = new Page( new PageIdentifier( $mockTitle, 4 ), $mockRevisions ); + + return array( + array( array( $page1 ), array( 1 => $page1 ) ), + array( array( $page2, $page1 ), array( 1 => $page1, 2 => $page2 ) ), + array( array( $page4, $page1 ), array( 1 => $page1, 4 => $page4 ) ), + array( new Pages( array( $page4, $page1 ) ), array( 1 => $page1, 4 => $page4 ) ), + ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/RedirectTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/RedirectTest.php new file mode 100644 index 00000000..0f561e92 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/RedirectTest.php @@ -0,0 +1,20 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\Redirect; +use Mediawiki\DataModel\Title; + +/** + * @covers \Mediawiki\DataModel\Redirect + * @author Addshore + */ +class RedirectTest extends \PHPUnit_Framework_TestCase { + + public function testJsonRoundTrip() { + $title = new Redirect( new Title( 'Foo', 12 ), new Title( 'bar', 13 ) ); + $json = $title->jsonSerialize(); + $this->assertEquals( $title, Redirect::jsonDeserialize( $json ) ); + } + +} diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/RevisionTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/RevisionTest.php new file mode 100644 index 00000000..e6260acb --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/RevisionTest.php @@ -0,0 +1,57 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Revision; + +/** + * @covers \Mediawiki\DataModel\Revision + * @author Addshore + */ +class RevisionTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $content, $pageIdentifier, $id, $editInfo, $user, $timestamp ) { + $rev = new Revision( $content, $pageIdentifier, $id, $editInfo, $user, $timestamp ); + $this->assertEquals( $content, $rev->getContent() ); + if( !is_null( $pageIdentifier ) ) { + $this->assertEquals( $pageIdentifier, $rev->getPageIdentifier() ); + } else { + $this->assertInstanceOf( '\Mediawiki\DataModel\PageIdentifier', $rev->getPageIdentifier() ); + } + + $this->assertEquals( $id, $rev->getId() ); + if( !is_null( $editInfo ) ) { + $this->assertEquals( $editInfo, $rev->getEditInfo() ); + } else { + $this->assertInstanceOf( '\Mediawiki\DataModel\EditInfo', $rev->getEditInfo() ); + } + $this->assertEquals( $user, $rev->getUser() ); + $this->assertEquals( $timestamp, $rev->getTimestamp() ); + } + + public function provideValidConstruction() { + $mockContent = $this->getMockBuilder( 'Mediawiki\DataModel\Content' ) + ->disableOriginalConstructor() + ->getMock(); + $mockEditInfo = $this->getMockBuilder( '\Mediawiki\DataModel\EditInfo' ) + ->disableOriginalConstructor() + ->getMock(); + $mockTitle = $this->getMockBuilder( 'Mediawiki\DataModel\Title' ) + ->disableOriginalConstructor() + ->getMock(); + + return array( + array( $mockContent, null, null, null, null, null ), + array( $mockContent, new PageIdentifier( null, 1 ), null , null, null,null ), + array( $mockContent, new PageIdentifier( null, 1 ), 1 , null, null, null ), + array( $mockContent, new PageIdentifier( null, 2 ), 1 , $mockEditInfo, null, null ), + array( $mockContent, new PageIdentifier( $mockTitle ), 1 , $mockEditInfo, 'foo', null ), + array( $mockContent, new PageIdentifier( $mockTitle, 3 ), 1 , $mockEditInfo, 'foo', '20141212121212' ), + ); + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/RevisionsTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/RevisionsTest.php new file mode 100644 index 00000000..6b7afbed --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/RevisionsTest.php @@ -0,0 +1,41 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\PageIdentifier; +use Mediawiki\DataModel\Revision; +use Mediawiki\DataModel\Revisions; + +/** + * @covers \Mediawiki\DataModel\Revisions + * @author Addshore + */ +class RevisionsTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $input, $expected ) { + $revisions = new Revisions( $input ); + $this->assertEquals( $expected, $revisions->toArray() ); + } + + public function provideValidConstruction() { + $mockContent = $this->getMockBuilder( 'Mediawiki\DataModel\Content' ) + ->disableOriginalConstructor() + ->getMock(); + + //todo mock these + $rev1 = new Revision( $mockContent, new PageIdentifier( null, 1 ), 1 ); + $rev2 = new Revision( $mockContent, new PageIdentifier( null, 1 ), 2 ); + $rev4 = new Revision( $mockContent, new PageIdentifier( null, 1 ), 4 ); + + return array( + array( array( $rev1 ), array( 1 => $rev1 ) ), + array( array( $rev2, $rev1 ), array( 1 => $rev1, 2 => $rev2 ) ), + array( array( $rev4, $rev1 ), array( 1 => $rev1, 4 => $rev4 ) ), + array( new Revisions( array( $rev4, $rev1 ) ), array( 1 => $rev1, 4 => $rev4 ) ), + ); + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/TitleTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/TitleTest.php new file mode 100644 index 00000000..2c4d73da --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/TitleTest.php @@ -0,0 +1,56 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\Title; + +/** + * @covers \Mediawiki\DataModel\Title + * @author Addshore + */ +class TitleTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $title, $ns ) { + $titleObj = new Title( $title, $ns ); + $this->assertEquals( $title, $titleObj->getText() ); + $this->assertEquals( $title, $titleObj->getTitle() ); + $this->assertEquals( $ns, $titleObj->getNs() ); + } + + public function provideValidConstruction() { + return array( + array( 'fooo', 0 ), + array( 'Foo:Bar', 15 ), + array( 'FooBar:Bar', 9999 ), + ); + } + + /** + * @dataProvider provideInvalidConstruction + */ + public function testInvalidConstruction( $title, $ns ) { + $this->setExpectedException( 'InvalidArgumentException' ); + new Title( $title, $ns ); + } + + public function provideInvalidConstruction() { + return array( + array( array(), array() ), + array( 'foo', array() ), + array( array(), 1 ), + array( null, 1 ), + array( null, null ), + array( 'foo', null ), + ); + } + + public function testJsonRoundTrip() { + $title = new Title( 'Foo', 19 ); + $json = $title->jsonSerialize(); + $this->assertEquals( $title, Title::jsonDeserialize( $json ) ); + } + +}
\ No newline at end of file diff --git a/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/UserTest.php b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/UserTest.php new file mode 100644 index 00000000..fcf89994 --- /dev/null +++ b/bin/reevotech/vendor/addwiki/mediawiki-datamodel/tests/UserTest.php @@ -0,0 +1,59 @@ +<?php + +namespace Mediawiki\DataModel\Test; + +use Mediawiki\DataModel\User; + +/** + * @covers \Mediawiki\DataModel\User + * @author Addshore + */ +class UserTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider provideValidConstruction + */ + public function testValidConstruction( $name, $id, $editcount, $registration, $groups, $rights, $gender ) { + $user = new User( $name, $id, $editcount, $registration, $groups, $rights, $gender ); + $this->assertEquals( $name, $user->getName() ); + $this->assertEquals( $id, $user->getId() ); + $this->assertEquals( $editcount, $user->getEditcount() ); + $this->assertEquals( $registration, $user->getRegistration() ); + $this->assertEquals( $groups['groups'], $user->getGroups() ); + $this->assertEquals( $groups['implicitgroups'], $user->getGroups( 'implicitgroups' ) ); + $this->assertEquals( $rights, $user->getRights() ); + $this->assertEquals( $gender, $user->getGender() ); + } + + public function provideValidConstruction() { + return array( + array( 'Username', 1, 1, 'TIMESTAMP', array( 'groups' => array(), 'implicitgroups' => array() ), array(), 'male' ), + array( 'Username', 1, 1, 'TIMESTAMP', array( 'groups' => array(), 'implicitgroups' => array() ), array(), 'female' ), + array( 'Username', 99999999, 99999997, 'TIMESTAMP', array( 'groups' => array(), 'implicitgroups' => array() ), array(), 'male' ), + array( 'Username', 1, 1, null, array( 'groups' => array(), 'implicitgroups' => array() ), array(), 'female' ), + ); + } + + /** + * @dataProvider provideInvalidConstruction + */ + public function testInvalidConstruction( $name, $id, $editcount, $registration, $groups, $rights, $gender ) { + $this->setExpectedException( 'InvalidArgumentException' ); + new User( $name, $id, $editcount, $registration, $groups, $rights, $gender ); + } + + public function provideInvalidConstruction() { + return array( + array( 'Username', 1, 1, 'TIMESTAMP', 'bad', array(), 'male' ), + array( 'Username', 1, 1, 'TIMESTAMP', array( 'groups' => array(), 'implicitgroups' => array() ), 'bad', 'male' ), + array( 'Username', 1, 1, 'TIMESTAMP', array( 'groups' => array(), 'implicitgroups' => array() ), array(), 1 ), + array( 'Username', 1, 'bad', 'TIMESTAMP', array( 'groups' => array(), 'implicitgroups' => array() ), array(), 'male' ), + array( 'Username', 'bad', 1, 'TIMESTAMP', array( 'groups' => array(), 'implicitgroups' => array() ), array(), 'male' ), + array( 14287941, 1, 1, 'TIMESTAMP', array( 'groups' => array(), 'implicitgroups' => array() ), array(), 'male' ), + array( 'Username', 1, 1, 'TIMESTAMP', array( 'groups' => array(), 'foo' => array() ), array(), 'male' ), + array( 'Username', 1, 1, 'TIMESTAMP', array( 'groups' => array() ), array(), 'male' ), + array( 'Username', 1, 1, 'TIMESTAMP', array(), array(), 'male' ), + ); + } + +} diff --git a/bin/reevotech/vendor/autoload.php b/bin/reevotech/vendor/autoload.php new file mode 100644 index 00000000..99420711 --- /dev/null +++ b/bin/reevotech/vendor/autoload.php @@ -0,0 +1,7 @@ +<?php + +// autoload.php @generated by Composer + +require_once __DIR__ . '/composer/autoload_real.php'; + +return ComposerAutoloaderInit1597705ddb4a19e7b99e0b2375ab438e::getLoader(); diff --git a/bin/reevotech/vendor/composer/ClassLoader.php b/bin/reevotech/vendor/composer/ClassLoader.php new file mode 100644 index 00000000..2c72175e --- /dev/null +++ b/bin/reevotech/vendor/composer/ClassLoader.php @@ -0,0 +1,445 @@ +<?php + +/* + * This file is part of Composer. + * + * (c) Nils Adermann <naderman@naderman.de> + * Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Jordi Boggiano <j.boggiano@seld.be> + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath.'\\'; + if (isset($this->prefixDirsPsr4[$search])) { + foreach ($this->prefixDirsPsr4[$search] as $dir) { + $length = $this->prefixLengthsPsr4[$first][$search]; + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/bin/reevotech/vendor/composer/LICENSE b/bin/reevotech/vendor/composer/LICENSE new file mode 100644 index 00000000..f27399a0 --- /dev/null +++ b/bin/reevotech/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/bin/reevotech/vendor/composer/autoload_classmap.php b/bin/reevotech/vendor/composer/autoload_classmap.php new file mode 100644 index 00000000..7a91153b --- /dev/null +++ b/bin/reevotech/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ +<?php + +// autoload_classmap.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( +); diff --git a/bin/reevotech/vendor/composer/autoload_files.php b/bin/reevotech/vendor/composer/autoload_files.php new file mode 100644 index 00000000..03507c9c --- /dev/null +++ b/bin/reevotech/vendor/composer/autoload_files.php @@ -0,0 +1,13 @@ +<?php + +// autoload_files.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( + 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', + '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', + 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', + '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', +); diff --git a/bin/reevotech/vendor/composer/autoload_namespaces.php b/bin/reevotech/vendor/composer/autoload_namespaces.php new file mode 100644 index 00000000..b7fc0125 --- /dev/null +++ b/bin/reevotech/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ +<?php + +// autoload_namespaces.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( +); diff --git a/bin/reevotech/vendor/composer/autoload_psr4.php b/bin/reevotech/vendor/composer/autoload_psr4.php new file mode 100644 index 00000000..bc85a820 --- /dev/null +++ b/bin/reevotech/vendor/composer/autoload_psr4.php @@ -0,0 +1,16 @@ +<?php + +// autoload_psr4.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( + 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'), + 'Mediawiki\\DataModel\\' => array($vendorDir . '/addwiki/mediawiki-datamodel/src'), + 'Mediawiki\\Api\\' => array($vendorDir . '/addwiki/mediawiki-api-base/src', $vendorDir . '/addwiki/mediawiki-api/src'), + 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), + 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), + 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), +); diff --git a/bin/reevotech/vendor/composer/autoload_real.php b/bin/reevotech/vendor/composer/autoload_real.php new file mode 100644 index 00000000..10b15c45 --- /dev/null +++ b/bin/reevotech/vendor/composer/autoload_real.php @@ -0,0 +1,70 @@ +<?php + +// autoload_real.php @generated by Composer + +class ComposerAutoloaderInit1597705ddb4a19e7b99e0b2375ab438e +{ + private static $loader; + + public static function loadClassLoader($class) + { + if ('Composer\Autoload\ClassLoader' === $class) { + require __DIR__ . '/ClassLoader.php'; + } + } + + public static function getLoader() + { + if (null !== self::$loader) { + return self::$loader; + } + + spl_autoload_register(array('ComposerAutoloaderInit1597705ddb4a19e7b99e0b2375ab438e', 'loadClassLoader'), true, true); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(); + spl_autoload_unregister(array('ComposerAutoloaderInit1597705ddb4a19e7b99e0b2375ab438e', 'loadClassLoader')); + + $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit1597705ddb4a19e7b99e0b2375ab438e::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInit1597705ddb4a19e7b99e0b2375ab438e::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequire1597705ddb4a19e7b99e0b2375ab438e($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequire1597705ddb4a19e7b99e0b2375ab438e($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/bin/reevotech/vendor/composer/autoload_static.php b/bin/reevotech/vendor/composer/autoload_static.php new file mode 100644 index 00000000..71b15755 --- /dev/null +++ b/bin/reevotech/vendor/composer/autoload_static.php @@ -0,0 +1,75 @@ +<?php + +// autoload_static.php @generated by Composer + +namespace Composer\Autoload; + +class ComposerStaticInit1597705ddb4a19e7b99e0b2375ab438e +{ + public static $files = array ( + 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', + '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', + 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', + '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'P' => + array ( + 'Psr\\Log\\' => 8, + 'Psr\\Http\\Message\\' => 17, + ), + 'M' => + array ( + 'Mediawiki\\DataModel\\' => 20, + 'Mediawiki\\Api\\' => 14, + ), + 'G' => + array ( + 'GuzzleHttp\\Psr7\\' => 16, + 'GuzzleHttp\\Promise\\' => 19, + 'GuzzleHttp\\' => 11, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Psr\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + ), + 'Psr\\Http\\Message\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/http-message/src', + ), + 'Mediawiki\\DataModel\\' => + array ( + 0 => __DIR__ . '/..' . '/addwiki/mediawiki-datamodel/src', + ), + 'Mediawiki\\Api\\' => + array ( + 0 => __DIR__ . '/..' . '/addwiki/mediawiki-api-base/src', + 1 => __DIR__ . '/..' . '/addwiki/mediawiki-api/src', + ), + 'GuzzleHttp\\Psr7\\' => + array ( + 0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src', + ), + 'GuzzleHttp\\Promise\\' => + array ( + 0 => __DIR__ . '/..' . '/guzzlehttp/promises/src', + ), + 'GuzzleHttp\\' => + array ( + 0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src', + ), + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit1597705ddb4a19e7b99e0b2375ab438e::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit1597705ddb4a19e7b99e0b2375ab438e::$prefixDirsPsr4; + + }, null, ClassLoader::class); + } +} diff --git a/bin/reevotech/vendor/composer/installed.json b/bin/reevotech/vendor/composer/installed.json new file mode 100644 index 00000000..b7b07b4f --- /dev/null +++ b/bin/reevotech/vendor/composer/installed.json @@ -0,0 +1,489 @@ +[ + { + "name": "addwiki/mediawiki-datamodel", + "version": "0.7.1", + "version_normalized": "0.7.1.0", + "source": { + "type": "git", + "url": "https://github.com/addwiki/mediawiki-datamodel.git", + "reference": "05dd783715a92ec5449bab4091c0482cf3fcface" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/addwiki/mediawiki-datamodel/zipball/05dd783715a92ec5449bab4091c0482cf3fcface", + "reference": "05dd783715a92ec5449bab4091c0482cf3fcface", + "shasum": "" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9.2", + "mediawiki/mediawiki-codesniffer": "^13.0", + "phpunit/phpunit": "~4.8.0|~5.3.0" + }, + "time": "2018-01-10T19:14:13+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.7.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Mediawiki\\DataModel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Addshore" + } + ], + "description": "A Mediawiki datamodel", + "keywords": [ + "mediawiki" + ] + }, + { + "name": "psr/log", + "version": "1.1.0", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2018-11-20T15:27:04+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ] + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "version_normalized": "1.3.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "time": "2016-12-20T10:07:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ] + }, + { + "name": "ralouphie/getallheaders", + "version": "2.0.5", + "version_normalized": "2.0.5.0", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "~3.7.0", + "satooshi/php-coveralls": ">=1.0" + }, + "time": "2016-02-11T07:05:27+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders." + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-08-06T14:39:51+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ] + }, + { + "name": "guzzlehttp/psr7", + "version": "1.5.2", + "version_normalized": "1.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "9f83dded91781a01c63574e387eaa769be769115" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115", + "reference": "9f83dded91781a01c63574e387eaa769be769115", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "time": "2018-12-04T20:46:45+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ] + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.3.3", + "version_normalized": "6.3.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", + "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", + "shasum": "" + }, + "require": { + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4", + "php": ">=5.5" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.0" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "time": "2018-04-22T15:46:56+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ] + }, + { + "name": "addwiki/mediawiki-api-base", + "version": "2.4.0", + "version_normalized": "2.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/addwiki/mediawiki-api-base.git", + "reference": "33c147e91d05a48e953839fb3ad9e6386cfd85c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/addwiki/mediawiki-api-base/zipball/33c147e91d05a48e953839fb3ad9e6386cfd85c1", + "reference": "33c147e91d05a48e953839fb3ad9e6386cfd85c1", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "~6.0", + "guzzlehttp/promises": "~1.0", + "php": ">=5.5", + "psr/log": "~1.0" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9.2", + "mediawiki/mediawiki-codesniffer": "^13.0", + "phpunit/phpunit": "~4.8.0|~5.3.0" + }, + "suggest": { + "etsy/phan": "Allows running static analysis on the package (requires PHP 7+)" + }, + "time": "2017-11-02T10:53:36+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Mediawiki\\Api\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Addshore" + } + ], + "description": "A basic Mediawiki api base library", + "keywords": [ + "mediawiki" + ] + }, + { + "name": "addwiki/mediawiki-api", + "version": "0.7.2", + "version_normalized": "0.7.2.0", + "source": { + "type": "git", + "url": "https://github.com/addwiki/mediawiki-api.git", + "reference": "f52fc3760d82774512d344e41c45c878a2c6659e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/addwiki/mediawiki-api/zipball/f52fc3760d82774512d344e41c45c878a2c6659e", + "reference": "f52fc3760d82774512d344e41c45c878a2c6659e", + "shasum": "" + }, + "require": { + "addwiki/mediawiki-api-base": "~2.4", + "addwiki/mediawiki-datamodel": "~0.7.0" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "^0.9.2", + "mediawiki/mediawiki-codesniffer": "^13.0", + "monolog/monolog": "^1.23", + "phpunit/phpunit": "~4.8" + }, + "time": "2017-11-20T03:08:06+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.7.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Mediawiki\\Api\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Addshore" + } + ], + "description": "A MediaWiki API library", + "keywords": [ + "mediawiki" + ] + } +] diff --git a/bin/reevotech/vendor/guzzlehttp/guzzle/CHANGELOG.md b/bin/reevotech/vendor/guzzlehttp/guzzle/CHANGELOG.md new file mode 100644 index 00000000..17badd75 --- /dev/null +++ b/bin/reevotech/vendor/guzzlehttp/guzzle/CHANGELOG.md @@ -0,0 +1,1287 @@ +# Change Log + +## 6.3.3 - 2018-04-22 + +* Fix: Default headers when decode_content is specified + + +## 6.3.2 - 2018-03-26 + +* Fix: Release process + + +## 6.3.1 - 2018-03-26 + +* Bug fix: Parsing 0 epoch expiry times in cookies [#2014](https://github.com/guzzle/guzzle/pull/2014) +* Improvement: Better ConnectException detection [#2012](https://github.com/guzzle/guzzle/pull/2012) +* Bug fix: Malformed domain that contains a "/" [#1999](https://github.com/guzzle/guzzle/pull/1999) +* Bug fix: Undefined offset when a cookie has no first key-value pair [#1998](https://github.com/guzzle/guzzle/pull/1998) +* Improvement: Support PHPUnit 6 [#1953](https://github.com/guzzle/guzzle/pull/1953) +* Bug fix: Support empty headers [#1915](https://github.com/guzzle/guzzle/pull/1915) +* Bug fix: Ignore case during header modifications [#1916](https://github.com/guzzle/guzzle/pull/1916) + ++ Minor code cleanups, documentation fixes and clarifications. + + +## 6.3.0 - 2017-06-22 + +* Feature: force IP resolution (ipv4 or ipv6) [#1608](https://github.com/guzzle/guzzle/pull/1608), [#1659](https://github.com/guzzle/guzzle/pull/1659) +* Improvement: Don't include summary in exception message when body is empty [#1621](https://github.com/guzzle/guzzle/pull/1621) +* Improvement: Handle `on_headers` option in MockHandler [#1580](https://github.com/guzzle/guzzle/pull/1580) +* Improvement: Added SUSE Linux CA path [#1609](https://github.com/guzzle/guzzle/issues/1609) +* Improvement: Use class reference for getting the name of the class instead of using hardcoded strings [#1641](https://github.com/guzzle/guzzle/pull/1641) +* Feature: Added `read_timeout` option [#1611](https://github.com/guzzle/guzzle/pull/1611) +* Bug fix: PHP 7.x fixes [#1685](https://github.com/guzzle/guzzle/pull/1685), [#1686](https://github.com/guzzle/guzzle/pull/1686), [#1811](https://github.com/guzzle/guzzle/pull/1811) +* Deprecation: BadResponseException instantiation without a response [#1642](https://github.com/guzzle/guzzle/pull/1642) +* Feature: Added NTLM auth [#1569](https://github.com/guzzle/guzzle/pull/1569) +* Feature: Track redirect HTTP status codes [#1711](https://github.com/guzzle/guzzle/pull/1711) +* Improvement: Check handler type during construction [#1745](https://github.com/guzzle/guzzle/pull/1745) +* Improvement: Always include the Content-Length if there's a body [#1721](https://github.com/guzzle/guzzle/pull/1721) +* Feature: Added convenience method to access a cookie by name [#1318](https://github.com/guzzle/guzzle/pull/1318) +* Bug fix: Fill `CURLOPT_CAPATH` and `CURLOPT_CAINFO` properly [#1684](https://github.com/guzzle/guzzle/pull/1684) +* Improvement: Use `\GuzzleHttp\Promise\rejection_for` function instead of object init [#1827](https://github.com/guzzle/guzzle/pull/1827) + + ++ Minor code cleanups, documentation fixes and clarifications. + +## 6.2.3 - 2017-02-28 + +* Fix deprecations with guzzle/psr7 version 1.4 + +## 6.2.2 - 2016-10-08 + +* Allow to pass nullable Response to delay callable +* Only add scheme when host is present +* Fix drain case where content-length is the literal string zero +* Obfuscate in-URL credentials in exceptions + +## 6.2.1 - 2016-07-18 + +* Address HTTP_PROXY security vulnerability, CVE-2016-5385: + https://httpoxy.org/ +* Fixing timeout bug with StreamHandler: + https://github.com/guzzle/guzzle/pull/1488 +* Only read up to `Content-Length` in PHP StreamHandler to avoid timeouts when + a server does not honor `Connection: close`. +* Ignore URI fragment when sending requests. + +## 6.2.0 - 2016-03-21 + +* Feature: added `GuzzleHttp\json_encode` and `GuzzleHttp\json_decode`. + https://github.com/guzzle/guzzle/pull/1389 +* Bug fix: Fix sleep calculation when waiting for delayed requests. + https://github.com/guzzle/guzzle/pull/1324 +* Feature: More flexible history containers. + https://github.com/guzzle/guzzle/pull/1373 +* Bug fix: defer sink stream opening in StreamHandler. + https://github.com/guzzle/guzzle/pull/1377 +* Bug fix: do not attempt to escape cookie values. + https://github.com/guzzle/guzzle/pull/1406 +* Feature: report original content encoding and length on decoded responses. + https://github.com/guzzle/guzzle/pull/1409 +* Bug fix: rewind seekable request bodies before dispatching to cURL. + https://github.com/guzzle/guzzle/pull/1422 +* Bug fix: provide an empty string to `http_build_query` for HHVM workaround. + https://github.com/guzzle/guzzle/pull/1367 + +## 6.1.1 - 2015-11-22 + +* Bug fix: Proxy::wrapSync() now correctly proxies to the appropriate handler + https://github.com/guzzle/guzzle/commit/911bcbc8b434adce64e223a6d1d14e9a8f63e4e4 +* Feature: HandlerStack is now more generic. + https://github.com/guzzle/guzzle/commit/f2102941331cda544745eedd97fc8fd46e1ee33e +* Bug fix: setting verify to false in the StreamHandler now disables peer + verification. https://github.com/guzzle/guzzle/issues/1256 +* Feature: Middleware now uses an exception factory, including more error + context. https://github.com/guzzle/guzzle/pull/1282 +* Feature: better support for disabled functions. + https://github.com/guzzle/guzzle/pull/1287 +* Bug fix: fixed regression where MockHandler was not using `sink`. + https://github.com/guzzle/guzzle/pull/1292 + +## 6.1.0 - 2015-09-08 + +* Feature: Added the `on_stats` request option to provide access to transfer + statistics for requests. https://github.com/guzzle/guzzle/pull/1202 +* Feature: Added the ability to persist session cookies in CookieJars. + https://github.com/guzzle/guzzle/pull/1195 +* Feature: Some compatibility updates for Google APP Engine + https://github.com/guzzle/guzzle/pull/1216 +* Feature: Added support for NO_PROXY to prevent the use of a proxy based on + a simple set of rules. https://github.com/guzzle/guzzle/pull/1197 +* Feature: Cookies can now contain square brackets. + https://github.com/guzzle/guzzle/pull/1237 +* Bug fix: Now correctly parsing `=` inside of quotes in Cookies. + https://github.com/guzzle/guzzle/pull/1232 +* Bug fix: Cusotm cURL options now correctly override curl options of the + same name. https://github.com/guzzle/guzzle/pull/1221 +* Bug fix: Content-Type header is now added when using an explicitly provided + multipart body. https://github.com/guzzle/guzzle/pull/1218 +* Bug fix: Now ignoring Set-Cookie headers that have no name. +* Bug fix: Reason phrase is no longer cast to an int in some cases in the + cURL handler. https://github.com/guzzle/guzzle/pull/1187 +* Bug fix: Remove the Authorization header when redirecting if the Host + header changes. https://github.com/guzzle/guzzle/pull/1207 +* Bug fix: Cookie path matching fixes + https://github.com/guzzle/guzzle/issues/1129 +* Bug fix: Fixing the cURL `body_as_string` setting + https://github.com/guzzle/guzzle/pull/1201 +* Bug fix: quotes are no longer stripped when parsing cookies. + https://github.com/guzzle/guzzle/issues/1172 +* Bug fix: `form_params` and `query` now always uses the `&` separator. + https://github.com/guzzle/guzzle/pull/1163 +* Bug fix: Adding a Content-Length to PHP stream wrapper requests if not set. + https://github.com/guzzle/guzzle/pull/1189 + +## 6.0.2 - 2015-07-04 + +* Fixed a memory leak in the curl handlers in which references to callbacks + were not being removed by `curl_reset`. +* Cookies are now extracted properly before redirects. +* Cookies now allow more character ranges. +* Decoded Content-Encoding responses are now modified to correctly reflect + their state if the encoding was automatically removed by a handler. This + means that the `Content-Encoding` header may be removed an the + `Content-Length` modified to reflect the message size after removing the + encoding. +* Added a more explicit error message when trying to use `form_params` and + `multipart` in the same request. +* Several fixes for HHVM support. +* Functions are now conditionally required using an additional level of + indirection to help with global Composer installations. + +## 6.0.1 - 2015-05-27 + +* Fixed a bug with serializing the `query` request option where the `&` + separator was missing. +* Added a better error message for when `body` is provided as an array. Please + use `form_params` or `multipart` instead. +* Various doc fixes. + +## 6.0.0 - 2015-05-26 + +* See the UPGRADING.md document for more information. +* Added `multipart` and `form_params` request options. +* Added `synchronous` request option. +* Added the `on_headers` request option. +* Fixed `expect` handling. +* No longer adding default middlewares in the client ctor. These need to be + present on the provided handler in order to work. +* Requests are no longer initiated when sending async requests with the + CurlMultiHandler. This prevents unexpected recursion from requests completing + while ticking the cURL loop. +* Removed the semantics of setting `default` to `true`. This is no longer + required now that the cURL loop is not ticked for async requests. +* Added request and response logging middleware. +* No longer allowing self signed certificates when using the StreamHandler. +* Ensuring that `sink` is valid if saving to a file. +* Request exceptions now include a "handler context" which provides handler + specific contextual information. +* Added `GuzzleHttp\RequestOptions` to allow request options to be applied + using constants. +* `$maxHandles` has been removed from CurlMultiHandler. +* `MultipartPostBody` is now part of the `guzzlehttp/psr7` package. + +## 5.3.0 - 2015-05-19 + +* Mock now supports `save_to` +* Marked `AbstractRequestEvent::getTransaction()` as public. +* Fixed a bug in which multiple headers using different casing would overwrite + previous headers in the associative array. +* Added `Utils::getDefaultHandler()` +* Marked `GuzzleHttp\Client::getDefaultUserAgent` as deprecated. +* URL scheme is now always lowercased. + +## 6.0.0-beta.1 + +* Requires PHP >= 5.5 +* Updated to use PSR-7 + * Requires immutable messages, which basically means an event based system + owned by a request instance is no longer possible. + * Utilizing the [Guzzle PSR-7 package](https://github.com/guzzle/psr7). + * Removed the dependency on `guzzlehttp/streams`. These stream abstractions + are available in the `guzzlehttp/psr7` package under the `GuzzleHttp\Psr7` + namespace. +* Added middleware and handler system + * Replaced the Guzzle event and subscriber system with a middleware system. + * No longer depends on RingPHP, but rather places the HTTP handlers directly + in Guzzle, operating on PSR-7 messages. + * Retry logic is now encapsulated in `GuzzleHttp\Middleware::retry`, which + means the `guzzlehttp/retry-subscriber` is now obsolete. + * Mocking responses is now handled using `GuzzleHttp\Handler\MockHandler`. +* Asynchronous responses + * No longer supports the `future` request option to send an async request. + Instead, use one of the `*Async` methods of a client (e.g., `requestAsync`, + `getAsync`, etc.). + * Utilizing `GuzzleHttp\Promise` instead of React's promise library to avoid + recursion required by chaining and forwarding react promises. See + https://github.com/guzzle/promises + * Added `requestAsync` and `sendAsync` to send request asynchronously. + * Added magic methods for `getAsync()`, `postAsync()`, etc. to send requests + asynchronously. +* Request options + * POST and form updates + * Added the `form_fields` and `form_files` request options. + * Removed the `GuzzleHttp\Post` namespace. + * The `body` request option no longer accepts an array for POST requests. + * The `exceptions` request option has been deprecated in favor of the + `http_errors` request options. + * The `save_to` request option has been deprecated in favor of `sink` request + option. +* Clients no longer accept an array of URI template string and variables for + URI variables. You will need to expand URI templates before passing them + into a client constructor or request method. +* Client methods `get()`, `post()`, `put()`, `patch()`, `options()`, etc. are + now magic methods that will send synchronous requests. +* Replaced `Utils.php` with plain functions in `functions.php`. +* Removed `GuzzleHttp\Collection`. +* Removed `GuzzleHttp\BatchResults`. Batched pool results are now returned as + an array. +* Removed `GuzzleHttp\Query`. Query string handling is now handled using an + associative array passed into the `query` request option. The query string + is serialized using PHP's `http_build_query`. If you need more control, you + can pass the query string in as a string. +* `GuzzleHttp\QueryParser` has been replaced with the + `GuzzleHttp\Psr7\parse_query`. + +## 5.2.0 - 2015-01-27 + +* Added `AppliesHeadersInterface` to make applying headers to a request based + on the body more generic and not specific to `PostBodyInterface`. +* Reduced the number of stack frames needed to send requests. +* Nested futures are now resolved in the client rather than the RequestFsm +* Finishing state transitions is now handled in the RequestFsm rather than the + RingBridge. +* Added a guard in the Pool class to not use recursion for request retries. + +## 5.1.0 - 2014-12-19 + +* Pool class no longer uses recursion when a request is intercepted. +* The size of a Pool can now be dynamically adjusted using a callback. + See https://github.com/guzzle/guzzle/pull/943. +* Setting a request option to `null` when creating a request with a client will + ensure that the option is not set. This allows you to overwrite default + request options on a per-request basis. + See https://github.com/guzzle/guzzle/pull/937. +* Added the ability to limit which protocols are allowed for redirects by + specifying a `protocols` array in the `allow_redirects` request option. +* Nested futures due to retries are now resolved when waiting for synchronous + responses. See https://github.com/guzzle/guzzle/pull/947. +* `"0"` is now an allowed URI path. See + https://github.com/guzzle/guzzle/pull/935. +* `Query` no longer typehints on the `$query` argument in the constructor, + allowing for strings and arrays. +* Exceptions thrown in the `end` event are now correctly wrapped with Guzzle + specific exceptions if necessary. + +## 5.0.3 - 2014-11-03 + +This change updates query strings so that they are treated as un-encoded values +by default where the value represents an un-encoded value to send over the +wire. A Query object then encodes the value before sending over the wire. This +means that even value query string values (e.g., ":") are url encoded. This +makes the Query class match PHP's http_build_query function. However, if you +want to send requests over the wire using valid query string characters that do +not need to be encoded, then you can provide a string to Url::setQuery() and +pass true as the second argument to specify that the query string is a raw +string that should not be parsed or encoded (unless a call to getQuery() is +subsequently made, forcing the query-string to be converted into a Query +object). + +## 5.0.2 - 2014-10-30 + +* Added a trailing `\r\n` to multipart/form-data payloads. See + https://github.com/guzzle/guzzle/pull/871 +* Added a `GuzzleHttp\Pool::send()` convenience method to match the docs. +* Status codes are now returned as integers. See + https://github.com/guzzle/guzzle/issues/881 +* No longer overwriting an existing `application/x-www-form-urlencoded` header + when sending POST requests, allowing for customized headers. See + https://github.com/guzzle/guzzle/issues/877 +* Improved path URL serialization. + + * No longer double percent-encoding characters in the path or query string if + they are already encoded. + * Now properly encoding the supplied path to a URL object, instead of only + encoding ' ' and '?'. + * Note: This has been changed in 5.0.3 to now encode query string values by + default unless the `rawString` argument is provided when setting the query + string on a URL: Now allowing many more characters to be present in the + query string without being percent encoded. See http://tools.ietf.org/html/rfc3986#appendix-A + +## 5.0.1 - 2014-10-16 + +Bugfix release. + +* Fixed an issue where connection errors still returned response object in + error and end events event though the response is unusable. This has been + corrected so that a response is not returned in the `getResponse` method of + these events if the response did not complete. https://github.com/guzzle/guzzle/issues/867 +* Fixed an issue where transfer statistics were not being populated in the + RingBridge. https://github.com/guzzle/guzzle/issues/866 + +## 5.0.0 - 2014-10-12 + +Adding support for non-blocking responses and some minor API cleanup. + +### New Features + +* Added support for non-blocking responses based on `guzzlehttp/guzzle-ring`. +* Added a public API for creating a default HTTP adapter. +* Updated the redirect plugin to be non-blocking so that redirects are sent + concurrently. Other plugins like this can now be updated to be non-blocking. +* Added a "progress" event so that you can get upload and download progress + events. +* Added `GuzzleHttp\Pool` which implements FutureInterface and transfers + requests concurrently using a capped pool size as efficiently as possible. +* Added `hasListeners()` to EmitterInterface. +* Removed `GuzzleHttp\ClientInterface::sendAll` and marked + `GuzzleHttp\Client::sendAll` as deprecated (it's still there, just not the + recommended way). + +### Breaking changes + +The breaking changes in this release are relatively minor. The biggest thing to +look out for is that request and response objects no longer implement fluent +interfaces. + +* Removed the fluent interfaces (i.e., `return $this`) from requests, + responses, `GuzzleHttp\Collection`, `GuzzleHttp\Url`, + `GuzzleHttp\Query`, `GuzzleHttp\Post\PostBody`, and + `GuzzleHttp\Cookie\SetCookie`. This blog post provides a good outline of + why I did this: http://ocramius.github.io/blog/fluent-interfaces-are-evil/. + This also makes the Guzzle message interfaces compatible with the current + PSR-7 message proposal. +* Removed "functions.php", so that Guzzle is truly PSR-4 compliant. Except + for the HTTP request functions from function.php, these functions are now + implemented in `GuzzleHttp\Utils` using camelCase. `GuzzleHttp\json_decode` + moved to `GuzzleHttp\Utils::jsonDecode`. `GuzzleHttp\get_path` moved to + `GuzzleHttp\Utils::getPath`. `GuzzleHttp\set_path` moved to + `GuzzleHttp\Utils::setPath`. `GuzzleHttp\batch` should now be + `GuzzleHttp\Pool::batch`, which returns an `objectStorage`. Using functions.php + caused problems for many users: they aren't PSR-4 compliant, require an + explicit include, and needed an if-guard to ensure that the functions are not + declared multiple times. +* Rewrote adapter layer. + * Removing all classes from `GuzzleHttp\Adapter`, these are now + implemented as callables that are stored in `GuzzleHttp\Ring\Client`. + * Removed the concept of "parallel adapters". Sending requests serially or + concurrently is now handled using a single adapter. + * Moved `GuzzleHttp\Adapter\Transaction` to `GuzzleHttp\Transaction`. The + Transaction object now exposes the request, response, and client as public + properties. The getters and setters have been removed. +* Removed the "headers" event. This event was only useful for changing the + body a response once the headers of the response were known. You can implement + a similar behavior in a number of ways. One example might be to use a + FnStream that has access to the transaction being sent. For example, when the + first byte is written, you could check if the response headers match your + expectations, and if so, change the actual stream body that is being + written to. +* Removed the `asArray` parameter from + `GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header + value as an array, then use the newly added `getHeaderAsArray()` method of + `MessageInterface`. This change makes the Guzzle interfaces compatible with + the PSR-7 interfaces. +* `GuzzleHttp\Message\MessageFactory` no longer allows subclasses to add + custom request options using double-dispatch (this was an implementation + detail). Instead, you should now provide an associative array to the + constructor which is a mapping of the request option name mapping to a + function that applies the option value to a request. +* Removed the concept of "throwImmediately" from exceptions and error events. + This control mechanism was used to stop a transfer of concurrent requests + from completing. This can now be handled by throwing the exception or by + cancelling a pool of requests or each outstanding future request individually. +* Updated to "GuzzleHttp\Streams" 3.0. + * `GuzzleHttp\Stream\StreamInterface::getContents()` no longer accepts a + `maxLen` parameter. This update makes the Guzzle streams project + compatible with the current PSR-7 proposal. + * `GuzzleHttp\Stream\Stream::__construct`, + `GuzzleHttp\Stream\Stream::factory`, and + `GuzzleHttp\Stream\Utils::create` no longer accept a size in the second + argument. They now accept an associative array of options, including the + "size" key and "metadata" key which can be used to provide custom metadata. + +## 4.2.2 - 2014-09-08 + +* Fixed a memory leak in the CurlAdapter when reusing cURL handles. +* No longer using `request_fulluri` in stream adapter proxies. +* Relative redirects are now based on the last response, not the first response. + +## 4.2.1 - 2014-08-19 + +* Ensuring that the StreamAdapter does not always add a Content-Type header +* Adding automated github releases with a phar and zip + +## 4.2.0 - 2014-08-17 + +* Now merging in default options using a case-insensitive comparison. + Closes https://github.com/guzzle/guzzle/issues/767 +* Added the ability to automatically decode `Content-Encoding` response bodies + using the `decode_content` request option. This is set to `true` by default + to decode the response body if it comes over the wire with a + `Content-Encoding`. Set this value to `false` to disable decoding the + response content, and pass a string to provide a request `Accept-Encoding` + header and turn on automatic response decoding. This feature now allows you + to pass an `Accept-Encoding` header in the headers of a request but still + disable automatic response decoding. + Closes https://github.com/guzzle/guzzle/issues/764 +* Added the ability to throw an exception immediately when transferring + requests in parallel. Closes https://github.com/guzzle/guzzle/issues/760 +* Updating guzzlehttp/streams dependency to ~2.1 +* No longer utilizing the now deprecated namespaced methods from the stream + package. + +## 4.1.8 - 2014-08-14 + +* Fixed an issue in the CurlFactory that caused setting the `stream=false` + request option to throw an exception. + See: https://github.com/guzzle/guzzle/issues/769 +* TransactionIterator now calls rewind on the inner iterator. + See: https://github.com/guzzle/guzzle/pull/765 +* You can now set the `Content-Type` header to `multipart/form-data` + when creating POST requests to force multipart bodies. + See https://github.com/guzzle/guzzle/issues/768 + +## 4.1.7 - 2014-08-07 + +* Fixed an error in the HistoryPlugin that caused the same request and response + to be logged multiple times when an HTTP protocol error occurs. +* Ensuring that cURL does not add a default Content-Type when no Content-Type + has been supplied by the user. This prevents the adapter layer from modifying + the request that is sent over the wire after any listeners may have already + put the request in a desired state (e.g., signed the request). +* Throwing an exception when you attempt to send requests that have the + "stream" set to true in parallel using the MultiAdapter. +* Only calling curl_multi_select when there are active cURL handles. This was + previously changed and caused performance problems on some systems due to PHP + always selecting until the maximum select timeout. +* Fixed a bug where multipart/form-data POST fields were not correctly + aggregated (e.g., values with "&"). + +## 4.1.6 - 2014-08-03 + +* Added helper methods to make it easier to represent messages as strings, + including getting the start line and getting headers as a string. + +## 4.1.5 - 2014-08-02 + +* Automatically retrying cURL "Connection died, retrying a fresh connect" + errors when possible. +* cURL implementation cleanup +* Allowing multiple event subscriber listeners to be registered per event by + passing an array of arrays of listener configuration. + +## 4.1.4 - 2014-07-22 + +* Fixed a bug that caused multi-part POST requests with more than one field to + serialize incorrectly. +* Paths can now be set to "0" +* `ResponseInterface::xml` now accepts a `libxml_options` option and added a + missing default argument that was required when parsing XML response bodies. +* A `save_to` stream is now created lazily, which means that files are not + created on disk unless a request succeeds. + +## 4.1.3 - 2014-07-15 + +* Various fixes to multipart/form-data POST uploads +* Wrapping function.php in an if-statement to ensure Guzzle can be used + globally and in a Composer install +* Fixed an issue with generating and merging in events to an event array +* POST headers are only applied before sending a request to allow you to change + the query aggregator used before uploading +* Added much more robust query string parsing +* Fixed various parsing and normalization issues with URLs +* Fixing an issue where multi-valued headers were not being utilized correctly + in the StreamAdapter + +## 4.1.2 - 2014-06-18 + +* Added support for sending payloads with GET requests + +## 4.1.1 - 2014-06-08 + +* Fixed an issue related to using custom message factory options in subclasses +* Fixed an issue with nested form fields in a multi-part POST +* Fixed an issue with using the `json` request option for POST requests +* Added `ToArrayInterface` to `GuzzleHttp\Cookie\CookieJar` + +## 4.1.0 - 2014-05-27 + +* Added a `json` request option to easily serialize JSON payloads. +* Added a `GuzzleHttp\json_decode()` wrapper to safely parse JSON. +* Added `setPort()` and `getPort()` to `GuzzleHttp\Message\RequestInterface`. +* Added the ability to provide an emitter to a client in the client constructor. +* Added the ability to persist a cookie session using $_SESSION. +* Added a trait that can be used to add event listeners to an iterator. +* Removed request method constants from RequestInterface. +* Fixed warning when invalid request start-lines are received. +* Updated MessageFactory to work with custom request option methods. +* Updated cacert bundle to latest build. + +4.0.2 (2014-04-16) +------------------ + +* Proxy requests using the StreamAdapter now properly use request_fulluri (#632) +* Added the ability to set scalars as POST fields (#628) + +## 4.0.1 - 2014-04-04 + +* The HTTP status code of a response is now set as the exception code of + RequestException objects. +* 303 redirects will now correctly switch from POST to GET requests. +* The default parallel adapter of a client now correctly uses the MultiAdapter. +* HasDataTrait now initializes the internal data array as an empty array so + that the toArray() method always returns an array. + +## 4.0.0 - 2014-03-29 + +* For more information on the 4.0 transition, see: + http://mtdowling.com/blog/2014/03/15/guzzle-4-rc/ +* For information on changes and upgrading, see: + https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40 +* Added `GuzzleHttp\batch()` as a convenience function for sending requests in + parallel without needing to write asynchronous code. +* Restructured how events are added to `GuzzleHttp\ClientInterface::sendAll()`. + You can now pass a callable or an array of associative arrays where each + associative array contains the "fn", "priority", and "once" keys. + +## 4.0.0.rc-2 - 2014-03-25 + +* Removed `getConfig()` and `setConfig()` from clients to avoid confusion + around whether things like base_url, message_factory, etc. should be able to + be retrieved or modified. +* Added `getDefaultOption()` and `setDefaultOption()` to ClientInterface +* functions.php functions were renamed using snake_case to match PHP idioms +* Added support for `HTTP_PROXY`, `HTTPS_PROXY`, and + `GUZZLE_CURL_SELECT_TIMEOUT` environment variables +* Added the ability to specify custom `sendAll()` event priorities +* Added the ability to specify custom stream context options to the stream + adapter. +* Added a functions.php function for `get_path()` and `set_path()` +* CurlAdapter and MultiAdapter now use a callable to generate curl resources +* MockAdapter now properly reads a body and emits a `headers` event +* Updated Url class to check if a scheme and host are set before adding ":" + and "//". This allows empty Url (e.g., "") to be serialized as "". +* Parsing invalid XML no longer emits warnings +* Curl classes now properly throw AdapterExceptions +* Various performance optimizations +* Streams are created with the faster `Stream\create()` function +* Marked deprecation_proxy() as internal +* Test server is now a collection of static methods on a class + +## 4.0.0-rc.1 - 2014-03-15 + +* See https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40 + +## 3.8.1 - 2014-01-28 + +* Bug: Always using GET requests when redirecting from a 303 response +* Bug: CURLOPT_SSL_VERIFYHOST is now correctly set to false when setting `$certificateAuthority` to false in + `Guzzle\Http\ClientInterface::setSslVerification()` +* Bug: RedirectPlugin now uses strict RFC 3986 compliance when combining a base URL with a relative URL +* Bug: The body of a request can now be set to `"0"` +* Sending PHP stream requests no longer forces `HTTP/1.0` +* Adding more information to ExceptionCollection exceptions so that users have more context, including a stack trace of + each sub-exception +* Updated the `$ref` attribute in service descriptions to merge over any existing parameters of a schema (rather than + clobbering everything). +* Merging URLs will now use the query string object from the relative URL (thus allowing custom query aggregators) +* Query strings are now parsed in a way that they do no convert empty keys with no value to have a dangling `=`. + For example `foo&bar=baz` is now correctly parsed and recognized as `foo&bar=baz` rather than `foo=&bar=baz`. +* Now properly escaping the regular expression delimiter when matching Cookie domains. +* Network access is now disabled when loading XML documents + +## 3.8.0 - 2013-12-05 + +* Added the ability to define a POST name for a file +* JSON response parsing now properly walks additionalProperties +* cURL error code 18 is now retried automatically in the BackoffPlugin +* Fixed a cURL error when URLs contain fragments +* Fixed an issue in the BackoffPlugin retry event where it was trying to access all exceptions as if they were + CurlExceptions +* CURLOPT_PROGRESS function fix for PHP 5.5 (69fcc1e) +* Added the ability for Guzzle to work with older versions of cURL that do not support `CURLOPT_TIMEOUT_MS` +* Fixed a bug that was encountered when parsing empty header parameters +* UriTemplate now has a `setRegex()` method to match the docs +* The `debug` request parameter now checks if it is truthy rather than if it exists +* Setting the `debug` request parameter to true shows verbose cURL output instead of using the LogPlugin +* Added the ability to combine URLs using strict RFC 3986 compliance +* Command objects can now return the validation errors encountered by the command +* Various fixes to cache revalidation (#437 and 29797e5) +* Various fixes to the AsyncPlugin +* Cleaned up build scripts + +## 3.7.4 - 2013-10-02 + +* Bug fix: 0 is now an allowed value in a description parameter that has a default value (#430) +* Bug fix: SchemaFormatter now returns an integer when formatting to a Unix timestamp + (see https://github.com/aws/aws-sdk-php/issues/147) +* Bug fix: Cleaned up and fixed URL dot segment removal to properly resolve internal dots +* Minimum PHP version is now properly specified as 5.3.3 (up from 5.3.2) (#420) +* Updated the bundled cacert.pem (#419) +* OauthPlugin now supports adding authentication to headers or query string (#425) + +## 3.7.3 - 2013-09-08 + +* Added the ability to get the exception associated with a request/command when using `MultiTransferException` and + `CommandTransferException`. +* Setting `additionalParameters` of a response to false is now honored when parsing responses with a service description +* Schemas are only injected into response models when explicitly configured. +* No longer guessing Content-Type based on the path of a request. Content-Type is now only guessed based on the path of + an EntityBody. +* Bug fix: ChunkedIterator can now properly chunk a \Traversable as well as an \Iterator. +* Bug fix: FilterIterator now relies on `\Iterator` instead of `\Traversable`. +* Bug fix: Gracefully handling malformed responses in RequestMediator::writeResponseBody() +* Bug fix: Replaced call to canCache with canCacheRequest in the CallbackCanCacheStrategy of the CachePlugin +* Bug fix: Visiting XML attributes first before visiting XML children when serializing requests +* Bug fix: Properly parsing headers that contain commas contained in quotes +* Bug fix: mimetype guessing based on a filename is now case-insensitive + +## 3.7.2 - 2013-08-02 + +* Bug fix: Properly URL encoding paths when using the PHP-only version of the UriTemplate expander + See https://github.com/guzzle/guzzle/issues/371 +* Bug fix: Cookie domains are now matched correctly according to RFC 6265 + See https://github.com/guzzle/guzzle/issues/377 +* Bug fix: GET parameters are now used when calculating an OAuth signature +* Bug fix: Fixed an issue with cache revalidation where the If-None-Match header was being double quoted +* `Guzzle\Common\AbstractHasDispatcher::dispatch()` now returns the event that was dispatched +* `Guzzle\Http\QueryString::factory()` now guesses the most appropriate query aggregator to used based on the input. + See https://github.com/guzzle/guzzle/issues/379 +* Added a way to add custom domain objects to service description parsing using the `operation.parse_class` event. See + https://github.com/guzzle/guzzle/pull/380 +* cURL multi cleanup and optimizations + +## 3.7.1 - 2013-07-05 + +* Bug fix: Setting default options on a client now works +* Bug fix: Setting options on HEAD requests now works. See #352 +* Bug fix: Moving stream factory before send event to before building the stream. See #353 +* Bug fix: Cookies no longer match on IP addresses per RFC 6265 +* Bug fix: Correctly parsing header parameters that are in `<>` and quotes +* Added `cert` and `ssl_key` as request options +* `Host` header can now diverge from the host part of a URL if the header is set manually +* `Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor` was rewritten to change from using SimpleXML to XMLWriter +* OAuth parameters are only added via the plugin if they aren't already set +* Exceptions are now thrown when a URL cannot be parsed +* Returning `false` if `Guzzle\Http\EntityBody::getContentMd5()` fails +* Not setting a `Content-MD5` on a command if calculating the Content-MD5 fails via the CommandContentMd5Plugin + +## 3.7.0 - 2013-06-10 + +* See UPGRADING.md for more information on how to upgrade. +* Requests now support the ability to specify an array of $options when creating a request to more easily modify a + request. You can pass a 'request.options' configuration setting to a client to apply default request options to + every request created by a client (e.g. default query string variables, headers, curl options, etc.). +* Added a static facade class that allows you to use Guzzle with static methods and mount the class to `\Guzzle`. + See `Guzzle\Http\StaticClient::mount`. +* Added `command.request_options` to `Guzzle\Service\Command\AbstractCommand` to pass request options to requests + created by a command (e.g. custom headers, query string variables, timeout settings, etc.). +* Stream size in `Guzzle\Stream\PhpStreamRequestFactory` will now be set if Content-Length is returned in the + headers of a response +* Added `Guzzle\Common\Collection::setPath($path, $value)` to set a value into an array using a nested key + (e.g. `$collection->setPath('foo/baz/bar', 'test'); echo $collection['foo']['bar']['bar'];`) +* ServiceBuilders now support storing and retrieving arbitrary data +* CachePlugin can now purge all resources for a given URI +* CachePlugin can automatically purge matching cached items when a non-idempotent request is sent to a resource +* CachePlugin now uses the Vary header to determine if a resource is a cache hit +* `Guzzle\Http\Message\Response` now implements `\Serializable` +* Added `Guzzle\Cache\CacheAdapterFactory::fromCache()` to more easily create cache adapters +* `Guzzle\Service\ClientInterface::execute()` now accepts an array, single command, or Traversable +* Fixed a bug in `Guzzle\Http\Message\Header\Link::addLink()` +* Better handling of calculating the size of a stream in `Guzzle\Stream\Stream` using fstat() and caching the size +* `Guzzle\Common\Exception\ExceptionCollection` now creates a more readable exception message +* Fixing BC break: Added back the MonologLogAdapter implementation rather than extending from PsrLog so that older + Symfony users can still use the old version of Monolog. +* Fixing BC break: Added the implementation back in for `Guzzle\Http\Message\AbstractMessage::getTokenizedHeader()`. + Now triggering an E_USER_DEPRECATED warning when used. Use `$message->getHeader()->parseParams()`. +* Several performance improvements to `Guzzle\Common\Collection` +* Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`: + createRequest, head, delete, put, patch, post, options, prepareRequest +* Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()` +* Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface` +* Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to + `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a + resource, string, or EntityBody into the $options parameter to specify the download location of the response. +* Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a + default `array()` +* Added `Guzzle\Stream\StreamInterface::isRepeatable` +* Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use + $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or + $client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))`. +* Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use $client->getConfig()->getPath('request.options/headers')`. +* Removed `Guzzle\Http\ClientInterface::expandTemplate()` +* Removed `Guzzle\Http\ClientInterface::setReque |