*/ class Directory { /** * @var \GuzzleHttp\ClientInterface */ private $http; /** * @var \Friendica\Directory\Models\ProfilePollQueue */ private $profilePollQueueModel; /** * @var \Psr\Log\LoggerInterface */ private $logger; /** * @var array */ private $settings = [ 'probe_timeout' => 5 ]; public function __construct( \GuzzleHttp\ClientInterface $http, \Friendica\Directory\Models\ProfilePollQueue $profilePollQueueModel, \Psr\Log\LoggerInterface $logger, array $settings) { $this->http = $http; $this->profilePollQueueModel = $profilePollQueueModel; $this->logger = $logger; $this->settings = array_merge($this->settings, $settings); } /** * @param string $directory_url * @param int|null $last_polled * @return bool */ public function __invoke(string $directory_url, int $last_polled = null): bool { $this->logger->info('Pull from directory with URL: ' . $directory_url); try { $host = parse_url($directory_url, PHP_URL_HOST); if (!$host) { throw new \Exception('Missing hostname in polled directory URL: ' . $directory_url); } if (!\Friendica\Directory\Utils\Network::isPublicHost($host)) { throw new \Exception('Private/reserved IP in polled directory URL: ' . $directory_url); } $profiles = $this->getPullResult($directory_url, $last_polled); foreach ($profiles as $profile_url) { $result = $this->profilePollQueueModel->add($profile_url); $this->logger->debug('Profile queue add URL: ' . $profile_url . ' - ' . $result); } $this->logger->info('Successfully pulled ' . count($profiles) . ' profiles'); return true; } catch (\Exception $e) { $this->logger->warning($e->getMessage()); return false; } } private function getPullResult(string $directory_url, ?int $last_polled = null): array { $path = '/sync/pull/all'; if ($last_polled) { $path = '/sync/pull/since/' . $last_polled; } $pull_data = $this->http->get($directory_url . $path, ['timeout' => max($this->settings['probe_timeout'], 1)])->getBody()->getContents(); $data = json_decode($pull_data, true); if (!isset($data['results']) || !is_array($data['results'])) { throw new \Exception('Invalid directory pull data for directory with URL: ' . $directory_url . $path); } return $data['results']; } }