Skip to content
This repository has been archived by the owner on Nov 2, 2020. It is now read-only.

Commit

Permalink
feat(News): Add Site News model
Browse files Browse the repository at this point in the history
Now we can manage site news,
though some function is not ready..

BREAKING CHANGE: DB structure change: TABLE `news` added
  • Loading branch information
Rhilip committed May 31, 2019
1 parent 07c7fd1 commit e9397fb
Show file tree
Hide file tree
Showing 12 changed files with 448 additions and 9 deletions.
9 changes: 9 additions & 0 deletions apps/components/User/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,13 @@ public function inBookmarkList($tid = null)
{
return in_array($tid, $this->getBookmarkList());
}

public function isPrivilege($require_class)
{
if (is_string($require_class)) {
$require_class = app()->config->get('authority.' . $require_class);
}

return $this->class >= $require_class;
}
}
11 changes: 10 additions & 1 deletion apps/controllers/IndexController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ class IndexController extends Controller
// 默认动作
public function actionIndex()
{
return $this->render('index');
// Get Last News from redis cache
$news = app()->redis->get('Site:recent_news');
if (empty($news)) { // Get news from Database and cache it in redis
$news = app()->pdo->createCommand('SELECT * FROM news ORDER BY create_at DESC LIMIT :max')->bindParams([
'max' => app()->config->get('base.max_news_sum')
])->queryAll();
app()->redis->set('Site:recent_news',$news,86400);
}

return $this->render('index',['news'=>$news]);
}
}
101 changes: 101 additions & 0 deletions apps/controllers/NewsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php
/**
* Created by PhpStorm.
* User: Rhilip
* Date: 2019/5/31
* Time: 10:09
*/

namespace apps\controllers;


use apps\models\form\NewEditForm;
use Rid\Http\Controller;

class NewsController extends Controller
{
public function actionIndex() {

$query = app()->request->get('query','title');
$search = app()->request->get('search','');
if (empty($search)) {
$count = app()->pdo->createCommand('SELECT COUNT(*) FROM `news`;')->queryScalar();
} else {
$count = app()->pdo->createCommand([
['SELECT COUNT(*) FROM `news` WHERE 1=1 '],
['AND `title` LIKE :search ', 'params' => ['search' => "%$search%"], 'if' => ($query == 'title' && !empty($search))],
['AND `body` LIKE :search ', 'params' => ['search' => "%$search%"], 'if' => ($query == 'body' && !empty($search))],
['AND `title` LIKE :st OR `body` LIKE :sb ', 'params' => ['st' => "%$search%",'sb' => "%$search%"], 'if' => ($query == 'both' && !empty($search))],
])->queryScalar();
}

$page = app()->request->get('page',1);
if (!filter_var($page,FILTER_VALIDATE_INT)) $page = 1;
$limit = 10;

$news = app()->pdo->createCommand([
['SELECT * FROM `news` WHERE 1=1 '],
['AND `title` LIKE :search ', 'params' => ['search' => "%$search%"], 'if' => ($query == 'title' && !empty($search))],
['AND `body` LIKE :search ', 'params' => ['search' => "%$search%"], 'if' => ($query == 'body' && !empty($search))],
['AND `title` LIKE :st OR `body` LIKE :sb ', 'params' => ['st' => "%$search%",'sb' => "%$search%"], 'if' => ($query == 'both' && !empty($search))],
['ORDER BY create_at DESC '],
['LIMIT :offset, :rows', 'params' => ['offset' => ($page - 1) * $limit, 'rows' => $limit]],
])->queryAll();

return $this->render('news/index', ['news' => $news, 'query' => $query, 'search' => $search, 'count' => $count, 'limit' => $limit]);

}

public function actionNew() {
if (app()->request->isPost()) {
$newform = new NewEditForm();
$newform->setData(app()->request->post());
$success = $newform->validate();
if (!$success) {
return $this->render('errors/action_fail', ['title' => 'new blog failed', 'msg' => $newform->getError()]);
} else {
$newform->flush(); // Save the news
return app()->response->redirect('/news');
}
} elseif (app()->user->isPrivilege('manage_news')) {
return $this->render('news/edit');
}
return $this->render('errors/action_fail', ['title' => 'Action Failed', 'msg' => 'action not allowed']);
}

public function actionEdit()
{
if (app()->request->isPost()) {
$newform = new NewEditForm();
$newform->setData(app()->request->post());
$success = $newform->validate();
if (!$success) {
return $this->render('errors/action_fail', ['title' => 'Upload Failed', 'msg' => $newform->getError()]);
} else {
$newform->flush(); // Save the news
return app()->response->redirect('/news');
}
} elseif (app()->user->isPrivilege('manage_news')) {
$id = app()->request->get('id', 0);
if (filter_var($id, FILTER_VALIDATE_INT) && $id > 0) {
// TODO add other check
$news = app()->pdo->createCommand('SELECT * FROM news WHERE id= :id')->bindParams(['id' => $id])->queryOne();
return $this->render('news/edit', ['news' => $news]);
}
}
return $this->render('errors/action_fail', ['title' => 'Action Failed', 'msg' => 'action not allowed']);
}

public function actionDelete() {
if (app()->user->isPrivilege('manage_news')) {
$id = app()->request->get('id',0);
if (filter_var($id,FILTER_VALIDATE_INT) && $id > 0) {
// TODO add other check
app()->pdo->createCommand('DELETE FROM news WHERE id= :id')->bindParams(['id'=>$id])->execute();
}
return app()->response->redirect('/news');
}
return $this->render('errors/action_fail', ['title' => 'Action Failed', 'msg' => 'action not allowed']);

}
}
66 changes: 66 additions & 0 deletions apps/models/form/NewEditForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
/**
* Created by PhpStorm.
* User: Rhilip
* Date: 2019/5/31
* Time: 19:56
*/

