Improve caching

This commit is contained in:
Jay Trees 2022-02-23 13:14:50 +01:00
parent 3a239019e3
commit 71783a8910
4 changed files with 237 additions and 51 deletions

37
src/api/cache.php Normal file
View file

@ -0,0 +1,37 @@
<?php
/**
* Generate cache for product
*
* @author Jay Trees <github.jay@grandel.anonaddy.me>
*/
use wishthis\EmbedCache;
$api = true;
$response = array(
'success' => false,
);
require '../../index.php';
switch ($_SERVER['REQUEST_METHOD']) {
case 'GET':
$cache = new EmbedCache($_GET['url']);
$info = $cache->get(true);
if ($info->url) {
$database->query('UPDATE `products`
SET `url` = "' . $info->url . '"
WHERE `id` = ' . $_GET['product_id'] . '
;');
}
$response['success'] = true;
$response['data'] = $info;
break;
}
header('Content-type: application/json; charset=utf-8');
echo json_encode($response);
die();

View file

@ -52,6 +52,136 @@ $(function() {
* Cards
*/
$('.wishlist-cards').html(wishlists[wishlistIndex].cards);
/**
* Generate cache
*/
var timerInterval = 200;
var timerCache = setTimeout(
function generateCache() {
var cards = $('.ui.card[data-cache="false"]');
cards.each(function(index, card) {
card = $(card);
var href = card.find('.content [href]').prop('href');
var product_id = card.data('id');
card.addClass('loading');
fetch('/src/api/cache.php?product_id=' + product_id + '&url=' + href, {
method: 'GET'
})
.then(response => response.json())
.then(response => {
if (response.success) {
var info = response.data;
/**
* Elements
*/
var elementImage = card.children('.image');
var elementContent = card.children('.content').first();
var elementDetails = card.children('.extra.content.details');
var elementButtons = card.children('.extra.content.buttons');
/**
* Image
*/
if (info.image) {
if (!elementImage.length) {
card.prepend(
'<div class="image">' +
'<img src="' + info.image + '">' +
'</div>'
);
}
}
/**
* Header
*/
var elementContentHeader = elementContent.children('.header');
var elementContentHeaderTitle = elementContentHeader.children('a');
/** Favicon */
if (info.favicon) {
elementContentHeader.prepend(
'<img src="' + info.favicon + '">'
);
}
/** Title */
if (info.title) {
elementContentHeaderTitle.text(info.title);
}
/**
* Meta
*/
var elementContentMeta = elementContent.children('.meta');
if (info.keywords.length) {
if (!elementContentMeta.length) {
elementContent.append(
'<div class="meta">' + info.keywords.join(', ') + '</div>'
);
}
}
/**
* Description
*/
var elementContentDescription = elementContent.children('.description');
if (info.description) {
if (!elementContentDescription.length) {
elementContent.append(
'<div class="description">' + info.description + '</div>'
);
}
}
/**
* Details
*/
if (info.publishedTime || info.providerName) {
if (!elementDetails.length) {
elementButtons.before().append(
'<div class="extra content details"></div>'
);
if (info.publishedTime) {
elementContent.children('.extra.content.details').append(
'<span class="right floated">' + info.publishedTime + '</span>'
);
}
if (info.providerName) {
elementContent.children('.extra.content.details').append(
info.providerName
);
}
}
}
/**
* Finish
*/
card.attr('data-cache', true);
card.removeClass('loading');
if (cards.length > 0) {
setTimeout(generateCache, timerInterval);
}
}
});
return false;
});
},
timerInterval
);
});
/**

View file

@ -12,22 +12,25 @@ namespace wishthis;
class EmbedCache
{
private $directory = ROOT . '/src/cache';
private string $directory = ROOT . '/src/cache';
public function __construct()
private string $identifier;
private string $filepath;
public function __construct(private string $url)
{
$this->identifier = md5($this->url);
$this->filepath = $this->directory . '/' . $this->identifier;
}
public function get(string $url): mixed
public function get(bool $generateCache = true): mixed
{
$info = null;
$identifier = md5($url);
$filepath = $this->directory . '/' . $identifier;
$maxAge = 2592000; // 30 days
$age = file_exists($filepath) ? time() - filemtime($filepath) : $maxAge;
$age = file_exists($this->filepath) ? time() - filemtime($this->filepath) : $maxAge;
if (file_exists($filepath) && $age <= $maxAge) {
$info = json_decode(file_get_contents($filepath));
if ($this->exists() && $age <= $maxAge) {
$info = json_decode(file_get_contents($this->filepath));
} else {
/**
* @link https://github.com/oscarotero/Embed
@ -52,12 +55,12 @@ class EmbedCache
$info_simplified->providerUrl = '';
$info_simplified->publishedTime = '';
$info_simplified->redirect = '';
$info_simplified->title = $url;
$info_simplified->url = $url;
$info_simplified->title = $this->url;
$info_simplified->url = $this->url;
/*
if ($generateCache) {
try {
$info = $embed->get($url);
$info = $embed->get($this->url);
$info_simplified->authorName = (string) $info->authorName;
$info_simplified->authorUrl = (string) $info->authorUrl;
@ -79,15 +82,24 @@ class EmbedCache
$info_simplified->title = (string) $info->title;
$info_simplified->url = (string) $info->url;
} catch (\Throwable $ex) {
$generateCache = false;
$info_simplified->title = $ex->getMessage();
}
*/
}
$info = $info_simplified;
// file_put_contents($filepath, json_encode($info));
if ($generateCache) {
file_put_contents($this->filepath, json_encode($info));
}
}
return $info;
}
public function exists(): bool
{
return file_exists($this->filepath);
}
}

View file

@ -80,11 +80,12 @@ class Wishlist
if (!empty($products)) { ?>
<div class="ui stackable three column grid container">
<?php foreach ($products as $product) {
$cache = new EmbedCache();
$info = $cache->get($product['url']);
$cache = new EmbedCache($product['url']);
$info = $cache->get(false);
$exists = $cache->exists() ? 'true' : 'false';
?>
<div class="column">
<div class="ui fluid card stretch" data-id="<?= $product['id'] ?>">
<div class="ui fluid card stretch" data-id="<?= $product['id'] ?>" data-cache="<?= $exists ?>">
<?php if ($info->image) { ?>
<div class="image">
@ -119,20 +120,26 @@ class Wishlist
</div>
<?php } ?>
</div>
<div class="extra content">
<?php if ($info->publishedTime || $info->providerName) { ?>
<div class="extra content details">
<?php if ($info->publishedTime) { ?>
<span class="right floated">
<?= $info->publishedTime ?>
</span>
<?php } ?>
<?php if ($info->providerName) { ?>
<?= $info->providerName ?>
<?php } ?>
</div>
<div class="extra content">
<?php } ?>
<div class="extra content buttons">
<?php if ($info->url) { ?>
<a class="ui tiny button" href="<?= $info->url ?>" target="_blank">View</a>
<?php } ?>
<?php if (isset($_SESSION['user']) && $this->data['user'] === $_SESSION['user']['id']) { ?>
<a class="ui tiny red button delete">Delete</a>
<?php } else { ?>