Skip to content

Commit

Permalink
feat: demo with php:8.1.10-apache-buster
Browse files Browse the repository at this point in the history
  • Loading branch information
soulteary committed Oct 3, 2022
1 parent bfc0da9 commit d97385b
Show file tree
Hide file tree
Showing 9 changed files with 358 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data
6 changes: 6 additions & 0 deletions app/assets/css/bootstrap.min.css

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions app/assets/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#root {
max-width: 680px;
margin: 0 auto;
}

#brand-container .logo {
width: 40px;
top: 0;
position: absolute;
}

#whispers-container .whisper-content {
white-space: pre;
}

#whispers-container #pagination {
float: right;
}

#whispers-container #page-info {
float: right;
font-size: 12px;
margin-top: 10px;
}

#post-container textarea {
resize: none;
}
1 change: 1 addition & 0 deletions app/assets/img/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/assets/img/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions app/assets/js/main.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

180 changes: 180 additions & 0 deletions app/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
<?php
date_default_timezone_set('Asia/shanghai');

defined('TEMPLATE_DIR') or define('TEMPLATE_DIR', '/usr/share/nginx/html/templates');
defined('DATA_DIR') or define('DATA_DIR', '/usr/share/nginx/html/data');
defined('WHISPER_PER_PAGE') or define('WHISPER_PER_PAGE', 5);
defined('ERROR_IS_EMPTY') or define('ERROR_IS_EMPTY', '内容不能为空');

if (defined('DATA_DIR')) {
if (!file_exists(DATA_DIR)) {
mkdir(DATA_DIR);
}
} else {
echo "需要定义数据目录";
exit;
}

if (!class_exists('Template')) {
class Template
{
protected $dir = TEMPLATE_DIR . DIRECTORY_SEPARATOR;
protected $vars = array();
public function __construct($dir = null)
{
if ($dir !== null) {
$this->dir = $dir;
}
}
public function render($file)
{
if (file_exists($this->dir . $file)) {
include $this->dir . $file;
} else {
throw new Exception('no template file ' . $file . ' present in directory ' . $this->dir);
}
}
public function __set($name, $value)
{
$this->vars[$name] = $value;
}
public function __get($name)
{
return $this->vars[$name];
}
}
}

if (!class_exists('Whisper')) {
class Whisper
{
public function __construct()
{
if (empty($_POST['content'])) {
$start_time = microtime(true);
$page = 1;
if (!empty($_GET['p'])) {
$page = (int) filter_var($_GET['p'], FILTER_SANITIZE_NUMBER_INT);
if ($page < 1) {
$page = 1;
}
}

$tpl = new Template();
$tpl->data = $this->loadData($page);

ob_start();
$tpl->render('main.html');
ob_end_flush();

$end_time = microtime(true);
echo "\n<!-- " . round($end_time - $start_time, 3) . "s -->";
} else {

$content = trim($_POST['content']);
if (strlen($content) == 0) {
echo ERROR_IS_EMPTY;
exit;
}
$content = (string) filter_var($content, FILTER_SANITIZE_SPECIAL_CHARS);
$this->postWhisper($content);
}
}

private function postWhisper($content)
{
$date = date('Y-m-d g:i:s A');
$filename = DATA_DIR . DIRECTORY_SEPARATOR . date('YmdHis') . ".txt";
$file = fopen($filename, "w+");
$content = $date . "\n" . $content . "\n";
fwrite($file, $content);
fclose($file);
header("location: /");
}

private function loadData($page)
{
$result = [
'whispers' => [],
'pagination' => ['hide' => true],
];

$files = [];
if ($handle = @opendir(DATA_DIR)) {
while ($file = readdir($handle)) {
if (!is_dir($file)) {
$files[] = $file;
}
}
}
rsort($files);

$total = sizeof($files);
if ($total == 0) {
return $result;
}

$page = $page - 1;
$start = $page * WHISPER_PER_PAGE;
if (($start + WHISPER_PER_PAGE) > $total) {
$last = $total;
} else {
$last = $start + WHISPER_PER_PAGE;
}

for ($i = $start; $i < $last; $i++) {
$raw = file(DATA_DIR . DIRECTORY_SEPARATOR . $files[$i]);

$date = trim($raw[0]);
unset($raw[0]);

$content = "";
foreach ($raw as $value) {
$content .= $value;
}
$data = array(
'date' => $date,
'content' => $content,
);
$result['whispers'][] = $data;
}

$result['pagination'] = $this->getPagination($start, $last, $page, $total);
return $result;
}

private function getPagination($start, $last, $page, $total)
{
if ($total <= WHISPER_PER_PAGE) {
return ['hide' => true];
}

$page = $page + 1;
$next = 0;
$prev = 0;

if ($start == 0) {
if ($last < $total) {
$next = $page + 1;
}
} else {
if ($last < $total) {
$next = $page + 1;
$prev = $page - 1;
} else {
$prev = $page - 1;
}
}

return [
'hide' => false,
'prev' => $prev,
'next' => $next,
'page' => $page,
'last' => ceil($total / 5),
];
}
}
}

