<?php

/*!
    \class   MPLookupOperator mplookupoperator.php
    \ingroup eZTemplateOperators
    \brief   Takes a postal code and looks up Canadian MP. Returns possible MPs if there is an ambiguity. Can also check / clean postalcodes.
    \version 1.0
    \date    Wednesday 03 March 2010 10:41:57 am
    \author  Matthew Carroll

    Copyright 2010, Matthew Carroll

    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 3 of the License, or
    (at your option) any later version.

    Example:
    \code
    {$postalcode|mplookup}
    \endcode

    This is built as a module for the eZpublish Content Management System. If you want to use this elsewhere, probably all you want is the
    lookup() function below. Please be sure to change the user agent string.
*/

class MPLookupOperator
{
    
/*!
        Constructor, does nothing by default.
    */
    
function MPlookupOperator()
    {
    }

    
/*!
        \return an array with the template operator name.
    */
    
function operatorList()
    {
        return array( 
'mplookup''mpcheckpc''mpcleanpc' );
    }

    
/*!
        \return true to tell the template engine that the parameter list exists per operator type,
            this is needed for operator classes that have multiple operators.
    */
    
function namedParameterPerOperator()
    {
        return 
true;
    }

    
/*!
        See eZTemplateOperator::namedParameterList
    */
    
function namedParameterList()
    {
        return array( 
'mplookup'  => array( 'lang' => array( 'type' => 'string',
                                                             
'required' => false,
                                                             
'default' => 'eng-CA' ) ),
                      
'mpcleanpc' => array(),
                      
'mpcheckpc' => array() );
    }


    
/*!
     |mplookup looks up the MP and returns one (or more) possible MPs. |mpcleanpc and |mpcheckpc clean or check validity of postal codes.
    */
    
function modify$tpl$operatorName$operatorParameters$rootNamespace$currentNamespace, &$operatorValue$namedParameters$placement )
    {
        switch ( 
$operatorName )
        {
            case 
'mplookup':
            {
                
$operatorValue $this->lookup$operatorValue$namedParameters['lang'] );
            }
            break;
            case 
'mpcleanpc':
            {
                
$operatorValue $this->cleanpc$operatorValue );
            }
            break;
            case 
'mpcheckpc':
            {
                
$operatorValue $this->checkpc$operatorValue );
            }
            break;
        }
    }
    function 
cleanpc$postalcode )
    {
        return 
strtoupperpreg_replace'/[^a-zA-Z0-9]/'''$postalcode ) );
    }
    function 
checkpc$postalcode )
    {
        return 
preg_match'/^([A-Z][0-9]){3}$/'$this->cleanpc$postalcode ) );
    }
    function 
lookup$postalcode$lang )
    {
        if ( 
$this->checkpc$postalcode ) )
        {
            
$postalcode $this->cleanpc$postalcode );
            
$urlbase 'http://www.parl.gc.ca/parlinfo';
            switch( 
$lang )
            {
                case 
'fre-CA':
                    
$url $urlbase '/Compilations/HouseOfCommons/MemberByPostalCode.aspx?Language=F&PostalCode=';
                    break;
                case 
'eng-CA':
                default:
                    
$url $urlbase '/Compilations/HouseOfCommons/MemberByPostalCode.aspx?PostalCode=';
                    break;
            }
            
$url .= $postalcode;
            
$useragent 'CBAN email my MP tool (http://cban.ca, webmaster@cban.ca)';
            
            
$xpathallmps "id('ctl00_cphContent_pnlWithMP')/div";
            
            
$c curl_init($url);
            
curl_setopt($cCURLOPT_RETURNTRANSFERTRUE);
            
curl_setopt($cCURLOPT_USERAGENT$useragent);
            
curl_setopt($cCURLOPT_TIMEOUT10);
            
$page curl_exec($c);
            if ( 
$page === false )
            {
                
eZDebug::writeError"Error: Unexpected CURL connecting to {$url}; curl_error: " curl_error($c) );
                
curl_close($c);
                return 
false;
            }
            
curl_close($c);
            
            
$doc = new DOMDocument();
            
$doc->preserveWhiteSpace false;
            @
$doc->loadHTML($page);
            
