├── 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 | ?>
--------------------------------------------------------------------------------