oxonlinevatidcheck.php

Go to the documentation of this file.
00001 <?php
00002 
00006 class oxOnlineVatIdCheck extends oxCompanyVatInChecker
00007 {
00008 
00014     protected $_blServiceIsOn = null;
00015 
00021     protected static $_aVatCheckCache = array();
00022 
00027     const BUSY_RETRY_CNT = 1;
00028 
00033     const BUSY_RETRY_WAITUSEC = 500000;
00034 
00040     protected $_sWsdl = 'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl';
00041 
00045     public function __construct()
00046     {
00047     }
00048 
00056     public function validate(oxCompanyVatIn $oVatIn)
00057     {
00058         $oCheckVat = new stdClass();
00059         $oCheckVat->countryCode = $oVatIn->getCountryCode();
00060         $oCheckVat->vatNumber = $oVatIn->getNumbers();
00061 
00062         $blResult = $this->_checkOnline($oCheckVat);
00063         if (!$blResult) {
00064             $this->setError('ID_NOT_VALID');
00065         }
00066 
00067         return $blResult;
00068     }
00069 
00079     protected function _parseError($sErrorMsg)
00080     {
00081         if (!$sErrorMsg || $sErrorMsg == 'INVALID_INPUT') {
00083             $oEx = oxNew('oxInputException');
00084             $oEx->setMessage('VAT_MESSAGE_' . ($sErrorMsg ? $sErrorMsg : 'ID_NOT_VALID'));
00085             throw $oEx;
00086         }
00087 
00089         $oEx = oxNew('oxConnectionException');
00090         $oEx->setAdress($this->getWsdlUrl());
00091         $oEx->setMessage('VAT_MESSAGE_' . $sErrorMsg);
00092         $oEx->debugOut();
00093         throw $oEx;
00094     }
00095 
00107     public function checkUid($sCompVatId)
00108     {
00109         if (isset(self::$_aVatCheckCache[$sCompVatId])) {
00110             if (true === self::$_aVatCheckCache[$sCompVatId]) {
00111                 return true;
00112             }
00113             if (is_string(self::$_aVatCheckCache[$sCompVatId])) {
00114                 $this->_parseError(self::$_aVatCheckCache[$sCompVatId]);
00115             }
00116 
00117             return false;
00118         }
00119 
00120         $oCheckVat = new stdClass();
00121         $oCheckVat->countryCode = substr($sCompVatId, 0, 2);
00122         $oCheckVat->vatNumber = substr($sCompVatId, 2);
00123 
00124         if (!$this->_checkOnline($oCheckVat)) {
00125             $sErrorMsg = $this->_getError();
00126             self::$_aVatCheckCache[$sCompVatId] = $sErrorMsg;
00127             $this->_parseError($sErrorMsg);
00128         }
00129 
00130         return self::$_aVatCheckCache[$sCompVatId] = true;
00131     }
00132 
00144     public function catchWarning($iErrNo, $sErrStr, $sErrFile, $iErrLine)
00145     {
00146         // message to write to exception log
00147         $sLogMessage = "Warning: $sErrStr in $sErrFile on line $iErrLine";
00148 
00149         // fetching exception log file name
00150         $oEx = oxNew("oxException");
00151         $sLogFileName = $oEx->getLogFileName();
00152 
00153         // logs error message
00154         return oxRegistry::getUtils()->writeToLog($sLogMessage, $sLogFileName);
00155     }
00156 
00165     protected function _isServiceAvailable()
00166     {
00167         if ($this->_blServiceIsOn === null) {
00168             $this->_blServiceIsOn = class_exists('SoapClient') ? true : false;
00169             if ($this->_blServiceIsOn) {
00170                 $rFp = @fopen($this->getWsdlUrl(), 'r');
00171                 $this->_blServiceIsOn = $rFp !== false;
00172                 if ($this->_blServiceIsOn) {
00173                     $sWsdl = '';
00174                     while (!feof($rFp)) {
00175                         $sWsdl .= fread($rFp, 8192);
00176                     }
00177                     fclose($rFp);
00178 
00179                     // validating wsdl file
00180                     try {
00181                         $oDomDocument = new DOMDocument();
00182                         $oDomDocument->loadXML($sWsdl);
00183                     } catch (Exception $oExcp) {
00184                         // invalid xml
00185                         $this->_blServiceIsOn = false;
00186                     }
00187                 }
00188             }
00189         }
00190 
00191         return $this->_blServiceIsOn;
00192     }
00193 
00202     protected function _checkOnline($oCheckVat)
00203     {
00204         if ($this->_isServiceAvailable()) {
00205             $iTryMoreCnt = self::BUSY_RETRY_CNT;
00206 
00207             //T2009-07-02
00208             //how long socket should wait for server RESPONSE
00209             ini_set('default_socket_timeout', 5);
00210 
00211             // setting local error handler to catch possible soap errors
00212             set_error_handler(array($this, 'catchWarning'), E_WARNING);
00213 
00214             do {
00215                 try {
00216                     //connection_timeout = how long we should wait to CONNECT to wsdl server
00217                     $oSoapClient = new SoapClient($this->getWsdlUrl(), array("connection_timeout" => 5));
00218                     $this->setError('');
00219                     $oRes = $oSoapClient->checkVat($oCheckVat);
00220                     $iTryMoreCnt = 0;
00221                 } catch (SoapFault $e) {
00222                     $this->setError($e->faultstring);
00223                     if ($this->getError() == "SERVER_BUSY") {
00224                         usleep(self::BUSY_RETRY_WAITUSEC);
00225                     } else {
00226                         $iTryMoreCnt = 0;
00227                     }
00228                 }
00229             } while (0 < $iTryMoreCnt--);
00230 
00231             // restoring previous error handler
00232             restore_error_handler();
00233 
00234             return (bool) $oRes->valid;
00235         } else {
00236             $this->setError("SERVICE_UNREACHABLE");
00237 
00238             return false;
00239         }
00240     }
00241 
00249     protected function _getError()
00250     {
00251         $sError = '';
00252         if ($this->_sError) {
00253             $sRegex = '/\{ \'([A-Z_]*)\' \}/';
00254             $n = preg_match($sRegex, $this->_sError, $aMatches);
00255             $sError = ($aMatches[1]) ? $aMatches[1] : 'SERVICE_UNAVAILABLE';
00256         }
00257 
00258         return $sError;
00259     }
00260 
00266     public function getWsdlUrl()
00267     {
00268         // overriding wsdl url
00269         if (($sWsdl = oxRegistry::getConfig()->getConfigParam("sVatIdCheckInterfaceWsdl"))) {
00270             $this->_sWsdl = $sWsdl;
00271         }
00272 
00273         return $this->_sWsdl;
00274     }
00275 
00283     public function isDisabled()
00284     {
00285         return (bool) oxRegistry::getConfig()->getConfigParam("blVatIdCheckDisabled");
00286     }
00287 }