/** * @return bool */ protected function isTwitterApiAvailable() { $availableTwitterApi = false; /** @var \WeavingTheWeb\Bundle\ApiBundle\Entity\Token $token */ $token = $this->tokenRepository->refreshFreezeCondition($this->accessor->userToken, $this->logger); if (!$token->isFrozen()) { try { if (!$this->accessor->isApiRateLimitReached('/statuses/user_timeline')) { $availableTwitterApi = true; } } catch (\Exception $exception) { if ($exception->getCode() === 52) { $availableTwitterApi = true; } else { $this->tokenRepository->freezeToken($this->accessor->userToken); } } } else { /** @var \WeavingTheWeb\Bundle\ApiBundle\Entity\Token $unfrozenToken */ $unfrozenToken = $this->tokenRepository->findFirstUnfrozenToken(); if (is_null($unfrozenToken)) { $now = new \DateTime(); $this->moderator->waitFor($token->getFrozenUntil()->getTimestamp() - $now->getTimestamp(), ['{{ token }}' => substr($token->getOauthToken(), 0, '8')]); } else { $this->setupAccessor(['token' => $unfrozenToken->getOauthToken(), 'secret' => $unfrozenToken->getOauthTokenSecret()]); $availableTwitterApi = true; } } return $availableTwitterApi; }
/** * @param $endpoint * @return \API|mixed|object * @throws \WeavingTheWeb\Bundle\TwitterBundle\Exception\UnavailableResourceException */ public function contactEndpoint($endpoint) { $parameters = array(); $response = null; $tokens = $this->getTokens(); $httpClient = $this->httpClient; /** @var \WeavingTheWeb\Bundle\ApiBundle\Entity\Token $token */ $token = $this->tokenRepository->refreshFreezeCondition($tokens['oauth'], $this->logger); if ($token->isFrozen()) { $now = new \DateTime(); $this->moderator->waitFor($token->getFrozenUntil()->getTimestamp() - $now->getTimestamp(), ['{{ token }}' => substr($token->getOauthToken(), 0, '8')]); } try { if (is_null($this->authenticationHeader)) { /** @var \TwitterOAuth $connection */ $connection = new $httpClient($tokens['key'], $tokens['secret'], $tokens['oauth'], $tokens['oauth_secret']); $content = $connection->get($endpoint, $parameters); } else { $this->setupClient(); $httpClient->setHeader('Authorization', $this->authenticationHeader); $httpClient->request('GET', $endpoint); /** @var \Symfony\Component\HttpFoundation\Response $response */ $response = $httpClient->getResponse(); $encodedContent = $response->getContent(); $content = json_decode($encodedContent); } } catch (\Exception $exception) { $this->logger->error($exception->getMessage(), $exception->getTrace()); $content = (object) ['errors' => [(object) ['message' => $exception->getMessage(), 'code' => $exception->getCode()]]]; } $this->logger->info('[info] ' . $endpoint); if ($this->hasError($content)) { $errorMessage = $content->errors[0]->message; $errorCode = $content->errors[0]->code; $this->logger->error('[message] ' . $errorMessage); $this->logger->error('[code] ' . $errorCode); $this->logger->error('[token] ' . $token->getOauthToken()); $reflection = new \ReflectionClass(__NAMESPACE__ . '\\TwitterErrorAwareInterface'); $errorCodes = $reflection->getConstants(); if (in_array($errorCode, $errorCodes)) { if ($errorCode == self::ERROR_EXCEEDED_RATE_LIMIT) { $this->tokenRepository->freezeToken($token->getOauthToken()); } $this->throwException($errorMessage, $errorCode); } else { /** Freeze token and wait for 15 minutes before getting back to operation */ $this->tokenRepository->freezeToken($token->getOauthToken()); $this->moderator->waitFor(15 * 60, ['{{ token }}' => substr($token->getOauthToken(), 0, '8')]); return $this->contactEndpoint($endpoint); } } return $content; }