mirror of
https://github.com/sorenpeter/timeline.git
synced 2025-12-15 10:57:01 +00:00
Merge with gallery
This commit is contained in:
commit
3c3f1d2f38
23 changed files with 1164 additions and 640 deletions
|
|
@ -35,10 +35,11 @@ $routes = [
|
|||
'/login' => 'login.php',
|
||||
'/logout' => 'logout.php',
|
||||
'/profile' => 'profile.php',
|
||||
'/profile' => 'profile.php',
|
||||
'/gallery' => 'gallery.php',
|
||||
//'/profile/([a-zA-Z0-9_-]+)' => 'profile.php',
|
||||
'/conv/([a-zA-Z0-9]{7})' => 'conv.php', // matches only twtHash of exactly 7 alphanumeric characters
|
||||
'/post/([a-zA-Z0-9]{7})' => 'post.php', // matches only twtHash of exactly 7 alphanumeric characters
|
||||
//'/thumb' => 'thumb.php',
|
||||
'/webmention' => 'webmention_endpoint.php',
|
||||
];
|
||||
|
||||
|
|
|
|||
297
libs/Cropper.php
Normal file
297
libs/Cropper.php
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
<?php
|
||||
|
||||
namespace CoffeeCode\Cropper;
|
||||
|
||||
use Exception;
|
||||
use WebPConvert\Convert\Exceptions\ConversionFailedException;
|
||||
use WebPConvert\WebPConvert;
|
||||
|
||||
/**
|
||||
* Class CoffeeCode Cropper
|
||||
*
|
||||
* @author Robson V. Leite <https://github.com/robsonvleite>
|
||||
* @package CoffeeCode\Cropper
|
||||
*/
|
||||
class Cropper
|
||||
{
|
||||
/** @var string */
|
||||
private string $cachePath;
|
||||
|
||||
/** @var string */
|
||||
private string $imagePath;
|
||||
|
||||
/** @var string */
|
||||
private string $imageName;
|
||||
|
||||
/** @var string */
|
||||
private string $imageMime;
|
||||
|
||||
/** @var int */
|
||||
private int $quality;
|
||||
|
||||
/** @var int */
|
||||
private int $compressor;
|
||||
|
||||
/**@var bool */
|
||||
private bool $webP;
|
||||
|
||||
/**
|
||||
* Allow jpg and png to thumb and cache generate
|
||||
* @var array allowed media types
|
||||
*/
|
||||
private static array $allowedExt = ['image/jpeg', "image/png"];
|
||||
|
||||
/** @var ConversionFailedException */
|
||||
public ConversionFailedException $exception;
|
||||
|
||||
/**
|
||||
* Cropper constructor.
|
||||
* compressor must be 1-9
|
||||
* quality must be 1-100
|
||||
*
|
||||
* @param string $cachePath
|
||||
* @param int $quality
|
||||
* @param int $compressor
|
||||
* @param bool $webP
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(string $cachePath, int $quality = 75, int $compressor = 5, bool $webP = false)
|
||||
{
|
||||
$this->cachePath = $cachePath;
|
||||
$this->quality = $quality;
|
||||
$this->compressor = $compressor;
|
||||
$this->webP = $webP;
|
||||
|
||||
if (!file_exists($this->cachePath) || !is_dir($this->cachePath)) {
|
||||
if (!mkdir($this->cachePath, 0755, true)) {
|
||||
throw new Exception("Could not create cache folder");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an thumb image
|
||||
*
|
||||
* @param string $imagePath
|
||||
* @param int $width
|
||||
* @param int|null $height
|
||||
* @return null|string
|
||||
*/
|
||||
public function make(string $imagePath, int $width, int $height = null): ?string
|
||||
{
|
||||
if (!file_exists($imagePath)) {
|
||||
return "Image not found";
|
||||
}
|
||||
|
||||
$this->imagePath = $imagePath;
|
||||
$this->imageName = $this->name($this->imagePath, $width, $height);
|
||||
$this->imageMime = mime_content_type($this->imagePath);
|
||||
|
||||
if (!in_array($this->imageMime, self::$allowedExt)) {
|
||||
return "Not a valid JPG or PNG image";
|
||||
}
|
||||
|
||||
return $this->image($width, $height);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $width
|
||||
* @param int|null $height
|
||||
* @return string|null
|
||||
*/
|
||||
private function image(int $width, int $height = null): ?string
|
||||
{
|
||||
$imageWebP = "{$this->cachePath}/{$this->imageName}.webp";
|
||||
$imageExt = "{$this->cachePath}/{$this->imageName}." . pathinfo($this->imagePath)['extension'];
|
||||
|
||||
if ($this->webP && file_exists($imageWebP) && is_file($imageWebP)) {
|
||||
return $imageWebP;
|
||||
}
|
||||
|
||||
if (file_exists($imageExt) && is_file($imageExt)) {
|
||||
return $imageExt;
|
||||
}
|
||||
|
||||
return $this->imageCache($width, $height);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param int|null $width
|
||||
* @param int|null $height
|
||||
* @return string
|
||||
*/
|
||||
protected function name(string $name, int $width = null, int $height = null): string
|
||||
{
|
||||
$filterName = mb_convert_encoding(htmlspecialchars(mb_strtolower(pathinfo($name)["filename"])), 'ISO-8859-1',
|
||||
'UTF-8');
|
||||
$formats = mb_convert_encoding('ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜüÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿRr"!@#$%&*()_-+={[}]/?;:.,\\\'<>°ºª',
|
||||
'ISO-8859-1', 'UTF-8');
|
||||
$replace = 'aaaaaaaceeeeiiiidnoooooouuuuuybsaaaaaaaceeeeiiiidnoooooouuuyybyrr ';
|
||||
$trimName = trim(strtr($filterName, $formats, $replace));
|
||||
$name = str_replace(["-----", "----", "---", "--"], "-", str_replace(" ", "-", $trimName));
|
||||
|
||||
$hash = $this->hash($this->imagePath);
|
||||
$widthName = ($width ? "-{$width}" : "");
|
||||
$heightName = ($height ? "x{$height}" : "");
|
||||
|
||||
return "{$name}{$widthName}{$heightName}-{$hash}";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
protected function hash(string $path): string
|
||||
{
|
||||
return hash("crc32", pathinfo($path)['basename']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cache
|
||||
*
|
||||
* @param string|null $imagePath
|
||||
* @example $t->flush("images/image.jpg"); clear image name and variations size
|
||||
* @example $t->flush(); clear all image cache folder
|
||||
*/
|
||||
public function flush(string $imagePath = null): void
|
||||
{
|
||||
foreach (scandir($this->cachePath) as $file) {
|
||||
$file = "{$this->cachePath}/{$file}";
|
||||
if ($imagePath && strpos($file, $this->hash($imagePath))) {
|
||||
$this->imageDestroy($file);
|
||||
} elseif (!$imagePath) {
|
||||
$this->imageDestroy($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $width
|
||||
* @param int|null $height
|
||||
* @return null|string
|
||||
*/
|
||||
private function imageCache(int $width, int $height = null): ?string
|
||||
{
|
||||
list($src_w, $src_h) = getimagesize($this->imagePath);
|
||||
$height = ($height ?? ($width * $src_h) / $src_w);
|
||||
|
||||
$src_x = 0;
|
||||
$src_y = 0;
|
||||
|
||||
$cmp_x = $src_w / $width;
|
||||
$cmp_y = $src_h / $height;
|
||||
|
||||
if ($cmp_x > $cmp_y) {
|
||||
$src_x = round(($src_w - ($src_w / $cmp_x * $cmp_y)) / 2);
|
||||
$src_w = round($src_w / $cmp_x * $cmp_y);
|
||||
} elseif ($cmp_y > $cmp_x) {
|
||||
$src_y = round(($src_h - ($src_h / $cmp_y * $cmp_x)) / 2);
|
||||
$src_h = round($src_h / $cmp_y * $cmp_x);
|
||||
}
|
||||
|
||||
$height = (int)$height;
|
||||
$src_x = (int)$src_x;
|
||||
$src_y = (int)$src_y;
|
||||
$src_w = (int)$src_w;
|
||||
$src_h = (int)$src_h;
|
||||
|
||||
if ($this->imageMime == "image/jpeg") {
|
||||
return $this->fromJpg($width, $height, $src_x, $src_y, $src_w, $src_h);
|
||||
}
|
||||
|
||||
if ($this->imageMime == "image/png") {
|
||||
return $this->fromPng($width, $height, $src_x, $src_y, $src_w, $src_h);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $imagePatch
|
||||
*/
|
||||
private function imageDestroy(string $imagePatch): void
|
||||
{
|
||||
if (file_exists($imagePatch) && is_file($imagePatch)) {
|
||||
unlink($imagePatch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
* @param int $src_x
|
||||
* @param int $src_y
|
||||
* @param int $src_w
|
||||
* @param int $src_h
|
||||
* @return string
|
||||
*/
|
||||
private function fromJpg(int $width, int $height, int $src_x, int $src_y, int $src_w, int $src_h): string
|
||||
{
|
||||
$thumb = imagecreatetruecolor($width, $height);
|
||||
$source = imagecreatefromjpeg($this->imagePath);
|
||||
|
||||
imagecopyresampled($thumb, $source, 0, 0, $src_x, $src_y, $width, $height, $src_w, $src_h);
|
||||
imagejpeg($thumb, "{$this->cachePath}/{$this->imageName}.jpg", $this->quality);
|
||||
|
||||
imagedestroy($thumb);
|
||||
imagedestroy($source);
|
||||
|
||||
if ($this->webP) {
|
||||
return $this->toWebP("{$this->cachePath}/{$this->imageName}.jpg");
|
||||
}
|
||||
|
||||
return "{$this->cachePath}/{$this->imageName}.jpg";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
* @param int $src_x
|
||||
* @param int $src_y
|
||||
* @param int $src_w
|
||||
* @param int $src_h
|
||||
* @return string
|
||||
*/
|
||||
private function fromPng(int $width, int $height, int $src_x, int $src_y, int $src_w, int $src_h): string
|
||||
{
|
||||
$thumb = imagecreatetruecolor($width, $height);
|
||||
$source = imagecreatefrompng($this->imagePath);
|
||||
|
||||
imagealphablending($thumb, false);
|
||||
imagesavealpha($thumb, true);
|
||||
imagecopyresampled($thumb, $source, 0, 0, $src_x, $src_y, $width, $height, $src_w, $src_h);
|
||||
imagepng($thumb, "{$this->cachePath}/{$this->imageName}.png", $this->compressor);
|
||||
|
||||
imagedestroy($thumb);
|
||||
imagedestroy($source);
|
||||
|
||||
if ($this->webP) {
|
||||
return $this->toWebP("{$this->cachePath}/{$this->imageName}.png");
|
||||
}
|
||||
|
||||
return "{$this->cachePath}/{$this->imageName}.png";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $image
|
||||
* @param bool $unlinkImage
|
||||
* @return string
|
||||
*/
|
||||
public function toWebP(string $image, $unlinkImage = true): string
|
||||
{
|
||||
try {
|
||||
$webPConverted = pathinfo($image)["dirname"] . "/" . pathinfo($image)["filename"] . ".webp";
|
||||
WebPConvert::convert($image, $webPConverted, ["default-quality" => $this->quality]);
|
||||
|
||||
if ($unlinkImage) {
|
||||
unlink($image);
|
||||
}
|
||||
|
||||
return $webPConverted;
|
||||
} catch (ConversionFailedException $exception) {
|
||||
$this->exception = $exception;
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -115,6 +115,7 @@ class Slimdown {
|
|||
// Substitute _ and * in links so they don't break the URLs
|
||||
$link = str_replace (['_', '*'], ['{^^^}', '{~~~}'], $link);
|
||||
return sprintf ('<img src=\'%s\' alt=\'%s\' />', $link, $text);
|
||||
//return sprintf ('<img src=\'/thumb?image=%s\' alt=\'%s\' />', $link, $text); // added support for thumbnail generation on the fly
|
||||
}
|
||||
|
||||
private static function fix_link ($regs) {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,41 @@
|
|||
/* === SimpleCSS overwrites === */
|
||||
:root, ::backdrop {
|
||||
|
||||
/* Default (light) theme */
|
||||
--sans-font: -apple-system,BlinkMacSystemFont,"Avenir Next",Avenir,"Nimbus Sans L",Roboto,"Noto Sans","Segoe UI",Arial,Helvetica,"Helvetica Neue",sans-serif;
|
||||
--mono-font: Consolas,Menlo,Monaco,"Andale Mono","Ubuntu Mono",monospace;
|
||||
--standard-border-radius: 0.5rem;
|
||||
--bg: #fff;
|
||||
--accent-bg: #f5f7ff;
|
||||
--text: #212121;
|
||||
--text-light: #585858;
|
||||
--border: #d8dae1; /*#898EA4;*/
|
||||
--accent: #0d47a1;
|
||||
--code: #d81b60;
|
||||
--preformatted: #444;
|
||||
--marked: #ffdd33;
|
||||
--disabled: #efefef;
|
||||
}
|
||||
|
||||
::backdrop, :root {
|
||||
--sans-font: -apple-system,BlinkMacSystemFont,"Avenir Next",Avenir,"Nimbus Sans L",Roboto,"Noto Sans","Segoe UI",Arial,Helvetica,"Helvetica Neue",sans-serif;
|
||||
--mono-font: Consolas,Menlo,Monaco,"Andale Mono","Ubuntu Mono",monospace;
|
||||
--standard-border-radius: 0.5rem;
|
||||
--bg: #fff;
|
||||
--accent-bg: #f5f7ff;
|
||||
--text: #212121;
|
||||
--text-light: #585858;
|
||||
--border: #d8dae1; /*#898EA4;*/
|
||||
--accent: #0d47a1;
|
||||
--code: #d81b60;
|
||||
--preformatted: #444;
|
||||
--marked: #ffdd33;
|
||||
--disabled: #efefef;
|
||||
/* Dark theme */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root,
|
||||
::backdrop {
|
||||
color-scheme: dark;
|
||||
--bg: #212121;
|
||||
--accent-bg: #2b2b2b;
|
||||
--text: #dcdcdc;
|
||||
--text-light: #ababab;
|
||||
--accent: #ffb300;
|
||||
--code: #f06292;
|
||||
--preformatted: #ccc;
|
||||
--disabled: #111;
|
||||
}
|
||||
/* Add a bit of transparency so light media isn't so glaring in dark mode */
|
||||
img,
|
||||
video {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
body > header {
|
||||
|
|
@ -117,6 +139,7 @@ img {
|
|||
max-width: 100%;
|
||||
height: auto;
|
||||
border-radius: 0.25rem;
|
||||
border: thin solid var(--border);
|
||||
}
|
||||
|
||||
img.avatar {
|
||||
|
|
@ -183,10 +206,6 @@ article .twt-msg {
|
|||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
article .twt-msg a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
article .twt-msg > blockquote {
|
||||
margin: 0;
|
||||
border-left: thick solid grey;
|
||||
|
|
@ -217,9 +236,6 @@ article small a:visited {
|
|||
|
||||
}
|
||||
|
||||
article small a:hover {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
/* === New Post Form === */
|
||||
|
||||
|
|
@ -238,11 +254,14 @@ nav.pagnation {
|
|||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
|
||||
/* === REFRESH === */
|
||||
|
||||
#refreshInfo {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#refreshInfo {
|
||||
display: block;
|
||||
text-align: center:
|
||||
}
|
||||
|
||||
|
|
@ -253,8 +272,31 @@ nav.pagnation {
|
|||
float: right;
|
||||
}
|
||||
|
||||
/* == Gallery ===================== */
|
||||
|
||||
.gallery {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto ;
|
||||
display: grid;
|
||||
grid-gap: 0.75rem;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
/*grid-auto-rows: 225px;*/
|
||||
/*grid-auto-flow: dense;*/
|
||||
}
|
||||
|
||||
.gallery a img {
|
||||
/* https://web.dev/aspect-ratio/ */
|
||||
aspect-ratio: 1 / 1;
|
||||
width: 100%;
|
||||
/*height: 100%;*/
|
||||
object-fit: cover;
|
||||
/*background-color: var(--border-color);*/
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
|
||||
/* === FOOTER === */
|
||||
|
||||
footer {
|
||||
border-top: thin solid grey;
|
||||
margin-top: 1rem;
|
||||
|
|
|
|||
459
libs/twtxt.php
459
libs/twtxt.php
|
|
@ -1,875 +1,452 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
|
||||
$config = parse_ini_file('private/config.ini');
|
||||
|
||||
|
||||
|
||||
if ($config['debug_mode']) {
|
||||
|
||||
ini_set('display_errors', '1');
|
||||
|
||||
ini_set('display_startup_errors', '1');
|
||||
|
||||
error_reporting(E_ALL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class TwtxtFile {
|
||||
|
||||
public $mainURL = ''; // First found URL
|
||||
|
||||
public $URLs = [];
|
||||
|
||||
public $nick = '';
|
||||
|
||||
public $avatar = '';
|
||||
|
||||
public $emoji = '';
|
||||
|
||||
public $description = '';
|
||||
|
||||
public $lang = 'en'; // Default language
|
||||
|
||||
public $links = [];
|
||||
|
||||
public $following = [];
|
||||
|
||||
public $twts = [];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Twt {
|
||||
|
||||
public $originalTwtStr;
|
||||
|
||||
public $hash;
|
||||
|
||||
public $fullDate;
|
||||
|
||||
public $displayDate;
|
||||
|
||||
public $content;
|
||||
|
||||
public $replyToHash;
|
||||
|
||||
public $mentions;
|
||||
|
||||
public $avatar;
|
||||
|
||||
public $emoji;
|
||||
|
||||
public $nick;
|
||||
|
||||
public $mainURL;
|
||||
|
||||
public $images;
|
||||
}
|
||||
|
||||
|
||||
|
||||
# https://stackoverflow.com/a/39360281/13173382
|
||||
|
||||
# Confirm that this temorary fix is not skipping something
|
||||
|
||||
/*
|
||||
|
||||
stream_context_set_default([
|
||||
|
||||
'ssl' => [
|
||||
|
||||
'peer_name' => 'generic-server',
|
||||
|
||||
'verify_peer' => FALSE,
|
||||
|
||||
'verify_peer_name' => FALSE,
|
||||
|
||||
'allow_self_signed' => TRUE
|
||||
|
||||
]
|
||||
|
||||
]
|
||||
|
||||
);
|
||||
|
||||
curl_setopt($curl, CURLOPT_SSLVERSION, 4);
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
* The function searches for a key-value pair in a string and returns the value if found.
|
||||
|
||||
*
|
||||
|
||||
* @param keyToFind The key we want to find in the string.
|
||||
|
||||
* @param string The string in which to search for the key-value pair.
|
||||
|
||||
*
|
||||
|
||||
* @return the value of the key that matches the given keyToFind in the given string. If a match is
|
||||
|
||||
* found, the function returns the value of the key as a string after trimming any whitespace. If no
|
||||
|
||||
* match is found, the function returns null.
|
||||
|
||||
*/
|
||||
|
||||
function getSingleParameter($keyToFind, $string) {
|
||||
|
||||
if (!str_contains($string, $keyToFind)) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$pattern = '/\s*' . $keyToFind . '\s*=\s*([^#\n]+)/';
|
||||
|
||||
//$pattern = '/\s*' . $keyToFind . '\s*=\s*([^\s#]+)/'; // Only matches the first word
|
||||
|
||||
preg_match($pattern, $string, $matches);
|
||||
|
||||
|
||||
|
||||
if (isset($matches[1])) {
|
||||
|
||||
return trim($matches[1]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getDoubleParameter($keywordToFind, $string) {
|
||||
|
||||
// Returns string or null
|
||||
|
||||
$pattern = '/#\s*' . preg_quote($keywordToFind, '/') . '\s*=\s*(\S+)\s*(\S+)/';
|
||||
|
||||
// Matches "# <keyword> = <value> <value>"
|
||||
|
||||
preg_match($pattern, $string, $matches);
|
||||
|
||||
|
||||
|
||||
if (isset($matches[1]) && isset($matches[2])) {
|
||||
|
||||
$result = array($matches[1], $matches[2]);
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getReplyHashFromTwt(string $twtString): string {
|
||||
|
||||
// Extract the text between parentheses using regular expressions
|
||||
|
||||
$pattern = '/\(#([^\)]+)\)/'; // Matches "(#<text>)"
|
||||
|
||||
preg_match($pattern, $twtString, $matches);
|
||||
|
||||
|
||||
|
||||
if (isset($matches[1])) {
|
||||
|
||||
$textBetweenParentheses = $matches[1];
|
||||
|
||||
return $textBetweenParentheses;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getMentionsFromTwt(string $twtString) {
|
||||
|
||||
$pattern = '/@<([^>]+)\s([^>]+)>/'; // Matches "@<nick url>"
|
||||
|
||||
function getImagesFromTwt(string $twtString) {
|
||||
$pattern = '/(<img[^>]+>)/i';
|
||||
preg_match_all($pattern, $twtString, $matches, PREG_SET_ORDER);
|
||||
|
||||
|
||||
|
||||
$result = array();
|
||||
|
||||
|
||||
|
||||
foreach ($matches as $match) {
|
||||
|
||||
$nick = $match[1];
|
||||
|
||||
$url = $match[2];
|
||||
|
||||
$result[] = array("nick" => $nick, "url" => $url);
|
||||
|
||||
$result[] = array($match[0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
function getMentionsFromTwt(string $twtString) {
|
||||
$pattern = '/@<([^>]+)\s([^>]+)>/'; // Matches "@<nick url>"
|
||||
preg_match_all($pattern, $twtString, $matches, PREG_SET_ORDER);
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach ($matches as $match) {
|
||||
$nick = $match[1];
|
||||
$url = $match[2];
|
||||
$result[] = array("nick" => $nick, "url" => $url);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function replaceMentionsFromTwt(string $twtString): string {
|
||||
|
||||
// Example input: 'Hello @<eapl.mx https://eapl.mx/twtxt.txt>, how are you? @<nick https://server.com/something/twtxt.txt>';
|
||||
|
||||
// Example output: Hello <a href="?url=https://eapl.mx/twtxt.txt">@eapl.mx@eapl.mx/twtxt.txt</a>, how are you? <a href="?url=https://server.com/something/twtxt.txt">@nick@server.com/something/twtxt.txt</a>
|
||||
|
||||
|
||||
|
||||
$pattern = '/@<([^ ]+)\s([^>]+)>/';
|
||||
|
||||
//$replacement = '<a href="/?url=$2">@$1</a>';
|
||||
|
||||
$replacement = '<a href="'.str_replace("/index.php", "", $_SERVER["SCRIPT_NAME"]).'/?profile=$2">@$1</a>';
|
||||
$replacement .= '<a href="$2" class="webmention"></a>'; // Adds a hidden link direcly to the twtxt.txt of the mentioned target
|
||||
|
||||
#$twtString = '@<nick https://eapl.mx/twtxt.txt>';
|
||||
|
||||
#$pattern = '/@<([^ ]+) ([^>]+)>/';
|
||||
|
||||
#$replacement = '@$1';
|
||||
|
||||
$result = preg_replace($pattern, $replacement, $twtString);
|
||||
|
||||
return $result;
|
||||
|
||||
|
||||
|
||||
// from https://github.com/hxii/picoblog/blob/master/picoblog.php
|
||||
|
||||
//$pattern = '/\@<([a-zA-Z0-9\.]+)\W+(https?:\/\/[^>]+)>/';
|
||||
|
||||
//return preg_replace($pattern,'<a href="$2">@$1</a>',$twtString);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function replaceLinksFromTwt(string $twtString) {
|
||||
|
||||
|
||||
|
||||
// TODO: Make this NOT match with `inline code` to avoid links in code-snippets
|
||||
|
||||
// 1. Look into how yarnd handles this
|
||||
|
||||
|
||||
|
||||
// Regular expression pattern to match URLs
|
||||
|
||||
$pattern = '/(?<!\S)(\b(https?|ftp|gemini|spartan|gopher):\/\/\S+|\b(?!:\/\/)\w+(?:\.\w+)+(?:\/\S+)?)(?!\S)/';
|
||||
|
||||
|
||||
|
||||
// Replace URLs with clickable links
|
||||
|
||||
$replacement = '<a href="$1">$1</a>';
|
||||
|
||||
$result = preg_replace($pattern, $replacement, $twtString);
|
||||
|
||||
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function replaceMarkdownLinksFromTwt(string $twtString) {
|
||||
|
||||
$pattern = '/\[([^\]]+)\]\(([^)]+)\)/';
|
||||
|
||||
|
||||
|
||||
$replacement = '<a href="$2">$1</a>';
|
||||
|
||||
$result = preg_replace($pattern, $replacement, $twtString);
|
||||
|
||||
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function replaceImagesFromTwt(string $twtString) {
|
||||
|
||||
$pattern = '/!\[(.*?)\]\((.*?)\)/';
|
||||
|
||||
//$replacement = '<img src="$2" alt="$1">';
|
||||
|
||||
$replacement = '<a href="$2"><img src="$2" alt="$1"></a>';
|
||||
|
||||
$result = preg_replace($pattern, $replacement, $twtString);
|
||||
|
||||
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function replaceTagsFromTwt(string $twtString) {
|
||||
|
||||
$pattern = '/#(\w+)?/';
|
||||
|
||||
$replacement = '<a href="#">#\1</a>'; // Dummy link
|
||||
|
||||
//$replacement = '<a href="?tag=$1" class="tag">#${1}</a>';
|
||||
|
||||
$result = preg_replace($pattern, $replacement, $twtString);
|
||||
|
||||
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function getTimeElapsedString($timestamp, $full = false) {
|
||||
|
||||
$now = new DateTime;
|
||||
|
||||
$ago = new DateTime;
|
||||
|
||||
$ago->setTimestamp($timestamp);
|
||||
|
||||
|
||||
|
||||
$agoText = 'ago';
|
||||
|
||||
if ($now < $ago) {
|
||||
|
||||
$agoText = 'in the future';
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$diff = $now->diff($ago);
|
||||
|
||||
|
||||
|
||||
//$diff->w = floor($diff->d / 7);
|
||||
|
||||
$w = floor($diff->d / 7);
|
||||
|
||||
$d = $diff->d - ($w * 7);
|
||||
|
||||
//$diff->d -= $diff->w * 7;
|
||||
|
||||
|
||||
|
||||
$string = array(
|
||||
|
||||
'y' => 'year',
|
||||
|
||||
'm' => 'month',
|
||||
|
||||
'w' => 'week',
|
||||
|
||||
'd' => 'day',
|
||||
|
||||
'h' => 'hour',
|
||||
|
||||
'i' => 'minute',
|
||||
|
||||
's' => 'second',
|
||||
|
||||
);
|
||||
|
||||
foreach ($string as $k => &$v) { // k is key, and v is value... Obviously
|
||||
|
||||
if ($k === 'w') {
|
||||
|
||||
if ($w) {
|
||||
|
||||
$v = $w . ' ' . $v . ($w > 1 ? 's' : '');
|
||||
|
||||
} else {
|
||||
|
||||
unset($string[$k]);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ($diff->$k) {
|
||||
|
||||
$v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
|
||||
|
||||
} else {
|
||||
|
||||
unset($string[$k]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!$full) $string = array_slice($string, 0, 1);
|
||||
|
||||
return $string ? implode(', ', $string) . " $agoText" : 'just now';
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getCachedFileContentsOrUpdate($fileURL, $cacheDurationSecs = 15) {
|
||||
|
||||
# TODO: Process the Warning
|
||||
|
||||
# Warning: file_get_contents(https://eapl.mx/twtxt.net):
|
||||
|
||||
# failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in
|
||||
|
||||
|
||||
|
||||
$cacheFilePath = getCachedFileName($fileURL);
|
||||
|
||||
|
||||
|
||||
// Check if cache file exists and it's not expired
|
||||
|
||||
if (file_exists($cacheFilePath) && (time() - filemtime($cacheFilePath)) < $cacheDurationSecs) {
|
||||
|
||||
return file_get_contents($cacheFilePath);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// File doesn't exist in cache or has expired, so fetch and cache it
|
||||
|
||||
$contents = file_get_contents($fileURL);
|
||||
|
||||
file_put_contents($cacheFilePath, $contents);
|
||||
|
||||
|
||||
|
||||
return $contents;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getCachedFileContents($filePath) {
|
||||
|
||||
$cacheFile = getCachedFileName($filePath);
|
||||
|
||||
|
||||
|
||||
// Check if cache file exists and it's not expired
|
||||
|
||||
if (file_exists($cacheFile)) {
|
||||
|
||||
return file_get_contents($cacheFile);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function updateCachedFile($filePath, $cacheDurationSecs = 15) {
|
||||
|
||||
$cacheFilePath = getCachedFileName($filePath);
|
||||
|
||||
|
||||
|
||||
// File doesn't exist in cache or has expired, so fetch and cache it
|
||||
|
||||
// TODO: Seems it's not working right!
|
||||
|
||||
$fileDoesntExist = !file_exists($cacheFilePath);
|
||||
|
||||
$fileIsOld = false;
|
||||
|
||||
if (!$fileDoesntExist) {
|
||||
|
||||
$fileIsOld = !((time() - filemtime($cacheFilePath)) < $cacheDurationSecs);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($fileDoesntExist || $fileIsOld) {
|
||||
|
||||
#echo "Loading Cached file $cacheFilePath<br>\n";
|
||||
|
||||
$contents = @file_get_contents($filePath);
|
||||
|
||||
|
||||
|
||||
if ($contents === false) {
|
||||
|
||||
// File loaded with errors, skip saving it
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
file_put_contents($cacheFilePath, $contents);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getTwtsFromTwtxtString($url) {
|
||||
|
||||
$fileContent = getCachedFileContents($url);
|
||||
|
||||
|
||||
|
||||
if (is_null($fileContent)) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
$fileContent = mb_convert_encoding($fileContent, 'UTF-8');
|
||||
|
||||
|
||||
|
||||
$fileLines = explode("\n", $fileContent);
|
||||
|
||||
|
||||
|
||||
$twtxtData = new TwtxtFile();
|
||||
|
||||
|
||||
|
||||
foreach ($fileLines as $currentLine) {
|
||||
|
||||
// Remove empty lines
|
||||
|
||||
if (empty($currentLine)) {
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (str_starts_with($currentLine, '#')) {
|
||||
|
||||
// Check if comments (starting with #) have some metadata
|
||||
|
||||
if (!is_null(getSingleParameter('url', $currentLine))) {
|
||||
|
||||
$currentURL = getSingleParameter('url', $currentLine);
|
||||
|
||||
|
||||
|
||||
if (empty($twtxtData->URLs)) {
|
||||
|
||||
$twtxtData->mainURL = $currentURL;
|
||||
|
||||
}
|
||||
|
||||
$twtxtData->URLs[] = $currentURL;
|
||||
|
||||
}
|
||||
|
||||
if (!is_null(getSingleParameter('nick', $currentLine))) {
|
||||
|
||||
$twtxtData->nick = getSingleParameter('nick', $currentLine);
|
||||
|
||||
}
|
||||
|
||||
if (!is_null(getSingleParameter('avatar', $currentLine))) {
|
||||
|
||||
$twtxtData->avatar = getSingleParameter('avatar', $currentLine);
|
||||
|
||||
}
|
||||
|
||||
if (!is_null(getSingleParameter('emoji', $currentLine))) {
|
||||
|
||||
$twtxtData->emoji = getSingleParameter('emoji', $currentLine);
|
||||
|
||||
}
|
||||
|
||||
if (!is_null(getSingleParameter('lang', $currentLine))) {
|
||||
|
||||
$twtxtData->lang = getSingleParameter('lang', $currentLine);
|
||||
|
||||
}
|
||||
|
||||
if (!is_null(getSingleParameter('description', $currentLine))) {
|
||||
|
||||
$twtxtData->description = getSingleParameter('description', $currentLine);
|
||||
|
||||
// TODO - FIX BUG: only takes first word!
|
||||
|
||||
}
|
||||
|
||||
if (!is_null(getSingleParameter('follow', $currentLine))) {
|
||||
|
||||
$twtxtData->following[] = getSingleParameter('follow', $currentLine);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!str_starts_with($currentLine, '#')) {
|
||||
|
||||
$explodedLine = explode("\t", $currentLine);
|
||||
|
||||
if (count($explodedLine) >= 2) {
|
||||
|
||||
$dateStr = $explodedLine[0];
|
||||
|
||||
$twtContent = $explodedLine[1];
|
||||
|
||||
|
||||
|
||||
$twtContent = replaceMentionsFromTwt($twtContent);
|
||||
|
||||
|
||||
|
||||
// Convert HTML problematic characters
|
||||
|
||||
//$twtContent = htmlentities($twtContent); // TODO: Messing up rendering of @mentions #BUG
|
||||
|
||||
|
||||
|
||||
// Replace the Line separator character (U+2028)
|
||||
|
||||
// \u2028 is \xE2 \x80 \xA8 in UTF-8
|
||||
|
||||
// Check here: https://www.mclean.net.nz/ucf/
|
||||
|
||||
//$twtContent = str_replace("\xE2\x80\xA8", "<br>\n", $twtContent);
|
||||
|
||||
|
||||
|
||||
// For some reason I was having trouble finding this nomenclature
|
||||
|
||||
// that's why I leave the UTF-8 representation for future reference
|
||||
|
||||
$twtContent = str_replace("\u{2028}", "\n<br>\n", $twtContent);
|
||||
|
||||
|
||||
|
||||
//$twtContent = replaceMarkdownLinksFromTwt($twtContent);
|
||||
|
||||
//$twtContent = replaceImagesFromTwt($twtContent);
|
||||
|
||||
$twtContent = Slimdown::render($twtContent);
|
||||
|
||||
$twtContent = replaceLinksFromTwt($twtContent); // TODO:
|
||||
|
||||
|
||||
|
||||
// Get and remote the hash
|
||||
|
||||
// Get and remove the hash
|
||||
$hash = getReplyHashFromTwt($twtContent);
|
||||
|
||||
if ($hash) {
|
||||
|
||||
$twtContent = str_replace("(#$hash)", '', $twtContent);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: Make ?tag= filtering feature
|
||||
|
||||
//$twtContent = replaceTagsFromTwt($twtContent);
|
||||
|
||||
|
||||
|
||||
// TODO: Get mentions
|
||||
|
||||
$mentions = getMentionsFromTwt($twtContent);
|
||||
|
||||
|
||||
|
||||
// Get Lang metadata
|
||||
|
||||
|
||||
|
||||
if (($timestamp = strtotime($dateStr)) === false) {
|
||||
|
||||
//echo "The string ($dateStr) is incorrect";
|
||||
|
||||
// Incorrect date string, skip this twt
|
||||
|
||||
continue;
|
||||
|
||||
} else {
|
||||
|
||||
$displayDate = getTimeElapsedString($timestamp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: Only 1 twt by second is allowed here
|
||||
|
||||
$twt = new Twt();
|
||||
|
||||
|
||||
|
||||
$twt->originalTwtStr = $currentLine;
|
||||
|
||||
$twt->hash = getHashFromTwt($currentLine, $twtxtData->mainURL);
|
||||
|
||||
$twt->fullDate = date('j F Y h:i:s A', $timestamp) . ' (UTC)';
|
||||
|
||||
$twt->displayDate = $displayDate;
|
||||
|
||||
$twt->content = $twtContent;
|
||||
|
||||
$twt->replyToHash = $hash;
|
||||
|
||||
$twt->mentions = $mentions;
|
||||
|
||||
$twt->avatar = $twtxtData->avatar;
|
||||
|
||||
$twt->emoji = $twtxtData->emoji;
|
||||
|
||||
$twt->nick = $twtxtData->nick;
|
||||
|
||||
$twt->mainURL = $twtxtData->mainURL;
|
||||
|
||||
|
||||
|
||||
$twtxtData->twts[$timestamp] = $twt;
|
||||
|
||||
// TODO: Interpret the content as markdown -- @DONE using Slimdown.php above
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return $twtxtData;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function insertFollowingURL($urlString) {
|
||||
|
||||
// Check if it's a valid URL
|
||||
|
||||
// Retrieve the nickname, if didn't find a nick, ask for one
|
||||
|
||||
|
||||
|
||||
$originalCode = '
|
||||
|
||||
Lorem ipsum dolor sit amet,
|
||||
|
||||
#~~~#
|
||||
|
||||
consectetur adipiscing elit.';
|
||||
|
||||
|
||||
|
||||
$text = '#~~~#';
|
||||
|
||||
$newText = '123' . PHP_EOL . $text;
|
||||
|
||||
$result = str_replace('#~~~#', $newText, $originalCode);
|
||||
|
||||
|
||||
|
||||
echo $result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getCachedFileName($filePath) {
|
||||
|
||||
return __DIR__ . '/../private/cache/' . hash('sha256', $filePath); // TODO: make better path
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!function_exists('str_starts_with')) {
|
||||
|
||||
function str_starts_with($haystack, $needle) {
|
||||
|
||||
return (string)$needle !== '' && strncmp($haystack, $needle, strlen($needle)) === 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!function_exists('str_ends_with')) {
|
||||
|
||||
function str_ends_with($haystack, $needle) {
|
||||
|
||||
return $needle !== '' && substr($haystack, -strlen($needle)) === (string)$needle;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!function_exists('str_contains')) {
|
||||
|
||||
function str_contains($haystack, $needle) {
|
||||
|
||||
return $needle !== '' && mb_strpos($haystack, $needle) !== false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
51
partials/__img_posts.php
Normal file
51
partials/__img_posts.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
Gallery render of images posted to a twtxt.txt -- by darch.dk (2022)
|
||||
https://www.reddit.com/r/css/comments/8vmo4u/problem_fitting_image_to_css_grid/
|
||||
*/
|
||||
|
||||
echo '<div class="gallery">';
|
||||
|
||||
foreach ($twts as $twt) {
|
||||
$img_array = getImagesFromTwt($twt->content);
|
||||
|
||||
foreach ($img_array as $img) {
|
||||
//echo '<a href="'.$baseURL.'/post/'.$twt->hash.'">'.$img[0].'</a>';
|
||||
// Workaround until cache issue is resolved
|
||||
echo '<a href="'.$baseURL.'/?profile='.$twt->mainURL.'#'.$twt->hash.'">'.$img[0].'</a>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
|
||||
|
||||
/*
|
||||
|
||||
// old way from Pixelblog, for refernece/inspiration
|
||||
|
||||
// Loop through each post and extract date and entry text:
|
||||
|
||||
foreach ($img_posts as $post) {
|
||||
|
||||
$date = preg_filter('/^(?<date>[^\t]+)\t(?<entry>.+)/', '\1', $post);
|
||||
$entry = preg_filter('/^(?<date>[^\t]+)\t(?<entry>.+)/', '\2', $post);
|
||||
$text_only = preg_filter('/!\[(.*?)\]\((.*?)\)/', '\1', $entry); // this gives the post without the markdown img links (not sure why, but it works)
|
||||
$text_only = trim($text_only);
|
||||
$text_only = strip_tags($text_only);
|
||||
|
||||
preg_match_all('/!\[(?<alt>.*?)\]\((?<url>.*?)\)/', $entry, $img_array);
|
||||
//echo '<pre>'; print_r($img_array); echo '</pre>'; // FOR DEBUGING
|
||||
|
||||
foreach ($img_array['url'] as $img => $val) {
|
||||
$url = $img_array['url'][$img];
|
||||
//$alt = $img_array['alt'][$img];
|
||||
echo '<a href="'.$baseURL.'/?id='.$date.'"><img src="'.$url.'" alt="'.$text_only.'" title="'.$text_only.'" loading=lazy></a>';
|
||||
//echo '<a href="' . $base_url . '?id=' . $date . '"><img src="' . $base_url . 'system/thumb.php?src=' . $url . '&size=600x&crop=1" alt="' . $text_only . '" title="' . $text_only . '" loading=lazy></a>';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
?>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
# Shows the timeline for a user
|
||||
declare(strict_types=1);
|
||||
declare (strict_types = 1);
|
||||
|
||||
# Parameters
|
||||
#
|
||||
|
|
@ -25,9 +25,8 @@ require_once('libs/Slimdown.php');
|
|||
const TWTS_PER_PAGE = 50;
|
||||
|
||||
// TODO: Move twts per page to config.ini
|
||||
// Add a fallback if the number tis invalid (it should be between 1 and 999)
|
||||
// Add a fallback if the number is invalid (it should be between 1 and 999)
|
||||
$config = parse_ini_file('private/config.ini');
|
||||
//$url = $config['public_txt_url'];
|
||||
|
||||
// TODO: Take the title from the config.ini
|
||||
$title = "Timeline"; // Fallback, should be set in all views
|
||||
|
|
@ -57,21 +56,18 @@ if(isset($_GET['selectList'])){
|
|||
date_default_timezone_set('UTC');
|
||||
|
||||
if (!empty($_GET['url'])) {
|
||||
$url = $_GET['url'];
|
||||
$url = $_GET['url'];
|
||||
}
|
||||
|
||||
if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
|
||||
die('Not a valid URL');
|
||||
die('Not a valid URL');
|
||||
}
|
||||
|
||||
//$validSession = has_valid_session();
|
||||
//echo("Valid session: $validSession");
|
||||
|
||||
$cacheRefreshTime = $config['cache_refresh_time'];
|
||||
$fileContent = getCachedFileContentsOrUpdate($url, $cacheRefreshTime);
|
||||
|
||||
if ($fileContent === false) {
|
||||
die("$url couldn't be retrieved.");
|
||||
die("$url couldn't be retrieved.");
|
||||
}
|
||||
|
||||
$fileContent = mb_convert_encoding($fileContent, 'UTF-8');
|
||||
|
|
@ -79,64 +75,66 @@ $fileLines = explode("\n", $fileContent);
|
|||
$twtFollowingList = [];
|
||||
|
||||
if (!empty($_GET['profile'])) { // Show profile for some user
|
||||
$twtsURL = $_GET['profile'];
|
||||
if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
|
||||
die('Not a valid URL');
|
||||
}
|
||||
$twtsURL = $_GET['profile'];
|
||||
if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
|
||||
die('Not a valid URL');
|
||||
}
|
||||
|
||||
$parsedTwtxtFile = getTwtsFromTwtxtString($twtsURL);
|
||||
if (!is_null($parsedTwtxtFile)) {
|
||||
$parsedTwtxtFiles[$parsedTwtxtFile->mainURL] = $parsedTwtxtFile;
|
||||
}
|
||||
$parsedTwtxtFile = getTwtsFromTwtxtString($twtsURL);
|
||||
if (!is_null($parsedTwtxtFile)) {
|
||||
$parsedTwtxtFiles[$parsedTwtxtFile->mainURL] = $parsedTwtxtFile;
|
||||
}
|
||||
|
||||
} else { // Show timeline for the URL
|
||||
$parsedTwtxtFiles = [];
|
||||
foreach ($fileLines as $currentLine) {
|
||||
if (str_starts_with($currentLine, '#')) {
|
||||
if (!is_null(getDoubleParameter('follow', $currentLine))) {
|
||||
$follow = getDoubleParameter('follow', $currentLine);
|
||||
$twtFollowingList[] = $follow;
|
||||
$parsedTwtxtFiles = [];
|
||||
foreach ($fileLines as $currentLine) {
|
||||
if (str_starts_with($currentLine, '#')) {
|
||||
if (!is_null(getDoubleParameter('follow', $currentLine))) {
|
||||
$follow = getDoubleParameter('follow', $currentLine);
|
||||
$twtFollowingList[] = $follow;
|
||||
|
||||
// Read the parsed files if in Cache
|
||||
$followURL = $follow[1];
|
||||
$parsedTwtxtFile = getTwtsFromTwtxtString($followURL);
|
||||
if (!is_null($parsedTwtxtFile)) {
|
||||
$parsedTwtxtFiles[$parsedTwtxtFile->mainURL] = $parsedTwtxtFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Read the parsed files if in Cache
|
||||
$followURL = $follow[1];
|
||||
$parsedTwtxtFile = getTwtsFromTwtxtString($followURL);
|
||||
if (!is_null($parsedTwtxtFile)) {
|
||||
$parsedTwtxtFiles[$parsedTwtxtFile->mainURL] = $parsedTwtxtFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$twts = [];
|
||||
|
||||
# Combine all the followers twts
|
||||
foreach ($parsedTwtxtFiles as $currentTwtFile) {
|
||||
if (!is_null($currentTwtFile)) {
|
||||
$twts += $currentTwtFile->twts;
|
||||
}
|
||||
if (!is_null($currentTwtFile)) {
|
||||
$twts += $currentTwtFile->twts;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_GET['hash'])) {
|
||||
$hash = $_GET['hash'];
|
||||
$twts = array_filter($twts, function($twt) use ($hash) {
|
||||
return $twt->hash === $hash || $twt->replyToHash === $hash;
|
||||
});
|
||||
$hash = $_GET['hash'];
|
||||
$twts = array_filter($twts, function ($twt) use ($hash) {
|
||||
return $twt->hash === $hash || $twt->replyToHash === $hash;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
krsort($twts, SORT_NUMERIC);
|
||||
|
||||
if (!empty($_GET['hash'])) {
|
||||
$twts = array_reverse($twts, true);
|
||||
$twts = array_reverse($twts, true);
|
||||
}
|
||||
|
||||
$page = 1;
|
||||
if (!empty($_GET['page'])) {
|
||||
$page = intval($_GET['page']);
|
||||
$page = intval($_GET['page']);
|
||||
}
|
||||
|
||||
$startingTwt = (($page - 1) * TWTS_PER_PAGE);
|
||||
$twts = array_slice($twts, $startingTwt, TWTS_PER_PAGE);
|
||||
// If we should paginate our twts list
|
||||
if (!empty($paginateTwts)) {
|
||||
$startingTwt = (($page - 1) * TWTS_PER_PAGE);
|
||||
$twts = array_slice($twts, $startingTwt, TWTS_PER_PAGE);
|
||||
}
|
||||
|
||||
$baseURL = str_replace("/index.php", "", $_SERVER['SCRIPT_NAME']);
|
||||
|
|
|
|||
|
|
@ -19,9 +19,13 @@ $profile = getTwtsFromTwtxtString($config['public_txt_url']);
|
|||
|
||||
<header>
|
||||
<p>
|
||||
<a href="<?= $baseURL ?>">
|
||||
<a href="/">
|
||||
<img class="avatar" src="<?= $profile->avatar ?>" alt="" loading="lazy">
|
||||
<!-- Timeline for --><?= $profile->nick ?></a>@<?= parse_url($profile->mainURL, PHP_URL_HOST); ?>
|
||||
<?= parse_url($profile->mainURL, PHP_URL_HOST); ?>
|
||||
</a>
|
||||
<!-- <a href="<?= $baseURL ?>">
|
||||
<img class="avatar" src="<?= $profile->avatar ?>" alt="" loading="lazy">
|
||||
<?= $profile->nick ?></a>@<?= parse_url($profile->mainURL, PHP_URL_HOST); ?> -->
|
||||
</p>
|
||||
<nav>
|
||||
|
||||
|
|
@ -29,15 +33,19 @@ $profile = getTwtsFromTwtxtString($config['public_txt_url']);
|
|||
<?php //if ($validSession) { // TODO: Make login seqcure ?>
|
||||
<?php if( isset($_SESSION['password'])) { /*
|
||||
if($_SESSION['password']=="$password") {*/ // Hacky login ?>
|
||||
<li><?php include 'partials/lists.php'; ?></li>
|
||||
<li><a href="<?= $baseURL ?>/refresh?url=<?= $url ?>">Refresh</a></li>
|
||||
<li><a href="<?= $baseURL ?>">Timeline</a></li>
|
||||
<li><a href="<?= $baseURL ?>?profile=<?=$url ?>">Profile</a></li>
|
||||
<li><a href="<?= $baseURL ?>/gallery?profile=<?= $profile->mainURL ?>">Gallery</a></li>
|
||||
<li><a href="<?= $baseURL ?>/following">Following <?php // echo count($twtFollowingList); ?></a></li>
|
||||
<li><a href="<?= $baseURL ?>/add">Add feed</a></li>
|
||||
<li><a href="<?= $baseURL ?>/?profile=<?=$url ?>">Profile</a></li>
|
||||
<li><a href="<?= $baseURL ?>/logout">Log Out</a></li>
|
||||
<li><?php include 'partials/lists.php'; ?></li>
|
||||
<?php /*}*/ } else { ?>
|
||||
<li><a href="<?= $baseURL ?>">Timeline</a></li>
|
||||
<li><a href="<?= $baseURL ?>?profile=<?= $url ?>">Profile</a></li>
|
||||
<li><a href="<?= $baseURL ?>/gallery?profile=<?= $profile->mainURL ?>">Gallery</a></li>
|
||||
<li><a href="<?= $baseURL ?>/following">Following <?php // echo count($twtFollowingList); ?></a></li>
|
||||
<li><a href="<?= $baseURL ?>/?profile=<?= $url ?>">Profile</a></li>
|
||||
<li><a href="<?= $baseURL ?>/login">Log in</a></li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -2,52 +2,39 @@
|
|||
|
||||
// Get info about profile from URL as an objects
|
||||
if (!empty($_GET['profile'])) {
|
||||
$url = $twtsURL;
|
||||
$url = $twtsURL;
|
||||
}
|
||||
$profile = getTwtsFromTwtxtString($url);
|
||||
|
||||
?>
|
||||
$profile = getTwtsFromTwtxtString($url);
|
||||
$profileURL = $baseURL . '/?profile=' . $profile->mainURL;
|
||||
?>
|
||||
|
||||
<div class="profile">
|
||||
|
||||
<a href="<?= $profile->mainURL ?>">
|
||||
<img class="avatar" src="<?= $profile->avatar ?>" alt="" loading="lazy">
|
||||
<a href="<?=$profileURL?>">
|
||||
<img class="avatar" src="<?=$profile->avatar?>" alt="" loading="lazy">
|
||||
</a>
|
||||
|
||||
<div>
|
||||
<a href="<?= $profile->mainURL ?>" class="author">
|
||||
<strong><?= $profile->nick ?></strong>@<?= parse_url($profile->mainURL, PHP_URL_HOST); ?>
|
||||
<a href="<?=$profileURL?>" class="author">
|
||||
<strong><?=$profile->nick?></strong>@<?=parse_url($profile->mainURL, PHP_URL_HOST);?>
|
||||
</a>
|
||||
|
||||
<p><?= $profile->description ?></p>
|
||||
<p><?=$profile->description?></p>
|
||||
|
||||
<small>
|
||||
<!-- <a href="">Posts</a> | -->
|
||||
<a href="<?=$profileURL?>">Posts</a> |
|
||||
<!-- <a href="">Replies</a> | -->
|
||||
<!-- <a href="">Gallery</a> | -->
|
||||
<a href="<?=$baseURL?>/gallery?profile=<?=$profile->mainURL?>">Gallery</a>
|
||||
|
||||
<!-- <span class="right"> -->
|
||||
<span class="right">
|
||||
<!-- <a href="following.php">Following <?php echo count($twtFollowingList); ?></a> | -->
|
||||
<a target="_blank" href="<?= $profile->mainURL ?>"></i><?= $profile->mainURL ?></a>
|
||||
<a target="_blank" href="<?=$profile->mainURL?>"></i><?=$profile->mainURL?></a>
|
||||
(<a href="https://yarn.social">How to follow</a>)
|
||||
<!-- </span> -->
|
||||
</span>
|
||||
|
||||
</small>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- <nav>
|
||||
<ul>
|
||||
<li><a href="">Posts</a></li>
|
||||
<li><a href="">Replies</a></li>
|
||||
<li><a href="">Gallery</a></li>
|
||||
</ul>
|
||||
|
||||
<ul class="right">
|
||||
<li><a href="https://yarn.social" class="button">How to follow...</a></li>
|
||||
<li><a href="following.php">Following <?php echo count($twtFollowingList); ?></a></li>
|
||||
<li><a target="_blank" href="<?= $profile->mainURL ?>"></i>twtxt.txt</a></li>
|
||||
</ul>
|
||||
</nav> -->
|
||||
|
|
@ -1,59 +1,51 @@
|
|||
<!-- <center>
|
||||
<?php if (!empty($_GET['profile'])) { ?>
|
||||
<em>Twts for <a href="<?= $twtsURL ?>"><?= $twtsURL ?></a></em>
|
||||
<?php } else { ?>
|
||||
<em>Timeline for <a href="<?= $url ?>"><?= $url ?></a></em>
|
||||
<?php } ?>
|
||||
</center> -->
|
||||
<!--
|
||||
<?php if (!empty($_GET['profile'])) {?>
|
||||
<em>Twts for <a href="<?=$twtsURL?>"><?=$twtsURL?></a></em>
|
||||
<?php } else {?>
|
||||
<em>Timeline for <a href="<?=$url?>"><?=$url?></a></em>
|
||||
<?php }?>
|
||||
-->
|
||||
|
||||
<?php foreach ($twts as $twt) { ?>
|
||||
<article class="post-entry">
|
||||
<a href="<?= $baseURL ?>/?profile=<?= $twt->mainURL ?>">
|
||||
<img src='<?= $twt->avatar ?>' class="avatar" onerror="this.onerror=null;this.src='imgs/image_not_found.png';">
|
||||
</a>
|
||||
<div>
|
||||
<a href="<?= $baseURL ?>/?profile=<?= $twt->mainURL ?>" class="author">
|
||||
<strong><?= $twt->nick ?></strong>@<?= parse_url($twt->mainURL, PHP_URL_HOST); ?>
|
||||
</a>
|
||||
<?php foreach ($twts as $twt) {?>
|
||||
<article class="post-entry" id="<?=$twt->hash?>">
|
||||
<a href="<?=$baseURL?>/?profile=<?=$twt->mainURL?>">
|
||||
<img src='<?=$twt->avatar?>' class="avatar" onerror="this.onerror=null;this.src='imgs/image_not_found.png';">
|
||||
</a>
|
||||
<div>
|
||||
<a href="<?=$baseURL?>/?profile=<?=$twt->mainURL?>" class="author">
|
||||
<strong><?=$twt->nick?></strong>@<?=parse_url($twt->mainURL, PHP_URL_HOST);?>
|
||||
</a>
|
||||
|
||||
<div class="twt-msg">
|
||||
<?= $twt->content ?>
|
||||
<div class="twt-msg">
|
||||
<?=$twt->content?>
|
||||
</div>
|
||||
|
||||
<!-- Not sure what this does...
|
||||
<?php foreach ($twt->mentions as $mention) { ?>
|
||||
<br><?= $mention['nick'] ?>(<?= $mention['url'] ?>)
|
||||
<?php } ?>
|
||||
-->
|
||||
</div>
|
||||
<small>
|
||||
<?php
|
||||
if ($twt->replyToHash) {
|
||||
echo 'In reply to: <a href="' . $baseURL . '/conv/' . $twt->replyToHash . '">#' . $twt->replyToHash . '</a>';
|
||||
//echo '<a href="/conv/'.$twt->replyToHash.'">Convesation</a>';
|
||||
}
|
||||
|
||||
<small>
|
||||
<?php
|
||||
|
||||
if($twt->replyToHash) {
|
||||
echo 'In reply to: <a href="'.$baseURL.'/conv/'.$twt->replyToHash.'">#'.$twt->replyToHash.'</a>';
|
||||
//echo '<a href="/conv/'.$twt->replyToHash.'">Convesation</a>';
|
||||
}
|
||||
if ($twt->replyToHash && isset($_SESSION['password'])) {
|
||||
echo ' | ';
|
||||
}
|
||||
|
||||
if ($twt->replyToHash && isset($_SESSION['password'])) {
|
||||
echo ' | ';
|
||||
}
|
||||
if (isset($_SESSION['password'])) {
|
||||
echo '<a href="' . $baseURL . '/new?hash=' . $twt->hash . '">Reply</a>';
|
||||
}
|
||||
|
||||
if (isset($_SESSION['password'])) {
|
||||
echo '<a href="'.$baseURL.'/new?hash='.$twt->hash.'">Reply</a>';
|
||||
}
|
||||
|
||||
?>
|
||||
<!-- (<a href="new_twt.php?hash=<?= $twt->hash ?>">via email</a>) TODO: mailto-link -->
|
||||
<a href='<?= $baseURL ?>/post/<?= $twt->hash ?>' class="right"><span title="<?= $twt->fullDate ?> "><?= $twt->displayDate ?></span></a>
|
||||
</small>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<?php }
|
||||
?>
|
||||
<!-- (<a href="new_twt.php?hash=<?=$twt->hash?>">via email</a>) TODO: mailto-link -->
|
||||
<a href='<?=$baseURL?>/post/<?=$twt->hash?>' class="right"><span title="<?=$twt->fullDate?> "><?=$twt->displayDate?></span></a>
|
||||
</small>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<?php }
|
||||
|
||||
if (!isset($_SESSION['password'])) {
|
||||
echo '<center><a href="mailto:'.$config['email'].'?subject=RE: '.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'" class="button">Comment via email</a></center>';
|
||||
}
|
||||
echo '<center><a href="mailto:' . $config['email'] . '?subject=RE: ' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . '" class="button">Comment via email</a></center>';
|
||||
}
|
||||
|
||||
?>
|
||||
79
views/__Thumbnail.php
Normal file
79
views/__Thumbnail.php
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
// Based on: https://github.com/Francesco-Chen/Thumbnail-Gallery-PHP
|
||||
|
||||
function createThumbnail($src, $dest, $thumbHeight) {
|
||||
list($width, $height, $type) = getimagesize($src);
|
||||
$aspectRatio = $width / $height;
|
||||
$thumbWidth = $thumbHeight * $aspectRatio;
|
||||
|
||||
switch ($type) {
|
||||
case IMAGETYPE_JPEG:
|
||||
$image = imagecreatefromjpeg($src);
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
$image = imagecreatefrompng($src);
|
||||
break;
|
||||
case IMAGETYPE_WEBP: // Support webp format
|
||||
$image = imagecreatefromwebp($src);
|
||||
break;
|
||||
default:
|
||||
return false; // Unsupported image type
|
||||
}
|
||||
|
||||
$thumb = imagecreatetruecolor($thumbWidth, $thumbHeight);
|
||||
|
||||
imagecopyresampled($thumb, $image, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $width, $height);
|
||||
|
||||
switch ($type) {
|
||||
case IMAGETYPE_JPEG:
|
||||
imagejpeg($thumb, $dest);
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
imagepng($thumb, $dest);
|
||||
break;
|
||||
case IMAGETYPE_WEBP: // Support webp format
|
||||
imagewebp($thumb, $dest);
|
||||
break;
|
||||
}
|
||||
|
||||
imagedestroy($thumb);
|
||||
imagedestroy($image);
|
||||
return true;
|
||||
}
|
||||
|
||||
// $galleryDir = "gallery/";
|
||||
$thumbDir = "private/thumb/";
|
||||
$allowedExtensions = array("jpg", "jpeg", "png", "gif", "webp");
|
||||
|
||||
// Check and create the "thumb" directory if it doesn't exist
|
||||
if (!file_exists($thumbDir)) {
|
||||
mkdir($thumbDir);
|
||||
}
|
||||
|
||||
/*
|
||||
$galleryFiles = scandir($galleryDir);
|
||||
|
||||
foreach ($galleryFiles as $file) {
|
||||
$extension = pathinfo($file, PATHINFO_EXTENSION);
|
||||
if (in_array(strtolower($extension), $allowedExtensions)) {
|
||||
$imageURL = $galleryDir . $file;
|
||||
$thumbURL = $thumbDir . $file;
|
||||
|
||||
if (!file_exists($thumbURL)) {
|
||||
createThumbnail($imageURL, $thumbURL, 200); // The thumbnail will have a height of 200 pixels.
|
||||
}
|
||||
|
||||
echo '
|
||||
<a
|
||||
data-fancybox="gallery"
|
||||
data-src="' . $imageURL . '"
|
||||
data-caption="' . $file . '"
|
||||
>
|
||||
<img src="' . $thumbURL . '" height="200" />
|
||||
</a>
|
||||
';
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
|
@ -30,13 +30,13 @@ if (!empty($_GET['url'])) { // Show twts for some user
|
|||
$parsedTwtxtFiles[$parsedTwtxtFile->mainURL] = $parsedTwtxtFile;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else { // Show timeline for the URL
|
||||
$twtsURL = $config['public_txt_url'];
|
||||
// $twtsURL = "https://lyse.isobeef.org/twtxt.txt";
|
||||
// $profile = getTwtsFromTwtxtString($twtsURL);
|
||||
header("Location: ".$baseURL."/profile?url=".$twtsURL);
|
||||
|
||||
|
||||
/*
|
||||
if (filter_var($twtsURL, FILTER_VALIDATE_URL) === FALSE) {
|
||||
die('Not a valid URL');
|
||||
|
|
@ -59,7 +59,7 @@ foreach ($parsedTwtxtFiles as $currentTwtFile) {
|
|||
|
||||
krsort($twts, SORT_NUMERIC);
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
<div class="profile">
|
||||
|
||||
|
|
@ -75,13 +75,13 @@ krsort($twts, SORT_NUMERIC);
|
|||
<p><?= $profile->description ?></p>
|
||||
|
||||
<small>
|
||||
<!-- <a href="">Posts</a> |
|
||||
<a href="">Replies</a> |
|
||||
<!-- <a href="">Posts</a> |
|
||||
<a href="">Replies</a> |
|
||||
<a href="">Gallery</a> |
|
||||
-->
|
||||
<!-- <span class="right"> -->
|
||||
<!-- <a href="/following.php">Following <?php echo count($twtFollowingList); ?></a> | -->
|
||||
<a target="_blank" href="<?= $profile->mainURL ?>"></i>twtxt.txt</a> |
|
||||
<a target="_blank" href="<?= $profile->mainURL ?>"></i>twtxt.txt</a> |
|
||||
<a href="https://yarn.social">How to follow</a>
|
||||
<!-- </span> -->
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ krsort($twts, SORT_NUMERIC);
|
|||
|
||||
<!-- PHP: NEW POST BOX -->
|
||||
<?php
|
||||
if( isset($_SESSION['password'])) {
|
||||
if( isset($_SESSION['password'])) {
|
||||
include 'views/new_twt.php'; // TODO: Split up new_twt into a view and a partial
|
||||
} ?>
|
||||
|
||||
211
views/__thumb.php
Normal file
211
views/__thumb.php
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
<?php
|
||||
/**
|
||||
* @description
|
||||
* Thumbnails on the fly with cache from local and remote images
|
||||
*
|
||||
* Parameters:
|
||||
* image absolute path of local image starting with "/" (e.g. /images/toast.jpg)
|
||||
* width width of final image in pixels (e.g. 700)
|
||||
* height height of final image in pixels (e.g. 700)
|
||||
* nocache (optional) does not read image from the cache
|
||||
* quality (optional, 0-100, default: 90) quality of output image
|
||||
*
|
||||
* @example
|
||||
* <img src="/thumb.php?width=100&height=100&image=http://url.to/image.jpg" />
|
||||
*
|
||||
* @see https://gist.github.com/dmkuznetsov/f0038b578c1cb6ccd44d
|
||||
* @license MIT
|
||||
*/
|
||||
define('DEFAULT_WIDTH', 300);
|
||||
define('DEFAULT_HEIGHT', 300);
|
||||
define('DEFAULT_QUALITY', 100);
|
||||
define('CACHE_DIR', rtrim(sys_get_temp_dir(), '/') . '/thumbnails/');
|
||||
define('DOCUMENT_ROOT', $_SERVER['DOCUMENT_ROOT']);
|
||||
|
||||
//if (!isset($_GET['image'], $_GET['width'], $_GET['height'])) {
|
||||
if (!isset($_GET['image'])) {
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
//echo 'Error: no image/width/height was specified';
|
||||
echo 'Error: no image was specified';
|
||||
exit();
|
||||
}
|
||||
|
||||
// Made width and height optional and define their defaults.
|
||||
// by: sp@darch.dk (with help from chatGPT, 2024-02-03)
|
||||
if (!isset($_GET['width'], $_GET['height'])) {
|
||||
$resizeWidth = $width = DEFAULT_WIDTH;
|
||||
$resizeHeight = $height = DEFAULT_HEIGHT;
|
||||
} else {
|
||||
$resizeWidth = $width = (int)$_GET['width'];
|
||||
$resizeHeight = $height = (int)$_GET['height'];
|
||||
}
|
||||
|
||||
$quality = (isset($_GET['quality'])) ? (int)$_GET['quality'] : DEFAULT_QUALITY;
|
||||
$nocache = isset($_GET['nocache']);
|
||||
|
||||
if (!is_dir(CACHE_DIR)) {
|
||||
mkdir(CACHE_DIR, 0755, true);
|
||||
}
|
||||
|
||||
// Make sure we can read and write the cache directory
|
||||
if (!is_readable(CACHE_DIR)) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
echo 'Error: the cache directory is not readable';
|
||||
exit();
|
||||
} else if (!is_writable(CACHE_DIR)) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
echo 'Error: the cache directory is not writable';
|
||||
exit();
|
||||
}
|
||||
|
||||
$originalImageSource = (string)$_GET['image'];
|
||||
$image = getImagePath($originalImageSource);
|
||||
|
||||
if ($image[0] != '/' || strpos(dirname($image), ':') || preg_match('/(\.\.|<|>)/', $image)) {
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
echo 'Error: malformed image path. Image paths must begin with \'/\'';
|
||||
exit();
|
||||
}
|
||||
|
||||
if (!$image || !file_exists($image)) {
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
echo 'Error: image does not exist: ' . $image;
|
||||
exit();
|
||||
}
|
||||
|
||||
$size = getimagesize($image);
|
||||
$mime = $size['mime'];
|
||||
|
||||
if (substr($mime, 0, 6) != 'image/') {
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
echo 'Error: requested file is not an accepted type: ' . $image;
|
||||
exit();
|
||||
}
|
||||
|
||||
$originalWidth = $size[0];
|
||||
$originalHeight = $size[1];
|
||||
$thumbHash = md5($image . $width . $height . $quality);
|
||||
$thumbPath = CACHE_DIR . $thumbHash;
|
||||
|
||||
if (!$nocache && file_exists($thumbPath)) {
|
||||
$imageModified = filemtime($image);
|
||||
$thumbModified = filemtime($thumbPath);
|
||||
if ($imageModified < $thumbModified) {
|
||||
$data = file_get_contents($thumbPath);
|
||||
findBrowserCache(md5($data), gmdate('D, d M Y H:i:s', $thumbModified) . ' GMT');
|
||||
header("Content-type: $mime");
|
||||
header('Content-Length: ' . strlen($data));
|
||||
echo $data;
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$saveAlphaChannel = false;
|
||||
$imageCreationFunction = 'imagecreatefromjpeg';
|
||||
$imageOutputFunction = 'imagejpeg';
|
||||
$dst = imagecreatetruecolor($width, $height);
|
||||
switch ($size['mime']) {
|
||||
case 'image/gif':
|
||||
$imageCreationFunction = 'imagecreatefromgif';
|
||||
$imageOutputFunction = 'imagepng';
|
||||
$quality = round(10 - ($quality / 10));
|
||||
$saveAlphaChannel = true;
|
||||
break;
|
||||
case 'image/x-png':
|
||||
case 'image/png':
|
||||
$imageCreationFunction = 'imagecreatefrompng';
|
||||
$imageOutputFunction = 'imagepng';
|
||||
$quality = round(10 - ($quality / 10));
|
||||
$saveAlphaChannel = true;
|
||||
break;
|
||||
}
|
||||
$src = $imageCreationFunction($image);
|
||||
|
||||
if ($saveAlphaChannel) {
|
||||
imagealphablending($dst, false);
|
||||
imagesavealpha($dst, true);
|
||||
}
|
||||
|
||||
$ratio = $originalWidth / $originalHeight;
|
||||
if ($width / $height <= $ratio) {
|
||||
$resizeWidth = $height * $ratio;
|
||||
} else {
|
||||
$resizeHeight = $width / $ratio;
|
||||
}
|
||||
|
||||
// This is where the image is being resized
|
||||
imagecopyresampled($dst, $src, 0, 0, 0, 0, $resizeWidth, $resizeHeight, $originalWidth, $originalHeight);
|
||||
|
||||
$imageOutputFunction($dst, $thumbPath, $quality);
|
||||
ob_start();
|
||||
$imageOutputFunction($dst, null, $quality);
|
||||
$data = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
imagedestroy($src);
|
||||
imagedestroy($dst);
|
||||
|
||||
if ($nocache && file_exists($image)) {
|
||||
unlink($image);
|
||||
}
|
||||
|
||||
findBrowserCache(md5($data), gmdate('D, d M Y H:i:s', filemtime($thumbPath)) . ' GMT');
|
||||
header("Content-type: $mime");
|
||||
header('Content-Length: ' . strlen($data));
|
||||
echo $data;
|
||||
exit;
|
||||
|
||||
function getImagePath($image)
|
||||
{
|
||||
if (!filter_var($image, FILTER_VALIDATE_URL)) {
|
||||
$image = DOCUMENT_ROOT . '/' . ltrim($image, '/');
|
||||
} else {
|
||||
$ext = pathinfo(preg_replace('/^(s?f|ht)tps?:\/\/[^\/]+/i', '', $image), PATHINFO_EXTENSION);
|
||||
$tmpImagePath = CACHE_DIR . md5($image);
|
||||
if ($ext) {
|
||||
$tmpImagePath .= '.' . $ext;
|
||||
}
|
||||
if (!file_exists($tmpImagePath)) {
|
||||
$imageContent = file_get_contents($image);
|
||||
if (!$imageContent) {
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
echo 'Error: can not download image';
|
||||
exit();
|
||||
} else {
|
||||
file_put_contents($tmpImagePath, $imageContent);
|
||||
}
|
||||
}
|
||||
$image = $tmpImagePath;
|
||||
}
|
||||
return $image;
|
||||
}
|
||||
|
||||
|
||||
function findBrowserCache($tag, $lastModified)
|
||||
{
|
||||
header("Last-Modified: $lastModified");
|
||||
header("ETag: \"{$tag}\"");
|
||||
|
||||
$ifNoneMatch = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
|
||||
stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) :
|
||||
false;
|
||||
|
||||
$ifModifiedSince = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
|
||||
stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) :
|
||||
false;
|
||||
|
||||
if (!$ifModifiedSince && !$ifNoneMatch) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($ifNoneMatch && $ifNoneMatch != $tag && $ifNoneMatch != '"' . $tag . '"') {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($ifModifiedSince && $ifModifiedSince != $lastModified) {
|
||||
return;
|
||||
}
|
||||
|
||||
header('HTTP/1.1 304 Not Modified');
|
||||
exit();
|
||||
}
|
||||
211
views/__thumb_dm.php
Normal file
211
views/__thumb_dm.php
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
Simplified version of http://github.com/jamiebicknell/Thumb:
|
||||
EXIF, bw and sharpening features removed
|
||||
*/
|
||||
|
||||
define('THUMB_CACHE', 'thucache/'); // Path to cache directory (must be writeable)
|
||||
define('THUMB_CACHE_AGE', 86400); // Duration of cached files in seconds
|
||||
define('THUMB_BROWSER_CACHE', true); // Browser cache true or false
|
||||
define('JPEG_QUALITY', 90); // Quality of generated JPEGs (0 - 100; 100 being best)
|
||||
|
||||
|
||||
$src = isset($_GET['src']) ? $_GET['src'] : false;
|
||||
$size = isset($_GET['size']) ? str_replace(array('<', 'x'), '', $_GET['size']) != '' ? $_GET['size'] : 100 : 100;
|
||||
$crop = isset($_GET['crop']) ? max(0, min(1, $_GET['crop'])) : 1;
|
||||
$trim = isset($_GET['trim']) ? max(0, min(1, $_GET['trim'])) : 0;
|
||||
$zoom = isset($_GET['zoom']) ? max(0, min(1, $_GET['zoom'])) : 0;
|
||||
$align = isset($_GET['align']) ? $_GET['align'] : false;
|
||||
$sharpen = isset($_GET['sharpen']) ? max(0, min(100, $_GET['sharpen'])) : 0;
|
||||
$gray = isset($_GET['gray']) ? max(0, min(1, $_GET['gray'])) : 0;
|
||||
$ignore = isset($_GET['ignore']) ? max(0, min(1, $_GET['ignore'])) : 0;
|
||||
$path = parse_url($src);
|
||||
|
||||
if (isset($path['scheme'])) {
|
||||
$base = parse_url('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
|
||||
if (preg_replace('/^www\./i', '', $base['host']) == preg_replace('/^www\./i', '', $path['host'])) {
|
||||
$base = explode('/', preg_replace('/\/+/', '/', $base['path']));
|
||||
$path = explode('/', preg_replace('/\/+/', '/', $path['path']));
|
||||
$temp = $path;
|
||||
$part = count($base);
|
||||
foreach ($base as $k => $v) {
|
||||
if ($v == $path[$k]) {
|
||||
array_shift($temp);
|
||||
} else {
|
||||
if ($part - $k > 1) {
|
||||
$temp = array_pad($temp, 0 - (count($temp) + ($part - $k) - 1), '..');
|
||||
break;
|
||||
} else {
|
||||
$temp[0] = './' . $temp[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
$src = implode('/', $temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!extension_loaded('gd')) {
|
||||
die('GD extension is not installed');
|
||||
}
|
||||
if (!is_writable(THUMB_CACHE)) {
|
||||
die('Cache not writable');
|
||||
}
|
||||
if (isset($path['scheme']) || !file_exists($src)) {
|
||||
die('File cannot be found');
|
||||
}
|
||||
if (!in_array(strtolower(substr(strrchr($src, '.'), 1)), array('gif', 'jpg', 'jpeg', 'png'))) {
|
||||
die('File is not an image');
|
||||
}
|
||||
|
||||
|
||||
$file_salt = 'v1.0.5';
|
||||
$file_size = filesize($src);
|
||||
$file_time = filemtime($src);
|
||||
$file_date = gmdate('D, d M Y H:i:s T', $file_time);
|
||||
$file_type = strtolower(substr(strrchr($src, '.'), 1));
|
||||
$file_hash = md5($file_salt . ($src.$size.$crop.$trim.$zoom.$align.$sharpen.$gray.$ignore) . $file_time);
|
||||
$file_temp = THUMB_CACHE . $file_hash . '.img.txt';
|
||||
$file_name = basename(substr($src, 0, strrpos($src, '.')) . strtolower(strrchr($src, '.')));
|
||||
|
||||
|
||||
if (!file_exists(THUMB_CACHE . 'index.html')) {
|
||||
touch(THUMB_CACHE . 'index.html');
|
||||
}
|
||||
if (($fp = fopen(THUMB_CACHE . 'index.html', 'r')) !== false) {
|
||||
if (flock($fp, LOCK_EX)) {
|
||||
if (time() - THUMB_CACHE_AGE > filemtime(THUMB_CACHE . 'index.html')) {
|
||||
$files = glob(THUMB_CACHE . '*.img.txt');
|
||||
if (is_array($files) && count($files) > 0) {
|
||||
foreach ($files as $file) {
|
||||
if (time() - THUMB_CACHE_AGE > filemtime($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
touch(THUMB_CACHE . 'index.html');
|
||||
}
|
||||
flock($fp, LOCK_UN);
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
|
||||
if (THUMB_BROWSER_CACHE && (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH']))) {
|
||||
if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $file_date && $_SERVER['HTTP_IF_NONE_MATCH'] == $file_hash) {
|
||||
header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!file_exists($file_temp)) {
|
||||
list($w0, $h0, $type) = getimagesize($src);
|
||||
$data = file_get_contents($src);
|
||||
if ($ignore && $type == 1) {
|
||||
if (preg_match('/\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)/s', $data)) {
|
||||
header('Content-Type: image/gif');
|
||||
header('Content-Length: ' . $file_size);
|
||||
header('Content-Disposition: inline; filename="' . $file_name . '"');
|
||||
header('Last-Modified: ' . $file_date);
|
||||
header('ETag: ' . $file_hash);
|
||||
header('Accept-Ranges: none');
|
||||
if (THUMB_BROWSER_CACHE) {
|
||||
header('Cache-Control: max-age=604800, must-revalidate');
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s T', strtotime('+7 days')));
|
||||
} else {
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s T'));
|
||||
header('Pragma: no-cache');
|
||||
}
|
||||
die($data);
|
||||
}
|
||||
}
|
||||
$oi = imagecreatefromstring($data);
|
||||
|
||||
list($w,$h) = explode('x', str_replace('<', '', $size) . 'x');
|
||||
$w = ($w != '') ? floor(max(8, min(1500, $w))) : '';
|
||||
$h = ($h != '') ? floor(max(8, min(1500, $h))) : '';
|
||||
if (strstr($size, '<')) {
|
||||
$h = $w;
|
||||
$crop = 0;
|
||||
$trim = 1;
|
||||
} elseif (!strstr($size, 'x')) {
|
||||
$h = $w;
|
||||
} elseif ($w == '' || $h == '') {
|
||||
$w = ($w == '') ? ($w0 * $h) / $h0 : $w;
|
||||
$h = ($h == '') ? ($h0 * $w) / $w0 : $h;
|
||||
$crop = 0;
|
||||
$trim = 1;
|
||||
}
|
||||
$trim_w = ($trim) ? 1 : ($w == '') ? 1 : 0;
|
||||
$trim_h = ($trim) ? 1 : ($h == '') ? 1 : 0;
|
||||
if ($crop) {
|
||||
$w1 = (($w0 / $h0) > ($w / $h)) ? floor($w0 * $h / $h0) : $w;
|
||||
$h1 = (($w0 / $h0) < ($w / $h)) ? floor($h0 * $w / $w0) : $h;
|
||||
if (!$zoom) {
|
||||
if ($h0 < $h || $w0 < $w) {
|
||||
$w1 = $w0;
|
||||
$h1 = $h0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$w1 = (($w0 / $h0) < ($w / $h)) ? floor($w0 * $h / $h0) : floor($w);
|
||||
$h1 = (($w0 / $h0) > ($w / $h)) ? floor($h0 * $w / $w0) : floor($h);
|
||||
$w = floor($w);
|
||||
$h = floor($h);
|
||||
if (!$zoom) {
|
||||
if ($h0 < $h && $w0 < $w) {
|
||||
$w1 = $w0;
|
||||
$h1 = $h0;
|
||||
}
|
||||
}
|
||||
}
|
||||
$w = ($trim_w) ? (($w0 / $h0) > ($w / $h)) ? min($w, $w1) : $w1 : $w;
|
||||
$h = ($trim_h) ? (($w0 / $h0) < ($w / $h)) ? min($h, $h1) : $h1 : $h;
|
||||
|
||||
$x = strpos($align, 'l') !== false ? 0 : (strpos($align, 'r') !== false ? $w - $w1 : ($w - $w1) / 2);
|
||||
$y = strpos($align, 't') !== false ? 0 : (strpos($align, 'b') !== false ? $h - $h1 : ($h - $h1) / 2);
|
||||
$im = imagecreatetruecolor($w, $h);
|
||||
$bg = imagecolorallocate($im, 255, 255, 255);
|
||||
imagefill($im, 0, 0, $bg);
|
||||
switch ($type) {
|
||||
case 1:
|
||||
imagecopyresampled($im, $oi, $x, $y, 0, 0, $w1, $h1, $w0, $h0);
|
||||
imagegif($im, $file_temp);
|
||||
break;
|
||||
case 2:
|
||||
imagecopyresampled($im, $oi, $x, $y, 0, 0, $w1, $h1, $w0, $h0);
|
||||
imagejpeg($im, $file_temp, JPEG_QUALITY);
|
||||
break;
|
||||
case 3:
|
||||
imagefill($im, 0, 0, imagecolorallocatealpha($im, 0, 0, 0, 127));
|
||||
imagesavealpha($im, true);
|
||||
imagealphablending($im, false);
|
||||
imagecopyresampled($im, $oi, $x, $y, 0, 0, $w1, $h1, $w0, $h0);
|
||||
imagepng($im, $file_temp);
|
||||
break;
|
||||
}
|
||||
imagedestroy($im);
|
||||
imagedestroy($oi);
|
||||
}
|
||||
|
||||
|
||||
header('Content-Type: image/' . $file_type);
|
||||
header('Content-Length: ' . filesize($file_temp));
|
||||
header('Content-Disposition: inline; filename="' . $file_name . '"');
|
||||
header('Last-Modified: ' . $file_date);
|
||||
header('ETag: ' . $file_hash);
|
||||
header('Accept-Ranges: none');
|
||||
if (THUMB_BROWSER_CACHE) {
|
||||
header('Cache-Control: max-age=604800, must-revalidate');
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s T', strtotime('+7 days')));
|
||||
} else {
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s T'));
|
||||
header('Pragma: no-cache');
|
||||
}
|
||||
|
||||
|
||||
readfile($file_temp);
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
<?php require_once('partials/base.php');
|
||||
<?php
|
||||
require_once('partials/base.php');
|
||||
|
||||
// TODO: Give a warning if the file is not found
|
||||
$config = parse_ini_file('private/config.ini');
|
||||
|
|
@ -66,8 +67,6 @@ if (isset($_POST['url'])) {
|
|||
} else { ?>
|
||||
|
||||
<?php
|
||||
require_once("partials/base.php");
|
||||
|
||||
$title = "Add feed - ".$title;
|
||||
|
||||
include 'partials/header.php';
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
<?php require_once("partials/base.php");
|
||||
<?php
|
||||
$paginateTwts = false;
|
||||
require_once("partials/base.php");
|
||||
|
||||
// Get the hashes (both post and replies) as $id from the router and return an inverted list
|
||||
if (!empty($id)) {
|
||||
|
|
@ -19,7 +21,7 @@ include_once 'partials/header.php';
|
|||
|
||||
<p>Recent twts in reply to <a href="<?= $baseURL ?>/post/<?= $id ?>">#<?= $id ?></a></p>
|
||||
|
||||
<!-- PHP: GET TIMELIE --><?php include_once 'partials/timeline.php'?>
|
||||
<!-- PHP: GET TIMELINE --><?php include_once 'partials/timeline.php'?>
|
||||
|
||||
<?php
|
||||
if (isset($_SESSION['password'])) {
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ include 'partials/header.php';
|
|||
?>
|
||||
|
||||
<center>
|
||||
<h1>Following <?php echo count($twtFollowingList); ?> feeds</h1>
|
||||
<h1><?= $profile->nick ?> follows <?php echo count($twtFollowingList); ?> feeds</h1>
|
||||
|
||||
<table>
|
||||
|
||||
|
||||
<tr>
|
||||
<!-- <th></th> -->
|
||||
<th>Nick</th>
|
||||
|
|
|
|||
|
|
@ -1,28 +1,91 @@
|
|||
<!-- PHP: GET CONFIG --><?php include '../config.php' ?>
|
||||
<?php
|
||||
require_once("partials/base.php");
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../layout/default.css?v=1.1">
|
||||
<link rel="stylesheet" type="text/css" media="all" href="../custom.css?v=1.1">
|
||||
<title><?=$title?> - Gallery</title>
|
||||
</head>
|
||||
<body>
|
||||
// require_once 'libs/Thumbnail.php';
|
||||
|
||||
<!-- PHP: GET HEADER --><?php include $base_path.'layout/header.php';?>
|
||||
$title = "Gallery - ".$title;
|
||||
|
||||
<!-- PHP: GET PROFILE CARD --><?php include $base_path.'layout/profile.php';?>
|
||||
include_once 'partials/header.php';
|
||||
|
||||
require_once("libs/Cropper.php");
|
||||
$thumb = new \CoffeeCode\Cropper\Cropper("media/thumbnails", 75, 5, true);
|
||||
|
||||
?>
|
||||
|
||||
|
||||
<!-- PHP: PROFILE CARD -->
|
||||
<?php
|
||||
if (!empty($_GET['profile'])) { // Show twts for some user
|
||||
$twtsURL = $_GET['profile'];
|
||||
|
||||
// TODO: Give a propper error if feed is not valid
|
||||
if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
|
||||
die('Not a valid URL');
|
||||
}
|
||||
|
||||
// $parsedTwtxtFile = getTwtsFromTwtxtString($twtsURL);
|
||||
if (!is_null($parsedTwtxtFile)) {
|
||||
$parsedTwtxtFiles[$parsedTwtxtFile->mainURL] = $parsedTwtxtFile;
|
||||
include 'partials/profile.php';
|
||||
}
|
||||
} else {
|
||||
// TODO: default to rendering the local users gallery, if no profile specified
|
||||
//echo $profile->mainURL;;
|
||||
//$twtsURL = $profile->mainURL; // correct URL for twtxt.txt
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
|
||||
<!-- PHP: GALLERY -->
|
||||
<div class="gallery">
|
||||
|
||||
<?php include $base_path.'system/gallery.php' ?>
|
||||
<?php
|
||||
foreach ($twts as $twt) {
|
||||
$img_array = getImagesFromTwt($twt->content);
|
||||
|
||||
foreach ($img_array as $img) {
|
||||
echo '<a href="'.$baseURL.'/conv/'.$twt->hash.'">'.$img[0].'</a>';
|
||||
}
|
||||
|
||||
/*
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadHTML($twt->content);
|
||||
$img_array = $doc->getElementsByTagName('img');
|
||||
|
||||
foreach ($img_array as $img) {
|
||||
$url = $img->getAttribute('src');
|
||||
$alt = $img->getAttribute('alt');
|
||||
//echo "<br/>Title:" . $img->getAttribute('title');
|
||||
|
||||
echo "<img src='{$thumb->make($url, 200)}' alt='".$alt."' title='".$alt."'>";
|
||||
}
|
||||
|
||||
/*
|
||||
foreach ($img_array as $img) {
|
||||
echo $img[0];
|
||||
$extension = pathinfo($img, PATHINFO_EXTENSION);
|
||||
if (in_array(strtolower($extension), $allowedExtensions)) {
|
||||
$imageURL = $galleryDir . $img;
|
||||
$thumbURL = $thumbDir . $img;
|
||||
|
||||
if (!file_exists($thumbURL)) {
|
||||
createThumbnail($imageURL, $thumbURL, 200); // The thumbnail will have a height of 200 pixels.
|
||||
}
|
||||
|
||||
echo '<a href="'.$baseURL.'/conv/'.$twt->hash.'">
|
||||
<img src="' . $thumbURL . '" height="200" />
|
||||
</a>';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- PHP: GET FOOTER --><?php include $base_path.'layout/footer.php';?>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
<!-- PHP: FOOTER --><?php include_once 'partials/footer.php';?>
|
||||
|
|
@ -1,32 +1,39 @@
|
|||
<?php
|
||||
require_once("partials/base.php");
|
||||
// Only paginate if it's a main timeline view
|
||||
$paginateTwts = true;
|
||||
|
||||
//$title = "Login - ".$title;
|
||||
if (!empty($_GET['profile'])) { // Show twts for some user (Profile view)
|
||||
$twtsURL = $_GET['profile'];
|
||||
|
||||
// TODO: Give a proper error if URL is not valid
|
||||
if (filter_var($twtsURL, FILTER_VALIDATE_URL) === FALSE) {
|
||||
die('Not a valid URL');
|
||||
}
|
||||
|
||||
// If it's a profile, don't paginate
|
||||
$paginateTwts = false;
|
||||
}
|
||||
|
||||
// Load twts, taking $paginateTwts into consideration
|
||||
require_once 'partials/base.php';
|
||||
include_once 'partials/header.php';
|
||||
?>
|
||||
|
||||
<!-- PHP: PROFILE CARD -->
|
||||
<?php
|
||||
if (!empty($_GET['profile'])) { // Show twts for some user
|
||||
<?php
|
||||
if (!empty($_GET['profile'])) { // Show twts for some user (Profile view)
|
||||
$twtsURL = $_GET['profile'];
|
||||
|
||||
// TODO: Give a propper error if feed is not valid
|
||||
if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
|
||||
die('Not a valid URL');
|
||||
}
|
||||
|
||||
// $parsedTwtxtFile = getTwtsFromTwtxtString($twtsURL);
|
||||
if (!is_null($parsedTwtxtFile)) {
|
||||
$parsedTwtxtFiles[$parsedTwtxtFile->mainURL] = $parsedTwtxtFile;
|
||||
include 'partials/profile.php';
|
||||
}
|
||||
} ?>
|
||||
|
||||
}
|
||||
?>
|
||||
|
||||
<!-- PHP: NEW POST BOX -->
|
||||
<?php
|
||||
if( isset($_SESSION['password'])) {
|
||||
if (isset($_SESSION['password'])) {
|
||||
include 'views/new_twt.php'; // TODO: Split up new_twt into a view and a partial
|
||||
}
|
||||
?>
|
||||
|
|
@ -34,4 +41,3 @@ if( isset($_SESSION['password'])) {
|
|||
<!-- PHP: TIMELINE --><?php include_once 'partials/timeline.php'?>
|
||||
|
||||
<!-- PHP: FOOTER --><?php include_once 'partials/footer.php';?>
|
||||
|
||||
|
|
|
|||
|
|
@ -84,12 +84,11 @@ if (isset($_POST['submit'])) {
|
|||
exit;
|
||||
|
||||
} else {
|
||||
require_once("partials/base.php");
|
||||
|
||||
require_once("partials/base.php");
|
||||
$title = "New post - ".$title;
|
||||
|
||||
$title = "New post - ".$title;
|
||||
|
||||
include_once 'partials/header.php';
|
||||
include_once 'partials/header.php';
|
||||
?>
|
||||
|
||||
<article id="new_twt">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<?php require_once("partials/base.php");
|
||||
<?php
|
||||
require_once("partials/base.php");
|
||||
|
||||
// Get the hash (only post, not replies) as $id from the router
|
||||
if (!empty($id)) {
|
||||
|
|
|
|||
|
|
@ -93,4 +93,3 @@ echo '<script language="javascript">
|
|||
document.getElementById("refreshCounter").innerHTML = "";
|
||||
history.back();
|
||||
</script>';
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue