Plugin Directory

Changeset 1700883


Ignore:
Timestamp:
07/22/2017 08:23:40 PM (9 years ago)
Author:
john ackers
Message:

Get MPs email address from database table

File:
1 edited

Legend:

Unmodified
Added
Removed
  • ecampaign/branches/maintenance/uk/MP.class.php

    r1223910 r1700883  
    44class : MP
    55author : John Ackers
    6 modified : 11-Aug-2015
     6modified : 17-Jul-2017
    77
    88Supports the use of a %lookup button in a form.
     
    1212From May 2015, It makes use of
    1313http://www.parliament.uk/mps-lords-and-offices/mps/?search_term=
     14
     15From June 2017, parliament UK encodes the email addresses in
     16javascript and appropriate decodes is added below
    1417
    1518This class is loaded by ecampaign.php when the
     
    5760    return $html ;
    5861  }
    59 
     62 
     63 
     64  static function fetchResource($url)
     65  {     
     66    $ch = curl_init($url);
     67     
     68    curl_setopt($ch, CURLOPT_HEADER, 0);
     69    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
     70    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
     71     
     72    $xml = curl_exec($ch);
     73    $errno = curl_errno($ch);
     74    if ($errno != 0) {
     75      $error = curl_error($ch);
     76      throw new Exception($errno . " " . $error . " from ". $url);
     77    } 
     78    if (false !== strpos($xml, "BAD REQUEST"))
     79      throw new Exception($xml . " from  " . $url);
     80   
     81    if ($xml == false)
     82      throw new Exception("Unable to fetch from " . $url);
     83
     84    curl_close($ch);
     85    $json = json_decode($xml, True);
     86    if (empty($json))
     87      throw new Exception("Unable to decode result to JSON object ".  $xml . " from " . $url);
     88    return $json ;   
     89  }
     90
     91    /**
     92     * Accept a call from the client to lookup constituent's MP details
     93     *
     94     * @throws Exception
     95     * @return $response for browser
     96     */
     97  function lookup() {
     98    $desiredFields = array (
     99        self::sPostID,
     100        self::sUKPostcode,
     101        self::sCampaignEmail,
     102        self::sVisitorName,
     103        self::sVisitorEmail
     104    );
     105    $controlFields = array (
     106        self::sPostID => new EcampaignField ( self::sPostID )
     107    );
     108    $this->fieldSet = EcampaignField::requestPartialMap ( $desiredFields, array_merge ( $controlFields, self::$allFields ) );
     109   
     110    if (empty ( $this->fieldSet->ukpostcode )) {
     111      throw new Exception ( "Postcode field is empty" );
     112    }
     113
     114    $url = "https://www.theyworkforyou.com/api/getMP?&postcode=" . urlencode($this->fieldSet->ukpostcode) 
     115                                                  . "&key=BeRwCCEyNTGyDTMVFzCW2fXe"
     116                                                  . "&output=js";
     117                                                 
     118    $mpInfo = self::fetchResource($url);
     119    $member_id = $mpInfo ['member_id'];
     120    $constituency = $mpInfo ['constituency'];
     121    global $wpdb ;
     122
     123    $query = $wpdb->prepare ( "select constituency, `First name`, `Surname`, `Addressable Title`, addressAs, email from mp where constituency='%s'", $constituency );
     124
     125    $wpdb->show_errors(false);
     126    $mpStored = $wpdb->get_row ( $query, ARRAY_A );
     127    $error = $wpdb->last_error; // not formally documented
     128    if (!empty($error))
     129      throw new Exception($error);
     130   
     131    if (!$mpStored)
     132      throw new Exception("Unable to find MP in local database for " . $this->fieldSet->ukpostcode);
     133   
     134    if ($mpInfo['given_name'] != $mpStored['First name'])
     135      throw new Exception ( "Yuk, first names don't match" . $mpInfo['full_name']);
     136
     137    if ($mpInfo['family_name'] != $mpStored['Surname'])
     138      throw new Exception ( "Yuk, last names don't match" . $mpInfo['full_name']);
     139     
     140    $name = $mpStored['Addressable Title']; 
     141    $memberName = empty($name) ?   $mpInfo['full_name'] . " MP"  : $name ;
     142    $name = $mpStored['addressAs'];
     143    $addressAs =  empty($name) ?   $mpInfo['full_name']          : $name ;
     144       
     145    $target = array ();
     146    $target ['name'] = $memberName;
     147   
     148    $emails = explode(' ',$mpStored['email']) ; $email = $emails[0];  // take first email address on the line
     149   
     150    if (!filter_var($email, FILTER_VALIDATE_EMAIL))
     151      throw new Exception ("Invalid email address for " . $mpInfo['full_name']);
     152     
     153    $target ['email']=  $this->testMode->isDiverted() ? $this->fieldSet->campaignEmail : $email;
     154    $source = "";
     155    $this->log->write ( "lookup", $this->fieldSet, "$memberName\r\n$constituencyName\r\nsource:" . $source );
     156    $response = array (
     157        "target" => array (
     158            $target
     159        ),
     160        "constituency" => $constituencyName,
     161        "success" => true,
     162        "callbackJS" => 'updateMessageFields',
     163        "msg" => $memberName,
     164        "regexp" => array (
     165            'pattern' => "[name]",
     166            'replacement' => $addressAs
     167        )
     168    );
     169    return $response;
     170  }
    60171  /*
    61172   * email the original or updated message to the party or parties that are the target of
     
    64175   */
    65176
    66   function lookup()
     177  function lookupOld()
    67178  {
    68179    $desiredFields = array(self::sPostID, self::sUKPostcode, self::sCampaignEmail, self::sVisitorName, self::sVisitorEmail);
     
    78189
    79190    $memberName = $biography['name'];
    80     $memberEmail = $biography['email'];   
    81     $constituencyName = $biography['constituency'];   
     191    $memberEmail = self::deCFEmail($biography['email']);   // 30-june-2017
     192    $constituencyName = $biography['constituency']; 
     193   
    82194
    83195    $target = array();
     
    85197    $target['email'] = $this->testMode->isDiverted() ? $this->fieldSet->campaignEmail : $memberEmail;
    86198
    87     $this->log->write("lookup", $this->fieldSet, "$memberName\r\n$constituencyName\r\nsource:".$biography['source']);
     199    $this->log->write("lookup", $this->fieldSet, "$memberName\r\n$constituencyName\r\nsource:".$source);
    88200    $response = array("target" => array($target),
    89201                 "constituency" => $constituencyName,
     
    124236    }
    125237  }
     238   
     239  /**
     240   * As of 30 June 2017, email addresses are encoded by Cloudfare
     241   * decoder credit http://blog.safebuff.com/2016/06/01/Cloudflare-Email-Protection-Decoder/
     242   */
     243   
     244  private static function deCFEmail($c){
     245    $k = hexdec(substr($c,0,2));
     246    for($i=2,$m='';$i<strlen($c)-1;$i+=2)$m.=chr(hexdec(substr($c,$i,2))^$k);
     247    return $m;
     248  }     
    126249
    127250  private static function matchChain($regexpAr, $page, $flags)
     
    146269  private static function lookupMPBiography($postcode)   
    147270  {         
    148     # test area #  https://regex101.com/r/yG6oH6/1
    149     # revised 27 July 2015
    150 
    151     $regexBio = array('name'         => '<h1>(?<name>[^>]+)<\/h1>',
     271    # test area #  https://regex101.com/r/yG6oH6/1,  revised 27 July 2015
     272    # test area #  https://regex101.com/r/yG6oH6/2,  revised 30 Jun  2017
     273
     274
     275    $regexBio = array('name'         => '<h1>(?<name>[^<]+)<\/h1>',
    152276                      'constituency' => '<div\sid="commons-constituency">(?<constituency>[^<]*?)<\/div>',
    153                       'addressAs'    => '<div\sid="commons-addressas">(?<addressAs>[^<]*?)<\/div>.*?',
    154                       'email'        => '\"mailto:(?<email>[^\";]+)'); 
     277                      'addressAs'    => '<div\sid="commons-addressas">(?<addressAs>[^<]*?)<\/div>.*?',                   
     278 //                     'email'        => '\"mailto:(?<email>[^\";]+)'  // old version
     279                      'email'        => 'data-cfemail="(?<email>[^"]*)"#'   // 30 Jun 2017
     280                      );
    155281   
    156282    $page = self::fetchPage($postcode);
     
    161287    try {     
    162288      $biography = self::matchChain($regexBio, $page['body'], 'mixs');
    163       $biography['source'] = "[]" ;
    164289    }
    165290    catch (ErrorException $e)
    166291    {
     292        global $wpdb ;
     293        $charset_collate = $wpdb->get_charset_collate(); // hm not used
     294       
     295        // create a table to record errors extracting data from biogragphy page
     296        $query =
     297        'create table if not exists mp
     298           (url varchar(80),
     299            constituency varchar(80) null,
     300            addressas varchar(80) null,  email varchar(80) null,
     301            page mediumtext null)';
     302       
     303        $res = $wpdb->query($query);   
     304        $error = $wpdb->last_error; // not formally documented
     305        if (!empty($error))
     306            throw new Exception($error);
     307       
     308        $res = $wpdb->insert('mp',  array('url' => $postcode, 'page' => $page['body']));
     309        $error = $wpdb->last_error; // not formally documented
     310        if (!empty($error))
     311            throw new Exception($error);
     312       
    167313      $key = $e->getMessage();
    168             $pageLen = strlen($page);
     314      $pageLen = strlen($page);
    169315      throw new Exception("Unable to find MP's '$key' in their <a href='". $page['url'] ."'>biography page</a>");
    170316    }
    171     return $biography ;   
     317    return $biography ;
    172318  }
    173319}
Note: See TracChangeset for help on using the changeset viewer.