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 * Cards
*/ */
$('.wishlist-cards').html(wishlists[wishlistIndex].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 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; $info = null;
$identifier = md5($url);
$filepath = $this->directory . '/' . $identifier;
$maxAge = 2592000; // 30 days $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) { if ($this->exists() && $age <= $maxAge) {
$info = json_decode(file_get_contents($filepath)); $info = json_decode(file_get_contents($this->filepath));
} else { } else {
/** /**
* @link https://github.com/oscarotero/Embed * @link https://github.com/oscarotero/Embed
@ -52,42 +55,51 @@ class EmbedCache
$info_simplified->providerUrl = ''; $info_simplified->providerUrl = '';
$info_simplified->publishedTime = ''; $info_simplified->publishedTime = '';
$info_simplified->redirect = ''; $info_simplified->redirect = '';
$info_simplified->title = $url; $info_simplified->title = $this->url;
$info_simplified->url = $url; $info_simplified->url = $this->url;
/* if ($generateCache) {
try { try {
$info = $embed->get($url); $info = $embed->get($this->url);
$info_simplified->authorName = (string) $info->authorName; $info_simplified->authorName = (string) $info->authorName;
$info_simplified->authorUrl = (string) $info->authorUrl; $info_simplified->authorUrl = (string) $info->authorUrl;
$info_simplified->cms = (string) $info->cms; $info_simplified->cms = (string) $info->cms;
$info_simplified->code = (string) $info->code; $info_simplified->code = (string) $info->code;
$info_simplified->description = (string) $info->description; $info_simplified->description = (string) $info->description;
$info_simplified->favicon = (string) $info->favicon; $info_simplified->favicon = (string) $info->favicon;
$info_simplified->feeds = (array) $info->feeds; $info_simplified->feeds = (array) $info->feeds;
$info_simplified->icon = (string) $info->icon; $info_simplified->icon = (string) $info->icon;
$info_simplified->image = (string) $info->image; $info_simplified->image = (string) $info->image;
$info_simplified->keywords = (array) $info->keywords; $info_simplified->keywords = (array) $info->keywords;
$info_simplified->language = (string) $info->language; $info_simplified->language = (string) $info->language;
$info_simplified->languages = (array) $info->languages; $info_simplified->languages = (array) $info->languages;
$info_simplified->license = (string) $info->license; $info_simplified->license = (string) $info->license;
$info_simplified->providerName = (string) $info->providerName; $info_simplified->providerName = (string) $info->providerName;
$info_simplified->providerUrl = (string) $info->providerUrl; $info_simplified->providerUrl = (string) $info->providerUrl;
$info_simplified->publishedTime = $info->publishedTime ? $info->publishedTime->format('d.m.Y') : ''; $info_simplified->publishedTime = $info->publishedTime ? $info->publishedTime->format('d.m.Y') : '';
$info_simplified->redirect = (string) $info->redirect; $info_simplified->redirect = (string) $info->redirect;
$info_simplified->title = (string) $info->title; $info_simplified->title = (string) $info->title;
$info_simplified->url = (string) $info->url; $info_simplified->url = (string) $info->url;
} catch (\Throwable $ex) { } catch (\Throwable $ex) {
$info_simplified->title = $ex->getMessage(); $generateCache = false;
$info_simplified->title = $ex->getMessage();
}
} }
*/
$info = $info_simplified; $info = $info_simplified;
// file_put_contents($filepath, json_encode($info)); if ($generateCache) {
file_put_contents($this->filepath, json_encode($info));
}
} }
return $info; return $info;
} }
public function exists(): bool
{
return file_exists($this->filepath);
}
} }

View file

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