Advertisement
Guest User

Untitled

a guest
Aug 16th, 2012
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 33.00 KB | None | 0 0
  1. <?php
  2. /**
  3.  * botclasses.php - Bot classes for interacting with mediawiki.\
  4.  *
  5.  *  (c) 2008-2012 Chris G - http://en.wikipedia.org/wiki/User:Chris_G
  6.  *  (c) 2009-2010 Fale - http://en.wikipedia.org/wiki/User:Fale
  7.  *  (c) 2010      Kaldari - http://en.wikipedia.org/wiki/User:Kaldari
  8.  *  (c) 2011      Gutza - http://en.wikipedia.org/wiki/User:Gutza
  9.  *  (c) 2011-2012 Irønie - http://en.wikipedia.org/wiki/User:Irønie
  10.  *
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License
  22.  *  along with this program; if not, write to the Free Software
  23.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  *
  25.  *  Developers (add yourself here if you worked on the code):
  26.  *      Cobi    - [[User:Cobi]]    - Wrote the http class and some of the wikipedia class
  27.  *      Chris   - [[User:Chris_G]] - Wrote the most of the wikipedia class, project maintainer
  28.  *      Fale    - [[User:Fale]]    - Polish, wrote the extended and some of the wikipedia class
  29.  *      Kaldari - [[User:Kaldari]] - Submitted a patch for the imagematches function
  30.  *      Gutza   - [[User:Gutza]]   - Submitted a patch for http->setHTTPcreds(), and http->quiet
  31.  *      Irønie - [[User:Irønie]]  - Fixed bugs, tiny stuffs, French categories, $extra parameter, categorymembers, extends func, query-continue
  32.  **/
  33.  
  34. /**
  35.         // HOW TO USE ?
  36.  
  37.         include('botclasses.php');
  38.  
  39.         $wiki = new wikipedia;
  40.         $user = 'my_bot_account';
  41.         $pass = 'my_bot_password';
  42.         $wiki->url = 'http://en.wikipedia.org/w/api.php';
  43.         $wiki->user_agent = 'MyBot with botclasses.php';
  44.         $wiki->editlaps = 5; // delay in seconds between 2 edits (default 20s)
  45.         $wiki->login($user,$pass);
  46.  
  47.         // Read [[Wikipedia:Sandbox]]
  48.         $content = $wiki->getpage( 'Wikipedia:Sandbox' );
  49.         echo $content;
  50.  
  51.         // Add "Hello World" on the Sandbox page
  52.         $content .= "\n\nHello World";
  53.         $wiki->edit( 'Wikipedia:Sandbox', $content, 'Test', true, true);
  54.  
  55. **/
  56.  
  57.  
  58. /**
  59.  * This class is designed to provide a simplified interface to cURL which maintains cookies.
  60.  * @author Cobi
  61.  **/
  62. class http {
  63.     private $ch;
  64.     private $uid;
  65.     public $postfollowredirs;
  66.     public $getfollowredirs;
  67.     public $quiet=false;
  68.     public $user_agent = 'PHP Mediawiki Bot'; // 'php wikibot classes'; // should be changed (Bot policy)
  69.  
  70.     public function __construct () {
  71.         $this->ch = curl_init();
  72.         $this->uid = dechex(rand(0,99999999));
  73.         curl_setopt($this->ch,CURLOPT_COOKIEJAR,'cookies.'.$this->uid.'.dat');
  74.         curl_setopt($this->ch,CURLOPT_COOKIEFILE,'cookies.'.$this->uid.'.dat'); // TODO : Working with relative path ?
  75.         curl_setopt($this->ch,CURLOPT_MAXCONNECTS,100);
  76.         curl_setopt($this->ch,CURLOPT_CLOSEPOLICY,CURLCLOSEPOLICY_LEAST_RECENTLY_USED);
  77.         $this->postfollowredirs = 0;
  78.         $this->getfollowredirs = 1;
  79.     }
  80.  
  81.     public function post ($url,$data) {
  82.         $time = microtime(1);
  83.         curl_setopt($this->ch,CURLOPT_URL,$url);
  84.         curl_setopt($this->ch,CURLOPT_USERAGENT, $this->user_agent);
  85.         curl_setopt($this->ch,CURLOPT_FOLLOWLOCATION,$this->postfollowredirs);
  86.         curl_setopt($this->ch,CURLOPT_MAXREDIRS,10);
  87.         curl_setopt($this->ch,CURLOPT_HTTPHEADER, array('Expect:'));
  88.         curl_setopt($this->ch,CURLOPT_RETURNTRANSFER,1);
  89.         curl_setopt($this->ch,CURLOPT_TIMEOUT,30);
  90.         curl_setopt($this->ch,CURLOPT_CONNECTTIMEOUT,10);
  91.         curl_setopt($this->ch,CURLOPT_POST,1);
  92.         curl_setopt($this->ch,CURLOPT_POSTFIELDS, $data);
  93.         $data = curl_exec($this->ch);
  94.         if (!$this->quiet)
  95.             echo "\033[1;30m POST: ".$url.' ('.round((microtime(1) - $time),3).' s) ('.strlen($data)." b)\033[0m\n";
  96.         return $data;
  97.     }
  98.  
  99.     public function get ($url) {
  100.         $time = microtime(1);
  101.         curl_setopt($this->ch,CURLOPT_URL,$url);
  102.         curl_setopt($this->ch,CURLOPT_USERAGENT, $this->user_agent);
  103.         curl_setopt($this->ch,CURLOPT_FOLLOWLOCATION,$this->getfollowredirs);
  104.         curl_setopt($this->ch,CURLOPT_MAXREDIRS,10);
  105.         curl_setopt($this->ch,CURLOPT_HEADER,0);
  106.         curl_setopt($this->ch,CURLOPT_RETURNTRANSFER,1);
  107.         curl_setopt($this->ch,CURLOPT_TIMEOUT,30);
  108.         curl_setopt($this->ch,CURLOPT_CONNECTTIMEOUT,10);
  109.         curl_setopt($this->ch,CURLOPT_HTTPGET,1);
  110.         if( preg_match('`^https://`i', $url) ) {
  111.             curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, true); // + CURLOPT_CAINFO
  112.             curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 2); // default 2
  113.         }
  114.         $data = curl_exec($this->ch);
  115.         return $data;
  116.     }
  117.  
  118.     public function setHTTPcreds($uname,$pwd) {
  119.         curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
  120.         curl_setopt($this->ch, CURLOPT_USERPWD, $uname.":".$pwd);
  121.     }
  122.  
  123.     public function __destruct () {
  124.         curl_close($this->ch);
  125.         @unlink('cookies.'.$this->uid.'.dat');
  126.     }
  127. }
  128.  
  129.  
  130.  
  131. /**
  132.  * This class is interacts with wikipedia using api.php
  133.  * @author Chris G and Cobi
  134.  **/
  135. class wikipedia {
  136.     private $http;
  137.     private $token;
  138.     private $ecTimestamp;
  139.     private $editTimestamp;
  140.  
  141.     public $url;
  142.     public $editlaps; // delay in seconds between 2 edits
  143.  
  144.     /**
  145.     * This is our constructor.
  146.     * @return void
  147.     **/
  148.     public function __construct ($url='http://en.wikipedia.org/w/api.php',$hu=null,$hp=null) {
  149.         $this->http = new http;
  150.         $this->token = null;
  151.         $this->url = $url;
  152.         $this->ecTimestamp = null;
  153.         $this->editTimestamp = null;
  154.         $this->editlaps = 20;
  155.  
  156.         if ($hu!==null)
  157.             $this->http->setHTTPcreds($hu,$hp);
  158.     }
  159.  
  160.     public function __set($var,$val) {
  161.         switch($var) {
  162.             case 'quiet':
  163.                     $this->http->quiet=$val;
  164.                 break;
  165.             default:
  166.                 echo "WARNING: Unknown variable ($var)!\n";
  167.         }
  168.     }
  169.  
  170.     /**
  171.     * Sends a query to the api.
  172.     * @param $query The query string.
  173.     * @param $post POST data if its a post request (optional).
  174.     * @return The api result.
  175.     **/
  176.     public function query ($query,$post=null) {
  177.         if ($post==null)
  178.             $ret = $this->http->get($this->url.$query);
  179.         else
  180.             $ret = $this->http->post($this->url.$query,$post);
  181.         return unserialize($ret);
  182.     }
  183.    
  184.     /**
  185.     * Gets the content of a page. Returns false on error.
  186.     * @param $page The wikipedia page to fetch.
  187.     * @param $revid The revision id to fetch (optional)
  188.     * @return The wikitext for the page.
  189.     **/
  190.     public function getpage ($page,$revid=null,$detectEditConflict=false) {
  191.         $append = '';
  192.         if ($revid!=null)
  193.             $append = '&rvstartid='.$revid;
  194.         $x = $this->query('?action=query&format=php&prop=revisions&titles='.urlencode($page).'&rvlimit=1&rvprop=content|timestamp'.$append);
  195.         if( $x['query']['pages'] == false ) { return false; }
  196.         foreach( $x['query']['pages'] as $ret   ) {
  197.             if (isset($ret['revisions'][0]['*'])) {
  198.             if ($detectEditConflict)
  199.                 $this->ecTimestamp = $ret['revisions'][0]['timestamp'];
  200.             return $ret['revisions'][0]['*'];
  201.             } else
  202.             return false;
  203.         }
  204.     }
  205.  
  206.     /**
  207.     * Gets the page id for a page.
  208.     * @param $page The wikipedia page to get the id for.
  209.     * @return The page id of the page.
  210.     **/
  211.     public function getpageid ($page) {
  212.         $x = $this->query('?action=query&format=php&prop=revisions&titles='.urlencode($page).'&rvlimit=1&rvprop=content');
  213.         foreach ($x['query']['pages'] as $ret) {
  214.             return $ret['pageid'];
  215.         }
  216.     }
  217.  
  218.     /**
  219.     * Gets the number of contributions a user has.
  220.     * @param $user The username for which to get the edit count.
  221.     * @return The number of contributions the user has.
  222.     **/
  223.     public function contribcount ($user) {
  224.         $x = $this->query('?action=query&list=allusers&format=php&auprop=editcount&aulimit=1&aufrom='.urlencode($user));
  225.         return $x['query']['allusers'][0]['editcount'];
  226.     }
  227.  
  228.     /**
  229.      * Returns an array with all the members of $category
  230.      * @param $category The category to use.
  231.      * @param $subcat (bool) Go into sub categories?
  232.      * @return array
  233.      
  234.      // Mental Note: Read over all the changes below, work out what's going on (Chris)
  235.      **/
  236.      // Note cmlimit (mailing) : "Also note the documentation already say the default value is null, that is currently wrong."
  237.      // FIXED : Replaced $subcat (bool) by $subcat (numeric) for depth choice
  238.      // FIXED : Added $extra for extra parameters Example : $extra = 'cmnamespace=0|1|2&cmtype=page|subcat|file'
  239.      // FIXED : + 'Catégorie:' (french cat names)
  240.      // TODO : $categoryname for other languages -> http://fr.wikipedia.org/w/api.php?action=query&meta=siteinfo&siprop=namespacealiases voir subpages()
  241.  
  242.  
  243.     /*
  244.     TODO : verif update API : pas d'historique ou documentation complète => voir https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/core.git;a=history;f=includes/api
  245.  
  246.     **** API update nov 2011 ***** (Roan @ mediawiki-api@lists.wikimedia.org)
  247.  
  248.     To only list files, use &cmtype=file (previously &cmnamespace=6)
  249. To only list subcategories, use &cmtype=subcat (previously &cmnamespace=14)
  250. To only list 'normal' pages that aren't files or subcategories, use
  251. &cmtype=page (previously
  252. &cmnamespace=0|1|etc|everything|except|six|and|fourteen)
  253. You can combine values for cmtype, e.g. &cmtype=file|subcat to list
  254. both files and subcategories. The default value for cmtype is
  255. file|subcat|page (i.e. list everything).
  256.  
  257.     */
  258.  
  259.     function categorymembers ($category,$subcat=0, $extra=null) {
  260.         global $bouclecat;
  261.  
  262.         if($extra == TRUE) {
  263.                 $extra = str_replace('&&','&', '&'.$extra);
  264.         }
  265.         $continue = '';
  266.         $pages = array();
  267.         while (true) {
  268.             $res = $this->query('?action=query&list=categorymembers&cmtitle='.urlencode($category). $extra. '&format=php&cmlimit=500'.$continue);
  269.             if (isset($res['error'])) {
  270.                 echo "\nERROR query categorymembers\n"; print_r($res['error']);
  271.                 return false;
  272.             }
  273.             foreach ($res['query']['categorymembers'] as $x) {
  274.                 $pages[] = $x['title'];
  275.             }
  276.             if (empty($res['query-continue']['categorymembers'] )) {
  277.  
  278.                 if ($subcat>0) {
  279.                     foreach ($pages as $p) {
  280.                                                 // FIXED : French cat with utf8 strlen trick
  281.                                                 // TODO: Localise this
  282.                         if (substr($p,0,9)=='Category:' OR substr($p,0,11)=='Catégorie:' AND $bouclecat[$p] == FALSE ) {
  283.                                 $bouclecat[$p] = 1;
  284.                             $pages2 = $this->categorymembers($p, ($subcat-1), $extra );
  285.                             $pages = array_merge($pages,$pages2);
  286.                         }
  287.                     }
  288.                 }
  289.                 return $pages;
  290.             } else {
  291.                 unset($continue);
  292.                 foreach( $res['query-continue']['categorymembers'] AS $key => $val ) { // FIXED : API changes 07-2012
  293.                         $continue .= '&'.urlencode($key).'='.urlencode($val);
  294.                 }
  295.             }
  296.         }
  297.     }
  298.  
  299.     /**
  300.     * Returns a list of pages that link to $page.
  301.     * @param $page
  302.     * @param $extra (defaults to null)
  303.     * @return array
  304.     **/
  305.     public function whatlinkshere ($page,$extra=null) {
  306.         $continue = '';
  307.         $pages = array();
  308.         while (true) {
  309.             $res = $this->query('?action=query&list=backlinks&bltitle='.urlencode($page).'&bllimit=500&format=php'.$continue.$extra);
  310.             if (isset($res['error'])) {
  311.                 return false;
  312.             }
  313.             foreach ($res['query']['backlinks'] as $x) {
  314.                 $pages[] = $x['title'];
  315.             }
  316.             if (empty($res['query-continue']['backlinks'])) {
  317.                 return $pages;
  318.             } else {
  319.                 unset($continue);
  320.                 foreach ($res['query-continue']['backlinks'] as $key => $val) { // FIXED : API changes 07-2012
  321.                     $continue .= '&'.urlencode($key).'='.urlencode($val);
  322.                 }
  323.             }
  324.         }
  325.     }
  326.  
  327.     /**
  328.     * Returns a list of pages that include the image.
  329.     * @param $image
  330.     * @param $extra (defaults to null)
  331.     * @return array
  332.     **/
  333.     public function whereisincluded ($image,$extre=null) {
  334.         $continue = '';
  335.         $pages = array();
  336.         while (true) {
  337.             $res = $this->query('?action=query&list=imageusage&iutitle='.urlencode($image).'&iulimit=500&format=php'.$continue.$extra);
  338.             if (isset($res['error']))
  339.                 return false;
  340.             foreach ($res['query']['imageusage'] as $x) {
  341.                 $pages[] = $x['title'];
  342.             }
  343.             if (empty($res['query-continue']['imageusage'])) {
  344.                 return $pages;
  345.             } else {
  346.                 unset($continue);
  347.                 foreach($res['query-continue']['imageusage'] as $key => $val) { // FIXED : API changes 07-2012
  348.                     $continue .= '&'.urlencode($key).'='.urlencode($val);
  349.                 }
  350.             }
  351.         }
  352.     }
  353.  
  354.     /**
  355.     * Returns a list of pages that use the $template.
  356.     * @param $template the template we are intereste into
  357.     * @param $extra (defaults to null)
  358.     * @return array
  359.     **/
  360.     public function whatusethetemplate ($template,$extra=null) {
  361.         $continue = '';
  362.         $pages = array();
  363.         while (true) {
  364.             $res = $this->query('?action=query&list=embeddedin&eititle=Template:'.urlencode($template).'&eilimit=500&format=php'.$continue.$extra);
  365.             if (isset($res['error'])) {
  366.                 return false;
  367.             }
  368.             foreach ($res['query']['embeddedin'] as $x) {
  369.                 $pages[] = $x['title'];
  370.             }
  371.             if (empty($res['query-continue']['embeddedin'])) {
  372.                 return $pages;
  373.             } else {
  374.                 unset($continue);
  375.                 foreach($res['query-continue']['embeddedin'] as $key => $val) { // FIXED : API changes 07-2012
  376.                     $continue .= '&'.urlencode($key).'='.urlencode($val);
  377.                 }
  378.             }
  379.         }
  380.     }
  381.  
  382.     /**
  383.     * Returns an array with all the subpages of $page
  384.     * @param $page
  385.     * @param $extra extra parameters
  386.     * @return array
  387.     *          ADDED : + $extra
  388.     *          &apfilterredir=       - Which pages to list. One value: all, redirects, nonredirects
  389.     *          aplimit = 500 / 5000 for bots / default 10
  390.     **/
  391.     public function subpages ( $page, $extra='' ) {
  392.         /* Calculate all the namespace codes */
  393.         $ret = $this->query('?action=query&meta=siteinfo&siprop=namespaces&format=php');
  394.         foreach ($ret['query']['namespaces'] as $x) {
  395.             $namespaces[$x['*']] = $x['id'];
  396.         }
  397.         $temp = explode(':',$page,2);
  398.         $namespace = $namespaces[$temp[0]];
  399.         $title = $temp[1];
  400.         $continue = '';
  401.         $subpages = array();
  402.         while (true) {
  403.             $res = $this->query('?action=query&format=php&list=allpages&apprefix='.urlencode($title).'&aplimit=500&apnamespace='.$namespace.$continue.$extra);
  404.             if (isset($x[error])) {
  405.             return false;
  406.             }
  407.             foreach ($res['query']['allpages'] as $p) {
  408.             $subpages[] = $p['title'];
  409.             }
  410.             if (empty($res['query-continue']['allpages'])) {
  411.             return $subpages;
  412.             } else {
  413.             unset($continue);
  414.             foreach( $res['query-continue']['allpages'] AS $key => $val ) { // FIXED : API changes 07-2012
  415.                 $continue .= '&'.urlencode($key).'='.urlencode($val);
  416.             }
  417.             }
  418.         }
  419.     }
  420.  
  421.     /**
  422.     * This function takes a username and password and logs you into wikipedia.
  423.     * @param $user Username to login as.
  424.     * @param $pass Password that corrisponds to the username.
  425.     * @return array
  426.     **/
  427.     public function login ($user,$pass) {
  428.         $post = array('lgname' => $user, 'lgpassword' => $pass);
  429.         $ret = $this->query('?action=login&format=php',$post);
  430.         // This is now required - see https://bugzilla.wikimedia.org/show_bug.cgi?id=23076
  431.         if ($ret['login']['result'] == 'NeedToken') {
  432.             $post['lgtoken'] = $ret['login']['token'];
  433.             $ret = $this->query( '?action=login&format=php', $post );
  434.         }
  435.         if ($ret['login']['result'] != 'Success') {
  436.             echo "LOGIN ERROR on ". $this->url. "\n";
  437.             print_r($ret);
  438.             die();
  439.         } else {
  440.             return $ret;
  441.         }
  442.     }
  443.  
  444.     /**
  445.      * Check if we're allowed to edit $page.
  446.      * See http://en.wikipedia.org/wiki/Template:Bots
  447.      * for more info.
  448.      * @param $page The page we want to edit.
  449.      * @param $user The bot's username.
  450.      * @return bool
  451.      **/
  452.     function nobots ($page,$user=null,$text=null) {
  453.         if ($text == null) {
  454.             $text = $this->getpage($page);
  455.         }
  456.         if ($user != null) {
  457.             if (preg_match('/\{\{(nobots|bots\|allow=none|bots\|deny=all|bots\|optout=all|bots\|deny=.*?'.preg_quote($user,'/').'.*?)\}\}/iS',$text)) {
  458.                 return false;
  459.             }
  460.         } else {
  461.             if (preg_match('/\{\{(nobots|bots\|allow=none|bots\|deny=all|bots\|optout=all)\}\}/iS',$text)) {
  462.                 return false;
  463.             }
  464.         }
  465.         return true;
  466.     }
  467.  
  468.     /**
  469.      * This function returns the edit token for the current user.
  470.      * @return edit token.
  471.      **/
  472.     function getedittoken () {
  473.         $x = $this->query('?action=query&prop=info&intoken=edit&titles=Main%20Page&format=php');
  474.         foreach ($x['query']['pages'] as $ret) {
  475.             return $ret['edittoken'];
  476.         }
  477.     }
  478.  
  479.     /**
  480.      * Purges the cache of $page.
  481.      * @param $page The page to purge.
  482.      * @return Api result.
  483.      **/
  484.     function purgeCache($page) {
  485.         return $this->query('?action=purge&titles='.urlencode($page).'&format=php');
  486.     }
  487.  
  488.     /**
  489.      * Checks if $user has email enabled.
  490.      * Uses index.php.
  491.      * @param $user The user to check.
  492.      * @return bool.
  493.      **/
  494.     function checkEmail($user) {
  495.         $x = $this->query('?action=query&meta=allmessages&ammessages=noemailtext|notargettext&amlang=en&format=php');
  496.         $messages[0] = $x['query']['allmessages'][0]['*'];
  497.         $messages[1] = $x['query']['allmessages'][1]['*'];
  498.         $page = $this->http->get(str_replace('api.php','index.php',$this->url).'?title=Special:EmailUser&target='.urlencode($user));
  499.         if (preg_match('/('.preg_quote($messages[0],'/').'|'.preg_quote($messages[1],'/').')/i',$page)) {
  500.             return false;
  501.         } else {
  502.             return true;
  503.         }
  504.     }
  505.  
  506.     /**
  507.      * Returns all the pages $page is transcluded on.
  508.      * @param $page The page to get the transclusions from.
  509.      * @param $sleep The time to sleep between requets (set to null to disable).
  510.      * @return array.
  511.      **/
  512.      // eilimit : No more than 500 (5000 for bots) allowed, default=10
  513.      // $extra : eifilterredir=all, redirects, nonredirects
  514.      // einamespace    - The namespace to enumerate
  515.     function getTransclusions($page,$sleep=null,$extra=null) {
  516.         $continue = '';
  517.         $pages = array();
  518.         while (true) {
  519.             $ret = $this->query('?action=query&list=embeddedin&eititle='.urlencode($page).$continue.$extra.'&eilimit=5000&format=php');
  520.             if ($sleep != null) {
  521.                 echo "∆"; sleep($sleep);
  522.             }
  523.             foreach ($ret['query']['embeddedin'] as $x) {
  524.                 $pages[] = $x['title'];
  525.             }
  526.             if (isset($ret['query-continue']['embeddedin'])) {
  527.                 unset($continue);
  528.                 foreach( $ret['query-continue']['embeddedin'] AS $key => $val ) { // FIXED : API changes 07-2012
  529.                         $continue .= '&'.urlencode($key).'='.urlencode($val);
  530.                 }
  531.             } else {
  532.                 return $pages;
  533.             }
  534.         }
  535.     }
  536.  
  537.     /**
  538.      * Edits a page.
  539.      * @param $page Page name to edit.
  540.      * @param $data Data to post to page.
  541.      * @param $summary Edit summary to use.
  542.      * @param $minor Whether or not to mark edit as minor.  (Default false)
  543.      * @param $bot Whether or not to mark edit as a bot edit.  (Default true)
  544.      * @return api result
  545.      **/
  546.      // FIXED : $section=false/is_numeric to manage &section=0 (heading)
  547.     function edit ( $page, $data, $summary = '', $minor = false, $bot = true, $section = false, $detectEC=false, $maxlag='' ) {
  548.  
  549.         if ($this->token==null) {
  550.             $this->token = $this->getedittoken();
  551.         }
  552.         $params = array(
  553.             'title' => $page,
  554.             'text' => $data,
  555.             'token' => $this->token,
  556.             'summary' => $summary,
  557.             ($minor?'minor':'notminor') => '1',
  558.             ($bot?'bot':'notbot') => '1'
  559.         );
  560.         if ( is_numeric( $section ) ) {
  561.             $params['section'] = $section;
  562.         }
  563.         if ($this->ecTimestamp != null && $detectEC == true) {
  564.             $params['basetimestamp'] = $this->ecTimestamp;
  565.             $this->ecTimestamp = null;
  566.         }
  567.         if ($maxlag!='') {
  568.             $maxlag='&maxlag='.$maxlag;
  569.         }
  570.         // sécurité vitesse édition
  571.         if ( $this->editTimestamp > 0 AND ( time() - $this->editTimestamp ) < $this->editlaps ) {
  572.                 $waitsec = ($this->editlaps - (time()-($this->editTimestamp)) );
  573.                 echo "\nPause ".$waitsec." secondes...\n";
  574.                 sleep($waitsec);
  575.         }
  576.         $this->editTimestamp = time();
  577.         return $this->query('?action=edit&assert=user&format=php'.$maxlag,$params);
  578.     }
  579.  
  580.     /**
  581.     * Add a text at the bottom of a page
  582.     * @param $page The page we're working with.
  583.     * @param $text The text that you want to add.
  584.     * @param $summary Edit summary to use.
  585.     * @param $minor Whether or not to mark edit as minor.  (Default false)
  586.     * @param $bot Whether or not to mark edit as a bot edit.  (Default true)
  587.     * @return api result
  588.     **/
  589.     function addtext( $page, $text, $summary = '', $minor = false, $bot = true )
  590.     {
  591.         $data = $this->getpage( $page );
  592.         $data.= "\n" . $text;
  593.         return $this->edit( $page, $data, $summary, $minor, $bot );
  594.     }
  595.  
  596.     /**
  597.      * Moves a page.
  598.      * @param $old Name of page to move.
  599.      * @param $new New page title.
  600.      * @param $reason Move summary to use.
  601.      * @param $movetalk Move the page's talkpage as well.
  602.      * @return api result
  603.      **/
  604.     function move ($old,$new,$reason,$options=null) {
  605.         if ($this->token==null) {
  606.             $this->token = $this->getedittoken();
  607.         }
  608.         $params = array(
  609.             'from' => $old,
  610.             'to' => $new,
  611.             'token' => $this->token,
  612.             'reason' => $reason
  613.         );
  614.         if ($options != null) {
  615.             $option = explode('|',$options);
  616.             foreach ($option as $o) {
  617.                 $params[$o] = true;
  618.             }
  619.         }
  620.         return $this->query('?action=move&format=php',$params);
  621.     }
  622.  
  623.     /**
  624.      * Rollback an edit.
  625.      * @param $title Title of page to rollback.
  626.      * @param $user Username of last edit to the page to rollback.
  627.      * @param $reason Edit summary to use for rollback.
  628.      * @param $bot mark the rollback as bot.
  629.      * @return api result
  630.      **/
  631.     function rollback ($title,$user,$reason=null,$bot=false) {
  632.         $ret = $this->query('?action=query&prop=revisions&rvtoken=rollback&titles='.urlencode($title).'&format=php');
  633.         print_r($ret);
  634.         foreach ($ret['query']['pages'] as $x) {
  635.             $token = $x['revisions'][0]['rollbacktoken'];
  636.             break;
  637.         }
  638.         $params = array(
  639.             'title' => $title,
  640.             'user' => $user,
  641.             'token' => $token
  642.         );
  643.         if ($bot) {
  644.             $params['markbot'] = true;
  645.         }
  646.         if ($reason != null) { $params['summary'] = $reason; }
  647.             return $this->query('?action=rollback&format=php',$params);
  648.         }
  649.  
  650.     /**
  651.      * Blocks a user.
  652.      * @param $user The user to block.
  653.      * @param $reason The block reason.
  654.      * @param $expiry The block expiry.
  655.      * @param $options a piped string containing the block options.
  656.      * @return api result
  657.      **/
  658.     function block ($user,$reason='vand',$expiry='infinite',$options=null,$retry=true) {
  659.         if ($this->token==null) {
  660.             $this->token = $this->getedittoken();
  661.         }
  662.         $params = array(
  663.             'expiry' => $expiry,
  664.             'user' => $user,
  665.             'reason' => $reason,
  666.             'token' => $this->token
  667.         );
  668.         if ($options != null) {
  669.             $option = explode('|',$options);
  670.             foreach ($option as $o) {
  671.                 $params[$o] = true;
  672.             }
  673.         }
  674.         $ret = $this->query('?action=block&format=php',$params);
  675.         /* Retry on a failed token. */
  676.         if ($retry and $ret['error']['code']=='badtoken') {
  677.             $this->token = $this->getedittoken();
  678.             return $this->block($user,$reason,$expiry,$options,false);
  679.         }
  680.         return $ret;
  681.     }
  682.  
  683.     /**
  684.      * Unblocks a user.
  685.      * @param $user The user to unblock.
  686.      * @param $reason The unblock reason.
  687.      * @return api result
  688.      **/
  689.     function unblock ($user,$reason) {
  690.         if ($this->token==null) {
  691.             $this->token = $this->getedittoken();
  692.         }
  693.         $params = array(
  694.             'user' => $user,
  695.             'reason' => $reason,
  696.             'token' => $this->token
  697.         );
  698.         return $this->query('?action=unblock&format=php',$params);
  699.     }
  700.  
  701.     /**
  702.      * Emails a user.
  703.      * @param $target The user to email.
  704.      * @param $subject The email subject.
  705.      * @param $text The body of the email.
  706.      * @param $ccme Send a copy of the email to the user logged in.
  707.      * @return api result
  708.      **/
  709.     function email ($target,$subject,$text,$ccme=false) {
  710.         if ($this->token==null) {
  711.             $this->token = $this->getedittoken();
  712.         }
  713.         $params = array(
  714.             'target' => $target,
  715.             'subject' => $subject,
  716.             'text' => $text,
  717.             'token' => $this->token
  718.         );
  719.         if ($ccme) {
  720.             $params['ccme'] = true;
  721.         }
  722.         return $this->query('?action=emailuser&format=php',$params);
  723.     }
  724.  
  725.     /**
  726.      * Deletes a page.
  727.      * @param $title The page to delete.
  728.      * @param $reason The delete reason.
  729.      * @return api result
  730.      **/
  731.     function delete ($title,$reason) {
  732.         if ($this->token==null) {
  733.             $this->token = $this->getedittoken();
  734.         }
  735.         $params = array(
  736.             'title' => $title,
  737.             'reason' => $reason,
  738.             'token' => $this->token
  739.         );
  740.         return $this->query('?action=delete&format=php',$params);
  741.     }
  742.  
  743.     /**
  744.      * Undeletes a page.
  745.      * @param $title The page to undelete.
  746.      * @param $reason The undelete reason.
  747.      * @return api result
  748.      **/
  749.     function undelete ($title,$reason) {
  750.         if ($this->token==null) {
  751.             $this->token = $this->getedittoken();
  752.         }
  753.         $params = array(
  754.             'title' => $title,
  755.             'reason' => $reason,
  756.             'token' => $this->token
  757.         );
  758.         return $this->query('?action=undelete&format=php',$params);
  759.     }
  760.  
  761.     /**
  762.      * (Un)Protects a page.
  763.      * @param $title The page to (un)protect.
  764.      * @param $protections The protection levels (e.g. 'edit=autoconfirmed|move=sysop')
  765.      * @param $expiry When the protection should expire (e.g. '1 day|infinite')
  766.      * @param $reason The (un)protect reason.
  767.      * @param $cascade Enable cascading protection? (defaults to false)
  768.      * @return api result
  769.      **/
  770.     function protect ($title,$protections,$expiry,$reason,$cascade=false) {
  771.         if ($this->token==null) {
  772.             $this->token = $this->getedittoken();
  773.         }
  774.         $params = array(
  775.             'title' => $title,
  776.             'protections' => $protections,
  777.             'expiry' => $expiry,
  778.             'reason' => $reason,
  779.             'token' => $this->token
  780.         );
  781.         if ($cascade) {
  782.             $params['cascade'] = true;
  783.         }
  784.         return $this->query('?action=protect&format=php',$params);
  785.     }
  786.  
  787.     /**
  788.      * Uploads an image.
  789.      * @param $page The destination file name.
  790.      * @param $file The local file path.
  791.      * @param $desc The upload discrption (defaults to '').
  792.      **/
  793.      function upload ($page,$file,$desc='') {
  794.         if ($this->token == null) {
  795.                 $this->token = $this->getedittoken();
  796.         }
  797.         $params = array(
  798.                 'filename'        => $page,
  799.                 'comment'         => $desc,
  800.                 'text'            => $desc,
  801.                 'token'           => $this->token,
  802.                 'ignorewarnings'  => '1',
  803.                 'file'            => '@'.$file
  804.         );
  805.         return $this->query('?action=upload&format=php',$params);
  806.      }
  807.  
  808.     /*
  809.     $page - page
  810.     $revs - rev ids to delete (seperated with ,)
  811.     $comment - delete comment
  812.     */
  813.     function revdel ($page,$revs,$comment) {
  814.  
  815.         if ($this->token==null) {
  816.             $this->token = $this->getedittoken();
  817.         }
  818.  
  819.         $post = array(
  820.             'wpEditToken'       => $this->token,
  821.             'ids' => $revs,
  822.             'target' => $page,
  823.             'type' => 'revision',
  824.             'wpHidePrimary' => 1,
  825.             'wpHideComment' => 1,
  826.             'wpHideUser' => 0,
  827.             'wpRevDeleteReasonList' => 'other',
  828.             'wpReason' => $comment,
  829.             'wpSubmit' => 'Apply to selected revision(s)'
  830.         );
  831.         return $this->http->post(str_replace('api.php','index.php',$this->url).'?title=Special:RevisionDelete&action=submit',$post);
  832.     }
  833.  
  834.     /**
  835.      * Creates a new account.
  836.      * Uses index.php as there is no api to create accounts yet :(
  837.      * @param $username The username the new account will have.
  838.      * @param $password The password the new account will have.
  839.      * @param $email The email the new account will have.
  840.      **/
  841.     function createaccount ($username,$password,$email=null) {
  842.         $post = array(
  843.             'wpName' => $username,
  844.             'wpPassword' => $password,
  845.             'wpRetype' => $password,
  846.             'wpEmail' => $email,
  847.             'wpRemember' => 0,
  848.             'wpIgnoreAntiSpoof' => 0,
  849.             'wpCreateaccount' => 'Create account',
  850.         );
  851.         return $this->http->post(str_replace('api.php','index.php',$this->url).'?title=Special:UserLogin&action=submitlogin&type=signup',$post);
  852.     }
  853.  
  854.     /**
  855.      * Changes a users rights.
  856.      * @param $user   The user we're working with.
  857.      * @param $add    A pipe-separated list of groups you want to add.
  858.      * @param $remove A pipe-separated list of groups you want to remove.
  859.      * @param $reason The reason for the change (defaults to '').
  860.      **/
  861.     function userrights ($user,$add,$remove,$reason='') {
  862.         // get the userrights token
  863.         $token = $this->query('?action=query&list=users&ususers='.urlencode($user).'&ustoken=userrights&format=php');
  864.         $token = $token['query']['users'][0]['userrightstoken'];
  865.         $params = array(
  866.             'user' => $user,
  867.             'token' => $token,
  868.             'add' => $add,
  869.             'remove' => $remove,
  870.             'reason' => $reason
  871.         );
  872.         return $this->query('?action=userrights&format=php',$params);
  873.     }
  874.  
  875.     /**
  876.      * Gets the number of images matching a particular sha1 hash.
  877.      * @param $hash The sha1 hash for an image.
  878.      * @return The number of images with the same sha1 hash.
  879.      **/
  880.     function imagematches ($hash) {
  881.         $x = $this->query('?action=query&list=allimages&format=php&aisha1='.$hash);
  882.         return count($x['query']['allimages']);
  883.     }
  884.  
  885. }
  886.  
  887. /**
  888.  * This class extends the wiki class to provide an high level API for the most commons actions.
  889.  * @author Fale
  890.  **/
  891. class extended extends wikipedia
  892. {
  893.     /**
  894.      * Find a string
  895.      * @param $page The page we're working with.
  896.      * @param $string The string that you want to find.
  897.      * @return bool value (1 found and 0 not-found)
  898.      **/
  899.     function findstring( $page, $string )
  900.     {
  901.         $data = $this->getpage( $page );
  902.         if( strstr( $data, $string ) )
  903.             return 1;
  904.         else
  905.             return 0;
  906.     }
  907.  
  908.     /**
  909.      * Replace a string
  910.      * @param $page The page we're working with.
  911.      * @param $string The string that you want to replace.
  912.      * @param $newstring The string that will replace the present string.
  913.      * @return the new text of page
  914.      **/
  915.     function replacestring( $page, $string, $newstring )
  916.     {
  917.         $data = $this->getpage( $page );
  918.         return str_replace( $string, $newstring, $data );
  919.     }
  920.  
  921.     /**
  922.      * Get a template from a page
  923.      * @param $page The page we're working with
  924.      * @param $template The name of the template we are looking for
  925.      * @return the searched (NULL if the template has not been found)
  926.      **/
  927.     function gettemplate( $page, $template ) {
  928.        $data = $this->getpage( $page );
  929.        $template = preg_quote( $template, " " );
  930.        $r = "/{{" . $template . "(?:[^{}]*(?:{{[^}]*}})?)+(?:[^}]*}})?/i";
  931.        preg_match_all( $r, $data, $matches );
  932.        if( isset( $matches[0][0] ) )
  933.            return $matches[0][0];
  934.        else
  935.            return NULL;
  936.      }
  937.  
  938.        /*
  939.     * Return redirect page title or false
  940.     * TODO : boucle pour arriver sur bonne page. Attention boucle sans fin
  941.     */
  942.     function page_redirect($page) {
  943.         $data = $this->getpage( $page );
  944.         if( preg_match('/^#REDIRECT(?:ION)? ?\[\[([^\]]+)\]\]/i', $data, $matches) ) {
  945.             return (string) trim($matches[1]);
  946.         }else{
  947.             return FALSE;
  948.         }
  949.     }
  950.  
  951. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement