/** * Executes an API request that have at least the following information: * * - method: string method if the SOAP function * - data: data container for the SOAP function * * @param Object $request * @return stdClass */ public function execute(Bronto_Object $request) { $tries = 0; $maxTries = $this->_options->getRetries(); $method = $request->getMethod(); $data = $request->getData(); if ($data instanceof Bronto_Object) { $data = $data->toArray(); } do { try { if (!$this->isAuthenticated()) { $this->login(); } return $this->getSoapClient()->{$method}($data); } catch (Exception $e) { $tries++; $this->_lastRequest = $request; $this->_lastException = new Bronto_Api_Exception($e->getMessage(), $e->getCode(), $e, $tries, $request); $this->_options->safeError()->filter(array($this, 'handleRetry'))->orElse(array($this, 'handleFallThrough')); } } while ($tries < $maxTries); // It should never reach here, but we'll safely terminate throw new Bronto_Api_Exception("Max attempts have been reached."); }
/** * @see parent */ public function onFlush($iterator) { $now = Mage::getSingleton('core/date')->gmtDate(); try { foreach ($iterator as $result) { $queueRow = $this->_queueEntry($result->getOriginal()->getQueueRow()); $item = $result->getItem(); if ($item->getIsError()) { $queueRow->setBrontoImported(null)->setBrontoSuppressed("{$item->getErrorCode()}: {$item->getErrorString()}"); $this->_result->incrementError(); } else { $queueRow->setBrontoImported($now)->setBrontoSuppressed(null); $this->_result->incrementSuccess(); } $queueRow->save(); $this->_result->incrementTotal(); } $this->_flushLogs($iterator->getOperation()->getApi()); } catch (InvalidArgumentException $iae) { Mage::helper($this->_helper)->writeDebug("Client error: {$iae->getMessage()}"); } catch (Exception $e) { $request = $iterator->getRequest(); $requestData = $request->getData(); $objects = $requestData[$request->getKey()]; switch ($e->getCode()) { case 107: foreach ($objects as $object) { if (is_array($object) && !$object instanceof Bronto_Object) { $object = new Bronto_Object($object); } $queueRow = $this->_queueEntry($object->getQueueRow()); try { $iterator->getOperation()->getApi()->execute(new Bronto_Object(array('method' => $request->getMethod(), 'data' => array($request->getKey() => array($object->toArray())), 'hasUpdates' => true))); $queueRow->setBrontoImported($now)->setBrontoSuppressed(null); $this->_result->incrementSuccess(); } catch (Exception $e) { $queueRow->setBrontoImported(null)->setBrontoSuppressed("Failed to process contact."); $this->_result->incrementError(); } $queueRow->save(); $this->_result->incrementTotal(); $this->_flushLogs($iterator->getOperation()->getApi()); } break; default: if ($e->getCode() > 200) { foreach ($objects as $object) { if (is_array($object) && !$object instanceof Bronto_Object) { $object = new Bronto_Object($object); } $this->_queueEntry($object->getQueueRow())->setBrontoImported(null)->setBrontoSuppressed($e->getMessage())->save(); $this->_result->incrementError(); $this->_result->incrementTotal(); } } Mage::helper($this->_helper)->writeError($e); $this->_flushLogs($iterator->getOperation()->getApi()); } } }
/** * Create a request builder with a method, uri, and options * * @param string $method * @param string $uri * @param Bronto_Object $options * @param Bronto_Resource_Proxy $curl */ public function __construct($method, $uri, $options, $curl = null) { $this->_uri = $uri; $this->_method = $method; $this->_options = new Bronto_Object($options->toArray()); if (is_null($curl)) { $curl = new Bronto_Resource_Proxy("curl_"); } $this->_curl = $curl; }
/** * @see parent * * @param Bronto_Object $object * @param string $apiToken * @param int $attempts * @return int|false */ public function store(Bronto_Object $object, $apiToken, $attempts = 0) { // Only deliveries are retried if ($object->getTransferType() == 'Delivery') { if ($this->hasId() && empty($attempts)) { $this->unsId(); } try { $this->setObject(serialize($object->withToken($apiToken)))->setAttempts($attempts)->setLastAttempt(Mage::getSingleton('core/date')->gmtDate())->save(); Mage::helper('bronto_common')->writeDebug('Storing failed delivery.'); return $this->getId(); } catch (Exception $e) { Mage::helper('bronto_common')->writeError('Failed to store delivery: ' . $e->getMessage()); return false; } } }
/** * @see parent * * @param string $name * @param array $args * @return mixed */ public function __call($name, $args) { $result = parent::__call($name, $args); if (preg_match('/(?:SoapClient|Observer|Retryer|Error)$/', $name)) { $this->_init(); } return $result; }
/** * Convenience method for adding/setting field values for contact * * @param Bronto_Object|string $fieldId * @param mixed $content * @return Bronto_Api_Model_Contact */ public function addField($fieldId, $content = null) { if (!array_key_exists('fields', $this->_data)) { $this->_set('fields', array()); } if ($fieldId instanceof Bronto_Object) { $data = $fieldId->toArray(); } else { $data = array('fieldId' => $fieldId, 'content' => $content); } $data['content'] = $this->_convert($data['fieldId'], $data['content']); if (array_key_exists($data['fieldId'], $this->_fieldIdToIndex)) { $this->_data['fields'][$this->_fieldIdToIndex[$data['fieldId']]] = $data; } else { $this->_fieldIdToIndex[$data['fieldId']] = array_push($this->_data['fields'], $data) - 1; } return $this; }
/** * @see parent * @param Bronto_Api_Exception $exception * @param Bronto_Api $api * @param Bronto_Object $request * @return boolean */ public function recover(Bronto_Api_Exception $exception, Bronto_Api $api, Bronto_Object $request) { $canRetry = $exception->getAttempts() < $api->getOptions()->getRetries(); if ($exception->isRecoverable() && $canRetry) { if ($exception->isInvalidSession()) { $api->login(); return true; } else { if ($exception->isNetworkRelated() && !$request->hasUpdates()) { // Incrementally backoff the read request $backOff = $api->getOptions()->getBackOff() * $exception->getAttempts(); sleep($backOff); return true; } } } return false; }
/** * Adds field options to the field as a chainable property * * @param Bronto_Object|string $value * @param mixed $label * @param boolean $isDefault * @return Bronto_Api_Model_Field */ public function addOption($value, $label = null, $isDefault = false) { if (!array_key_exists('options', $this->_data)) { $this->_data['options'] = array(); } if ($value instanceof Bronto_Object) { extract($value->toArray()); } if (is_bool($label)) { $isDefault = $label; $label = null; } if (is_null($label)) { $label = (string) $value; } if ($isDefault) { foreach ($this->_data['options'] as &$option) { $option['isDefault'] = false; } } $this->_data['options'][] = array('value' => $value, 'label' => $label, 'isDefault' => $isDefault); return $this; }
/** * @see parent * * @param string $rawType * @param array $data */ public function __construct($rawType, array $data = array()) { parent::__construct($data); $this->_rawType = $rawType; }
/** * @see parent * @param string $name * @param array $arguments * @return mixed */ public function __call($name, $arguments) { if (in_array($name, $this->_acceptablePrefixes)) { return $this->push($arguments); } else { if (preg_match("/^isFullOf{$this->_operation->getPluralizedType()}/", $name)) { $camelized = $this->_resolvedKey; if (!array_key_exists($camelized, $this->_data)) { return false; } return count($this->_data[$camelized]) >= $this->_limit; } else { try { parent::__call($name, $arguments); } catch (BadMethodCallException $bme) { throw new BadMethodCallException("For {$this->_method}, supported chains are: " . implode(', ', $this->_acceptablePrefixes), 0, $bme); } } } }
/** * @see parent * * @param string $name * @param array $arguments * @return mixed */ public function __call($name, $arguments) { list($prefix, $camelized) = $this->_camelizedValue($name); if (array_key_exists($camelized, $this->_requestFields)) { return parent::__call($name, $arguments); } else { $filter = $this->_data['filter']; $return = $filter->__call($name, $arguments); if ($return == $filter) { return $this; } else { return $return; } } }
/** * Magic invocation is used in field names where filter operators * are applicable. * * @param string $name * @param array $arguments * @return Bronto_Api_Read * @throws LogicException */ public function __call($name, $arguments) { switch ($name) { case 'equalTo': case 'notEqualTo': case 'startsWith': case 'endsWith': case 'doesNotStartWith': case 'doesNotEndWith': case 'greaterThan': case 'lessThan': case 'contains': case 'doesNotContain': case 'sameYear': case 'notSameYear': case 'sameDay': case 'notSameDay': case 'before': case 'after': case 'beforeOrSameDay': case 'afterOrSameDay': $this->_protectStatement($name); if (!array_key_exists($this->_currentField, $this->_data)) { $this->_data[$this->_currentField] = array(); } array_push($this->_data[$this->_currentField], array('operator' => ucfirst($name), 'value' => $arguments[0])); return $this->close(); case 'in': $this->_protectStatement($name); $value = is_array($arguments[0]) ? $arguments[0] : $arguments; return $this->_set('type', 'OR')->_set($this->_currentField, $value)->close(); case 'is': $this->_protectStatement($name); if (is_array($arguments[0])) { $value = $arguments[0]; } else { if (count($arguments) > 1) { $value = $arguments; } else { $value = array($arguments[0]); } } return $this->_set($this->_currentField, $value)->close(); default: return parent::__call($name, $arguments); } }