Elgg  Version 4.3
ImageFetcherService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Assets;
4 
6 use Elgg\Config;
12 
19 
20  protected const CACHE_PREFIX = 'image_fetcher_';
21 
25  protected $cache;
26 
30  protected $client;
31 
35  protected $config;
36 
40  protected $session;
41 
50  $this->config = $config;
51  $this->cache = $cache;
52  $this->session = $session;
53 
54  $proxy_config = $this->config->proxy ?? [];
55 
56  $options = [
57  RequestOptions::TIMEOUT => 5,
58  RequestOptions::HTTP_ERRORS => false,
59  RequestOptions::VERIFY => (bool) elgg_extract('verify_ssl', $proxy_config, true),
60  ];
61 
62  $host = elgg_extract('host', $proxy_config);
63  if (!empty($host)) {
64  $port = (int) elgg_extract('port', $proxy_config);
65  if ($port > 0) {
66  $host = rtrim($host, ':') . ":{$port}";
67  }
68 
69  $options[RequestOptions::PROXY] = $host;
70  }
71 
72  $this->client = new Client($options);
73  }
74 
87  public function getImage(string $image_url) {
88  if (empty($image_url)) {
89  throw new InvalidArgumentException('a non-empty image url is required for image fetching');
90  }
91 
92  $image_url = htmlspecialchars_decode($image_url);
93  $image_url = elgg_normalize_url($image_url);
94 
95  $cache = $this->loadFromCache($image_url);
96  if (!empty($cache)) {
97  return $cache;
98  }
99 
101  $options = [];
102 
103  if (stripos($image_url, $site->getURL()) === 0) {
104  // internal url, can use session cookie
105  $cookie_config = $this->config->getCookieConfig();
106 
107  $cookies = [
108  $cookie_config['session']['name'] => $this->session->getID(),
109  ];
110 
111  $domain = $cookie_config['session']['domain'] ?: $site->getDomain();
112 
113  $cookiejar = CookieJar::fromArray($cookies, $domain);
114  $options[RequestOptions::COOKIES] = $cookiejar;
115  }
116 
117  try {
118  $response = $this->client->get($image_url, $options);
119  } catch (TransferException $e) {
120  // this shouldn't happen, but just in case
121  return false;
122  }
123 
124  if ($response->getStatusCode() !== ELGG_HTTP_OK) {
125  return false;
126  }
127 
128  $result = [
129  'data' => $response->getBody()->getContents(),
130  'content-type' => $response->getHeaderLine('content-type') ?: 'application/octet-stream',
131  'name' => basename($image_url),
132  ];
133 
134  $this->saveToCache($image_url, $result);
135 
136  return $result;
137  }
138 
146  protected function loadFromCache(string $image_url): array {
147  $cache = $this->cache->load(self::CACHE_PREFIX . md5($image_url));
148 
149  return is_array($cache) ? $cache : [];
150  }
151 
160  protected function saveToCache(string $image_url, array $data): bool {
161  return $this->cache->save(self::CACHE_PREFIX . md5($image_url), $data);
162  }
163 }
Exception thrown if an argument is not of the expected type.
__construct(Config $config, SystemCache $cache,\ElggSession $session)
Constructor.
elgg_normalize_url($url)
Definition: output.php:153
const ELGG_HTTP_OK
Definition: constants.php:60
getImage(string $image_url)
Get an image.
if(elgg_trigger_plugin_hook('usersettings:save', 'user', $hooks_params, true)) foreach($request->validation() ->all() as $item) $data
Definition: save.php:53
$site
Definition: icons.php:5
$options
Elgg admin footer.
Definition: footer.php:6
loadFromCache(string $image_url)
Load an image url from cache.
Fetch external images server side.
saveToCache(string $image_url, array $data)
Save image data in system cache for easy reuse.
elgg_get_site_entity()
Get the current site entity.
Definition: entities.php:99
elgg_extract($key, $array, $default=null, $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:547
$domain
Definition: layout.php:32