2023-06-30 23:39:01 +02:00
< ? php
/*
* speedie - blog
*
* Copyright ( C ) 2007 - 2011 Steven Frank < http :// stevenf . com />
* Copyright ( C ) 2023 speedie < speedie @ speedie . site >
*
2023-07-01 12:45:01 +02:00
* See LICENSE . blog file for copyright and license details .
2023-06-30 23:39:01 +02:00
*/
2023-07-02 01:32:43 +02:00
// some settings
define ( 'BLOG_EXT' , " md " );
define ( 'BLOG_TITLE' , " speedie's blog " );
define ( 'BLOG_DESC' , " speedie's blog, about stuff I want to talk about. " );
define ( 'BLOG_URL' , " https://speedie.site/blog " );
define ( 'BLOG_LATEST_TEXT' , " Latest blog post: " );
define ( 'BLOG_DIR' , " /articles " );
define ( 'DISPLAY_NUM' , false );
define ( 'DISPLAY_ID' , false );
define ( 'ENABLE_TITLE' , true );
define ( 'ENABLE_HEAD' , true );
define ( 'ENABLE_FOOTER' , true );
define ( 'META_DESC' , true );
define ( 'META_ENC' , true );
spl_autoload_register ( function ( $class ) {
2023-06-30 23:39:01 +02:00
require str_replace ( '\\' , DIRECTORY_SEPARATOR , ltrim ( $class , '\\' )) . '.php' ;
});
define ( 'SELF' , $_SERVER [ 'SCRIPT_NAME' ]);
2023-07-01 21:37:27 +02:00
define ( 'VIEW' , '' );
2023-07-02 01:32:43 +02:00
define ( 'BASE_URI' , str_replace ( '/index.php' , '' , $_SERVER [ 'SCRIPT_NAME' ]));
define ( 'BLOG_PATH' , dirname ( __FILE__ ) . BLOG_DIR );
2023-06-30 23:39:01 +02:00
2023-07-02 01:32:43 +02:00
use md\MarkdownExtra ;
2023-06-30 23:39:01 +02:00
2023-07-02 01:32:43 +02:00
function isntNull ( $label , $alt_word = null ) {
2023-06-30 23:39:01 +02:00
return is_null ( $alt_word ) ? $label : $alt_word ;
}
function truncate ( $text , $chars ) {
if ( strlen ( $text ) <= $chars ) {
return $text ;
}
$text = $text . " " ;
$text = substr ( $text , 0 , $chars );
$text = substr ( $text , 0 , strrpos ( $text , ' ' ));
$text = $text . " ... " ;
return $text ;
}
function printHeader ( $title , $action , $html ) {
// TODO: Improve this garbage, I suck at PHP and this is just stuff I found on the internet.
if ( META_DESC ) {
$nhtml = $html ;
$nhtml = preg_replace ( '@<p\b[^>]*>(?=.*?<a\b[^>]*>).*?<\@p>@si' , '' , $nhtml );
$nhtml = preg_replace ( '@<(li)[^>]*?>.*?</\\1>@si' , '' , $nhtml );
$nhtml = preg_replace ( '@<(ul)[^>]*?>.*?</\\1>@si' , '' , $nhtml );
$nhtml = strip_tags ( $nhtml );
$nhtml = preg_replace ( '/\s*$^\s*/m' , " \n " , $nhtml );
$nhtml = truncate ( $nhtml , 512 );
}
if ( ENABLE_HEAD ) {
2023-07-01 19:05:57 +02:00
print " <!DOCTYPE html> \n " ;
print " <head> \n " ;
2023-06-30 23:39:01 +02:00
if ( META_DESC && $action != 'home' ) {
2023-07-01 19:05:57 +02:00
print " <meta name= \" description \" content= \" $nhtml\ " > \n " ;
} else if ( META_DESC ) {
print " <meta name= \" description \" content= " . BLOG_DESC . " > \n " ;
2023-06-30 23:39:01 +02:00
}
if ( ENABLE_TITLE ) {
2023-07-01 19:05:57 +02:00
print " <title> $title </title> \n " ;
2023-06-30 23:39:01 +02:00
}
include ( " php/header.php " );
print " </head> \n " ;
}
print " <body> \n " ;
2023-07-01 19:42:01 +02:00
print " <div class= \" content \" > \n \n " ;
2023-06-30 23:39:01 +02:00
}
function printFooter () {
if ( ENABLE_FOOTER ) {
print " </body> \n " ;
2023-07-01 19:05:57 +02:00
print " <footer> \n " ;
2023-06-30 23:39:01 +02:00
include ( " php/footer.php " );
2023-07-01 19:05:57 +02:00
print " </footer> \n " ;
2023-06-30 23:39:01 +02:00
}
}
2023-08-30 08:15:01 +02:00
function getDateForPost ( $postName ) {
2023-07-02 01:32:43 +02:00
$file = BLOG_PATH . " / $postName . " . BLOG_EXT . " .date " ;
2023-06-30 23:39:01 +02:00
if ( file_exists ( $file )) {
return file_get_contents ( $file );
} else {
2023-07-01 13:24:33 +02:00
return 0 ;
2023-06-30 23:39:01 +02:00
}
}
2023-08-28 17:14:43 +02:00
function getNameForPost ( $postName ) {
$file = BLOG_PATH . " / $postName . " . BLOG_EXT . " .title " ;
$title = $postName ;
if ( file_exists ( $file )) {
return rtrim ( file_get_contents ( $file ));
}
return $postName ;
}
2023-07-02 01:32:43 +02:00
function getAllPostNames ( $path = " " ) {
2023-06-30 23:39:01 +02:00
$filenames = array ();
$dir = opendir ( BLOG_PATH . " / $path " );
while ( $filename = readdir ( $dir ) ) {
if ( $filename [ 0 ] == " . " ) {
continue ;
}
if ( is_dir ( BLOG_PATH . " / $path / $filename " ) ) {
2023-07-02 01:32:43 +02:00
array_push ( $filenames , ... getAllPostNames ( " $path / $filename " ) );
2023-06-30 23:39:01 +02:00
continue ;
}
if ( preg_match ( " / " . BLOG_EXT . " $ / " , $filename ) != 1 ) {
continue ;
}
$filename = substr ( $filename , 0 , - ( strlen ( BLOG_EXT ) + 1 ) );
$filenames [] = substr ( " $path / $filename " , 1 );
}
closedir ( $dir );
return $filenames ;
}
2023-07-02 01:32:43 +02:00
function fileNameForPost ( $post ) {
return BLOG_PATH . " / $post . " . BLOG_EXT ;
2023-06-30 23:39:01 +02:00
}
2023-07-02 01:32:43 +02:00
function dateForPost ( $post ) {
$file = BLOG_PATH . " / $post . " . BLOG_EXT . " .date " ;
2023-06-30 23:39:01 +02:00
2023-07-01 13:24:33 +02:00
if ( file_exists ( $file )) {
2023-06-30 23:39:01 +02:00
return file_get_contents ( $file );
}
}
2023-07-02 01:32:43 +02:00
function numForPost ( $post ) {
$file = BLOG_PATH . " / $post . " . BLOG_EXT . " .num " ;
2023-06-30 23:39:01 +02:00
2023-07-02 22:25:13 +02:00
if ( file_exists ( $file )) {
return file_get_contents ( $file );
} else {
return 0 ;
}
2023-06-30 23:39:01 +02:00
}
function sanitizeFilename ( $inFileName ) {
2023-07-01 19:22:12 +02:00
return str_replace ( array ( '~' , '..' , '\\' , ':' , '|' , '&' , '.' , '+' , '!' ), '-' , $inFileName );
2023-06-30 23:39:01 +02:00
}
2023-07-02 01:32:43 +02:00
function postURL ( $post ) {
return SELF . VIEW . " / " . str_replace ( " %2F " , " / " , str_replace ( " %23 " , " # " , urlencode ( sanitizeFilename ( $post ))));
2023-06-30 23:39:01 +02:00
}
2023-07-02 01:32:43 +02:00
function postLink ( $post , $title , $attributes = " " ) {
return " <a href= \" " . postURL ( $post ) . " \" $attributes > $title </a> " ;
2023-06-30 23:39:01 +02:00
}
function toHTMLID ( $noid ) {
return str_replace ( " " , " - " , $noid );
}
function toHTML ( $inText ) {
$parser = new MarkdownExtra ;
$parser -> no_markup = true ;
$outHTML = $parser -> transform ( $inText );
preg_match_all ( " / \ [ \ [(.*?) \ ] \ ]/ " , $outHTML , $matches , PREG_PATTERN_ORDER );
for ( $i = 0 ; $i < count ( $matches [ 0 ]); $i ++ ) {
$fullLinkText = $matches [ 1 ][ $i ];
$linkTitleSplit = explode ( '|' , $fullLinkText );
2023-07-02 01:32:43 +02:00
$linkedPost = $linkTitleSplit [ 0 ]; // split away an eventual link text
$linkText = ( count ( $linkTitleSplit ) > 1 ) ? $linkTitleSplit [ 1 ] : $linkedPost ;
$postPart = explode ( '#' , $linkedPost )[ 0 ]; // split away an eventual anchor part
$linkedFilename = fileNameForPost ( sanitizeFilename ( $postPart ));
2023-06-30 23:39:01 +02:00
$exists = file_exists ( $linkedFilename );
}
preg_match_all ( " /<h([1-4])>(.*?)< \ /h \\ 1>/ " , $outHTML , $matches , PREG_PATTERN_ORDER );
for ( $i = 0 ; $i < count ( $matches [ 0 ]); $i ++ ) {
$prefix = " <h " . $matches [ 1 ][ $i ] . " > " ;
$caption = $matches [ 2 ][ $i ];
$suffix = substr_replace ( $prefix , " / " , 1 , 0 );
}
return $outHTML ;
}
$action = isset ( $_REQUEST [ 'action' ]) ? $_REQUEST [ 'action' ] : 'view' ;
2023-07-02 01:32:43 +02:00
$newPost = " " ;
2023-06-30 23:39:01 +02:00
$text = " " ;
$html = " " ;
2023-07-01 12:33:55 +02:00
$rss = " " ;
2023-06-30 23:39:01 +02:00
2023-07-02 01:32:43 +02:00
$post = preg_match ( '@^/@' , @ $_SERVER [ " PATH_INFO " ]) ?
urldecode ( substr ( $_SERVER [ " PATH_INFO " ], 1 )) : urldecode ( @ $_REQUEST [ 'post' ]);
$post = sanitizeFilename ( $post );
2023-06-30 23:39:01 +02:00
2023-07-02 01:32:43 +02:00
if ( $post != '' ) {
$filename = fileNameForPost ( $post );
2023-06-30 23:39:01 +02:00
2023-07-01 12:33:55 +02:00
if ( file_exists ( $filename ) ) {
$text = file_get_contents ( $filename );
2023-06-30 23:39:01 +02:00
} else {
2023-07-02 01:32:43 +02:00
$newPost = NULL ;
2023-07-01 12:33:55 +02:00
include ( 'php/404.php' );
die ();
2023-06-30 23:39:01 +02:00
}
2023-07-01 12:33:55 +02:00
} else {
$action = 'home' ;
2023-06-30 23:39:01 +02:00
}
if ( $action === 'home' ) {
2023-07-02 01:32:43 +02:00
$postNames = getAllPostNames ();
2023-06-30 23:39:01 +02:00
$filelist = array ();
$sortBy = isset ( $_REQUEST [ 'sortBy' ]) ? $_REQUEST [ 'sortBy' ] : 'name' ;
2023-07-02 01:32:43 +02:00
foreach ( $postNames as $post ) {
2023-07-02 22:25:13 +02:00
$filelist [ $post ] = strtotime ( dateForPost ( $post ));
2023-06-30 23:39:01 +02:00
}
arsort ( $filelist , SORT_NUMERIC );
2023-07-01 12:33:55 +02:00
// Create the RSS feed
$rss .= " <rss version= \" 2.0 \" xmlns:atom= \" http://www.w3.org/2005/Atom \" > \n " ;
$rss .= " <channel> \n " ;
$rss .= " <title> " . BLOG_TITLE . " </title> \n " ;
$rss .= " <description> " . BLOG_DESC . " </description> \n " ;
$rss .= " <atom:link href= \" " . BLOG_URL . " \" rel= \" self \" type= \" application/rss+xml \" /> \n " ;
2023-07-01 21:37:27 +02:00
// Print text before blog itself
$html .= " <h2>Blog</h2> \n " ;
$html .= " <p>This is a list of all my blog posts. If you prefer, you can also read them using your favorite RSS reader through <a href= \" rss.xml \" >my feed.</a> \n " ;
2023-08-30 08:00:28 +02:00
$html .= " <p>If you wish, you can also get site updates, through the <a href= \" news.xml \" >updates feed</a> or <a href= \" news.php \" > your web browser.</a> The feed is updated whenever there are important things to announce with the site, or a new release for my software is out.</p> \n " ;
2023-07-01 21:37:27 +02:00
$html .= " <ul> \n " ;
$f = " 0 " ;
2023-07-02 01:32:43 +02:00
$num = " " ;
foreach ( $filelist as $postName => $postDate ) {
2023-07-01 21:37:27 +02:00
if ( DISPLAY_NUM ) {
$i += 1 ;
$num = " $i " ;
}
if ( DISPLAY_ID ) {
2023-07-02 01:32:43 +02:00
$i = numForPost ( $postName );
2023-07-01 21:37:27 +02:00
$num = " $i " ;
}
2023-08-30 08:15:01 +02:00
$pubDate = date ( 'r' , strtotime ( getDateForPost ( $postName )));
2023-07-02 01:32:43 +02:00
$link = postURL ( $postName , $postName );
$description = toHTML ( file_get_contents ( fileNameForPost ( $postName )));
2023-08-28 17:14:43 +02:00
$title = getNameForPost ( $postName );
2023-07-01 12:33:55 +02:00
$rss .= " <item> \n " ;
2023-08-28 17:14:43 +02:00
$rss .= " <title> $title </title> \n " ;
2023-07-01 12:33:55 +02:00
$rss .= " <link> $link </link> \n " ;
$rss .= " <guid> $link </guid> \n " ;
$rss .= " <pubDate> $pubDate </pubDate> \n " ;
$rss .= " <description> \n " ;
$rss .= " <![CDATA[ \n " ;
$rss .= " $description\n " ;
$rss .= " ]]> \n " ;
$rss .= " </description> \n " ;
$rss .= " </item> \n " ;
2023-07-01 21:37:27 +02:00
$html .= " <li> " ;
if ( ! $f ) {
2023-08-30 08:15:01 +02:00
$html .= " <p class= \" latest \" ><strong> $num </strong> " . BLOG_LATEST_TEXT . postLink ( $postName , $title ) . " , written " . getDateForPost ( $postName ) . " </p> " ;
2023-07-01 21:37:27 +02:00
$f = 1 ;
} else {
2023-08-30 08:15:01 +02:00
$html .= " <p><strong> $num </strong> " . postLink ( $postName , $title ) . " , written " . getDateForPost ( $postName ) . " </p> " ;
2023-07-01 21:37:27 +02:00
}
$html .= " </li> \n " ;
2023-06-30 23:39:01 +02:00
}
2023-07-01 12:33:55 +02:00
2023-07-01 21:37:27 +02:00
$html .= " </ul> \n " ;
2023-07-02 01:32:43 +02:00
// Write end of the post
2023-07-01 21:37:27 +02:00
$html .= " <h3>Archived blog posts</h3> \n " ;
$html .= " <p>Some blog posts have been archived because they're written out of frustration, are irrelevant or just aren't worth reading. You can still access the blog posts through these RSS feeds:</p> \n " ;
$html .= " <ul> \n " ;
$html .= " <li><a href= \" rss-archived-01.xml \" >Blog post archive feed (1-36)</a></li> \n " ;
$html .= " <li><a href= \" rss-archived-02.xml \" >Blog post archive feed (37-49)</a></li> \n " ;
$html .= " </ul> \n " ;
2023-07-01 12:33:55 +02:00
// End the RSS feed
$rss .= " </channel> \n " ;
$rss .= " </rss> \n " ;
if ( file_get_contents ( 'rss.xml' ) != $rss ) {
file_put_contents ( 'rss.xml' , $rss );
}
2023-07-02 01:32:43 +02:00
} else { // convert the post and view it
2023-08-30 08:15:01 +02:00
$name = getNameForPost ( $post );
$date = getDateForPost ( $post );
$html .= " <h1> $name </h1> \n " ;
$html .= " <p> $date </p> \n " ;
2023-06-30 23:39:01 +02:00
$html .= empty ( $text ) ? '' : toHTML ( $text );
}
// All blog posts
if (( $action === 'home' )) {
2023-07-02 01:32:43 +02:00
$title = isntNull ( " Blog posts " );
2023-08-28 17:31:10 +02:00
} else {
$title = getNameForPost ( $post );
2023-06-30 23:39:01 +02:00
}
// print text
printHeader ( $title , $action , $html );
2023-07-01 19:42:01 +02:00
2023-07-01 13:26:43 +02:00
print " $html\n " ;
2023-06-30 23:39:01 +02:00
print " </div> \n " ;
printFooter ();
2023-07-01 19:05:57 +02:00
print " </html> \n " ;