Skip to content

Instantly share code, notes, and snippets.

@miko007
Created October 23, 2024 12:36
Show Gist options
  • Save miko007/34f6fde8e2a772ae4f773bb12ea81df8 to your computer and use it in GitHub Desktop.
Save miko007/34f6fde8e2a772ae4f773bb12ea81df8 to your computer and use it in GitHub Desktop.
Unsplash Random Photo replacement
<?php declare(strict_types=1);
###############################################################################
# #
# Maschinendeck Unsplash wrapper #
# #
###############################################################################
/**
* This script provides a replacement for the old
* `https://source.unsplash.com/random` endpoint, which is no longer available
*
* specific search terms can be provided by the `query` GET parameter:
* https://mydomain.tld/unsplash.php?query=blue,textured
*
* @author MikO <[email protected]>
* @license MIT
* @version 1.0.0
*/
// Copyright (C) 2024 MikO <[email protected]>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// NOTE: place your "Access Key" here. you get that by registering at
// https://unsplash.com/developers and creating an application. This is
// designed to work with the "non-production" plan, as it will not exceed
// 50 requests to the API per hour due to caching.
const ACCESS_KEY = "YOUR_ACCESS_KEY";
const FILENAME = __DIR__."/latest.json";
class UnsplashClient {
private const URL = "https://api.unsplash.com";
private CurlHandle $socket;
public function __construct(string $accessKey) {
$this->socket = curl_init();
curl_setopt($this->socket, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->socket, CURLOPT_HTTPHEADER, [
"Authorization: Client-ID $accessKey"
]);
}
public function __destruct() {
curl_close($this->socket);
}
public function query(string $url) : ?object {
curl_setopt($this->socket, CURLOPT_URL, self::URL.$url);
$result = curl_exec($this->socket);
if (!$result)
return null;
$object = json_decode($result);
if (!$object)
return null;
if (isset($object->errors) && count($object->errors) > 0)
throw new ErrorException(implode(";", $object->errors));
return $object;
}
}
function error(string $message) : void {
http_response_code(500);
header("Content-type: text/plain");
echo $message;
exit(1);
}
$result = null;
$client = new UnsplashClient(ACCESS_KEY);
$lastTime = file_exists(FILENAME) ? filemtime(FILENAME) : time();
$now = time();
$differenceMinutes = intval(($now - $lastTime) / 60);
if ($differenceMinutes > 2 || !file_exists(FILENAME)) {
try {
$query = $_GET["query"] ?? "";
$result = $client->query("/photos/random?query=".$query);
} catch (ErrorException $exception) {
error($exception->getMessage());
}
file_put_contents(FILENAME, json_encode($result, JSON_PRETTY_PRINT));
} else {
$result = json_decode(file_get_contents(FILENAME));
if (!$result)
error("cached JSON file could not be decoded");
}
if (!isset($result->urls) || !isset($result->urls->regular))
error("response from unsplash is missing urls");
$imageData = file_get_contents($result->urls->regular);
if (!$imageData)
error("did not receive image data from unsplash");
// unsplash does not tell us the MIME-type of the photo, so we assume its always
// `image/png`
header("Content-type: image/png");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
echo $imageData;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment