diff options
author | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
---|---|---|
committer | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
commit | fc7369835258467bf97eb64f184b93691f9a9fd5 (patch) | |
tree | daabd60089d2dd76d9f5fb416b005fbe159c799d /bin |
first commit
Diffstat (limited to 'bin')
351 files changed, 35590 insertions, 0 deletions
diff --git a/bin/bkp/bkp_wiki.sh b/bin/bkp/bkp_wiki.sh new file mode 100755 index 00000000..c9aef4a4 --- /dev/null +++ b/bin/bkp/bkp_wiki.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# ---- +# Copyright (C) 2013-2020 - Reevo Project (http://reevo.org) +# License: Affero GPL version 3 - http://www.gnu.org/licenses/agpl.html +# ES: Este archivos es parte de: reevo-web (http://git.reevo.org/reevo/reevo-web) +# EN: This file is part of: reevo-web (http://git.reevo.org/reevo/reevo-web) +# ---- + +cd /srv/reevo-2020/bin/bkp/ + +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` + +DB=`cat $RUTA/etc/global_config.php | grep '^$REEVO_DB_WIKI' | cut -d '"' -f 2` +TIMESTAMP=`date +%Y-%m-%d-%H:%M:%S` + +echo "" +echo "Se va a generar una copia de la BD: $DB" +mysqldump --user=$USER --password=$PASSWORD $DB > "$RUTA/bkp/wiki/$DOMINIO-$DB-$TIMESTAMP.sql" + +echo "" +echo "Se comprime la BD" +bzip2 "$RUTA/bkp/wiki/$DOMINIO-$DB-$TIMESTAMP.sql" + +echo "Generamos enlace simbolico" +rm "$RUTA/bkp/wiki/ultimo" +ln -s "$RUTA/bkp/wiki/$DOMINIO-$DB-$TIMESTAMP.sql.bz2" "$RUTA/bkp/wiki/ultimo" diff --git a/bin/wiki/ImportarImagenPrensa.php b/bin/wiki/ImportarImagenPrensa.php new file mode 100644 index 00000000..91a247e4 --- /dev/null +++ b/bin/wiki/ImportarImagenPrensa.php @@ -0,0 +1,119 @@ +<?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 importa las imagenes de los objetos de prensa +# ---- + +// ini_set( 'post_max_size', '50M' ); +// ini_set( 'upload_max_filesize', '50M' ); +// 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 de la página como parámetro + +function ImportarImagenPrensa($pagetitle, $services) { + global $REEVO_URL; + $page = $services->newPageGetter()->getFromTitle( $pagetitle ); + $pagecontent = $page->getRevisions()->getLatest(); + if (!$pagecontent) { + echo "No existe una página con el nombre '$pagetitle'\n"; + return; + } + + + $pagecontent = $page->getRevisions()->getLatest()->getContent()->getData(); + + // armo un array con las propiedades de SMW + $rows = explode("|", $pagecontent); + foreach($rows as $row => $data) + { + $row_data = explode('=', $data); + $page_properties[$row_data[0]] = $row_data[1]; + } + + if (array_key_exists('prensa:imagen', $page_properties)) { + echo "La página '$pagetitle' ya tiene una imagen\n"; + return; + } + + if (array_key_exists('prensa:elggid', $page_properties)) { + $elggidtmp = $page_properties['prensa:elggid']; + $elggid = preg_replace( "/\r|\n/", "", $elggidtmp ); + // echo $url; + } else { + echo "La página '$pagetitle' no tiene definida la propiedad 'prensa:elggid'\n"; + return; + } + + // Definimos el nombre del archivo de la imagen + $pagename = str_replace( ":", "-", $pagetitle); + $snapshot_name = $pagename . '.jpg'; + $snaphot_pagecontent = 'Imagen importada desde sitio anterior para [['. $pagetitle .']]'; + $snaphot_desc = 'Imagen importada desde sitio anterior para [['. $pagetitle .']]'; + $fileUploader = $services->newFileUploader(); + $fileUploader->setChunkSize( 256 * 10 ); + exec("cp /srv/reevo-web/files/red/recext/{$elggid}/`ls /srv/reevo-web/files/red/recext/{$elggid}/` /tmp/imagen && convert /tmp/imagen /tmp/imagen.jpg"); + $fileUploader->upload( $snapshot_name, '/tmp/imagen.jpg', $snaphot_pagecontent, $snaphot_desc ); + + // Crea nueva o actualiza existente + $linkContent = str_replace('}}','|prensa:imagen='. $snapshot_name . '}}', $pagecontent); + + $newContent = new \Mediawiki\DataModel\Content( $linkContent ); + $title = new \Mediawiki\DataModel\Title( $pagetitle ); + $identifier = new \Mediawiki\DataModel\PageIdentifier( $title ); + $revision = new \Mediawiki\DataModel\Revision( $newContent, $identifier ); + $services->newRevisionSaver()->save( $revision ); + $link = urlencode("http://{$REEVO_URL}/Archivo:{$snapshot_name}"); + echo "Importe la imagen para '{$pagetitle}' y se subio a: '{$link}'\n\n"; +} + + +if ($argv[1]) { + ImportarImagenPrensa($argv[1],$services); +} else { + echo "Al no indicar una página, voy a generar los snapshots de todas las pagínas que usen Plantilla:Prensa \n"; + + // Obtengo todas las paginas con Plantilla:Prensa + $pageListGetter = $services->newPageListGetter(); + $examplePages = $pageListGetter->getPageListFromPageTransclusions( 'Template:Prensa' ); + $array = accessProtected($examplePages,'pages'); + foreach ( $array as $exPage ) { + $pagename = $exPage->getTitle()->getText(); + echo "$pagename \n"; + ImportarImagenPrensa($pagename, $services); + } +} + + + + +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/wiki/ListarPaginas.php b/bin/wiki/ListarPaginas.php new file mode 100644 index 00000000..96a4d6ef --- /dev/null +++ b/bin/wiki/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/wiki/PropiedadActualizar.php b/bin/wiki/PropiedadActualizar.php new file mode 100644 index 00000000..81f845b5 --- /dev/null +++ b/bin/wiki/PropiedadActualizar.php @@ -0,0 +1,120 @@ +<?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" +# ---- + + +// 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 ); + +$opciones = getopt('t:p:f:'); + +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/wiki/PropiedadObtener.php b/bin/wiki/PropiedadObtener.php new file mode 100644 index 00000000..114fba48 --- /dev/null +++ b/bin/wiki/PropiedadObtener.php @@ -0,0 +1,80 @@ +<?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 -t=Experiencia:Summerhill -p="experiencia:lugar" -p="experiencia:lugar-pais" +# ---- + + +// 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 ); + +$opciones = getopt('t:p:f:'); + +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"; + } +} else { + echo "Es necesario que definas el nombe de la pagina a revisar con -t='Pagina'\n"; +} + +// 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/wiki/composer.json b/bin/wiki/composer.json new file mode 100644 index 00000000..62491e7e --- /dev/null +++ b/bin/wiki/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "addwiki/mediawiki-api": "~0.7.0" + } +} diff --git a/bin/wiki/composer.lock b/bin/wiki/composer.lock new file mode 100644 index 00000000..0a32d572 --- /dev/null +++ b/bin/wiki/composer.lock @@ -0,0 +1,487 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "1dfde0453a3f59ee7cce361eee3cbcdf", + "packages": [ + { + "name": "addwiki/mediawiki-api", + "version": "0.7.2", + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.7.x-dev" + } + }, + "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" + ], + "time": "2017-11-20T03:08:06+00:00" + }, + { + "name": "addwiki/mediawiki-api-base", + "version": "2.4.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+)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4.x-dev" + } + }, + "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" + ], + "time": "2017-11-02T10:53:36+00:00" + }, + { + "name": "addwiki/mediawiki-datamodel", + "version": "0.7.1", + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.7.x-dev" + } + }, + "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" + ], + "time": "2018-01-10T19:14:13+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.3.3", + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.3-dev" + } + }, + "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" + ], + "time": "2018-04-22T15:46:56+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "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" + ], + "time": "2016-12-20T10:07:11+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.5.2", + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "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" + ], + "time": "2018-12-04T20:46:45+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "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" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.1.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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "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" + ], + "time": "2018-11-20T15:27:04+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "2.0.5", + "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" + }, + "type": "library", + "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.", + "time": "2016-02-11T07:05:27+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/bin/wiki/initReevo.php b/bin/wiki/initReevo.php new file mode 100644 index 00000000..81a006b0 --- /dev/null +++ b/bin/wiki/initReevo.php @@ -0,0 +1,11 @@ +<?php +/** + * scritp to initialise specifics wikifab pages, such as forms, properties, and home page + * + * @file + * @ingroup Maintenance + */ +require_once __DIR__ . '/initReevoClass.php'; + +$maintClass = "InitReevo"; +require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/bin/wiki/initReevoClass.php b/bin/wiki/initReevoClass.php new file mode 100644 index 00000000..ee67ded7 --- /dev/null +++ b/bin/wiki/initReevoClass.php @@ -0,0 +1,210 @@ +<?php +# ---- +# Copyright (C) 2013-2020 - Reevo Project (http://reevo.org) +# License: Affero GPL version 3 - http://www.gnu.org/licenses/agpl.html +# ES: Script usado para importar páginas de REEVO como formularios, propiedades, etc. +# Creditos: Basado en WikiFab: https://github.com/Wikifab/wikifab-main/tree/master/maintenance +# ---- + +require_once '../../www/wiki/maintenance/Maintenance.php'; + +class InitReevo extends Maintenance { + + public function __construct() { + parent::__construct (); + $this->mDescription = "Init Reevo pages"; + $this->addArg( 'namespace', 'El namspace especifico del cual generar las pagínas. Tambien puede pasarse un nombre de página especifico, ej: Portada.mw', false ); + $this->addOption ( 'folder', 'Importa las paginas de las carpeta especificada', false , false); + $this->addOption ( 'setReevoHomePage', "Cambia la portada", false, false ); + $this->addOption ( 'force', "Fuerza la edición cuando las páginas ya existan", false, false ); + $this->addOption ( 'int', "Usar solo páginas internacionales, de la carpeta 'int'", false, false ); + } + + protected function getUpdateKey() { + return 'initialise_Reevo_Pages'; + } + + protected function updateSkippedMessage() { + return 'Reevo pages are allready setup'; + } + + public function execute() { + global $wgContLang; + + $setReevoHomePage = $this->getOption ( 'setReevoHomePage' ); + $force = $this->getOption ( 'force' ) ? true : false; + + if ($this->getOption ( 'folder' )) { + echo 'Voy a importar de la carpeta: '. $this->getOption ( 'folder' ); + $lang = $this->getOption ( 'folder' ); + } else { + $lang = $this->getOption ( 'int' ) ? 'int' : $wgContLang->getCode(); + } + + + $homePageFile = [ + 'es' => 'Portada.md', + 'en' => 'Main_Page.md', + 'int' => 'Portada.md' + ]; + + $pagelist = $this->getPageListToCreate ($lang); + + echo "Setting Up Reevo pages ...\n"; + + + if ($setReevoHomePage) { + echo "Setting wiki home page $setReevoHomePage\n"; + + $ret = Title::newMainPage(); + $pageTitle = $ret->getText(); + $title = $this->getPageName ( $pageTitle ); + $content = $this->getPageContent ( $homePageFile[$lang], $lang); + $this->createPage ( $title, $content, true); + + } else { + echo "No Setting wiki home page\n"; + } + + foreach ( $pagelist as $page ) { + if ($page == $homePageFile) { + continue; + } + $title = $this->getPageName ( $page ); + $content = $this->getPageContent ($page, $lang); + $this->createPage ( $title, $content , $force); + + $t = Title::newFromText( $title ); + $protection = "sysop"; + $user = User::newSystemUser( 'Admin', [ 'steal' => true ] ); + $cascade = ''; + $reason = 'Se protege por seguridad'; + + $restrictions = []; + foreach ( $t->getRestrictionTypes() as $type ) { + $restrictions[$type] = $protection; + } + + $page = WikiPage::factory( $t ); + $status = $page->doUpdateRestrictions( $restrictions, [], $cascade, $reason, $user ); + } + } + + /** + * Get a WikiPage object from a title string, if possible. + * + * @param string $titleName + * @param bool|string $load + * Whether load the object's state from the database: + * - false: don't load (if the pageid is given, it will still be loaded) + * - 'fromdb': load from a slave database + * - 'fromdbmaster': load from the master database + * @return WikiPage + */ + protected function getPage($titleName) { + $titleObj = Title::newFromText ( $titleName ); + if (! $titleObj || $titleObj->isExternal ()) { + trigger_error ( 'Fail to get title ' . $titleName, E_USER_WARNI ); + return false; + } + if (! $titleObj->canExist ()) { + trigger_error ( 'Title cannot be created ' . $titleName, E_USER_WARNING ); + return false; + } + $pageObj = WikiPage::factory ( $titleObj ); + + return $pageObj; + } + protected function getAdminUser() { + // get Admin user : (take the first user created) + $dbr = wfGetDB ( DB_SLAVE ); + $res = $dbr->select ( 'user', User::selectFields (), array (), __METHOD__, array ( + 'LIMIT' => 1, + 'ORDER BY' => 'user_id' + ) ); + $users = UserArray::newFromResult ( $res ); + $user = $users->current (); + + return $user; + } + protected function createPage($pageName, $text, $force = false) { + $wikipage = $this->getPage ( $pageName ); + + if ($wikipage->exists () && ! $force) { + echo "page $pageName allready exists.\n"; + return false; + } + + $user = $this->getAdminUser (); + + $content = ContentHandler::makeContent( $text, $wikipage->getTitle() ); + $result = $wikipage->doEditContent( $content, 'Actualizada automaticamente con versión de repositorio', $flags = 0, $baseRevId = false, $user ); + + if ($result->isOK ()) { + echo "page $pageName successfully created.\n"; + return true; + } else { + echo $result->getWikiText (); + } + + return false; + } + protected function getPageName($page) { + // $page = str_replace ( 'Formulario_', 'Formulario:', $page ); + // $page = str_replace ( 'Propiedad_', 'Propiedad:', $page ); + // if (strpos($page,'Template_') == 0) { + // $page = str_replace ( 'Plantilla_', 'Plantilla:', $page ); + // } + // $page = str_replace ( 'Modulo_', 'Modulo:', $page ); + // $page = str_replace ( 'Categoría_', 'Categoría:', $page ); + // $page = str_replace ( 'MediaWiki_', 'Mediawiki:', $page ); + // $page = str_replace ( 'Widget_', 'Widget:', $page ); + // $page = str_replace ( 'Ayuda_', 'Ayuda:', $page ); + // $page = str_replace ( 'Reevo_', 'Reevo:', $page ); + $page = str_replace ( '_', ' ', $page ); + $page = str_replace ( '~', '/', $page ); + $page = str_replace ( '.mw', '', $page ); + + return $page; + } + protected function getPagesDirs($lang) { + return [ + __DIR__ . '/reevoPages/' . $lang + ]; + } + protected function getPageContent($page, $lang = 'int') { + $dirs = $this->getPagesDirs($lang); + + foreach ($dirs as $dir) { + if (file_exists($dir . '/' . $page)) { + return file_get_contents ( $dir . '/' . $page ); + } + } + + throw new Exception('File not found : ' . $page); + } + protected function getPageListToCreate( $lang) { + + $result = [ ]; + + $dirs = $this->getPagesDirs($lang); + foreach ($dirs as $dir) { + $files = scandir ( $dir ); + foreach ( $files as $file ) { + if (preg_match ( '/^([a-zA-Z_0-9\-áéíóúñÁÉÍÓÚÑ~:’()])+\.mw$/', $file )) { + $namespace = $this->getArg( 0 ); + if ($namespace) { + if(strpos($file, $namespace) === 0) { + // echo "$file\n"; + $result[$file] = $file; + } + } else { + $result[$file] = $file; + } + } + } + } + print_r($result); + return $result; + } +} diff --git a/bin/wiki/reevoPages/int/Formulario:Audiovisual.mw b/bin/wiki/reevoPages/int/Formulario:Audiovisual.mw new file mode 100644 index 00000000..624bda1a --- /dev/null +++ b/bin/wiki/reevoPages/int/Formulario:Audiovisual.mw @@ -0,0 +1,90 @@ +<noinclude> +Este es el formulario "Audiovisual". +Para crear una página con este formulario, escribe el nombre de la página a continuación; +si ya existe una página con ese nombre, serás dirigido a un formulario para editar esa página. + + +{{#forminput:form=Audiovisual|query string=namespace=Audiovisual|autocomplete on namespace=Audiovisual}} + +</noinclude><includeonly> +<div id="wikiPreview" style="display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #AAAAAA;"></div> +{{{for template|audiovisual}}} + + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-audiovisual:titulo}}</div> +<div class="col-sm-10">{{{field|audiovisual:titulo|input type=text|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-audiovisual:estreno}}</div> +<div class="col-sm-10">{{{field|audiovisual:estreno|input type=year|mandatory|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-form-label col-sm-2 pt-0">{{int:rv-audiovisual:pais}}</div> +<div class="col-sm-10">{{{field|audiovisual:pais|class=form-control|input type=dropdown|mandatory|mapping using translate=rv-pais-}}} +</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">Estado</div> +<div class="col-sm-10">{{{field|Estado|input type=SF_Select|function=states:@@@@|sametemplate|field=audiovisual:pais|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-form-label col-sm-2 pt-0">{{int:rv-audiovisual:genero}}</div> +<div class="col-sm-10">{{{field|audiovisual:genero|input type=radiobutton|class=radio-inline|mandatory|default=documental|mapping using translate=rv-audiovisual:genero:}}} +</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-audiovisual:duracion}}</div> +<div class="col-sm-10">{{{field|audiovisual:duracion|mandatory|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-audiovisual:autoria}}</div> +<div class="col-sm-10">{{{field|audiovisual:autoria|input type=text|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-audiovisual:web}}</div> +<div class="col-sm-10">{{{field|audiovisual:web|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-audiovisual:urltrailer}}</div> +<div class="col-sm-10">{{{field|audiovisual:urltrailer|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-audiovisual:url}}</div> +<div class="col-sm-10">{{{field|audiovisual:url|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-audiovisual:magnet}}</div> +<div class="col-sm-10">{{{field|audiovisual:magnet|class=form-control}}}</div> +</div> + +<div class="form-group"> +<div class="row"> +<div class="col-form-label col-sm-2 pt-0">{{int:rv-audiovisual:sub}}</div> +<div class="col-sm-10">{{{field|audiovisual:sub|input type=checkboxes|class=radio-inline|mapping using translate=rv-audiovisual:sub:}}}</div> +</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-audiovisual:poster}}</div> +<div class="col-sm-10">{{{field|audiovisual:poster|input type=text|class=form-control|uploadable|image preview|default filename=audiovisual-poster-{{PAGENAME}}.jpg}}}</div> +</div> +{{{end template}}} + + +{{int:rv-form:label:content}} + +{{{standard input|free text|rows=10|autogrow|editor=wikieditor}}} + +{{{standard input|save}}} {{{standard input|preview}}} {{{standard input|changes}}} {{{standard input|cancel}}} +</includeonly> diff --git a/bin/wiki/reevoPages/int/Formulario:Experiencia.mw b/bin/wiki/reevoPages/int/Formulario:Experiencia.mw new file mode 100644 index 00000000..012ac493 --- /dev/null +++ b/bin/wiki/reevoPages/int/Formulario:Experiencia.mw @@ -0,0 +1,181 @@ +<noinclude> +Este es el formulario "Experiencia". +Para crear una página con este formulario, escribe el nombre de la página a continuación; +si ya existe una página con ese nombre, serás dirigido a un formulario para editar esa página. + + +{{#forminput:form=Experiencia|query string=namespace=Experiencia|autocomplete on namespace=Experiencia}} + +</noinclude><includeonly> +<div id="wikiPreview" style="display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #AAAAAA;"></div> +{{{for template|Experiencia}}} + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:descripcion}}{{#info:{{int:rv-experiencia:descripcion:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:descripcion|input type=textarea|class=form-control}}}</div> +</div> + +<hr/> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:contacto-url}}{{#info:{{int:rv-experiencia:contacto-url:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:contacto-url|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:contacto-email}}{{#info:{{int:rv-experiencia:contacto-email:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:contacto-email|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:contacto-telefono}}{{#info:{{int:rv-experiencia:contacto-telefono:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:contacto-telefono|class=form-control}}}</div> +</div> + +<hr/> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:lugar-pais}}{{#info:{{int:rv-experiencia:lugar-pais:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:lugar-pais|class=form-control|input type=dropdown|mandatory|mapping using translate=rv-pais-|feeds to p=Experiencia[experiencia:lugar]}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:lugar-provincia}}{{#info:{{int:rv-experiencia:lugar-provincia:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:lugar-provincia|input type=SF_Select|function=states:@@@@|sametemplate|field=experiencia:lugar-pais|class=form-control|feeds to map=Experiencia[experiencia:lugar]}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:lugar-ciudad}}{{#info:{{int:rv-experiencia:lugar-ciudad:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:lugar-ciudad|input type=text|feeds to map=Experiencia[experiencia:lugar]|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:lugar-calle}}{{#info:{{int:rv-experiencia:lugar-calle:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:lugar-calle|input type=text|feeds to map=Experiencia[experiencia:lugar]|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:lugar}}{{#info:{{int:rv-experiencia:lugar:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:lugar|input type=googlemaps|width=100%|class=form-control}}}</div> +</div> + + +<hr/> +<h2>Datos de organización y gestión</h2> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-inicio}}{{#info:{{int:rv-experiencia:info-inicio:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-inicio|input type=datepicker|class=form-control|week start=1|highlight days of week=0|date format=dd-mm-yy}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-final}}{{#info:{{int:rv-experiencia:info-final:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-final|input type=datepicker|class=form-control|week start=1|highlight days of week=0|date format=dd-mm-yy}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-organizacion}}{{#info:{{int:rv-experiencia:info-organizacion:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-organizacion|input type=dropbox|class=form-control|mapping using translate=rv-experiencia:respuesta-}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-gestion}}{{#info:{{int:rv-experiencia:info-gestion:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-gestion|input type=dropbox|class=form-control|mapping using translate=rv-experiencia:respuesta-}}}</div> +</div> + + +<hr/> +<h2>Datos demográficos</h2> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-nivel}}{{#info:{{int:rv-experiencia:info-nivel:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-nivel|input type=checkboxes|class=form-control|mapping using translate=rv-experiencia:respuesta-}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-niveleconomico}}{{#info:{{int:rv-experiencia:info-niveleconomico:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-niveleconomico|input type=dropbox|class=form-control|mapping using translate=rv-experiencia:respuesta-}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-contextosocial}}{{#info:{{int:rv-experiencia:info-contextosocial:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-contextosocial|input type=dropbox|class=form-control|mapping using translate=rv-experiencia:respuesta-}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-participantes}}{{#info:{{int:rv-experiencia:info-participantes:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-participantes|class=form-control|input type=regexp|message={{int:rv-form:label:valid:integer}}|regexp=/^[0-9 ]+$/}}}</div> +</div> + + +<hr/> +<h2>Aspectos educativos y pedagógicos</h2> + + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-corrientes}}{{#info:{{int:rv-experiencia:info-corrientes:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-corrientes|input type=tree|top category=Corrientes pedagógicas|list|hideroot}}}</div> +</div> + + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-enfoques}}{{#info:{{int:rv-experiencia:info-enfoques:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-enfoques|input type=tree|top category=Enfoques temáticos|list|hideroot}}}</div> +</div> + + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-tipoeducacion}}{{#info:{{int:rv-experiencia:info-tipoeducacion:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-tipoeducacion|input type=dropbox|class=form-control|mapping using translate=rv-experiencia:respuesta-}}}</div> +</div> + + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-certificacion}}{{#info:{{int:rv-experiencia:info-certificacion:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-certificacion|input type=dropbox|class=form-control|mapping using translate=rv-experiencia:respuesta-}}}</div> +</div> + + + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-virtual}}{{#info:{{int:rv-experiencia:info-virtual:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-virtual|input type=dropbox|class=form-control|mapping using translate=rv-experiencia:respuesta-}}}</div> +</div> + + +<hr/> +<h2>Aspectos económicos</h2> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-arancel}}{{#info:{{int:rv-experiencia:info-arancel:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-arancel|input type=dropbox|class=form-control|mapping using translate=rv-experiencia:respuesta-}}}</div> +</div> + + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-lucro}}{{#info:{{int:rv-experiencia:info-lucro:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-lucro|input type=dropbox|class=form-control|mapping using translate=rv-experiencia:respuesta-}}}</div> +</div> + + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-experiencia:info-voluntariado}}{{#info:{{int:rv-experiencia:info-voluntariado:ayuda}}}}</div> +<div class="col-sm-10">{{{field|experiencia:info-voluntariado|input type=dropbox|class=form-control|mapping using translate=rv-experiencia:respuesta-}}}</div> +</div> + + + + +{{{end template}}} + +'''Texto libre:''' + +{{{standard input|free text|rows=10|editor=wikieditor}}} + + +{{{standard input|summary}}} + +{{{standard input|minor edit}}} {{{standard input|watch}}} + +{{{standard input|save}}} {{{standard input|preview}}} {{{standard input|changes}}} {{{standard input|cancel}}} +</includeonly> diff --git a/bin/wiki/reevoPages/int/Formulario:Prensa.mw b/bin/wiki/reevoPages/int/Formulario:Prensa.mw new file mode 100644 index 00000000..39b8d356 --- /dev/null +++ b/bin/wiki/reevoPages/int/Formulario:Prensa.mw @@ -0,0 +1,64 @@ +<noinclude> +Este es el formulario "Prensa". +Para crear una página con este formulario, escribe el nombre de la página a continuación; +si ya existe una página con ese nombre, serás dirigido a un formulario para editar esa página. + + +{{#forminput:form=Prensa|query string=namespace=Prensa|autocomplete on namespace=Prensa}} + +</noinclude><includeonly> +<div id="wikiPreview" style="display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #AAAAAA;"></div> +{{{for template|Prensa}}} +{| class="formtable" + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-prensa:url}}</div> +<div class="col-sm-10">{{{field|prensa:url|unique|=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-prensa:fecha}}</div> +<div class="col-sm-10">{{{field|prensa:fecha|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-prensa:fuente}}</div> +<div class="col-sm-10">{{{field|prensa:fuente|class=form-control|values from property=prensa:fuente}}}</div> +</div> + +<div class="form-group"> +<div class="row"> +<div class="col-form-label col-sm-2 pt-0">{{int:rv-prensa:pais}}</div> +<div class="col-sm-10">{{{field|prensa:pais|class=form-control|input type=dropdown|mandatory|mapping using translate=rv-pais-}}} +</div> +</div> +</div> + +<div class="form-group"> +<div class="row"> +<div class="col-form-label col-sm-2 pt-0">{{int:rv-prensa:idioma}}</div> +<div class="col-sm-10">{{{field|prensa:idioma|input type=dropdown|class=radio-inline|mapping using translate=rv-prensa:idioma:}}}</div> +</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-prensa:descripcion}}</div> +<div class="col-sm-10">{{{field|prensa:descripcion|input type=textarea|class=form-control}}}</div> +</div> + +<div class="form-group row"> +<div class="col-sm-2 col-form-label">{{int:rv-prensa:imagen}}</div> +<div class="col-sm-10">{{{field|prensa:imagen|input type=text|class=form-control|uploadable|image preview|default filename=Prensa-{{PAGENAME}}.jpg}}}</div> +</div> + + +{{{end template}}} + + + +{{{standard input|summary}}} + +{{{standard input|minor edit}}} {{{standard input|watch}}} + +{{{standard input|save}}} {{{standard input|preview}}} {{{standard input|changes}}} {{{standard input|cancel}}} +</includeonly> diff --git a/bin/wiki/reevoPages/int/MediaWiki:Mainpage.mw b/bin/wiki/reevoPages/int/MediaWiki:Mainpage.mw new file mode 100644 index 00000000..f858d150 --- /dev/null +++ b/bin/wiki/reevoPages/int/MediaWiki:Mainpage.mw @@ -0,0 +1 @@ +Portada diff --git a/bin/wiki/reevoPages/int/MediaWiki:Sidebar.mw b/bin/wiki/reevoPages/int/MediaWiki:Sidebar.mw new file mode 100644 index 00000000..adb7d148 --- /dev/null +++ b/bin/wiki/reevoPages/int/MediaWiki:Sidebar.mw @@ -0,0 +1,15 @@ +* navigation +** Nosotrxs|{{int:rv-menu:nosotrxs}} +** Participar|{{int:rv-menu:participar}} +** Donar|{{int:rv-menu:donar}} +* rv-menu:ayuda +** Ayuda:Cómo se edita una página|{{int:rv-menu:ayuda:editar}} +** recentchanges-url|recentchanges +* rv-menu:contenidos +** Experiencia|{{int:rv-menu:contenidos:experiencia}} +** Prensa|{{int:rv-menu:contenidos:prensa}} +** Audiovisual|{{int:rv-menu:contenidos:audiovisual}} +** Bibliografía|{{int:rv-menu:contenidos:bibliografia}} +** Evento|{{int:rv-menu:contenidos:evento}} +** ---- +** Especial:FormStart|{{int:rv-menu:sumar}} diff --git a/bin/wiki/reevoPages/int/Plantilla:Audiovisual.mw b/bin/wiki/reevoPages/int/Plantilla:Audiovisual.mw new file mode 100644 index 00000000..d36aec01 --- /dev/null +++ b/bin/wiki/reevoPages/int/Plantilla:Audiovisual.mw @@ -0,0 +1,72 @@ +<noinclude> +<pre> +{{Audiovisual +|audiovisual:titulo= +|audiovisual:estreno= +|audiovisual:pais= +|audiovisual:duracion= +|audiovisual:autoria= +|audiovisual:genero= +|audiovisual:web= +|audiovisual:urltrailer= +|audiovisual:url= +|audiovisual:magnet= +|audiovisual:sub= +|audiovisual:poster= +}} +</pre> +</noinclude> +<includeonly><div class='col-lg-4 col-md-6 col-sm-12 col-xs-12'> +{| class="wikitable" +|+{{#if: {{{audiovisual:poster|}}} | [[Archivo:{{#setmainimage:{{{audiovisual:poster|}}}}}]] }} +|- +! {{int:rv-audiovisual:titulo}} +| [[Audiovisual:titulo::{{{audiovisual:titulo|}}}]] +|- +! {{int:rv-audiovisual:estreno}} +| [[Audiovisual:estreno::{{{audiovisual:estreno|}}}]] [{{SERVER}}/index.php?title=Especial%3ABuscarPorPropiedad&property=Audiovisual%3Aestreno&value={{{audiovisual:estreno|}}} +] +|- +! {{int:rv-audiovisual:pais}} +| {{int:rv-pais-{{{audiovisual:pais|}}}}}<span style="display:none">[[Audiovisual:pais::{{{audiovisual:pais|}}}]]</span> [{{SERVER}}/index.php?title=Especial%3ABuscarPorPropiedad&property=Audiovisual%3Apais&value={{{audiovisual:pais|}}} +] +|- +! {{int:rv-audiovisual:duracion}} +| [[Audiovisual:duracion::{{{audiovisual:duracion|}}}]] +|- +! {{int:rv-audiovisual:autoria}} +| [[Audiovisual:autoria::{{{audiovisual:autoria|}}}]] +|- +! {{int:rv-audiovisual:genero}} +| {{int:rv-audiovisual:genero:{{{audiovisual:genero|}}}}} [{{SERVER}}/index.php?title=Especial%3ABuscarPorPropiedad&property=Audiovisual%3Agenero&value={{{audiovisual:genero|}}} +] +|- +! {{int:rv-audiovisual:web}} +| [[Audiovisual:web::{{{audiovisual:web|}}}]] +|- +! {{int:rv-audiovisual:sub}} +| [[Audiovisual:sub::{{{audiovisual:sub|}}}]] +|}</div><div class='col-lg-8 col-md-6 col-sm-12 col-xs-12'>{{#if:{{{audiovisual:urltrailer|}}} | == {{int:rv-audiovisual:seccion:trailer}} == +{{#evu:{{{audiovisual:urltrailer|}}}}} +}} + +{{#if: {{{audiovisual:url|}}} | +== {{int:rv-audiovisual:seccion:online}} == +{{#evu:{{{audiovisual:url|}}}}} +}} + +{{#if: {{#rmatch:{{#USERNAME:}}|/(.*)\.(.*)\.(.*)\.(.*)/||{{#USERNAME:}}}} | +{{#if: {{{audiovisual:magnet|}}} | +== {{int:rv-audiovisual:seccion:descarga}} == +{{{audiovisual:magnet|}}} +}} +}} +</div> + +[[Categoría:Audiovisual]] + +<div style='display:none;'> +[[Audiovisual:poster::{{{audiovisual:poster|}}}]] +[[Audiovisual:genero::{{{audiovisual:genero|}}}]] +[[Audiovisual:url::{{{audiovisual:url|}}}]] +[[Audiovisual:urltrailer::{{{audiovisual:urltrailer|}}}]] +[[Audiovisual:magnet::{{{audiovisual:magnet|}}}]] +</div> +</includeonly> diff --git a/bin/wiki/reevoPages/int/Plantilla:Experiencia.mw b/bin/wiki/reevoPages/int/Plantilla:Experiencia.mw new file mode 100644 index 00000000..d35f59db --- /dev/null +++ b/bin/wiki/reevoPages/int/Plantilla:Experiencia.mw @@ -0,0 +1,131 @@ +<noinclude> +Esta es la plantilla "Experiencia". Debe llamarse en el siguiente formato: +<pre> +{{Experiencia +|experiencia:descripcion= + +|experiencia:contacto-url= +|experiencia:contacto-email= +|experiencia:contacto-telefono= + +|experiencia:imagen-destacada= + +|experiencia:lugar= +|experiencia:lugar-pais= +|experiencia:lugar-provincia= +|experiencia:lugar-ciudad= +|experiencia:lugar-calle= + +|experiencia:info-inicio= +|experiencia:info-final= +|experiencia:info-niveleconomico= +|experiencia:info-contextosocial= +|experiencia:info-participantes= +|experiencia:info-nivel= +|experiencia:info-organizacion= +|experiencia:info-gestion= +|experiencia:info-voluntariado= + +|experiencia:info-corrientes= +|experiencia:info-enfoques= + +|experiencia:info-certificacion= +|experiencia:info-tipoeducacion= +|experiencia:info-arancel= +|experiencia:info-lucro= +|experiencia:info-virtual= + +# Parametros que no son propiedades semanticas + +|experiencia:oldid= +|experiencia:imagen-destacada-zoom= +|banner-altura= +}} +</pre> +Editar la página para ver el texto de la plantilla. +</noinclude><includeonly>{{#if: {{{experiencia:info-final|}}} | +<div class="alert alert-warning"> +{{int:rv-experiencia:info-final-nota}}[[Categoría:Experiencias finalizadas]] +</div> +}} +<div class="intro-copete"> +[[Experiencia:descripcion::{{{experiencia:descripcion|}}}]]{{#description2:{{{experiencia:descripcion|}}}}} +</div> +<div class="intro-links"> +{{#if: {{{experiencia:contacto-url|}}} | <span id="intro-links-url"><span class="glyphicon glyphicon-home"></span> [{{{experiencia:contacto-url|}}} Sitio web] </span>}}{{#if: {{{experiencia:contacto-email|}}} | <nowiki> | </nowiki> <span id="intro-links-email"><span class="glyphicon glyphicon-envelope"></span> [[Experiencia:contacto-email::{{{experiencia:contacto-email|}}}]] </span>}}{{#if: {{{experiencia:contacto-telefono|}}} | <nowiki> | </nowiki> <span id="intro-links-telefono"><span class="glyphicon glyphicon-earphone"></span> [[Experiencia:contacto-telefono::{{{experiencia:contacto-telefono|}}}]] </span>}} +</div><div style='padding-left: 0 !important;' class='col-lg-4 col-md-6 col-sm-12 col-xs-12'> +{| class="wikitable" +|+ {{#if: {{{experiencia:lugar|}}} | {{#display_map:{{{experiencia:lugar|}}}|width=100%|enablefullscreen=yes|height=300|service=leaflet}} }}<span class="map-address">{{#if: {{{experiencia:lugar-calle|}}} | [[Experiencia:lugar-calle::{{{experiencia:lugar-calle|}}}]] }}, {{#if: {{{experiencia:lugar-ciudad|}}} | [[Experiencia:lugar-ciudad::{{{experiencia:lugar-ciudad|}}}]] }}, {{#if: {{{experiencia:lugar-provincia|}}} | [[Experiencia:lugar-provincia::{{{experiencia:lugar-provincia|}}}]] }}, {{#if: {{{experiencia:lugar-pais|}}} | {{int:rv-pais-{{{experiencia:lugar-pais|}}}}} <span style="display:none">[[Experiencia:lugar-pais::{{{experiencia:lugar-pais|}}}]]</span> }}</span> +|- {{#if: {{{experiencia:info-inicio|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-inicio}} +| [[Experiencia:info-inicio::{{{experiencia:info-inicio|}}}]] +|- {{#if: {{{experiencia:info-final|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-final}} +| [[Experiencia:info-final::{{{experiencia:info-final|}}}]] +|- {{#if: {{{experiencia:info-corrientes|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-corrientes}} +| {{#arraymap:{{{experiencia:info-corrientes|}}}|,|@|[[:Categoría:@|@]] |<nowiki>, </nowiki>}}<span style='display:none;'>[[Experiencia:info-corrientes::{{{experiencia:info-corrientes|}}}]]</span> +|- {{#if: {{{experiencia:info-enfoques|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-enfoques}} +| {{#arraymap:{{{experiencia:info-enfoques|}}}|,|@|[[:Categoría:@|@]] |<nowiki>, </nowiki>}}<span style='display:none;'>[[Experiencia:info-corrientes::{{{experiencia:info-corrientes|}}}]]</span> +|- {{#if: {{{experiencia:info-niveleconomico|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-niveleconomico}} +| {{int:rv-experiencia:respuesta-{{{experiencia:info-niveleconomico|}}}}} +|- {{#if: {{{experiencia:info-contextosocial|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-contextosocial}} +| {{int:rv-experiencia:respuesta-{{{experiencia:info-contextosocial|}}}}} +|- {{#if: {{{experiencia:info-participantes|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-participantes}} +| {{{experiencia:info-participantes|}}} +|- {{#if: {{{experiencia:info-nivel|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-nivel}} +| {{#arraymap:{{{experiencia:info-nivel|}}}|,|@|{{int:rv-experiencia:respuesta-@}} |<nowiki>, </nowiki>}}<span style='display:none;'>[[Experiencia:info-nivel::{{{experiencia:info-nivel|}}}]]</span> +|- {{#if: {{{experiencia:info-organizacion|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-organizacion}} +| {{int:rv-experiencia:respuesta-{{{experiencia:info-organizacion|}}}}} +|- {{#if: {{{experiencia:info-gestion|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-gestion}} +| {{int:rv-experiencia:respuesta-{{{experiencia:info-gestion|}}}}} +|- {{#if: {{{experiencia:info-tipoeducacion|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-tipoeducacion}} +| {{int:rv-experiencia:respuesta-{{{experiencia:info-tipoeducacion|}}}}} +|- {{#if: {{{experiencia:info-certificacion|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-certificacion}} +| {{int:rv-experiencia:respuesta-{{{experiencia:info-certificacion|}}}}} +|- {{#if: {{{experiencia:info-lucro|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-arancel}} +| {{int:rv-experiencia:respuesta-{{{experiencia:info-arancel|}}}}} +|- {{#if: {{{experiencia:info-lucro|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-lucro}} +| {{int:rv-experiencia:respuesta-{{{experiencia:info-lucro|}}}}} +|- {{#if: {{{experiencia:info-voluntariadol|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-voluntariadol}} +| {{int:rv-experiencia:respuesta-{{{experiencia:info-virtual|}}}}} +|- {{#if: {{{experiencia:info-virtual|}}} | | style="display:none;" }} +! {{int:rv-experiencia:info-virtual}} +| {{int:rv-experiencia:respuesta-{{{experiencia:info-virtual|}}}}} +|} +</div> +<div style="display:none;">{{#if: {{{experiencia:imagen-destacada|}}} | {{#setmainimage:{{{experiencia:imagen-destacada|}}}}} | {{#setmainimage:{{#replace:https://api.mapbox.com/v4/mapbox.satellite/{{#explode:{{{experiencia:lugar|}}}|, |1}},{{#explode:{{{experiencia:lugar|}}}|, |0}},{{#if: {{{experiencia:imagen-destacada-zoom|}}} | {{{experiencia:imagen-destacada-zoom|}}} | 9 }}/1000x400@2x.png?access_token=pk.eyJ1IjoiaWFjb21lbGxhIiwiYSI6ImNpdWJ3OHJoYTAwOHgyb3BneWd1NG16bjgifQ.8uFt1oMO57yDT9Xzb_ScAw}}| ||}}}} +[[Experiencia:lugar::{{{experiencia:lugar|}}}]] +[[Experiencia:info-niveleconomico::{{{experiencia:info-niveleconomico|}}}]] +[[Experiencia:info-organizacion::{{{experiencia:info-organizacion|}}}]] +[[Experiencia:info-gestion::{{{experiencia:info-gestion|}}}]] +[[Experiencia:info-contextosocial::{{{experiencia:info-contextosocial|}}}]] +[[Experiencia:info-participantes::{{{experiencia:info-participantes|}}}]] +[[Experiencia:info-tipoeducacion::{{{experiencia:info-tipoeducacion|}}}]] +[[Experiencia:info-certificacion::{{{experiencia:info-certificacion|}}}]] +[[Experiencia:info-arancel::{{{experiencia:info-arancel|}}}]] +[[Experiencia:info-lucro::{{{experiencia:info-lucro|}}}]] +[[Experiencia:info-voluntariado::{{{experiencia:info-voluntariado|}}}]] +[[Experiencia:info-virtual::{{{experiencia:info-virtual|}}}]] +[[Experiencia:contacto-url::{{{experiencia:contacto-url|}}}]] +[[Experiencia:oldid::{{{experiencia:oldid|}}}]] +[[Experiencia:pageid::{{PAGEID}}]] +</div>__NOTOC__ +{{#arraymap:{{{experiencia:info-corrientes|}}}|,|x|[[Categoría:x]] |<nowiki> </nowiki>}} +{{#arraymap:{{{experiencia:info-enfoques|}}}|,|x|[[Categoría:x]] |<nowiki> </nowiki>}} +[[Categoría:Experiencia]] +{{#if: {{{banner-altura|}}} | {{#css: .bannerimage {background-position: 0px {{{banner-altura|}}}% !important;} }} }} +<div class="clean-p"></div> +</includeonly> diff --git a/bin/wiki/reevoPages/int/Plantilla:Prensa-Archivo.mw b/bin/wiki/reevoPages/int/Plantilla:Prensa-Archivo.mw new file mode 100644 index 00000000..fadcad19 --- /dev/null +++ b/bin/wiki/reevoPages/int/Plantilla:Prensa-Archivo.mw @@ -0,0 +1,13 @@ +<noinclude> +<pre> +{{Prensa-Archivo +|prensa:archivo:imagen= +|prensa:archivo:texto= +}} +</pre> +</noinclude> +<includeonly> +<blockquote>{{int:rv-prensa:archivo:desc}}</blockquote> +[[Archivo:{{{prensa:archivo:imagen|}}}|right|300px|Snapshot del sitio web original]] +{{{prensa:archivo:texto|}}} +</includeonly> diff --git a/bin/wiki/reevoPages/int/Plantilla:Prensa-Vista.mw b/bin/wiki/reevoPages/int/Plantilla:Prensa-Vista.mw new file mode 100644 index 00000000..e12cbb2d --- /dev/null +++ b/bin/wiki/reevoPages/int/Plantilla:Prensa-Vista.mw @@ -0,0 +1,21 @@ +<noinclude> +<pre> +{{Plantilla:Prensa-Vista}} + +{{{1}}} Nombre de la Página (de la Persona) +{{{2}}} Imagen +{{{3}}} Fuente +{{{4}}} PageID + +</pre> +Editar la página para ver el texto de la plantilla. +</noinclude> +<includeonly>{{#css: + #objeto-{{{4}}} { + background-size: cover; + height: 300px; + background-image: url({{ #ifexist: Archivo:{{{2}}} | {{filepath: {{{2}}}}} | {{filepath:Prensa-sin_imagen.png}} }}); + position: relative; + } +}}<div class='col-lg-6 col-md-6 col-sm-12 col-xs-12 ficha-personal'><div class='objeto' id='objeto-{{{4}}}'><span class='pie'><span class='objeto-titulo'>{{{1}}}</span><br/>{{#if: {{{3}}}|({{{3}}})}}</span></div></div> +</includeonly> diff --git a/bin/wiki/reevoPages/int/Plantilla:Prensa.mw b/bin/wiki/reevoPages/int/Plantilla:Prensa.mw new file mode 100644 index 00000000..afc66cbe --- /dev/null +++ b/bin/wiki/reevoPages/int/Plantilla:Prensa.mw @@ -0,0 +1,49 @@ +<noinclude> +<pre> +{{Prensa +|prensa:url= +|prensa:fecha= +|prensa:fuente= +|prensa:pais= +|prensa:idioma= +|prensa:descripcion= +|prensa:etiquetas= +|prensa:imagen= +|prensa:elggid= +}} +</pre> +</noinclude><includeonly>{| class="wikitable" +|- +! {{int:rv-prensa:url}} +| [[Prensa:url::{{{prensa:url|}}}]] +{{#ifexist: {{FULLPAGENAME}}/Archivo | <small>[[{{FULLPAGENAME}}/Archivo|{{int:rv-prensa:archivo:leyenda}}]]</small> | }} +|- +! {{int:rv-prensa:fecha}} +| [[Prensa:fecha::{{{prensa:fecha|}}}]] +|- +! {{int:rv-prensa:fuente}} +| [[Prensa:fuente::{{{prensa:fuente|}}}]] +|- +! {{int:rv-prensa:pais}} +| {{int:rv-pais-{{{prensa:pais|}}}}}<span style="display:none">[[Prensa:pais::{{{prensa:pais|}}}]]</span> +|- +! {{int:rv-prensa:idioma}} +| [[Prensa:idioma::{{{prensa:idioma|}}}]] +|- +! {{int:rv-prensa:descripcion}} +| [[Prensa:descripcion::{{{prensa:descripcion|}}}]]{{#description2:{{{prensa:descripcion|}}}}} +|- +! {{int:rv-prensa:etiquetas}} +| [[Prensa:etiquetas::{{{prensa:etiquetas|}}}]] +|} + +[[Archivo:{{#setmainimage:{{{prensa:imagen|}}}}}]] + +<div style="display:none;"> +[[Prensa:elggid::{{{prensa:elggid|}}}]] +[[Prensa:imagen::{{{prensa:imagen|}}}]] +[[Prensa:pageid::{{PAGEID}}]] +</div> + +[[Categoría:Prensa]] +</includeonly> diff --git a/bin/wiki/reevoPages/int/Plantilla:Sistema-ImportarPerfil.mw b/bin/wiki/reevoPages/int/Plantilla:Sistema-ImportarPerfil.mw new file mode 100644 index 00000000..90ff2c55 --- /dev/null +++ b/bin/wiki/reevoPages/int/Plantilla:Sistema-ImportarPerfil.mw @@ -0,0 +1,8 @@ +<includeonly> +Existe una cuenta con este mismo nombre de usuario en la versión anterior de REEVO, puedes ver dicho perfil siguiente [https://red.reevo.org/profile/{{BASEPAGENAME}} este enlace]. + +Si es una cuenta tuya, podemos importar los datos de ese usuario a [[Usuario:{{BASEPAGENAME}}|tu perfil en la versión actual de REEVO]]. <b>Ten en cuenta que Se reemplazará todo el contenido de tu perfil actual</b>. + +'''{{#ifeq: {{BASEPAGENAME}} | {{#USERNAME:}} | [[Especial:ImportarPerfil|¡Importar datos de mi usuario anterior!]] | Identificate como este usuario para poder realizar la importación desde esta página }}''' + +</includeonly> diff --git a/bin/wiki/reevoPages/int/Plantilla:Sistema-ImportarPerfilMsg.mw b/bin/wiki/reevoPages/int/Plantilla:Sistema-ImportarPerfilMsg.mw new file mode 100644 index 00000000..c23dd23d --- /dev/null +++ b/bin/wiki/reevoPages/int/Plantilla:Sistema-ImportarPerfilMsg.mw @@ -0,0 +1,3 @@ +<includeonly> +Existe una cuenta con este mismo nombre de usuario en la versión anterior de REEVO, ¿quieres importar aquí los datos de ese perfil? [[{{FULLPAGENAME}}/ImportarPerfil|¡Sigue este enlace!]] +</includeonly> diff --git a/bin/wiki/reevoPages/int/Plantilla:Usuario.mw b/bin/wiki/reevoPages/int/Plantilla:Usuario.mw new file mode 100644 index 00000000..07cc32a2 --- /dev/null +++ b/bin/wiki/reevoPages/int/Plantilla:Usuario.mw @@ -0,0 +1,25 @@ +<noinclude> +<pre> +{{Usuario +|usuario:nombre= +|usuario:descripcion= +|usuario:web= +|usuario:avatar= +}} +</pre> +</noinclude><includeonly>{{#ifeq: {{BASEPAGENAME}} | {{#USERNAME:}} | {{#ifexist: {{FULLPAGENAME}}/ImportarPerfil | {{Sistema-ImportarPerfilMsg}} | }} | }} +{| class="wikitable" +|- +! {{int:rv-usuario:nombre}} +| [[Usuario:nombre::{{{usuario:nombre|}}}]] +|- +! {{int:rv-usuario:descripcion}} +| [[Usuario:descripcion::{{{usuario:descripcion|}}}]] +|- +! {{int:rv-usuario:web}} +| [[Usuario:web::{{{usuario:web|}}}]] +|} +[[Imagen:{{{usuario:avatar|}}}]] + +[[Categoría:Usuario]] +</includeonly> diff --git a/bin/wiki/reevoPages/int/Propiedad:Audiovisual:autoria.mw b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:autoria.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:autoria.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Audiovisual:duracion.mw b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:duracion.mw new file mode 100644 index 00000000..151cf481 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:duracion.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Número]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Audiovisual:estreno.mw b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:estreno.mw new file mode 100644 index 00000000..3c6e9d62 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:estreno.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Fecha]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Audiovisual:genero.mw b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:genero.mw new file mode 100644 index 00000000..af6c4dae --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:genero.mw @@ -0,0 +1,5 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::documental]] +* [[Permite el valor::ficcion]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Audiovisual:magnet.mw b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:magnet.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:magnet.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Audiovisual:pais.mw b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:pais.mw new file mode 100644 index 00000000..0f2e1b34 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:pais.mw @@ -0,0 +1,258 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::AC]] +* [[Permite el valor::AD]] +* [[Permite el valor::AE]] +* [[Permite el valor::AF]] +* [[Permite el valor::AG]] +* [[Permite el valor::AI]] +* [[Permite el valor::AL]] +* [[Permite el valor::AM]] +* [[Permite el valor::AO]] +* [[Permite el valor::AQ]] +* [[Permite el valor::AR]] +* [[Permite el valor::AS]] +* [[Permite el valor::AT]] +* [[Permite el valor::AU]] +* [[Permite el valor::AW]] +* [[Permite el valor::AX]] +* [[Permite el valor::AZ]] +* [[Permite el valor::BA]] +* [[Permite el valor::BB]] +* [[Permite el valor::BD]] +* [[Permite el valor::BE]] +* [[Permite el valor::BF]] +* [[Permite el valor::BG]] +* [[Permite el valor::BH]] +* [[Permite el valor::BI]] +* [[Permite el valor::BJ]] +* [[Permite el valor::BL]] +* [[Permite el valor::BM]] +* [[Permite el valor::BN]] +* [[Permite el valor::BO]] +* [[Permite el valor::BQ]] +* [[Permite el valor::BR]] +* [[Permite el valor::BS]] +* [[Permite el valor::BT]] +* [[Permite el valor::BW]] +* [[Permite el valor::BY]] +* [[Permite el valor::BZ]] +* [[Permite el valor::CA]] +* [[Permite el valor::CC]] +* [[Permite el valor::CD]] +* [[Permite el valor::CF]] +* [[Permite el valor::CG]] +* [[Permite el valor::CH]] +* [[Permite el valor::CI]] +* [[Permite el valor::CK]] +* [[Permite el valor::CL]] +* [[Permite el valor::CM]] +* [[Permite el valor::CN]] +* [[Permite el valor::CO]] +* [[Permite el valor::CR]] +* [[Permite el valor::CU]] +* [[Permite el valor::CV]] +* [[Permite el valor::CW]] +* [[Permite el valor::CX]] +* [[Permite el valor::CY]] +* [[Permite el valor::CZ]] +* [[Permite el valor::DE]] +* [[Permite el valor::DG]] +* [[Permite el valor::DJ]] +* [[Permite el valor::DK]] +* [[Permite el valor::DM]] +* [[Permite el valor::DO]] +* [[Permite el valor::DZ]] +* [[Permite el valor::EA]] +* [[Permite el valor::EC]] +* [[Permite el valor::EE]] +* [[Permite el valor::EG]] +* [[Permite el valor::EH]] +* [[Permite el valor::ER]] +* [[Permite el valor::ES]] +* [[Permite el valor::ET]] +* [[Permite el valor::EZ]] +* [[Permite el valor::FI]] +* [[Permite el valor::FJ]] +* [[Permite el valor::FK]] +* [[Permite el valor::FM]] +* [[Permite el valor::FO]] +* [[Permite el valor::FR]] +* [[Permite el valor::GA]] +* [[Permite el valor::GB]] +* [[Permite el valor::GD]] +* [[Permite el valor::GE]] +* [[Permite el valor::GF]] +* [[Permite el valor::GG]] +* [[Permite el valor::GH]] +* [[Permite el valor::GI]] +* [[Permite el valor::GL]] +* [[Permite el valor::GM]] +* [[Permite el valor::GN]] +* [[Permite el valor::GP]] +* [[Permite el valor::GQ]] +* [[Permite el valor::GR]] +* [[Permite el valor::GS]] +* [[Permite el valor::GT]] +* [[Permite el valor::GU]] +* [[Permite el valor::GW]] +* [[Permite el valor::GY]] +* [[Permite el valor::HK]] +* [[Permite el valor::HN]] +* [[Permite el valor::HR]] +* [[Permite el valor::HT]] +* [[Permite el valor::HU]] +* [[Permite el valor::IC]] +* [[Permite el valor::ID]] +* [[Permite el valor::IE]] +* [[Permite el valor::IL]] +* [[Permite el valor::IM]] +* [[Permite el valor::IN]] +* [[Permite el valor::IO]] +* [[Permite el valor::IQ]] +* [[Permite el valor::IR]] +* [[Permite el valor::IS]] +* [[Permite el valor::IT]] +* [[Permite el valor::JE]] +* [[Permite el valor::JM]] +* [[Permite el valor::JO]] +* [[Permite el valor::JP]] +* [[Permite el valor::KE]] +* [[Permite el valor::KG]] +* [[Permite el valor::KH]] +* [[Permite el valor::KI]] +* [[Permite el valor::KM]] +* [[Permite el valor::KN]] +* [[Permite el valor::KP]] +* [[Permite el valor::KR]] +* [[Permite el valor::KW]] +* [[Permite el valor::KY]] +* [[Permite el valor::KZ]] +* [[Permite el valor::LA]] +* [[Permite el valor::LB]] +* [[Permite el valor::LC]] +* [[Permite el valor::LI]] +* [[Permite el valor::LK]] +* [[Permite el valor::LR]] +* [[Permite el valor::LS]] +* [[Permite el valor::LT]] +* [[Permite el valor::LU]] +* [[Permite el valor::LV]] +* [[Permite el valor::LY]] +* [[Permite el valor::MA]] +* [[Permite el valor::MC]] +* [[Permite el valor::MD]] +* [[Permite el valor::ME]] +* [[Permite el valor::MF]] +* [[Permite el valor::MG]] +* [[Permite el valor::MH]] +* [[Permite el valor::MK]] +* [[Permite el valor::ML]] +* [[Permite el valor::MM]] +* [[Permite el valor::MN]] +* [[Permite el valor::MO]] +* [[Permite el valor::MP]] +* [[Permite el valor::MQ]] +* [[Permite el valor::MR]] +* [[Permite el valor::MS]] +* [[Permite el valor::MT]] +* [[Permite el valor::MU]] +* [[Permite el valor::MV]] +* [[Permite el valor::MW]] +* [[Permite el valor::MX]] +* [[Permite el valor::MY]] +* [[Permite el valor::MZ]] +* [[Permite el valor::NA]] +* [[Permite el valor::NC]] +* [[Permite el valor::NE]] +* [[Permite el valor::NF]] +* [[Permite el valor::NG]] +* [[Permite el valor::NI]] +* [[Permite el valor::NL]] +* [[Permite el valor::NO]] +* [[Permite el valor::NP]] +* [[Permite el valor::NR]] +* [[Permite el valor::NU]] +* [[Permite el valor::NZ]] +* [[Permite el valor::OM]] +* [[Permite el valor::PA]] +* [[Permite el valor::PE]] +* [[Permite el valor::PF]] +* [[Permite el valor::PG]] +* [[Permite el valor::PH]] +* [[Permite el valor::PK]] +* [[Permite el valor::PL]] +* [[Permite el valor::PM]] +* [[Permite el valor::PN]] +* [[Permite el valor::PR]] +* [[Permite el valor::PS]] +* [[Permite el valor::PT]] +* [[Permite el valor::PW]] +* [[Permite el valor::PY]] +* [[Permite el valor::QA]] +* [[Permite el valor::RE]] +* [[Permite el valor::RO]] +* [[Permite el valor::RS]] +* [[Permite el valor::RU]] +* [[Permite el valor::RW]] +* [[Permite el valor::SA]] +* [[Permite el valor::SB]] +* [[Permite el valor::SC]] +* [[Permite el valor::SD]] +* [[Permite el valor::SE]] +* [[Permite el valor::SG]] +* [[Permite el valor::SH]] +* [[Permite el valor::SI]] +* [[Permite el valor::SJ]] +* [[Permite el valor::SK]] +* [[Permite el valor::SL]] +* [[Permite el valor::SM]] +* [[Permite el valor::SN]] +* [[Permite el valor::SO]] +* [[Permite el valor::SR]] +* [[Permite el valor::SS]] +* [[Permite el valor::ST]] +* [[Permite el valor::SV]] +* [[Permite el valor::SX]] +* [[Permite el valor::SY]] +* [[Permite el valor::SZ]] +* [[Permite el valor::TA]] +* [[Permite el valor::TC]] +* [[Permite el valor::TD]] +* [[Permite el valor::TF]] +* [[Permite el valor::TG]] +* [[Permite el valor::TH]] +* [[Permite el valor::TJ]] +* [[Permite el valor::TK]] +* [[Permite el valor::TL]] +* [[Permite el valor::TM]] +* [[Permite el valor::TN]] +* [[Permite el valor::TO]] +* [[Permite el valor::TR]] +* [[Permite el valor::TT]] +* [[Permite el valor::TV]] +* [[Permite el valor::TW]] +* [[Permite el valor::TZ]] +* [[Permite el valor::UA]] +* [[Permite el valor::UG]] +* [[Permite el valor::UM]] +* [[Permite el valor::UN]] +* [[Permite el valor::US]] +* [[Permite el valor::UY]] +* [[Permite el valor::UZ]] +* [[Permite el valor::VA]] +* [[Permite el valor::VC]] +* [[Permite el valor::VE]] +* [[Permite el valor::VG]] +* [[Permite el valor::VI]] +* [[Permite el valor::VN]] +* [[Permite el valor::VU]] +* [[Permite el valor::WF]] +* [[Permite el valor::WS]] +* [[Permite el valor::XK]] +* [[Permite el valor::YE]] +* [[Permite el valor::YT]] +* [[Permite el valor::ZA]] +* [[Permite el valor::ZM]] +* [[Permite el valor::ZW]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Audiovisual:poster.mw b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:poster.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:poster.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Audiovisual:sub.mw b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:sub.mw new file mode 100644 index 00000000..67bbc4c5 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:sub.mw @@ -0,0 +1,6 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::es]] +* [[Permite el valor::en]] +* [[Permite el valor::pt]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Audiovisual:titulo.mw b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:titulo.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:titulo.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Audiovisual:url.mw b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:url.mw new file mode 100644 index 00000000..99d01fb4 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:url.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::URL]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Audiovisual:urltrailer.mw b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:urltrailer.mw new file mode 100644 index 00000000..99d01fb4 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:urltrailer.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::URL]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Audiovisual:web.mw b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:web.mw new file mode 100644 index 00000000..99d01fb4 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Audiovisual:web.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::URL]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:contacto-email.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:contacto-email.mw new file mode 100644 index 00000000..e64e22f2 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:contacto-email.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Dirección electrónica]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:contacto-telefono.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:contacto-telefono.mw new file mode 100644 index 00000000..fff74541 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:contacto-telefono.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Telephone number]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:contacto-url.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:contacto-url.mw new file mode 100644 index 00000000..99d01fb4 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:contacto-url.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::URL]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:descripcion.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:descripcion.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:descripcion.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:imagen-destacada.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:imagen-destacada.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:imagen-destacada.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-certificacion.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-certificacion.mw new file mode 100644 index 00000000..428006ae --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-certificacion.mw @@ -0,0 +1,5 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::si]] +* [[Permite el valor::no]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-contextosocial.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-contextosocial.mw new file mode 100644 index 00000000..1fe61ae8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-contextosocial.mw @@ -0,0 +1,8 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::urbano]] +* [[Permite el valor::rural]] +* [[Permite el valor::encierro]] +* [[Permite el valor::domiciliario]] +* [[Permite el valor::hospitalario]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-corrientes.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-corrientes.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-corrientes.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-final.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-final.mw new file mode 100644 index 00000000..3c6e9d62 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-final.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Fecha]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-inicio.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-inicio.mw new file mode 100644 index 00000000..3c6e9d62 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-inicio.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Fecha]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-lucro.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-lucro.mw new file mode 100644 index 00000000..428006ae --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-lucro.mw @@ -0,0 +1,5 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::si]] +* [[Permite el valor::no]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-nivel.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-nivel.mw new file mode 100644 index 00000000..f9cd11bd --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-nivel.mw @@ -0,0 +1,9 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::inicial]] +* [[Permite el valor::primario]] +* [[Permite el valor::secundario]] +* [[Permite el valor::terciario]] +* [[Permite el valor::mayores]] +* [[Permite el valor::intergeneracional]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-niveleconomico.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-niveleconomico.mw new file mode 100644 index 00000000..f26269d2 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-niveleconomico.mw @@ -0,0 +1,7 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::muybajo]] +* [[Permite el valor::bajo]] +* [[Permite el valor::medio]] +* [[Permite el valor::alto]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-participantes.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-participantes.mw new file mode 100644 index 00000000..151cf481 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-participantes.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Número]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-tipoeducacion.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-tipoeducacion.mw new file mode 100644 index 00000000..73556ab7 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-tipoeducacion.mw @@ -0,0 +1,6 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::formal]] +* [[Permite el valor::noformal]] +* [[Permite el valor::informal]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-virtual.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-virtual.mw new file mode 100644 index 00000000..ce300415 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:info-virtual.mw @@ -0,0 +1,6 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::si]] +* [[Permite el valor::no]] +* [[Permite el valor::parcial]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar-calle.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar-calle.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar-calle.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar-ciudad.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar-ciudad.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar-ciudad.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar-pais.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar-pais.mw new file mode 100644 index 00000000..97493371 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar-pais.mw @@ -0,0 +1,259 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::Argentina]] +* [[Permite el valor::AC]] +* [[Permite el valor::AD]] +* [[Permite el valor::AE]] +* [[Permite el valor::AF]] +* [[Permite el valor::AG]] +* [[Permite el valor::AI]] +* [[Permite el valor::AL]] +* [[Permite el valor::AM]] +* [[Permite el valor::AO]] +* [[Permite el valor::AQ]] +* [[Permite el valor::AR]] +* [[Permite el valor::AS]] +* [[Permite el valor::AT]] +* [[Permite el valor::AU]] +* [[Permite el valor::AW]] +* [[Permite el valor::AX]] +* [[Permite el valor::AZ]] +* [[Permite el valor::BA]] +* [[Permite el valor::BB]] +* [[Permite el valor::BD]] +* [[Permite el valor::BE]] +* [[Permite el valor::BF]] +* [[Permite el valor::BG]] +* [[Permite el valor::BH]] +* [[Permite el valor::BI]] +* [[Permite el valor::BJ]] +* [[Permite el valor::BL]] +* [[Permite el valor::BM]] +* [[Permite el valor::BN]] +* [[Permite el valor::BO]] +* [[Permite el valor::BQ]] +* [[Permite el valor::BR]] +* [[Permite el valor::BS]] +* [[Permite el valor::BT]] +* [[Permite el valor::BW]] +* [[Permite el valor::BY]] +* [[Permite el valor::BZ]] +* [[Permite el valor::CA]] +* [[Permite el valor::CC]] +* [[Permite el valor::CD]] +* [[Permite el valor::CF]] +* [[Permite el valor::CG]] +* [[Permite el valor::CH]] +* [[Permite el valor::CI]] +* [[Permite el valor::CK]] +* [[Permite el valor::CL]] +* [[Permite el valor::CM]] +* [[Permite el valor::CN]] +* [[Permite el valor::CO]] +* [[Permite el valor::CR]] +* [[Permite el valor::CU]] +* [[Permite el valor::CV]] +* [[Permite el valor::CW]] +* [[Permite el valor::CX]] +* [[Permite el valor::CY]] +* [[Permite el valor::CZ]] +* [[Permite el valor::DE]] +* [[Permite el valor::DG]] +* [[Permite el valor::DJ]] +* [[Permite el valor::DK]] +* [[Permite el valor::DM]] +* [[Permite el valor::DO]] +* [[Permite el valor::DZ]] +* [[Permite el valor::EA]] +* [[Permite el valor::EC]] +* [[Permite el valor::EE]] +* [[Permite el valor::EG]] +* [[Permite el valor::EH]] +* [[Permite el valor::ER]] +* [[Permite el valor::ES]] +* [[Permite el valor::ET]] +* [[Permite el valor::EZ]] +* [[Permite el valor::FI]] +* [[Permite el valor::FJ]] +* [[Permite el valor::FK]] +* [[Permite el valor::FM]] +* [[Permite el valor::FO]] +* [[Permite el valor::FR]] +* [[Permite el valor::GA]] +* [[Permite el valor::GB]] +* [[Permite el valor::GD]] +* [[Permite el valor::GE]] +* [[Permite el valor::GF]] +* [[Permite el valor::GG]] +* [[Permite el valor::GH]] +* [[Permite el valor::GI]] +* [[Permite el valor::GL]] +* [[Permite el valor::GM]] +* [[Permite el valor::GN]] +* [[Permite el valor::GP]] +* [[Permite el valor::GQ]] +* [[Permite el valor::GR]] +* [[Permite el valor::GS]] +* [[Permite el valor::GT]] +* [[Permite el valor::GU]] +* [[Permite el valor::GW]] +* [[Permite el valor::GY]] +* [[Permite el valor::HK]] +* [[Permite el valor::HN]] +* [[Permite el valor::HR]] +* [[Permite el valor::HT]] +* [[Permite el valor::HU]] +* [[Permite el valor::IC]] +* [[Permite el valor::ID]] +* [[Permite el valor::IE]] +* [[Permite el valor::IL]] +* [[Permite el valor::IM]] +* [[Permite el valor::IN]] +* [[Permite el valor::IO]] +* [[Permite el valor::IQ]] +* [[Permite el valor::IR]] +* [[Permite el valor::IS]] +* [[Permite el valor::IT]] +* [[Permite el valor::JE]] +* [[Permite el valor::JM]] +* [[Permite el valor::JO]] +* [[Permite el valor::JP]] +* [[Permite el valor::KE]] +* [[Permite el valor::KG]] +* [[Permite el valor::KH]] +* [[Permite el valor::KI]] +* [[Permite el valor::KM]] +* [[Permite el valor::KN]] +* [[Permite el valor::KP]] +* [[Permite el valor::KR]] +* [[Permite el valor::KW]] +* [[Permite el valor::KY]] +* [[Permite el valor::KZ]] +* [[Permite el valor::LA]] +* [[Permite el valor::LB]] +* [[Permite el valor::LC]] +* [[Permite el valor::LI]] +* [[Permite el valor::LK]] +* [[Permite el valor::LR]] +* [[Permite el valor::LS]] +* [[Permite el valor::LT]] +* [[Permite el valor::LU]] +* [[Permite el valor::LV]] +* [[Permite el valor::LY]] +* [[Permite el valor::MA]] +* [[Permite el valor::MC]] +* [[Permite el valor::MD]] +* [[Permite el valor::ME]] +* [[Permite el valor::MF]] +* [[Permite el valor::MG]] +* [[Permite el valor::MH]] +* [[Permite el valor::MK]] +* [[Permite el valor::ML]] +* [[Permite el valor::MM]] +* [[Permite el valor::MN]] +* [[Permite el valor::MO]] +* [[Permite el valor::MP]] +* [[Permite el valor::MQ]] +* [[Permite el valor::MR]] +* [[Permite el valor::MS]] +* [[Permite el valor::MT]] +* [[Permite el valor::MU]] +* [[Permite el valor::MV]] +* [[Permite el valor::MW]] +* [[Permite el valor::MX]] +* [[Permite el valor::MY]] +* [[Permite el valor::MZ]] +* [[Permite el valor::NA]] +* [[Permite el valor::NC]] +* [[Permite el valor::NE]] +* [[Permite el valor::NF]] +* [[Permite el valor::NG]] +* [[Permite el valor::NI]] +* [[Permite el valor::NL]] +* [[Permite el valor::NO]] +* [[Permite el valor::NP]] +* [[Permite el valor::NR]] +* [[Permite el valor::NU]] +* [[Permite el valor::NZ]] +* [[Permite el valor::OM]] +* [[Permite el valor::PA]] +* [[Permite el valor::PE]] +* [[Permite el valor::PF]] +* [[Permite el valor::PG]] +* [[Permite el valor::PH]] +* [[Permite el valor::PK]] +* [[Permite el valor::PL]] +* [[Permite el valor::PM]] +* [[Permite el valor::PN]] +* [[Permite el valor::PR]] +* [[Permite el valor::PS]] +* [[Permite el valor::PT]] +* [[Permite el valor::PW]] +* [[Permite el valor::PY]] +* [[Permite el valor::QA]] +* [[Permite el valor::RE]] +* [[Permite el valor::RO]] +* [[Permite el valor::RS]] +* [[Permite el valor::RU]] +* [[Permite el valor::RW]] +* [[Permite el valor::SA]] +* [[Permite el valor::SB]] +* [[Permite el valor::SC]] +* [[Permite el valor::SD]] +* [[Permite el valor::SE]] +* [[Permite el valor::SG]] +* [[Permite el valor::SH]] +* [[Permite el valor::SI]] +* [[Permite el valor::SJ]] +* [[Permite el valor::SK]] +* [[Permite el valor::SL]] +* [[Permite el valor::SM]] +* [[Permite el valor::SN]] +* [[Permite el valor::SO]] +* [[Permite el valor::SR]] +* [[Permite el valor::SS]] +* [[Permite el valor::ST]] +* [[Permite el valor::SV]] +* [[Permite el valor::SX]] +* [[Permite el valor::SY]] +* [[Permite el valor::SZ]] +* [[Permite el valor::TA]] +* [[Permite el valor::TC]] +* [[Permite el valor::TD]] +* [[Permite el valor::TF]] +* [[Permite el valor::TG]] +* [[Permite el valor::TH]] +* [[Permite el valor::TJ]] +* [[Permite el valor::TK]] +* [[Permite el valor::TL]] +* [[Permite el valor::TM]] +* [[Permite el valor::TN]] +* [[Permite el valor::TO]] +* [[Permite el valor::TR]] +* [[Permite el valor::TT]] +* [[Permite el valor::TV]] +* [[Permite el valor::TW]] +* [[Permite el valor::TZ]] +* [[Permite el valor::UA]] +* [[Permite el valor::UG]] +* [[Permite el valor::UM]] +* [[Permite el valor::UN]] +* [[Permite el valor::US]] +* [[Permite el valor::UY]] +* [[Permite el valor::UZ]] +* [[Permite el valor::VA]] +* [[Permite el valor::VC]] +* [[Permite el valor::VE]] +* [[Permite el valor::VG]] +* [[Permite el valor::VI]] +* [[Permite el valor::VN]] +* [[Permite el valor::VU]] +* [[Permite el valor::WF]] +* [[Permite el valor::WS]] +* [[Permite el valor::XK]] +* [[Permite el valor::YE]] +* [[Permite el valor::YT]] +* [[Permite el valor::ZA]] +* [[Permite el valor::ZM]] +* [[Permite el valor::ZW]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar-provincia.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar-provincia.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar-provincia.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar.mw b/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar.mw new file mode 100644 index 00000000..b97dda88 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Experiencia:lugar.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Coordenadas geográficas]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Prensa:descripcion.mw b/bin/wiki/reevoPages/int/Propiedad:Prensa:descripcion.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Prensa:descripcion.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Prensa:elggid.mw b/bin/wiki/reevoPages/int/Propiedad:Prensa:elggid.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Prensa:elggid.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Prensa:etiquetas.mw b/bin/wiki/reevoPages/int/Propiedad:Prensa:etiquetas.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Prensa:etiquetas.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Prensa:fecha.mw b/bin/wiki/reevoPages/int/Propiedad:Prensa:fecha.mw new file mode 100644 index 00000000..3c6e9d62 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Prensa:fecha.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Fecha]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Prensa:fuente.mw b/bin/wiki/reevoPages/int/Propiedad:Prensa:fuente.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Prensa:fuente.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Prensa:idioma.mw b/bin/wiki/reevoPages/int/Propiedad:Prensa:idioma.mw new file mode 100644 index 00000000..67bbc4c5 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Prensa:idioma.mw @@ -0,0 +1,6 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::es]] +* [[Permite el valor::en]] +* [[Permite el valor::pt]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Prensa:imagen.mw b/bin/wiki/reevoPages/int/Propiedad:Prensa:imagen.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Prensa:imagen.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Prensa:pageid.mw b/bin/wiki/reevoPages/int/Propiedad:Prensa:pageid.mw new file mode 100644 index 00000000..73f546f8 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Prensa:pageid.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. diff --git a/bin/wiki/reevoPages/int/Propiedad:Prensa:pais.mw b/bin/wiki/reevoPages/int/Propiedad:Prensa:pais.mw new file mode 100644 index 00000000..0f2e1b34 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Prensa:pais.mw @@ -0,0 +1,258 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::Texto]]. + +Los valores permitidos para esta propiedad son: +* [[Permite el valor::AC]] +* [[Permite el valor::AD]] +* [[Permite el valor::AE]] +* [[Permite el valor::AF]] +* [[Permite el valor::AG]] +* [[Permite el valor::AI]] +* [[Permite el valor::AL]] +* [[Permite el valor::AM]] +* [[Permite el valor::AO]] +* [[Permite el valor::AQ]] +* [[Permite el valor::AR]] +* [[Permite el valor::AS]] +* [[Permite el valor::AT]] +* [[Permite el valor::AU]] +* [[Permite el valor::AW]] +* [[Permite el valor::AX]] +* [[Permite el valor::AZ]] +* [[Permite el valor::BA]] +* [[Permite el valor::BB]] +* [[Permite el valor::BD]] +* [[Permite el valor::BE]] +* [[Permite el valor::BF]] +* [[Permite el valor::BG]] +* [[Permite el valor::BH]] +* [[Permite el valor::BI]] +* [[Permite el valor::BJ]] +* [[Permite el valor::BL]] +* [[Permite el valor::BM]] +* [[Permite el valor::BN]] +* [[Permite el valor::BO]] +* [[Permite el valor::BQ]] +* [[Permite el valor::BR]] +* [[Permite el valor::BS]] +* [[Permite el valor::BT]] +* [[Permite el valor::BW]] +* [[Permite el valor::BY]] +* [[Permite el valor::BZ]] +* [[Permite el valor::CA]] +* [[Permite el valor::CC]] +* [[Permite el valor::CD]] +* [[Permite el valor::CF]] +* [[Permite el valor::CG]] +* [[Permite el valor::CH]] +* [[Permite el valor::CI]] +* [[Permite el valor::CK]] +* [[Permite el valor::CL]] +* [[Permite el valor::CM]] +* [[Permite el valor::CN]] +* [[Permite el valor::CO]] +* [[Permite el valor::CR]] +* [[Permite el valor::CU]] +* [[Permite el valor::CV]] +* [[Permite el valor::CW]] +* [[Permite el valor::CX]] +* [[Permite el valor::CY]] +* [[Permite el valor::CZ]] +* [[Permite el valor::DE]] +* [[Permite el valor::DG]] +* [[Permite el valor::DJ]] +* [[Permite el valor::DK]] +* [[Permite el valor::DM]] +* [[Permite el valor::DO]] +* [[Permite el valor::DZ]] +* [[Permite el valor::EA]] +* [[Permite el valor::EC]] +* [[Permite el valor::EE]] +* [[Permite el valor::EG]] +* [[Permite el valor::EH]] +* [[Permite el valor::ER]] +* [[Permite el valor::ES]] +* [[Permite el valor::ET]] +* [[Permite el valor::EZ]] +* [[Permite el valor::FI]] +* [[Permite el valor::FJ]] +* [[Permite el valor::FK]] +* [[Permite el valor::FM]] +* [[Permite el valor::FO]] +* [[Permite el valor::FR]] +* [[Permite el valor::GA]] +* [[Permite el valor::GB]] +* [[Permite el valor::GD]] +* [[Permite el valor::GE]] +* [[Permite el valor::GF]] +* [[Permite el valor::GG]] +* [[Permite el valor::GH]] +* [[Permite el valor::GI]] +* [[Permite el valor::GL]] +* [[Permite el valor::GM]] +* [[Permite el valor::GN]] +* [[Permite el valor::GP]] +* [[Permite el valor::GQ]] +* [[Permite el valor::GR]] +* [[Permite el valor::GS]] +* [[Permite el valor::GT]] +* [[Permite el valor::GU]] +* [[Permite el valor::GW]] +* [[Permite el valor::GY]] +* [[Permite el valor::HK]] +* [[Permite el valor::HN]] +* [[Permite el valor::HR]] +* [[Permite el valor::HT]] +* [[Permite el valor::HU]] +* [[Permite el valor::IC]] +* [[Permite el valor::ID]] +* [[Permite el valor::IE]] +* [[Permite el valor::IL]] +* [[Permite el valor::IM]] +* [[Permite el valor::IN]] +* [[Permite el valor::IO]] +* [[Permite el valor::IQ]] +* [[Permite el valor::IR]] +* [[Permite el valor::IS]] +* [[Permite el valor::IT]] +* [[Permite el valor::JE]] +* [[Permite el valor::JM]] +* [[Permite el valor::JO]] +* [[Permite el valor::JP]] +* [[Permite el valor::KE]] +* [[Permite el valor::KG]] +* [[Permite el valor::KH]] +* [[Permite el valor::KI]] +* [[Permite el valor::KM]] +* [[Permite el valor::KN]] +* [[Permite el valor::KP]] +* [[Permite el valor::KR]] +* [[Permite el valor::KW]] +* [[Permite el valor::KY]] +* [[Permite el valor::KZ]] +* [[Permite el valor::LA]] +* [[Permite el valor::LB]] +* [[Permite el valor::LC]] +* [[Permite el valor::LI]] +* [[Permite el valor::LK]] +* [[Permite el valor::LR]] +* [[Permite el valor::LS]] +* [[Permite el valor::LT]] +* [[Permite el valor::LU]] +* [[Permite el valor::LV]] +* [[Permite el valor::LY]] +* [[Permite el valor::MA]] +* [[Permite el valor::MC]] +* [[Permite el valor::MD]] +* [[Permite el valor::ME]] +* [[Permite el valor::MF]] +* [[Permite el valor::MG]] +* [[Permite el valor::MH]] +* [[Permite el valor::MK]] +* [[Permite el valor::ML]] +* [[Permite el valor::MM]] +* [[Permite el valor::MN]] +* [[Permite el valor::MO]] +* [[Permite el valor::MP]] +* [[Permite el valor::MQ]] +* [[Permite el valor::MR]] +* [[Permite el valor::MS]] +* [[Permite el valor::MT]] +* [[Permite el valor::MU]] +* [[Permite el valor::MV]] +* [[Permite el valor::MW]] +* [[Permite el valor::MX]] +* [[Permite el valor::MY]] +* [[Permite el valor::MZ]] +* [[Permite el valor::NA]] +* [[Permite el valor::NC]] +* [[Permite el valor::NE]] +* [[Permite el valor::NF]] +* [[Permite el valor::NG]] +* [[Permite el valor::NI]] +* [[Permite el valor::NL]] +* [[Permite el valor::NO]] +* [[Permite el valor::NP]] +* [[Permite el valor::NR]] +* [[Permite el valor::NU]] +* [[Permite el valor::NZ]] +* [[Permite el valor::OM]] +* [[Permite el valor::PA]] +* [[Permite el valor::PE]] +* [[Permite el valor::PF]] +* [[Permite el valor::PG]] +* [[Permite el valor::PH]] +* [[Permite el valor::PK]] +* [[Permite el valor::PL]] +* [[Permite el valor::PM]] +* [[Permite el valor::PN]] +* [[Permite el valor::PR]] +* [[Permite el valor::PS]] +* [[Permite el valor::PT]] +* [[Permite el valor::PW]] +* [[Permite el valor::PY]] +* [[Permite el valor::QA]] +* [[Permite el valor::RE]] +* [[Permite el valor::RO]] +* [[Permite el valor::RS]] +* [[Permite el valor::RU]] +* [[Permite el valor::RW]] +* [[Permite el valor::SA]] +* [[Permite el valor::SB]] +* [[Permite el valor::SC]] +* [[Permite el valor::SD]] +* [[Permite el valor::SE]] +* [[Permite el valor::SG]] +* [[Permite el valor::SH]] +* [[Permite el valor::SI]] +* [[Permite el valor::SJ]] +* [[Permite el valor::SK]] +* [[Permite el valor::SL]] +* [[Permite el valor::SM]] +* [[Permite el valor::SN]] +* [[Permite el valor::SO]] +* [[Permite el valor::SR]] +* [[Permite el valor::SS]] +* [[Permite el valor::ST]] +* [[Permite el valor::SV]] +* [[Permite el valor::SX]] +* [[Permite el valor::SY]] +* [[Permite el valor::SZ]] +* [[Permite el valor::TA]] +* [[Permite el valor::TC]] +* [[Permite el valor::TD]] +* [[Permite el valor::TF]] +* [[Permite el valor::TG]] +* [[Permite el valor::TH]] +* [[Permite el valor::TJ]] +* [[Permite el valor::TK]] +* [[Permite el valor::TL]] +* [[Permite el valor::TM]] +* [[Permite el valor::TN]] +* [[Permite el valor::TO]] +* [[Permite el valor::TR]] +* [[Permite el valor::TT]] +* [[Permite el valor::TV]] +* [[Permite el valor::TW]] +* [[Permite el valor::TZ]] +* [[Permite el valor::UA]] +* [[Permite el valor::UG]] +* [[Permite el valor::UM]] +* [[Permite el valor::UN]] +* [[Permite el valor::US]] +* [[Permite el valor::UY]] +* [[Permite el valor::UZ]] +* [[Permite el valor::VA]] +* [[Permite el valor::VC]] +* [[Permite el valor::VE]] +* [[Permite el valor::VG]] +* [[Permite el valor::VI]] +* [[Permite el valor::VN]] +* [[Permite el valor::VU]] +* [[Permite el valor::WF]] +* [[Permite el valor::WS]] +* [[Permite el valor::XK]] +* [[Permite el valor::YE]] +* [[Permite el valor::YT]] +* [[Permite el valor::ZA]] +* [[Permite el valor::ZM]] +* [[Permite el valor::ZW]] diff --git a/bin/wiki/reevoPages/int/Propiedad:Prensa:url.mw b/bin/wiki/reevoPages/int/Propiedad:Prensa:url.mw new file mode 100644 index 00000000..99d01fb4 --- /dev/null +++ b/bin/wiki/reevoPages/int/Propiedad:Prensa:url.mw @@ -0,0 +1 @@ +Esta es una propiedad de tipo [[Tiene tipo de datos::URL]]. diff --git a/bin/wiki/reevoPages/int/REEVO:Audiovisual.mw b/bin/wiki/reevoPages/int/REEVO:Audiovisual.mw new file mode 100644 index 00000000..016cef9d --- /dev/null +++ b/bin/wiki/reevoPages/int/REEVO:Audiovisual.mw @@ -0,0 +1 @@ +{{#default_form:Audiovisual}} diff --git a/bin/wiki/reevoPages/int/REEVO:Experiencia.mw b/bin/wiki/reevoPages/int/REEVO:Experiencia.mw new file mode 100644 index 00000000..0b2593ee --- /dev/null +++ b/bin/wiki/reevoPages/int/REEVO:Experiencia.mw @@ -0,0 +1 @@ +{{#default_form:Experiencia}} diff --git a/bin/wiki/reevoPages/int/REEVO:Prensa.mw b/bin/wiki/reevoPages/int/REEVO:Prensa.mw new file mode 100644 index 00000000..9b094401 --- /dev/null +++ b/bin/wiki/reevoPages/int/REEVO:Prensa.mw @@ -0,0 +1 @@ +{{#default_form:Prensa}} diff --git a/bin/wiki/reevoPages/int/REEVO:Usuario.mw b/bin/wiki/reevoPages/int/REEVO:Usuario.mw new file mode 100644 index 00000000..2e73fb55 --- /dev/null +++ b/bin/wiki/reevoPages/int/REEVO:Usuario.mw @@ -0,0 +1 @@ +{{#default_form:Usuario}} diff --git a/bin/wiki/vendor/addwiki/mediawiki-api-base/.gitignore b/bin/wiki/vendor/addwiki/mediawiki-api-base/.gitignore new file mode 100644 index 00000000..9c16bff2 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api-base/.gitignore @@ -0,0 +1,6 @@ +.idea +vendor +composer.lock +test.php +docs/_build +phpunit.xml diff --git a/bin/wiki/vendor/addwiki/mediawiki-api-base/.phan/config.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/.phan/config.php new file mode 100644 index 00000000..28c1f4ad --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/.scrutinizer.yml b/bin/wiki/vendor/addwiki/mediawiki-api-base/.scrutinizer.yml new file mode 100644 index 00000000..ffc976e3 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/.travis.yml b/bin/wiki/vendor/addwiki/mediawiki-api-base/.travis.yml new file mode 100644 index 00000000..cb3e7641 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/LICENSE.md b/bin/wiki/vendor/addwiki/mediawiki-api-base/LICENSE.md new file mode 100644 index 00000000..0671f06a --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/README.md b/bin/wiki/vendor/addwiki/mediawiki-api-base/README.md new file mode 100644 index 00000000..ea2a7d4b --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/RELEASENOTES.md b/bin/wiki/vendor/addwiki/mediawiki-api-base/RELEASENOTES.md new file mode 100644 index 00000000..a84b19cc --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/build/travis/install-mediawiki.sh b/bin/wiki/vendor/addwiki/mediawiki-api-base/build/travis/install-mediawiki.sh new file mode 100644 index 00000000..59d29ba4 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/build/travis/run-webserver.sh b/bin/wiki/vendor/addwiki/mediawiki-api-base/build/travis/run-webserver.sh new file mode 100644 index 00000000..2412031c --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/composer.json b/bin/wiki/vendor/addwiki/mediawiki-api-base/composer.json new file mode 100644 index 00000000..c83fca09 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/docs/Makefile b/bin/wiki/vendor/addwiki/mediawiki-api-base/docs/Makefile new file mode 100644 index 00000000..54002b3b --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/docs/conf.py b/bin/wiki/vendor/addwiki/mediawiki-api-base/docs/conf.py new file mode 100644 index 00000000..cb3ce592 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/docs/index.rst b/bin/wiki/vendor/addwiki/mediawiki-api-base/docs/index.rst new file mode 100644 index 00000000..ac4860ce --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/docs/make.bat b/bin/wiki/vendor/addwiki/mediawiki-api-base/docs/make.bat new file mode 100644 index 00000000..7ce5e397 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/docs/multipart.rst b/bin/wiki/vendor/addwiki/mediawiki-api-base/docs/multipart.rst new file mode 100644 index 00000000..1b438c71 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/docs/overview.rst b/bin/wiki/vendor/addwiki/mediawiki-api-base/docs/overview.rst new file mode 100644 index 00000000..0e83549d --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/docs/quickstart.rst b/bin/wiki/vendor/addwiki/mediawiki-api-base/docs/quickstart.rst new file mode 100644 index 00000000..5db0601f --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/phpcs.xml b/bin/wiki/vendor/addwiki/mediawiki-api-base/phpcs.xml new file mode 100755 index 00000000..c4ca4081 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/phpunit.xml.dist b/bin/wiki/vendor/addwiki/mediawiki-api-base/phpunit.xml.dist new file mode 100644 index 00000000..a5874032 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/ApiRequester.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/ApiRequester.php new file mode 100644 index 00000000..cc3c8bcf --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/ApiUser.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/ApiUser.php new file mode 100644 index 00000000..b2f59153 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/AsyncApiRequester.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/AsyncApiRequester.php new file mode 100644 index 00000000..6190ac7e --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/FluentRequest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/FluentRequest.php new file mode 100644 index 00000000..0d10553b --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/Guzzle/ClientFactory.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/Guzzle/ClientFactory.php new file mode 100644 index 00000000..704a1660 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/Guzzle/MiddlewareFactory.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/Guzzle/MiddlewareFactory.php new file mode 100644 index 00000000..9e03c02f --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/MediawikiApi.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/MediawikiApi.php new file mode 100644 index 00000000..0c6c4fe3 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/MediawikiApiInterface.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/MediawikiApiInterface.php new file mode 100644 index 00000000..83580676 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/MediawikiSession.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/MediawikiSession.php new file mode 100644 index 00000000..c430695c --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/MultipartRequest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/MultipartRequest.php new file mode 100644 index 00000000..8d3fbdf4 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/Request.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/Request.php new file mode 100644 index 00000000..0daace2a --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/RsdException.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/RsdException.php new file mode 100644 index 00000000..b304f574 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/SimpleRequest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/SimpleRequest.php new file mode 100644 index 00000000..1e33348d --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/src/UsageException.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/src/UsageException.php new file mode 100644 index 00000000..77148f1b --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/tests/Integration/MediawikiApiTest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/tests/Integration/MediawikiApiTest.php new file mode 100644 index 00000000..da6683e4 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/tests/Integration/TestEnvironment.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/tests/Integration/TestEnvironment.php new file mode 100644 index 00000000..cb781508 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/tests/Integration/TokenHandlingTest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/tests/Integration/TokenHandlingTest.php new file mode 100644 index 00000000..68ec52be --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/ApiUserTest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/ApiUserTest.php new file mode 100644 index 00000000..7e0da7ca --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/FluentRequestTest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/FluentRequestTest.php new file mode 100644 index 00000000..93af921e --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/Guzzle/ClientFactoryTest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/Guzzle/ClientFactoryTest.php new file mode 100644 index 00000000..d84d0333 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/Guzzle/MiddlewareFactoryTest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/Guzzle/MiddlewareFactoryTest.php new file mode 100644 index 00000000..1cf7270a --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/MediawikiApiTest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/MediawikiApiTest.php new file mode 100644 index 00000000..a55f6739 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/MediawikiSessionTest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/MediawikiSessionTest.php new file mode 100644 index 00000000..667a526f --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/MultipartRequestTest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/MultipartRequestTest.php new file mode 100644 index 00000000..993c29e8 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/SimpleRequestTest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/SimpleRequestTest.php new file mode 100644 index 00000000..df979992 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/UsageExceptionTest.php b/bin/wiki/vendor/addwiki/mediawiki-api-base/tests/Unit/UsageExceptionTest.php new file mode 100644 index 00000000..2b7d6072 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/.gitignore b/bin/wiki/vendor/addwiki/mediawiki-api/.gitignore new file mode 100644 index 00000000..2bd8a05e --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/.scrutinizer.yml b/bin/wiki/vendor/addwiki/mediawiki-api/.scrutinizer.yml new file mode 100644 index 00000000..ffc976e3 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/.travis.yml b/bin/wiki/vendor/addwiki/mediawiki-api/.travis.yml new file mode 100644 index 00000000..26793151 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/LICENSE.md b/bin/wiki/vendor/addwiki/mediawiki-api/LICENSE.md new file mode 100644 index 00000000..0671f06a --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/README.md b/bin/wiki/vendor/addwiki/mediawiki-api/README.md new file mode 100644 index 00000000..325958fc --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/RELEASENOTES.md b/bin/wiki/vendor/addwiki/mediawiki-api/RELEASENOTES.md new file mode 100644 index 00000000..8d8bb9a1 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/bin/install-mediawiki.sh b/bin/wiki/vendor/addwiki/mediawiki-api/bin/install-mediawiki.sh new file mode 100755 index 00000000..030830ad --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/composer.json b/bin/wiki/vendor/addwiki/mediawiki-api/composer.json new file mode 100644 index 00000000..f49a19ca --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/docs/Makefile b/bin/wiki/vendor/addwiki/mediawiki-api/docs/Makefile new file mode 100644 index 00000000..46208266 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/docs/category_traverser.rst b/bin/wiki/vendor/addwiki/mediawiki-api/docs/category_traverser.rst new file mode 100644 index 00000000..497398e8 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/docs/conf.py b/bin/wiki/vendor/addwiki/mediawiki-api/docs/conf.py new file mode 100644 index 00000000..3310f585 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/docs/contributing.rst b/bin/wiki/vendor/addwiki/mediawiki-api/docs/contributing.rst new file mode 100644 index 00000000..c2cd2813 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/docs/file_uploader.rst b/bin/wiki/vendor/addwiki/mediawiki-api/docs/file_uploader.rst new file mode 100755 index 00000000..9f8b534f --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/docs/index.rst b/bin/wiki/vendor/addwiki/mediawiki-api/docs/index.rst new file mode 100644 index 00000000..558107b3 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/docs/make.bat b/bin/wiki/vendor/addwiki/mediawiki-api/docs/make.bat new file mode 100644 index 00000000..a5507331 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/docs/namespace_getter.rst b/bin/wiki/vendor/addwiki/mediawiki-api/docs/namespace_getter.rst new file mode 100644 index 00000000..c362833f --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/docs/page_list_getter.rst b/bin/wiki/vendor/addwiki/mediawiki-api/docs/page_list_getter.rst new file mode 100644 index 00000000..aad9f8a8 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/docs/page_purger.rst b/bin/wiki/vendor/addwiki/mediawiki-api/docs/page_purger.rst new file mode 100644 index 00000000..84cd7523 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/phpcs.xml b/bin/wiki/vendor/addwiki/mediawiki-api/phpcs.xml new file mode 100644 index 00000000..1c5b15ce --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/phpunit.xml.dist b/bin/wiki/vendor/addwiki/mediawiki-api/phpunit.xml.dist new file mode 100755 index 00000000..f674132b --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/CategoryLoopException.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/CategoryLoopException.php new file mode 100644 index 00000000..9612f050 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Generator/AnonymousGenerator.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Generator/AnonymousGenerator.php new file mode 100644 index 00000000..715e3c02 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Generator/ApiGenerator.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Generator/ApiGenerator.php new file mode 100644 index 00000000..923e98cd --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Generator/FluentGenerator.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Generator/FluentGenerator.php new file mode 100644 index 00000000..108f4999 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/MediawikiFactory.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/MediawikiFactory.php new file mode 100644 index 00000000..fc773ce5 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/CategoryTraverser.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/CategoryTraverser.php new file mode 100644 index 00000000..c82b5d69 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/FileUploader.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/FileUploader.php new file mode 100644 index 00000000..5ada5739 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/ImageRotator.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/ImageRotator.php new file mode 100644 index 00000000..ba5624dc --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/LogListGetter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/LogListGetter.php new file mode 100644 index 00000000..d9394919 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/NamespaceGetter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/NamespaceGetter.php new file mode 100644 index 00000000..c3f00030 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/PageDeleter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageDeleter.php new file mode 100644 index 00000000..60c43e30 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/PageGetter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageGetter.php new file mode 100644 index 00000000..6c5c54cf --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/PageListGetter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageListGetter.php new file mode 100644 index 00000000..6b6d0007 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/PageMover.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageMover.php new file mode 100644 index 00000000..f7eba2af --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/PageProtector.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageProtector.php new file mode 100644 index 00000000..e3988e84 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/PagePurger.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PagePurger.php new file mode 100644 index 00000000..6f9057f1 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/PageRestorer.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageRestorer.php new file mode 100644 index 00000000..a422bd97 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/PageWatcher.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/PageWatcher.php new file mode 100644 index 00000000..e7afab17 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/Parser.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/Parser.php new file mode 100644 index 00000000..da83e39e --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionDeleter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionDeleter.php new file mode 100644 index 00000000..b12a7278 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionPatroller.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionPatroller.php new file mode 100644 index 00000000..e642fd96 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionRestorer.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionRestorer.php new file mode 100644 index 00000000..fb82c252 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionRollbacker.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionRollbacker.php new file mode 100644 index 00000000..76a2f5c7 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionSaver.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionSaver.php new file mode 100644 index 00000000..00b91ee6 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionUndoer.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/RevisionUndoer.php new file mode 100644 index 00000000..e411030e --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/Service.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/Service.php new file mode 100644 index 00000000..4a4b466b --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/UserBlocker.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserBlocker.php new file mode 100644 index 00000000..9cf9f421 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/UserCreator.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserCreator.php new file mode 100644 index 00000000..8d74b107 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/UserGetter.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserGetter.php new file mode 100644 index 00000000..d3bfbd5b --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/src/Service/UserRightsChanger.php b/bin/wiki/vendor/addwiki/mediawiki-api/src/Service/UserRightsChanger.php new file mode 100644 index 00000000..4fbea9c1 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/fixtures/blue ℳ𝒲♥𝓊𝓃𝒾𝒸ℴ𝒹ℯ.png b/bin/wiki/vendor/addwiki/mediawiki-api/tests/fixtures/blue ℳ𝒲♥𝓊𝓃𝒾𝒸ℴ𝒹ℯ.png Binary files differnew file mode 100644 index 00000000..9f8efbc8 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-api/tests/fixtures/blue ℳ𝒲♥𝓊𝓃𝒾𝒸ℴ𝒹ℯ.png diff --git a/bin/wiki/vendor/addwiki/mediawiki-api/tests/fixtures/namespaces.json b/bin/wiki/vendor/addwiki/mediawiki-api/tests/fixtures/namespaces.json new file mode 100644 index 00000000..2933692a --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/integration/CategoryTraverserTest.php b/bin/wiki/vendor/addwiki/mediawiki-api/tests/integration/CategoryTraverserTest.php new file mode 100644 index 00000000..7161447d --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/integration/FileUploaderTest.php b/bin/wiki/vendor/addwiki/mediawiki-api/tests/integration/FileUploaderTest.php new file mode 100755 index 00000000..e805ee1d --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/integration/NamespaceGetterTest.php b/bin/wiki/vendor/addwiki/mediawiki-api/tests/integration/NamespaceGetterTest.php new file mode 100644 index 00000000..eea55f9f --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/integration/PageIntegrationTest.php b/bin/wiki/vendor/addwiki/mediawiki-api/tests/integration/PageIntegrationTest.php new file mode 100644 index 00000000..673eac8f --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/integration/PageListGetterTest.php b/bin/wiki/vendor/addwiki/mediawiki-api/tests/integration/PageListGetterTest.php new file mode 100644 index 00000000..39a973a4 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/integration/TestEnvironment.php b/bin/wiki/vendor/addwiki/mediawiki-api/tests/integration/TestEnvironment.php new file mode 100644 index 00000000..f40c0cd9 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/integration/UserIntegrationTest.php b/bin/wiki/vendor/addwiki/mediawiki-api/tests/integration/UserIntegrationTest.php new file mode 100644 index 00000000..29221edb --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/integration/phpunit.xml.dist b/bin/wiki/vendor/addwiki/mediawiki-api/tests/integration/phpunit.xml.dist new file mode 100644 index 00000000..4a0040c3 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/unit/Generator/AnonymousGeneratorTest.php b/bin/wiki/vendor/addwiki/mediawiki-api/tests/unit/Generator/AnonymousGeneratorTest.php new file mode 100644 index 00000000..67d6e450 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/unit/Generator/FluentGeneratorTest.php b/bin/wiki/vendor/addwiki/mediawiki-api/tests/unit/Generator/FluentGeneratorTest.php new file mode 100644 index 00000000..bd7cb0bf --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/unit/MediawikiFactoryTest.php b/bin/wiki/vendor/addwiki/mediawiki-api/tests/unit/MediawikiFactoryTest.php new file mode 100644 index 00000000..c4ce958f --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/unit/Service/PagePurgerTest.php b/bin/wiki/vendor/addwiki/mediawiki-api/tests/unit/Service/PagePurgerTest.php new file mode 100644 index 00000000..38199c26 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-api/tests/unit/phpunit.xml.dist b/bin/wiki/vendor/addwiki/mediawiki-api/tests/unit/phpunit.xml.dist new file mode 100644 index 00000000..8f4cecef --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/.gitignore b/bin/wiki/vendor/addwiki/mediawiki-datamodel/.gitignore new file mode 100644 index 00000000..014936d3 --- /dev/null +++ b/bin/wiki/vendor/addwiki/mediawiki-datamodel/.gitignore @@ -0,0 +1,5 @@ +.idea +vendor +composer.lock +test.php +docs/_build diff --git a/bin/wiki/vendor/addwiki/mediawiki-datamodel/.scrutinizer.yml b/bin/wiki/vendor/addwiki/mediawiki-datamodel/.scrutinizer.yml new file mode 100644 index 00000000..ffc976e3 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/.travis.yml b/bin/wiki/vendor/addwiki/mediawiki-datamodel/.travis.yml new file mode 100644 index 00000000..a58745e1 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/LICENSE.md b/bin/wiki/vendor/addwiki/mediawiki-datamodel/LICENSE.md new file mode 100644 index 00000000..0671f06a --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/README.md b/bin/wiki/vendor/addwiki/mediawiki-datamodel/README.md new file mode 100644 index 00000000..f0fdf1b1 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/RELEASENOTES.md b/bin/wiki/vendor/addwiki/mediawiki-datamodel/RELEASENOTES.md new file mode 100644 index 00000000..08df4aab --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/composer.json b/bin/wiki/vendor/addwiki/mediawiki-datamodel/composer.json new file mode 100644 index 00000000..9ac4e519 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/docs/Makefile b/bin/wiki/vendor/addwiki/mediawiki-datamodel/docs/Makefile new file mode 100644 index 00000000..af9b9d0b --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/docs/conf.py b/bin/wiki/vendor/addwiki/mediawiki-datamodel/docs/conf.py new file mode 100644 index 00000000..1f465d00 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/docs/index.rst b/bin/wiki/vendor/addwiki/mediawiki-datamodel/docs/index.rst new file mode 100644 index 00000000..c862502f --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/docs/make.bat b/bin/wiki/vendor/addwiki/mediawiki-datamodel/docs/make.bat new file mode 100644 index 00000000..6ff153c5 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/phpunit.xml.dist b/bin/wiki/vendor/addwiki/mediawiki-datamodel/phpunit.xml.dist new file mode 100644 index 00000000..d8bbce08 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/Content.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/Content.php new file mode 100644 index 00000000..c1372d46 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/EditInfo.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/EditInfo.php new file mode 100644 index 00000000..b6ba7845 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/File.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/File.php new file mode 100644 index 00000000..7851b3b8 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/Log.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/Log.php new file mode 100644 index 00000000..d3e48637 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/LogList.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/LogList.php new file mode 100644 index 00000000..9ce30263 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/NamespaceInfo.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/NamespaceInfo.php new file mode 100644 index 00000000..451ec972 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/Page.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/Page.php new file mode 100644 index 00000000..c3951e85 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/PageIdentifier.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/PageIdentifier.php new file mode 100644 index 00000000..528e3c88 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/Pages.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/Pages.php new file mode 100644 index 00000000..b8c5614c --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/Redirect.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/Redirect.php new file mode 100644 index 00000000..55b8b607 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/Revision.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/Revision.php new file mode 100644 index 00000000..09afe63f --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/Revisions.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/Revisions.php new file mode 100644 index 00000000..c6d2f436 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/Title.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/Title.php new file mode 100644 index 00000000..1fb15138 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/src/User.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/src/User.php new file mode 100644 index 00000000..fca5ddf3 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/tests/ContentTest.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/tests/ContentTest.php new file mode 100644 index 00000000..e412749a --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/tests/EditInfoTest.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/tests/EditInfoTest.php new file mode 100644 index 00000000..c3128bca --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/tests/FileTest.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/tests/FileTest.php new file mode 100644 index 00000000..0da77bd1 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/tests/LogListTest.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/tests/LogListTest.php new file mode 100644 index 00000000..1098a8a6 --- /dev/null +++ b/bin/wiki/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/wiki/vendor/addwiki/mediawiki-datamodel/tests/NamespaceInfoTest.php b/bin/wiki/vendor/addwiki/mediawiki-datamodel/tests/NamespaceInfoTest.php new file mode 100644 index 00000000..4587a8a0 --- /dev/null +++ b/bin/wiki/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 |