├── demo ├── edit.php └── search.php ├── LICENSE ├── README.md └── wikibot.class.php /demo/edit.php: -------------------------------------------------------------------------------- 1 | 'https://test.wikipedia.org', 6 | 'username'=>'Your Username', 7 | 'password'=>'Your Password' 8 | ]; 9 | 10 | $bot = new lm_wiki_bot($bot_config); 11 | 12 | $bot->edit([ 13 | 'title'=>'page title', 14 | 'text'=>'Hello' 15 | ]); 16 | -------------------------------------------------------------------------------- /demo/search.php: -------------------------------------------------------------------------------- 1 | 'https://en.wikipedia.org', 6 | 'username'=>'Your Username', 7 | 'password'=>'Your Password' 8 | ]; 9 | 10 | $bot = new lm_wiki_bot($bot_config); 11 | 12 | $data = $bot->search([ 13 | 'offset'=>10, 14 | 'limit'=>10, 15 | 'sort'=>'last_edit_desc', 16 | 'keyword'=>'cellular' 17 | ]); 18 | 19 | print_r($data); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 LeoMoon Studios 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LM Wikipedia bot 2 | LM Wikipedia bot is a PHP class to create, edit and search articles on Wikipedia 3 | 4 | ## Documentation 5 | 6 | ### Installation 7 | Include wikibot class: 8 | ```php 9 | require_once('wikibot.class.php'); 10 | ``` 11 | 12 | You just need a username and password for edit action. if you want to use search or get recent changes just set your local URL: 13 | ```php 14 | $bot = new lm_wiki_bot(['url'=>'https://fa.wikipedia.org']); 15 | ``` 16 | 17 | For add/edit or patrol you should do this: 18 | ```php 19 | $bot_config = [ 20 | 'url'=>'https://en.wikipedia.org', 21 | 'username'=>'account username', 22 | 'password'=>'account password' 23 | ]; 24 | $bot = new lm_wiki_bot($bot_config); 25 | ``` 26 | 27 | ### Search 28 | Perform a full text search 29 | 30 | Simple: 31 | ```php 32 | $results = $bot->search(['keyword'=>"something"]); 33 | ``` 34 | 35 | Advanced: 36 | ```php 37 | $results = $bot->search([ 38 | 'offset'=>10, 39 | 'limit'=>10, 40 | 'sort'=>'last_edit_desc' 41 | 'keyword'=>'something' 42 | ]); 43 | ``` 44 | 45 | Parameters: 46 | |Name|Description|Values|Default| 47 | |-----------|------------------------|-------------------------------------|-------| 48 | |namespace|Search only within these namespaces| [Namespace numbers](https://en.wikipedia.org/wiki/Wikipedia:Namespace) separate with \| |0| 49 | |limit|How many total pages to return|The value must be between 1 and 500|10| 50 | |offset|When more results are available, use this to continue|-|0 51 | |sort|Set the sort order of returned results|create_timestamp_asc, create_timestamp_desc, incoming_links_asc, incoming_links_desc, just_match, last_edit_asc, last_edit_desc, none, random, relevance|relevance| 52 | |prefix|Perform a prefix search for page titles|true or false|false| 53 | 54 | ### Recent Changes 55 | List all the recent changes to the wiki, in the same manner as Special:RecentChanges lists them 56 | 57 | Simple: 58 | ```php 59 | $results = $bot->recent(); 60 | ``` 61 | 62 | Advanced: 63 | ```php 64 | $results = $bot->recent([ 65 | 'limit'=>30, 66 | 'ns'=>0, 67 | 'sort'=>'older', 68 | 'type'=>'!patrolled' 69 | ]); 70 | ``` 71 | 72 | Parameters: 73 | |Name|Description|Values|Default| 74 | |-----------|------------------------|-------------------------------------|-------| 75 | |namespace|Search only within these namespaces| [Namespace numbers](https://en.wikipedia.org/wiki/Wikipedia:Namespace) separate with \| |0| 76 | |limit|How many total changes to return|The value must be between 1 and 500|10| 77 | |user|Only list changes by this user| user name, IP or user ID (e.g. #12345)|null| 78 | |order|In which direction to enumerate|newer, older|older| 79 | |type|Show only items that meet these criteria. For example: minor edits done by logged-in users|!anon, !autopatrolled, !bot, !minor, !patrolled, !redirect, anon, autopatrolled, bot, minor, patrolled, redirect, unpatrolled - separate with \| | null| 80 | 81 | ### Content 82 | Get the original wikitext content of a page: 83 | ```php 84 | $result = $bot->content("Software bot"); 85 | ``` 86 | 87 | Get parsed HTML content of a page: 88 | ```php 89 | $result = $bot->content("Software bot", "text"); 90 | ``` 91 | 92 | ### Add/Edit 93 | Create and edit pages 94 | 95 | Simple Edit/Create: 96 | ```php 97 | $bot->edit([ 98 | 'title'=>'page title', 99 | 'text'=>'Hello' 100 | ]); 101 | ``` 102 | 103 | Advanced sample: 104 | ```php 105 | $bot->edit([ 106 | 'pageid'=>22817, 107 | 'appendtext'=>'Goodbye', 108 | 'summary'=>'Test Edit comment', 109 | 'recreate'=>true, 110 | 'section'=>'new', 111 | 'sectiontitle'=>'Something' 112 | ]); 113 | ``` 114 | 115 | Parameters: 116 | |Name|Description|Values|Default| 117 | |-----------|------------------------|-------------------------------------|-------| 118 | |title|Title of the page to edit. Cannot be used together with pageid|-|-| 119 | |pageid|Page ID of the page to edit. Cannot be used together with title|-|-| 120 | |summary|Edit summary|-|section title when section=new and sectiontitle is not set| 121 | |section|Section number. 0 for the top section, new for a new section|-|-| 122 | |sectiontitle|The title for a new section|-|-| 123 | |text|Page content|-|-| 124 | |appendtext|Add this text to the end of the page. Overrides text|Use section=new to append a new section, rather than this parameter|-| 125 | |prependtext|Add this text to the beginning of the page. Overrides text|-|-| 126 | |createonly|Don't edit the page if it exists already|true or false|false| 127 | |recreate|Override any errors about the page having been deleted in the meantime|true or false|false| 128 | |undo|Undo this revision. Overrides text, prependtext and appendtext|The value must be no less than 0|-| 129 | |undoafter|Undo all revisions from undo to this one. If not set, just undo one revision|The value must be no less than 0|-| 130 | |redirect|Automatically resolve redirects|true or false|false| 131 | 132 | -------------------------------------------------------------------------------- /wikibot.class.php: -------------------------------------------------------------------------------- 1 | 7 | * @link http://arashsoleimani.com 8 | * @license https://opensource.org/licenses/MIT - The MIT License 9 | * @version 1.0 10 | * 11 | */ 12 | class lm_wiki_bot { 13 | 14 | private $url = "https://test.wikipedia.org/w/api.php"; 15 | private $username = ""; 16 | private $password = ""; 17 | private $logintoken = null; 18 | public $errorMessage = null; 19 | 20 | /** 21 | * Constractor 22 | * @param array $config [ 23 | * 'username'=> string, 24 | * 'password'=> string, 25 | * 'url'=>string 26 | * ] 27 | * 28 | * You just need a username and password for edit action. if you want to use search or get recent changes just set your local URL: 29 | * 30 | * $bot = new lm_wiki_bot(['url'=>'https://fa.wikipedia.org']); 31 | * 32 | * 33 | * For add/edit or patrol you should do this: 34 | * 35 | * $bot = new lm_wiki_bot([ 36 | * 'username'=>'YourBotUsername', 37 | * 'password'=>'YourBotPassword', 38 | * 'url'=>'https://en.wikipedia.org' 39 | * ]); 40 | * 41 | * 42 | */ 43 | function __construct($config=null){ 44 | if(isset($config['url'])){ 45 | $this->url = $config['url']."/w/api.php"; 46 | } 47 | if(isset($config['username'])){ 48 | $this->username = $config['username']; 49 | } 50 | if(isset($config['password'])){ 51 | $this->password = $config['password']; 52 | } 53 | 54 | } 55 | 56 | /** 57 | * Get token for login, edit (csrf), patrol 58 | * 59 | * @param string $type // login|patrol - default: csrf 60 | * 61 | * @return string 62 | */ 63 | private function token($type=null) { 64 | $requestInfo = [ 65 | "action" => "query", 66 | "meta" => "tokens" 67 | ]; 68 | if($type == "login"){ 69 | $requestInfo["type"] = "login"; 70 | $returnName = "logintoken"; 71 | }else{ 72 | $returnName = "csrftoken"; 73 | } 74 | 75 | $result = $this->get($requestInfo); 76 | $token = $result["query"]["tokens"][$returnName]; 77 | if($type == "login" && !is_null($token)) 78 | $this->logintoken = $token; 79 | 80 | return $token; 81 | } 82 | 83 | /** 84 | * Login request - needed for edit 85 | * 86 | * @return bool 87 | */ 88 | private function login() { 89 | if(!is_null($this->logintoken)) 90 | return true; 91 | $requestInfo = [ 92 | "action" => "login", 93 | "lgname" => $this->username, 94 | "lgpassword" => $this->password, 95 | "lgtoken" => $this->token('login') 96 | ]; 97 | $result = $this->post($requestInfo); 98 | if($result['login']['result'] == "Success"){ 99 | return true; 100 | }else{ 101 | $this->errorMessage = $result['login']['reason']; 102 | return false; 103 | } 104 | } 105 | 106 | /** 107 | * Send POST request to API 108 | * 109 | * @param array $requestInfo 110 | * 111 | * @return array 112 | */ 113 | private function post($requestInfo){ 114 | 115 | $requestInfo['format'] = 'json'; 116 | $ch = curl_init(); 117 | curl_setopt($ch, CURLOPT_URL, $this->url); 118 | curl_setopt($ch, CURLOPT_POST, true); 119 | curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($requestInfo)); 120 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 121 | curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt"); 122 | curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt"); 123 | $output = curl_exec($ch); 124 | curl_close($ch); 125 | $output = json_decode($output, true); 126 | return $output; 127 | } 128 | 129 | /** 130 | * Send GET request to API 131 | * 132 | * @param array $requestInfo 133 | * 134 | * @return array 135 | */ 136 | private function get($requestInfo){ 137 | 138 | $requestInfo['format'] = 'json'; 139 | $ch = curl_init($this->url."?".http_build_query($requestInfo)); 140 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 141 | curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt"); 142 | curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt"); 143 | $output = curl_exec($ch); 144 | curl_close($ch); 145 | $output = json_decode($output, true); 146 | return $output; 147 | } 148 | 149 | /** 150 | * Search 151 | * @param array $params 152 | * 153 | * Simple usage: 154 | * 155 | * $bot->search(['keyword'=>"something"]); 156 | * 157 | * 158 | * Advanced usage: 159 | * 160 | * $bot->search([ 161 | * 'offset'=>10, 162 | * 'limit'=>10, 163 | * 'sort'=>'last_edit_desc' 164 | * 'keyword'=>'something' 165 | * ]); 166 | * 167 | * 168 | * @return array 169 | */ 170 | public function search($params){ 171 | $requestInfo = ['action'=>'query']; 172 | if(isset($params['prefix'])){ 173 | $requestInfo['list'] = "prefixsearch"; 174 | $requestInfo['pssearch'] = $params['keyword']; 175 | $searchType = "prefixsearch"; 176 | }else{ 177 | $requestInfo['list'] = "search"; 178 | $requestInfo['srsearch'] = $params['keyword']; 179 | $searchType = "search"; 180 | } 181 | if(isset($params['ns'])) $requestInfo['srnamespace'] = $params['ns']; 182 | if(isset($params['offset'])) $requestInfo['sroffset'] = $params['offset']; 183 | if(isset($params['limit'])) $requestInfo['srlimit'] = $params['limit']; 184 | if(isset($params['sort'])) $requestInfo['srsort'] = $params['sort']; 185 | 186 | $data = $this->get($requestInfo); 187 | return $data['query'][$searchType]; 188 | } 189 | 190 | /** 191 | * Recent Changes 192 | * 193 | * @param array $params 194 | * 195 | * Simple usage: 196 | * 197 | * $bot->recent(); 198 | * 199 | * 200 | * Advanced sample: 201 | * 202 | * $bot->recent([ 203 | * 'limit'=>30, 204 | * 'ns'=>0, 205 | * 'sort'=>'older', 206 | * 'type'=>'!patrolled' 207 | * ]); 208 | * 209 | * 210 | * @return array 211 | */ 212 | public function recent($params=null){ 213 | $requestInfo = [ 214 | 'action'=>'query', 215 | 'list'=>'recentchanges' 216 | ]; 217 | if(isset($params['limit'])) $requestInfo['rclimit'] = $params['limit']; 218 | if(isset($params['user'])) $requestInfo['rcuser'] = $params['user']; 219 | if(isset($params['order'])) $requestInfo['rcdir'] = $params['order']; 220 | if(isset($params['ns'])) $requestInfo['rcnamespace'] = $params['ns']; 221 | if(isset($params['type'])){ 222 | $requestInfo['rcshow'] = $params['type']; 223 | $requestInfo['prop'] = $params['info']; 224 | } 225 | $requestInfo['rcprop'] = "title|sizes|timestamp|ids|user|userid|comment|redirect|tags"; 226 | $data = $this->get($requestInfo); 227 | printr($data); 228 | return $data['query']["recentchanges"]; 229 | } 230 | 231 | /** 232 | * Create and edit pages 233 | * @param array $params 234 | * 235 | * Simple Edit/Create 236 | * 237 | * $bot->edit([ 238 | * 'title'=>'something', 239 | * 'text'=>'Hello' 240 | * ]); 241 | * 242 | * 243 | * Advanced sample 244 | * 245 | * $bot->edit([ 246 | * 'pageid'=>22817, 247 | * 'appendtext'=>'Hello', 248 | * 'summary'=>'Test Edit', 249 | * 'recreate'=>true, 250 | * 'section'=>'new', 251 | * 'sectiontitle'=>'Something' 252 | * ]); 253 | * 254 | * 255 | * @return array 256 | */ 257 | public function edit($params){ 258 | $data = $this->login(); 259 | $requestInfo = [ 260 | "action" => "edit", 261 | "token" => $this->token() 262 | ]; 263 | 264 | if(isset($params['title'])) $requestInfo['title'] = $params['title']; 265 | if(isset($params['summary'])) $requestInfo['summary'] = $params['summary']; 266 | if(isset($params['recreate'])) $requestInfo['recreate'] = $params['recreate']; 267 | if(isset($params['createonly'])) $requestInfo['createonly'] = $params['createonly']; 268 | if(isset($params['prependtext'])) $requestInfo['prependtext'] = $params['prependtext']; 269 | if(isset($params['text'])) $requestInfo['text'] = $params['text']; 270 | if(isset($params['appendtext'])) $requestInfo['appendtext'] = $params['appendtext']; 271 | if(isset($params['pageid'])) $requestInfo['pageid'] = $params['pageid']; 272 | if(isset($params['section'])) $requestInfo['section'] = $params['section']; 273 | if(isset($params['sectiontitle'])) $requestInfo['sectiontitle'] = $params['sectiontitle']; 274 | if(isset($params['undo'])) $requestInfo['undo'] = $params['undo']; 275 | if(isset($params['undoafter'])) $requestInfo['undoafter'] = $params['undoafter']; 276 | if(isset($params['redirect'])) $requestInfo['redirect'] = $params['redirect']; 277 | $result = $this->post($requestInfo); 278 | return $result; 279 | } 280 | 281 | /** 282 | * Get the contents of a page 283 | * @param string $pageTitle 284 | * @param string $format 285 | * 286 | * Get the original wikitext content of a page: 287 | * 288 | * $bot->content("Software bot"); 289 | * 290 | * 291 | * Get parsed HTML content of a page: 292 | * 293 | * $bot->content("Software bot", "text"); 294 | * 295 | * 296 | * @return string 297 | */ 298 | public function content($title, $format="wikitext"){ 299 | $requestInfo = [ 300 | 'action'=>'parse', 301 | 'page'=>$title, 302 | 'prop'=>$format, 303 | 'formatversion'=>2 304 | ]; 305 | $data = $this->get($requestInfo); 306 | return $data['parse'][$format]; 307 | } 308 | 309 | /** 310 | * Show Errors 311 | */ 312 | public function show_errors(){ 313 | echo $this->errorMessage."\r\n"; 314 | } 315 | 316 | } 317 | ?> --------------------------------------------------------------------------------