/**
  * Performes a SOAP call
  *
  * @see SoapClient::__call()
  */
 public function __call($call, $args)
 {
     $retries = 0;
     do {
         try {
             // Call
             $Response = $this->doCall($call, $args);
             // Quit the loop on success
             break;
         } catch (Exception $E) {
             ++$retries;
             // Calculate seconds based on the number of retries
             $seconds = self::NUMBER_OF_SECONDS_SLEEP * $retries;
             // Try to get a new token
             if ($E->getMessage() == 'Unauthorized Request - Invalid Token') {
                 // Log the error
                 PlentymarketsLogger::getInstance()->error('Soap:Call', $call . ' failed: Unauthorized Request - Invalid Token', 1110);
                 // Refresh the token
                 $this->getToken();
                 $this->setSoapHeaders();
             } else {
                 PlentymarketsLogger::getInstance()->message('Soap:Call', $call . ' will wait ' . $seconds . ' seconds and then try again (' . $retries . '/' . self::NUMBER_OF_RETRIES_MAX . ')');
                 sleep($seconds);
             }
         }
     } while ($retries < self::NUMBER_OF_RETRIES_MAX);
     // Log the call's success state
     if (isset($Response->Success) && $Response->Success == true) {
         if ($call == 'GetServerTime') {
             if (!$this->Config->getApiIgnoreGetServerTime()) {
                 PlentymarketsLogger::getInstance()->message('Soap:Call', 'GetServerTime success');
             }
         } else {
             PlentymarketsLogger::getInstance()->message('Soap:Call', $call . ' success');
         }
         // Remember the timestamp
         if (!empty($this->timestampConfigKey)) {
             $this->Config->set($this->timestampConfigKey, time());
         }
     } else {
         PlentymarketsLogger::getInstance()->error('Soap:Call', $call . ' failed', 1100);
         if (isset($Response) && $this->Config->getApiLogHttpHeaders(false)) {
             PlentymarketsLogger::getInstance()->error('Soap:Call', var_export($Response, true));
         }
         if (isset($E) && $E instanceof Exception) {
             PlentymarketsLogger::getInstance()->error('Soap:Call:Request', htmlspecialchars($this->__getLastRequest()));
             PlentymarketsLogger::getInstance()->error('Soap:Call', $E->getMessage());
         }
     }
     // Log the HTTP headers?
     if ($this->Config->getApiLogHttpHeaders(false)) {
         PlentymarketsLogger::getInstance()->message('Soap:Call:Header:Request', $this->__getLastRequestHeaders());
         PlentymarketsLogger::getInstance()->message('Soap:Call:Header:Response', $this->__getLastResponseHeaders());
     }
     ++$this->numberOfCalls;
     return $Response;
 }
 /**
  * Performes a SOAP call
  *
  * @see SoapClient::__call()
  */
 public function __call($call, $args)
 {
     $retries = 0;
     do {
         try {
             $headers = $this->__getLastResponseHeaders();
             if ($headers) {
                 preg_match('/X-Plenty-Soap-Calls-Left: (-?\\d+)/', $headers, $matches);
                 $callsLeft = isset($matches[1]) ? (int) $matches[1] : -1;
                 preg_match('/X-Plenty-Soap-Seconds-Left: (-?\\d+)/', $headers, $matches);
                 $secondsLeft = isset($matches[1]) ? (int) $matches[1] : -1;
                 if (!($callsLeft % 50)) {
                     PyLog()->message('Soap:CallLimit', sprintf('Soap-Calls-Left: %d – Soap-Seconds-Left: %d', $callsLeft, $secondsLeft));
                 }
                 // check if the limit of the soap calls is already reached
                 if ($callsLeft != -1 && $callsLeft <= 10) {
                     $sleep = $secondsLeft + 5;
                     PyLog()->message('Soap:CallLimit', sprintf('Soap call limit reached. Waiting %d seconds.', $sleep));
                     sleep($sleep);
                     PyLog()->message('Soap:CallLimit', sprintf('Waited %d seconds.', $sleep));
                 }
             }
             // Call
             $Response = $this->doCall($call, $args);
             // Quit the loop on success
             break;
         } catch (Exception $E) {
             ++$retries;
             // Calculate seconds based on the number of retries
             $seconds = self::NUMBER_OF_SECONDS_SLEEP * $retries;
             // Try to get a new token
             if ($E->getMessage() == 'Unauthorized Request - Invalid Token') {
                 // Log the error
                 PlentymarketsLogger::getInstance()->error('Soap:Call', $call . ' failed: Unauthorized Request - Invalid Token', 1110);
                 // Refresh the token
                 $this->getToken();
                 $this->setSoapHeaders();
             } else {
                 PlentymarketsLogger::getInstance()->message('Soap:Call', $call . ' will wait ' . $seconds . ' seconds and then try again (' . $retries . '/' . self::NUMBER_OF_RETRIES_MAX . ')');
                 sleep($seconds);
             }
         }
     } while ($retries < self::NUMBER_OF_RETRIES_MAX);
     // Log the call's success state
     if (isset($Response->Success) && $Response->Success == true) {
         if ($call == 'GetServerTime') {
             if (!$this->Config->getApiIgnoreGetServerTime()) {
                 PlentymarketsLogger::getInstance()->message('Soap:Call', 'GetServerTime success');
             }
         } else {
             PlentymarketsLogger::getInstance()->message('Soap:Call', $call . ' success');
         }
         // Remember the timestamp
         if (!empty($this->timestampConfigKey)) {
             $this->Config->set($this->timestampConfigKey, time());
         }
     } else {
         PlentymarketsLogger::getInstance()->error('Soap:Call', $call . ' failed', 1100);
         if (isset($Response) && $this->Config->getApiLogHttpHeaders(false)) {
             PlentymarketsLogger::getInstance()->error('Soap:Call', var_export($Response, true));
         }
         if (isset($E) && $E instanceof Exception) {
             PlentymarketsLogger::getInstance()->error('Soap:Call:Request', htmlspecialchars($this->__getLastRequest()));
             PlentymarketsLogger::getInstance()->error('Soap:Call', $E->getMessage());
         }
     }
     // Log the HTTP headers?
     if ($this->Config->getApiLogHttpHeaders(false)) {
         PlentymarketsLogger::getInstance()->message('Soap:Call:Header:Request', $this->__getLastRequestHeaders());
         PlentymarketsLogger::getInstance()->message('Soap:Call:Header:Response', $this->__getLastResponseHeaders());
     }
     // Remember the timestamp for soap calls number of any kind
     if (!empty($this->soapCallsTimestampConfigKey)) {
         $this->Config->set($this->soapCallsTimestampConfigKey, time());
     }
     ++$this->numberOfCalls;
     return $Response;
 }