new Whisper();
122 changes: 122 additions & 0 deletions app/templates/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="assets/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/style.css">
<title>Whisper</title>
</head>
<body>
<div id="root">

<div class="container" id="brand-container">
<div class="row">
<div class="py-4 text-center">
<h2>
<span>Whisper</span>
<img class="logo" src="assets/img/logo.svg" alt="" width="72" height="57" />
</h2>
<p class="lead">a simplest example.</p>
</div>
</div>
</div>

<div class="container" id="post-container">
<div class="row">
<div class="col-xs-12">
<h4 class="mb-3"># Post a Whisper</h4>
<form class="mb-3" action="/" method="post" novalidate >
<div class="row g-3">
<div class="col-12">
<textarea class="form-control mb-2" placeholder="enter content here..." name="content" rows="4" required></textarea>
<button class="w-100 btn btn-primary" type="submit">Post</button>
</div>
</div>
</form>
</div>
</div>
</div>

<div class="container" id="whispers-container">
<?php if(!$this->data['pagination']['hide']):?>
<div class="row row-cols-sm-auto">
<div class="col-sm-9">
<hr class="my-3 w-100" />
</div>
<div class="col-sm-3">
<div aria-label="Page navigation" id="pagination">
<ul class="pagination justify-content-center pagination-sm">
<?php if($this->data['pagination']['prev']==0):?>
<li class="page-item disabled">
<a class="page-link">Previous</a>
</li>
<?php else:?>
<li class="page-item">
<a class="page-link" href="?p=<?=$this->data['pagination']['prev']?>">Previous</a>
</li>
<?php endif;?>
<?php if($this->data['pagination']['next']==0):?>
<li class="page-item disabled">
<a class="page-link">Next</a>
</li>
<?php else:?>
<li class="page-item">
<a class="page-link" href="?p=<?=$this->data['pagination']['next']?>">Next</a>
</li>
<?php endif;?>
</ul>
</div>
</div>
</div>
<?php endif;?>

<?php if(sizeof($this->data['whispers'])>0):?>
<div class="row row-cols-sm-auto">
<h4 class="col-sm-12">
<span># List</span>
<?php if(!$this->data['pagination']['hide']):?>
<span class="text-muted" id="page-info">Page #<?=$this->data['pagination']['page']?> / <?=$this->data['pagination']['last']?></span>
<?php endif;?>
</h4>
</div>

<div class="row">
<div class="col-xs-12">
<ul class="list-group w-auto">
<?php foreach ($this->data['whispers'] as $whisper): ?>
<li class="list-group-item d-flex gap-3 py-3" aria-current="true">
<img src="assets/img/icon.svg" width="32" height="32" class="rounded-circle flex-shrink-0">
<div class="d-flex gap-2 w-100 justify-content-between">
<div>
<h6 class="mb-0 whisper-content"><?=$whisper['content']?></h6>
<p class="mb-0 opacity-75"><?=$whisper['date']?></p>
</div>
<small class="opacity-50 text-nowrap timeago" data-value="<?=$whisper['date']?>"></small>
</div>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
<?php endif;?>
</div>

<div class="container">
<div class="row">
<div class="my-3 pt-3 text-muted text-center text-small">
<ul class="list-inline mb-1">
<li class="list-inline-item">&copy; 2007–<?=date('Y');?> @soulteary: <a href="https://soulteary.com/" target="_blank">Blog</a></li>
<li class="list-inline-item"><a href="https://www.zhihu.com/people/soulteary" target="_blank">Zhihu</a></li>
<li class="list-inline-item"><a href="https://weibo.com/u/1220149481" target="_blank">Weibo</a></li>
</ul>
</div>
</div>
</div>

</div>
<script src="assets/js/main.js"></script>
</body>
</html>
14 changes: 14 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: '3'

services:

talk:
image: php:8.1.10-apache-buster
restart: always
ports:
- 8090:80
volumes:
- ./app:/var/www/html/
- ./app/templates:/usr/share/nginx/html/templates:rw
- ./app/data:/usr/share/nginx/html/data:rw

0 comments on commit d97385b

Please sign in to comment.