friendica-directory/src/classes/Pollers/Directory.php

96 lines
2.4 KiB
PHP

<?php
namespace Friendica\Directory\Pollers;
use Friendica\Directory\Utils\Network;
/**
* @author Hypolite Petovan <hypolite@mrpetovan.com>
*/
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'];
}
}