namespace apps\models\form;


use Rid\Validators\Validator;

class NewEditForm extends Validator
{
public $id = 0;

public $user_id;
public $title;
public $body;
public $notify = 0;
public $force_read = 0;

public function __construct(array $config = [])
{
parent::__construct($config);
$this->user_id = app()->user->getId();
}

public static function inputRules()
{
return [
'id' => 'integer',
'title' => [
['required'],
['maxlength', ['max' => 255]]
],
'body' => 'required',
'notify' => [
['Integer'],
['Between', ['min' => 0, 'max' => 1]]
],
'force_read' => [
['Integer'],
['Between', ['min' => 0, 'max' => 1]]
]
];
}

public function flush() {
if ($this->id == 0) { // This is new news
app()->pdo->createCommand('INSERT INTO news (user_id,create_at,title,body,notify,force_read) VALUES (:uid,NOW(),:title,:body,:notify,:fread);')->bindParams([
'uid' => $this->user_id, 'title' => $this->title, 'body' => $this->body,
'notify' => $this->notify, 'fread' => $this->force_read
])->execute();
} else { // This is news edit
app()->pdo->createCommand('UPDATE news SET user_id = :uid, title = :title, body = :body, notify = :notify, force_read = :fread WHERE id=:id')->bindParams([
'id' => $this->id, 'uid' => $this->user_id,
'title' => $this->title, 'body' => $this->body,
'notify' => $this->notify, 'fread' => $this->force_read
])->execute();
}
// Clean News Cache
app()->redis->del('Site:recent_news');
}
}
7 changes: 6 additions & 1 deletion apps/public/static/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ body{background-color:#f6f6f6}
.color-rss{color:#5c7cfa}

/* Main Container */
.main-container{background-color:#eaeaea;padding-top:10px}
.main-container{background-color:#eaeaea;padding:10px 0}

/* Footer Menu */
#footer_menu{background-color:#383838;color:#C3C0B9;font-size:12px;margin-top:30px;padding-bottom:10px;padding-top:15px}
Expand All @@ -81,6 +81,11 @@ body{background-color:#f6f6f6}
#footer_menu a{color:#C3C0B9}
#footer_menu a:hover{color:#E84807}

/*-----------------------------------------------------------------------------------*/
/* 4. Page of '/index'
/*-----------------------------------------------------------------------------------*/


/*-----------------------------------------------------------------------------------*/
/* 4. Page of '/torrent'
/*-----------------------------------------------------------------------------------*/
Expand Down
28 changes: 28 additions & 0 deletions apps/public/static/js/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
;

const _location_search = new URLSearchParams(window.location.search);

function humanFileSize(bytes, fix, si) {
let thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh) {
Expand All @@ -16,13 +18,39 @@ function humanFileSize(bytes, fix, si) {
return bytes.toFixed(fix ? fix : 2) + ' ' + units[u];
}

function location_search_replace(new_params) {
let search = _location_search;
for (let i in new_params) {
search.set(i,new_params[i]);
}
return '?' + search.toString();
}

jQuery(document).ready(function() {
// Drop all support of IE 6-11
if ($.zui.browser.ie) {
$.zui.browser.tip();
}

// Declare Const
const api_point = '/api/v1';

// Active tooltop
$('[data-toggle="tooltip"]').tooltip();

// Active Pager which source from remote
$('ul[data-ride="remote_pager"]').pager({
page: _location_search.get('page') || 0,
maxNavCount: 8,
elements: ['first_icon', 'prev_icon', 'pages', 'next_icon', 'last_icon'],
linkCreator: function(page, pager) {
return location_search_replace({
'page': page,
'limit': pager.recPerPage
});
}
});

// TODO Add Scroll to TOP fixbar


Expand Down
42 changes: 38 additions & 4 deletions apps/views/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,51 @@
* Time: 11:38
*
* @var League\Plates\Template\Template $this
* @var array $news
*/

$can_manage_news = app()->user->isPrivilege('manage_news');
?>

<?= $this->layout('layout/base') ?>

<?php $this->start('title')?>Index<?php $this->end();?>

<?php $this->start('container') ?>
<!-- Main component for a primary marketing message or call to action -->
<div class="jumbotron">
<h1>Navbar <?= __('greeting',null); ?></h1>
<p><strong>I'm sorry for broken page since I'm rebuilding. <?= __('greet') ?></strong></p>
<div class="panel" id="news_panel">
<div class="panel-heading">Recent News - <small>[<a href="/news" target="_blank">All</a>]</small>
<?= $can_manage_news ? '<small>[<a href="/news/new">New</a>]</small>' : '' ?>
</div>
<div class="panel-body">
<?php if (empty($news)): ?>
No any news.
<?php else: ?>
<div class="list list-condensed">
<div class="items items-hover">
<?php foreach ($news as $index => $new): ?>
<div class="item">
<div class="item-heading">
<div class="pull-right">
<!-- TODO add delete Protect -->
<?= $can_manage_news ? "<a href=\"/news/edit?id={$new['id']}\"><i class=\"icon-pencil\"></i> Edit</a> &nbsp;<a href=\"/news/delete?id={$new['id']}\"><i class=\"icon-remove\"></i> Delete</a> &nbsp;" : '' ?>
<span class="text-muted"><?= $new['create_at'] ?></span>
</div>
<h4><a href="#new_<?= $new['id'] ?>" data-toggle="collapse"><?= $new['title'] ?></a></h4>
</div>
<div class="item-content collapse<?= $index === 0 ? ' in' : '' ?>" id="new_<?= $new['id'] ?>">
<div class="text"><?= $this->batch($new['body'],'format_ubbcode'); ?></div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
</div>
</div>

<!-- Main component for a primary marketing message or call to action -->
<div class="jumbotron">
<h1>Navbar <?= __('greeting', null); ?></h1>
<p><strong>I'm sorry for broken page since I'm rebuilding. <?= __('greet') ?></strong></p>
</div>
<?php $this->stop() ?>
52 changes: 52 additions & 0 deletions apps/views/news/edit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
/**
* Created by PhpStorm.
* User: Rhilip
* Date: 2019/5/31
* Time: 10:12
*
* @var League\Plates\Template\Template $this
*/
?>

<?= $this->layout('layout/base') ?>

<?php $this->start('title')?>Site News Edit<?php $this->end();?>

<?php $this->start('container') ?>
<div class="row">
<div class="text-center"><h2>New/Edit Site News</h2></div>
<div class="col-md-8 col-md-offset-2">
<form method="post">
<?php if (isset($news)): ?>
<label>
<input name="id" value="<?= $news['id'] ?>" style="display: none">
</label>
<?php endif; ?>
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title" placeholder="The title of news" value="<?= isset($news) ? $news['title'] : '' ?>">
</div>
<div class="form-group">
<label for="body">Body</label>
<textarea class="form-control" id="body" name="body" cols="100" rows="20" placeholder=""><?= isset($news) ? $news['body'] : '' ?></textarea>
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" name="notify" value="1"<?= isset($news) && $news['notify'] ? ' checked' : '' ?>> Notify All Member.
</label>
</div><!-- TODO add support -->
<div class="checkbox">
<label>
<input type="checkbox" name="force_read" value="1"<?= isset($news) && $news['force_read'] ? ' checked' : '' ?>> All Member <b>MUST</b> Read this News, Before they can do other things!!!
</label>
</div><!-- TODO add support -->
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
</div>
</div>
<?php $this->end();?>
Loading

0 comments on commit e9397fb

Please sign in to comment.