commit 7d6019b0fa0676580a03ca693f6b42f4794532ca
parent 304f885d3e6e73e0779ba3bacdd6de7bc659dee2
Author: Claudio Alessi <smoppy@gmail.com>
Date:   Wed, 19 Jun 2019 12:16:56 +0200
Few code cleanups and improvements (see below).
- Remove the need to call bored_init(): by default it's now called by
  bored_run()
- Improved humanstime(): some more work is still needed for production
- Constants VIEWDIR and DEFAULT_LAYOUT must be defined outside of bored
- Code cleanups.
Diffstat:
| M | README.md |  |  | 2 | -- | 
| M | bored.php |  |  | 263 | ++++++++++++++++++++++++++++++++++--------------------------------------------- | 
2 files changed, 113 insertions(+), 152 deletions(-)
diff --git a/README.md b/README.md
@@ -7,8 +7,6 @@ In a nutshell:
 <?php
 include('bored.php');
 
-bored_init();
-
 route('GET', '/hello/!name', function($name) {
 	return "Hello ${name}";
 });
diff --git a/bored.php b/bored.php
@@ -1,8 +1,5 @@
 <?php
 
-define('PATH_VIEWS', 'views');
-define('DEFAULT_LAYOUT', 'main');
-
 $HT_DEFAULT_FMTS = [
 	'year_0' => "An year ago",
 	'years_0' => "%d years ago",
@@ -12,6 +9,10 @@ $HT_DEFAULT_FMTS = [
 	'months_0' => "%d months ago",
 	'month_1' => "A month from now",
 	'months_1' => "%d months from now",
+	'week_0' => "A week ago",
+	'weeks_0' => "%d weeks ago",
+	'week_1' => "A week from now",
+	'weeks_1' => "%d weeks from now",
 	'day_0' => "A day ago",
 	'days_0' => "%d days ago",
 	'day_1' => "A day from now",
@@ -28,15 +29,21 @@ $HT_DEFAULT_FMTS = [
 	'seconds_0' => "%d seconds ago",
 	'second_1' => "A second from now",
 	'seconds_1' => "%d seconds from now",
+	'now_0' => "Just now",
+	'nows_0' => "Few seconds ago",
+	'now_1' => "Just now",
+	'nows_1' => "In a bit",
 ];
 
 $HT_DIVS = [
 	'year' => 60*60*24*365,
-	'month' => 60*60*24*31,
+	'month' => 60*60*24*30,
+	'week' => 60*60*24*7,
 	'day' => 60*60*24,
 	'hour' => 60*60,
 	'minute' => 60,
-	'second' => 0
+	'second' => 30,
+	'now' => 0,
 ];
 
 $dblink = null;
@@ -74,9 +81,9 @@ function route($method, $route, $func = null) {
         $mandatory = 0;
         foreach(explode('/', $route) as $arg) {
                 switch(@$arg[0]) {
-                        case '!': ++$argc; ++$mandatory; break;
-                        case '?': ++$argc; break;
-                        default: $name[] = $arg; break;
+		case '!': ++$argc; ++$mandatory; break;
+		case '?': ++$argc; break;
+		default: $name[] = $arg; break;
                 }
         }
         $name = implode('/', $name);
@@ -86,15 +93,18 @@ function route($method, $route, $func = null) {
         return 0;
 }
 
-function dbopen($host, $user, $pass, $name) {
-	if(!($r = @mysqli_connect($host, $user, $pass, $name)))
-		die('database error');
+function dbopen($host, $user, $pass, $dbname) {
 	global $dblink;
+
+	if(!($r = @mysqli_connect($host, $user, $pass, $dbname)))
+		die('database error');
 	$dblink = $r;
 	return $r;
 }
 
 function dbquery($sql, $limit = 1, $multi = false) {
+	global $dblink;
+
 	if(!is_string($sql) || !($sql = trim($sql)))
 		return false;
 
@@ -102,27 +112,19 @@ function dbquery($sql, $limit = 1, $multi = false) {
 	if(($ret = cache($ck)))
 		return $ret;
 
-	global $dblink;
 	$cn = "$sql-$limit-$multi";
-
 	$cmd = strtolower(substr($sql, 0, strpos($sql, ' ')));
-
 	if($cmd == 'select') {
 		if($limit == -1)
 			$limit = '18446744073709551615';
 		$sql .= " limit $limit";
 	}
 
-	if($multi)
-		$res = mysqli_multi_query($dblink, $sql);
-	else
-		$res = mysqli_query($dblink, $sql);
+	$res = $multi ? mysqli_multi_query($dblink, $sql) : mysqli_query($dblink, $sql);
 	if(!$res)
 		return false;
-
 	if($multi) {
 		$ret = [];
-
 		for($res = mysqli_use_result($dblink); $res; $res = mysqli_store_result($dblink)) {
 			$r = [];
 			while(($t = mysqli_fetch_assoc($res)))
@@ -131,53 +133,43 @@ function dbquery($sql, $limit = 1, $multi = false) {
 			mysqli_free_result($res);
 			mysqli_next_result($dblink);
 		}
+		return $ret;
 	}
-	else {
-		switch($cmd) {
-			case 'select':
-			case 'call':
-				if($cmd == 'select' && $limit == '1') {
-					$ret = mysqli_fetch_assoc($res);
-					break;
-				}
-
-				$ret = [];
-				while(($t = mysqli_fetch_assoc($res)))
-					$ret[] = $t;
-				break;
-
-			case 'insert':
-				$ret = mysqli_insert_id($dblink);
-				if(!$ret)
-					$ret = true;
-				break;
-
-			case 'delete':
-				$ret = mysqli_affected_rows($dblink);
-				break;
-
-			default:
-				$ret = $res;
-				break;
-		}
+	switch($cmd) {
+	case 'select':
+	case 'call':
+		$ret = [];
+		while(($t = mysqli_fetch_assoc($res)))
+			$ret[] = $t;
+		break;
+	case 'insert':
+		$ret = mysqli_insert_id($dblink);
+		if(!$ret)
+			$ret = true;
+		break;
+	case 'delete':
+		$ret = mysqli_affected_rows($dblink);
+		break;
+	default:
+		$ret = $res;
+		break;
 	}
-
 	return $ret;
 }
 
 function dbping($l = null) {
-        if(!$l) {
-                global $dblink;
+	global $dblink;
+
+        if(!$l)
                 $l = $dblink;
-        }
 	return mysqli_ping($l);
 }
 
 function dberr($l = null) {
-        if(!$l) {
-                global $dblink;
+	global $dblink;
+
+        if(!$l)
                 $l = $dblink;
-        }
         return mysqli_error($l);
 }
 
@@ -193,20 +185,10 @@ function dbout($s) {
 	return stripslashes(html_entity_decode($s, ENT_QUOTES, 'UTF-8'));
 }
 
-function dbput($tbl, $info) {
-	$vals = [];
-	foreach($info as $k => $v)
-		$vals["`$k`"] = dbin($v);
-	$sql = 'insert into `'.$tbl.'`
-		('.implode(',', array_keys($vals)).')
-		values ('.implode(',', array_values($vals)).')';
-	return dbquery($sql);
-}
-
 function dbids() {
 	/* Assuming transactional DB (InnoDB) */
 	$sql = "select LAST_INSERT_ID() as s,LAST_INSERT_ID() + ROW_COUNT() - 1 as e";
-	$t = dbquery($sql);
+	$t = dbquery($sql)[0];
 	return range($t["s"], $t["e"]);
 }
 
@@ -266,52 +248,34 @@ function sizefitbox($src, $dst) {
 	return "${w}x${h}";
 }
 
-function thumb($src, $size = '64x64', $force = 0) {
-	if(strpos($size, 'x') === false)
-		$size = (int)$size.'x'.(int)$size;
-	$pi = pathinfo($src);
-	/* Since imgresize() use the extension to identify the file type, it's
-	 * faster to returns here. */
-	if(!@$pi['extension'])
-		return null;
-	/* name.ext > name.size.ext */
-	$thumb = "${pi['dirname']}/${pi['filename']}.${size}.${pi['extension']}";
-	if(!$force && file_exists($thumb))
-		return $thumb;
-	$t = imgresize($src, $thumb, $size);
-	if($t)
-		return $t;
-	return $thumb;
-}
-
 function imgresize($src, $saveas, $whxy = '64x64-0,0', $opts = null) {
 	$in = null;
 	$out = null;
 	$transparency = false;
 	$ext = strtolower((string)@pathinfo($src)['extension']);
 	switch($ext) {
-		case 'jpg':
-		case 'jpeg':
-			$in = 'imagecreatefromjpeg';
-			$out = 'imagejpeg';
-			break;
-		case 'gif':
-			$in = 'imagecreatefromgif';
-			$out = 'imagegif';
-			/* imagegif() doesn't take a third param */
-			if($opts !== null)
-				$opts = null;
-			break;
-		case 'bmp':
-			$in = 'imagecreatefromwbmp';
-			$out = 'imagewbmp';
-			break;
-		case 'png':
-			$in = 'imagecreatefrompng';
-			$out = 'imagepng';
-			$transparency = true;
-			break;
-		default: /* unsupported image */ return -1;
+	case 'jpg':
+	case 'jpeg':
+		$in = 'imagecreatefromjpeg';
+		$out = 'imagejpeg';
+		break;
+	case 'gif':
+		$in = 'imagecreatefromgif';
+		$out = 'imagegif';
+		/* imagegif() doesn't take a third param */
+		if($opts !== null)
+			$opts = null;
+		break;
+	case 'bmp':
+		$in = 'imagecreatefromwbmp';
+		$out = 'imagewbmp';
+		break;
+	case 'png':
+		$in = 'imagecreatefrompng';
+		$out = 'imagepng';
+		$transparency = true;
+		break;
+	default: /* unsupported image */ return -1;
 	}
 	if(!($oi = $in($src)))
 		return 2;
@@ -390,37 +354,34 @@ function json($state, $res) {
 
 function sendmail($from, $to, $subj, $message, $files = null) {
 	ini_set('sendmail_from', $from);
-	$headers =      "From: $from\n" .
-			"Return-Path: <$from>\r\n" .
-			"MIME-Version: 1.0\n";
-
+	$headers = "From: $from\n" .
+		   "Return-Path: <$from>\r\n" .
+		   "MIME-Version: 1.0\n";
 	if(!(is_array($files) || count($files))) {
-		$headers .=     "Content-Type: text/html; charset=\"UTF-8\"\n" .
-				"Content-Transfer-Encoding: 7bit\n\n";
+		$headers .= "Content-Type: text/html; charset=\"UTF-8\"\n" .
+			    "Content-Transfer-Encoding: 7bit\n\n";
 	}
 	else {
 		$semi_rand = md5(time());
 		$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
-		$headers .=     "Content-Type: multipart/mixed; boundary=\"{$mime_boundary}\"\n";
-		$message =      "--{$mime_boundary}\n" .
-				"Content-Type: text/plain; charset=\"UTF-8\"\n" .
-				"Content-Transfer-Encoding: 7bit\n\n" .
-				$message . "\n\n";
+		$headers .= "Content-Type: multipart/mixed; boundary=\"{$mime_boundary}\"\n";
+		$message = "--{$mime_boundary}\n" .
+			   "Content-Type: text/plain; charset=\"UTF-8\"\n" .
+			   "Content-Transfer-Encoding: 7bit\n\n" .
+			   $message . "\n\n";
 		foreach($files as $fn) {
 			$f = basename($fn);
 			if(!is_file($fn))
 				continue;
 			$data = chunk_split(base64_encode(file_get_contents($fn)));
-
-			$message .=     "--{$mime_boundary}\n" .
-					"Content-Type: application/octet-stream; name=\"$f\"\n" .
-					"Content-Description: $f\n" .
-					"Content-Disposition: attachment; filename=\"$f\"; size=".filesize($fn).";\n" .
-					"Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
+			$message .= "--{$mime_boundary}\n" .
+				    "Content-Type: application/octet-stream; name=\"$f\"\n" .
+				    "Content-Description: $f\n" .
+				    "Content-Disposition: attachment; filename=\"$f\"; size=".filesize($fn).";\n" .
+				    "Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
 		}
 		$message .= "--{$mime_boundary}--";
 	}
-
 	return @mail($to, $subj, $message, $headers);
 }
 
@@ -442,37 +403,28 @@ function sess($k, $v = null) {
 }
 
 function pre($d) {
-	echo '<pre>';
-	print_r($d);
-	echo '</pre>';
+	echo '<pre>'.print_r($d,1).'</pre>';
 }
 
 function humanstime($timestamp, $fmts = null) {
-	global $HT_DIVS;
+	global $HT_DEFAULT_FMTS, $HT_DIVS;
 
 	$divs = $HT_DIVS;
 	$diff = time() - $timestamp;
 	$isfuture = ($diff < 0);
 	if($isfuture)
 		$diff = -$diff;
-
-	foreach($divs as $name => $delta) {
+	foreach($divs as $name => $delta)
 		if($diff >= $delta)
 			break;
-	}
-
-	$unit = $delta ? $diff / $delta : $diff;
+	$unit = (int)($delta ? $diff / $delta : $diff);
 	$ht = [
 		'name' => $name.($unit > 1 ? 's' : ''),
 		'unit' => $unit,
 		'isfuture' => $isfuture
 	];
-
-	if(!$fmts) {
-		global $HT_DEFAULT_FMTS;
+	if(!$fmts)
 		$fmts = $HT_DEFAULT_FMTS;
-	}
-
 	$k = $ht['name'].'_'.(int)$ht['isfuture'];
 	return sprintf($fmts[$k], $ht['unit']);
 }
@@ -480,10 +432,12 @@ function humanstime($timestamp, $fmts = null) {
 function curl_post($uri, $curlopts = []) {
 	$c = curl_init();
 
-	$curlopts[CURLOPT_RETURNTRANSFER] = 1;
-	$curlopts[CURLOPT_URL] = $uri;
-	$curlopts[CURLOPT_POST] = 1;
-	curl_setopt_array($c, $curlopts);
+	curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
+	curl_setopt($c, CURLOPT_URL, $uri);
+	curl_setopt($c, CURLOPT_POST, true);
+	if($curlopts)
+		foreach($curlopts as $k => $v)
+			curl_setopt($c, $k, $v);
 	$ret = curl_exec($c);
 	curl_close($c);
 	return $ret;
@@ -538,11 +492,13 @@ function buildhier($items, $pk = 'parent_id', $ck = 'id', $subk = 'children') {
 }
 
 function viewinc($name, $data = []) {
-	if(!defined('PATH_VIEWS'))
-		die('PATH_VIEWS not defined');
+	if(!defined("VIEWDIR"))
+		die("VIEWDIR not defined");
         foreach($data as $k => $v)
                 ${$k} = $v;
-        $view = PATH_VIEWS.'/'.implode('/', explode('.', $name)).'.php';
+        $view = VIEWDIR.'/'.implode('/', explode('.', $name)).'.php';
+	if(!file_exists($view))
+		return NULL;
         ob_start();
         require($view);
         $d = ob_get_contents();
@@ -556,8 +512,11 @@ function lviewinc($name, $data = [], $layout = null, $layoutdata = []) {
 			die('DEFAULT_LAYOUT not defined');
 		$layout = DEFAULT_LAYOUT;
 	}
+	$content = viewinc($name, $data);
+	if($content === NULL)
+		return NULL;
 	$layoutdata["viewname"] = $name;
-	$layoutdata["content"] = viewinc($name, $data);
+	$layoutdata["content"] = $content;
 	return viewinc($layout, $layoutdata);
 }
 
@@ -565,21 +524,25 @@ function view($name, $data = []) {
 	return lviewinc($name, $data, null, $data);
 }
 
-function bored_run() {
-	echo route($_SERVER['REQUEST_METHOD'], (string)@explode('?', $_SERVER['REQUEST_URI'])[0]);
-}
-
 function bored_init() {
+	setlocale(LC_CTYPE, "");
 	prepare_form();
 	session_start();
 	if(defined('DBHOST') && defined('DBUSER') && defined('DBPASS') && defined('DBNAME'))
 		dbopen(DBHOST, DBUSER, DBPASS, DBNAME);
 	register_shutdown_function(function() {
 		global $dblink;
+
 		if($dblink)
 			mysqli_close($dblink);
 		session_write_close();
 	});
 }
 
+function bored_run($noinit = 0) {
+	if(!$noinit)
+		bored_init();
+	echo route($_SERVER['REQUEST_METHOD'], (string)@explode('?', $_SERVER['REQUEST_URI'])[0]);
+}
+
 ?>