$domxpath = new DOMXpath($doc);
            
            
$result = array();
            
            
$allmpdivs $domxpath->query($xpathallmps);
            if ( 
$allmpdivs->length == )
            {
                
eZDebug::writeError"xpath query failed: could not find any MPs");
//                eZDebug::writeError($page);
                
return false;
            }
            
            foreach( 
$allmpdivs as $key1 => $mpdiv //only actually need the key!
            
{
                
$xpaths = array( 'mpname' => "id('ctl00_cphContent_repMP_ctl0" $key1 "_lnkPerson')",
                                 
'mpemail' => "id('ctl00_cphContent_repMP_ctl0" $key1 "_grdParliamentaryAddress_ctl02_HyperLink1')",
                                 
'riding' => "id('ctl00_cphContent_repMP_ctl0" $key1 "_lblYellowBar')",
                                 
'party' => "id('ctl00_cphContent_repMP_ctl0" $key1 "_lnkParty')",
                                 
'photo' => "id('ctl00_cphContent_repMP_ctl0" $key1 "_imgMember')",
                                 
'phone' => "id('ctl00_cphContent_repMP_ctl0" $key1 "_grdConstituencyAddress_ctl02_repConstituencyTelephones_ctl00_lblTelephonenumber')" );
                
                foreach( 
$xpaths as $key2 => $xpath )
                {
                    
$items $domxpath->query($xpath);
                    if ( 
$items->length == )
                    {
                        
eZDebug::writeError"xpath query failed for " $key2 );
                        return 
false;
                    }
                    else
                    {
                        switch( 
$key2 )
                        {
                            case 
'photo':
                                
$result[$key1][$key2] = $urlbase str_replace'../..'''utf8_decode$items->item(0)->getAttribute('src') ) );
                                break;
                            case 
'count':
                                
$result[$key1][$key2] = $items->length;
                                break;
                            case 
'mpname':
                                
$result[$key1]['url'] = $urlbase str_replace'../..'''utf8_decode$items->item(0)->getAttribute('href') ) );
                            default:
                                
$result[$key1][$key2] = utf8_decode$items->item(0)->nodeValue );
                                break;
                        }
                    }
                }
                
$result[$key1]['gender'] = false;
            }
            
            
$url2base "http://www.parl.gc.ca/Parlinfo/Lists/Members.aspx?Current=True&Gender=";
            
$xpath2 "id('ctl00_cphContent_ctl00_grdMembersList')/tr/td[1]/a";
            
            
$genders = array( 'F' => null'M' => null );
            
            foreach( 
$genders as $key => $gender )
            {
                
$url2 $url2base $key;
                
$c curl_init($url2);
                
curl_setopt($cCURLOPT_RETURNTRANSFERTRUE);
                
curl_setopt($cCURLOPT_USERAGENT$useragent);
                
curl_setopt($cCURLOPT_TIMEOUT10);
                
$page curl_exec($c);
                if ( 
$page === false )
                {
                    
eZDebug::writeError"Error: Unexpected CURL connecting to {$url2}; curl_error: " curl_error($c) );
                    
curl_close($c);
                    return 
false;
                }
                
curl_close($c);
                
                
$doc = new DOMDocument();
                
$doc->preserveWhiteSpace false;
                @
$doc->loadHTML($page);
                
$domxpath = new DOMXpath($doc);
                
                
$items $domxpath->query($xpath2);
                if ( 
$items->length == )
                {
                    
eZDebug::writeError"xpath query failed for gender lookup");
                }
                else
                {
                    
$genders[$key] = $items;
                }
            }
            
            foreach( 
$result as $key => $mp )
            {
                foreach( 
$genders as $gender => $mpgendernodelist )
                {
                    foreach( 
$mpgendernodelist as $mpgendernodeitem )
                    {
                        if ( 
$mp['mpname'] == utf8_decode$mpgendernodeitem->nodeValue ) )
                        {
                            
$result[$key]['gender'] = $gender;
                            break(
2);
                        }
                    }
                }
                
$result[$key]['mpname'] = explode', '$result[$key]['mpname'] );
                
$result[$key]['mpname'] = array_reverse$result[$key]['mpname'] );
                
$result[$key]['mpname'] = implode' '$result[$key]['mpname'] );
            }
            
            return 
$result;
        }
        else
        {
            return 
false;
        }
    }
}

?>