Merge pull request #224 from TheSerapher/issue-61

Adding custom news posts via admin panel
This commit is contained in:
Sebastian Grewe 2013-06-21 02:18:15 -07:00
commit f65ec1ef4d
12 changed files with 3466 additions and 20 deletions

View File

@ -7,6 +7,8 @@ require_once(CLASS_DIR . '/bitcoinwrapper.class.php');
require_once(INCLUDE_DIR . '/database.inc.php');
require_once(INCLUDE_DIR . '/smarty.inc.php');
// Load classes that need the above as dependencies
require_once(CLASS_DIR . '/base.class.php');
require_once(CLASS_DIR . '/news.class.php');
require_once(CLASS_DIR . '/block.class.php');
require_once(CLASS_DIR . '/user.class.php');
require_once(CLASS_DIR . '/share.class.php');
@ -16,3 +18,4 @@ require_once(CLASS_DIR . '/transaction.class.php');
require_once(CLASS_DIR . '/setting.class.php');
require_once(CLASS_DIR . '/mail.class.php');
require_once(CLASS_DIR . '/notification.class.php');
require_once(INCLUDE_DIR . '/lib/Michelf/Markdown.php');

View File

@ -0,0 +1,81 @@
<?php
// Make sure we are called from index.php
if (!defined('SECURITY'))
die('Hacking attempt');
// Our base class that defines
// some cross-class functions.
class Base {
private $sError = '';
public function setDebug($debug) {
$this->debug = $debug;
}
public function setMysql($mysqli) {
$this->mysqli = $mysqli;
}
public function setSmarty($smarty) {
$this->smarty = $smarty;
}
public function setUser($user) {
$this->user = $user;
}
public function setConfig($config) {
$this->config = $config;
}
public function setErrorMessage($msg) {
$this->sError = $msg;
}
public function getError() {
return $this->sError;
}
/**
* Get a single row from the table
* @param value string Value to search for
* @param search Return column to search for
* @param field string Search column
* @param type string Type of value
* @return array Return result
**/
protected function getSingle($value, $search='id', $field='id', $type="i") {
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("SELECT $search FROM $this->table WHERE $field = ? LIMIT 1");
if ($this->checkStmt($stmt)) {
$stmt->bind_param($type, $value);
$stmt->execute();
$stmt->bind_result($retval);
$stmt->fetch();
$stmt->close();
return $retval;
}
return false;
}
function checkStmt($bState) {
$this->debug->append("STA " . __METHOD__, 4);
if ($bState ===! true) {
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error);
$this->setErrorMessage('Internal application Error');
return false;
}
return true;
}
/**
* Update a single row in a table
* @param userID int Account ID
* @param field string Field to update
* @return bool
**/
protected function updateSingle($id, $field, $table='') {
if (empty($table)) $table = $this->table;
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("UPDATE $table SET " . $field['name'] . " = ? WHERE id = ? LIMIT 1");
if ($this->checkStmt($stmt) && $stmt->bind_param($field['type'].'i', $field['value'], $id) && $stmt->execute())
return true;
$this->debug->append("Unable to update " . $field['name'] . " with " . $field['value'] . " for ID $id");
return false;
}
}
?>

View File

@ -0,0 +1,102 @@
<?php
// Make sure we are called from index.php
if (!defined('SECURITY'))
die('Hacking attempt');
class News extends Base {
var $table = 'news';
public function getActive($id) {
$this->debug->append("STA " . __METHOD__, 5);
return $this->getSingle($id, 'active', 'id');
}
public function toggleActive($id) {
$this->debug->append("STA " . __METHOD__, 5);
$field = array('name' => 'active', 'type' => 'i', 'value' => !$this->getActive($id));
return $this->updateSingle($id, $field);
}
/**
* Get all active news
**/
public function getAllActive() {
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE active = 1");
if ($stmt && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC);
// Catchall
return false;
}
/**
* Get all news
**/
public function getAll() {
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table");
if ($stmt && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC);
// Catchall
return false;
}
/**
* Get a specific news entry
**/
public function getEntry($id) {
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE id = ?");
if ($stmt && $stmt->bind_param('i', $id) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_assoc();
// Catchall
return false;
}
/**
* Update a news entry
**/
public function updateNews($id, $header, $content, $active=0) {
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("UPDATE $this->table SET content = ?, header = ?, active = ? WHERE id = ?");
if ($stmt && $stmt->bind_param('ssii', $content, $header, $active, $id) && $stmt->execute() && $stmt->affected_rows == 1)
return true;
$this->setErrorMessage("Failed to update news entry $id");
return false;
}
public function deleteNews($id) {
$this->debug->append("STA " . __METHOD__, 4);
if (!is_int($id)) return false;
$stmt = $this->mysqli->prepare("DELETE FROM $this->table WHERE id = ?");
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $id) && $stmt->execute() && $stmt->affected_rows == 1)
return true;
$this->setErrorMessage("Failed to delete news entry $id");
return false;
}
/**
* Add a new mews entry to the table
* @param type string Type of the notification
* @return bool
**/
public function addNews($account_id, $aData, $active=false) {
$this->debug->append("STA " . __METHOD__, 4);
if (empty($aData['header'])) return false;
if (empty($aData['content'])) return false;
if (!is_int($account_id)) return false;
$stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, header, content, active) VALUES (?,?,?,?)");
if ($stmt && $stmt->bind_param('issi', $account_id, $aData['header'], $aData['content'], $active) && $stmt->execute())
return true;
$this->debug->append("Failed to add news: " . $this->mysqli->error);
$this->setErrorMessage("Unable to add new news: " . $this->mysqli->error);
return false;
}
}
$news = new News();
$news->setDebug($debug);
$news->setMysql($mysqli);
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
<?php
#
# Markdown Extra - A text-to-HTML conversion tool for web writers
#
# PHP Markdown Extra
# Copyright (c) 2004-2013 Michel Fortin
# <http://michelf.com/projects/php-markdown/>
#
# Original Markdown
# Copyright (c) 2004-2006 John Gruber
# <http://daringfireball.net/projects/markdown/>
#
namespace Michelf;
# Just force Michelf/Markdown.php to load. This is needed to load
# the temporary implementation class. See below for details.
\Michelf\Markdown::MARKDOWNLIB_VERSION;
#
# Markdown Extra Parser Class
#
# Note: Currently the implementation resides in the temporary class
# \Michelf\MarkdownExtra_TmpImpl (in the same file as \Michelf\Markdown).
# This makes it easier to propagate the changes between the three different
# packaging styles of PHP Markdown. Once this issue is resolved, the
# _MarkdownExtra_TmpImpl will disappear and this one will contain the code.
#
class MarkdownExtra extends \Michelf\_MarkdownExtra_TmpImpl {
### Parser Implementation ###
# Temporarily, the implemenation is in the _MarkdownExtra_TmpImpl class.
# See note above.
}
?>

View File

@ -0,0 +1,37 @@
<?php
// Make sure we are called from index.php
if (!defined('SECURITY')) die('Hacking attempt');
// Include markdown library
use \Michelf\Markdown;
if (@$_REQUEST['do'] == 'toggle_active')
if ($news->toggleActive($_REQUEST['id']))
$_SESSION['POPUP'][] = array('CONTENT' => 'News entry changed', 'TYPE' => 'success');
if (@$_REQUEST['do'] == 'add') {
if ($news->addNews($_SESSION['USERDATA']['id'], $_POST['data'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'News entry added', 'TYPE' => 'success');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => 'Failed to add new entry: ' . $news->getError(), 'TYPE' => 'errormsg');
}
}
if (@$_REQUEST['do'] == 'delete') {
if ($news->deleteNews((int)$_REQUEST['id'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Succesfully removed news entry', 'TYPE' => 'success');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => 'Failed to delete entry: ' . $news->getError(), 'TYPE' => 'errormsg');
}
}
// Fetch all news
$aNews = $news->getAll();
foreach ($aNews as $key => $aData) {
// Transform Markdown content to HTML
$aNews[$key]['content'] = Markdown::defaultTransform($aData['content']);
}
$smarty->assign("NEWS", $aNews);
$smarty->assign("CONTENT", "default.tpl");
?>

View File

@ -0,0 +1,21 @@
<?php
// Make sure we are called from index.php
if (!defined('SECURITY')) die('Hacking attempt');
// Include markdown library
use \Michelf\Markdown;
if (@$_REQUEST['do'] == 'save') {
if ($news->updateNews($_REQUEST['id'], $_REQUEST['header'], $_REQUEST['content'], $_REQUEST['active'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'News updated', 'TYPE' => 'success');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => 'News update failed: ' . $news->getError(), 'TYPE' => 'errormsg');
}
}
// Fetch news entry
$aNews = $news->getEntry($_REQUEST['id']);
$smarty->assign("NEWS", $aNews);
$smarty->assign("CONTENT", "default.tpl");
?>

View File

@ -1,9 +1,19 @@
<?php
// Make sure we are called from index.php
if (!defined('SECURITY'))
die('Hacking attempt');
if (!defined('SECURITY')) die('Hacking attempt');
// Include markdown library
use \Michelf\Markdown;
// Fetch active news to display
$aNews = $news->getAllActive();
foreach ($aNews as $key => $aData) {
// Transform Markdown content to HTML
$aNews[$key]['content'] = Markdown::defaultTransform($aData['content']);
}
// Tempalte specifics
$smarty->assign("NEWS", $aNews);
$smarty->assign("CONTENT", "default.tpl");
?>

View File

@ -0,0 +1,38 @@
{include file="global/block_header.tpl" BLOCK_HEADER="News Posts"}
{include file="global/block_header.tpl" BLOCK_HEADER="Add News Post"}
<form method="POST" action="{$smarty.server.PHP_SELF}">
<input type="hidden" name="page" value="{$smarty.request.page}">
<input type="hidden" name="action" value="{$smarty.request.action}">
<input type="hidden" name="do" value="add">
<table width="80%">
<tr>
<th>Header</th>
<td><input size="30" type="text" name="data[header]" required /></td>
</tr>
<tr>
<th>Content</th>
<td><textarea name="data[content]" required></textarea></td>
</tr>
<tr><td class="center" colspan="2"><input type="submit" value="Add" class="submit small"></td></tr>
</table>
</form>
{include file="global/block_footer.tpl"}
{section name=news loop=$NEWS}
{include
file="global/block_header.tpl"
BLOCK_HEADER="{$NEWS[news].header}"
BUTTONS="
<a href='{$smarty.server.PHP_SELF}?page={$smarty.request.page}&action=news_edit&id={$NEWS[news].id}'>Edit</a>&nbsp;
<a href='{$smarty.server.PHP_SELF}?page={$smarty.request.page}&action={$smarty.request.action}&do=delete&id={$NEWS[news].id}'>Delete</a>
"
}
{if $NEWS[news].active == 0}<font size="2px">This post is <font color="red"><b>inactive</b></font><br /><br />{/if}
{$NEWS[news].content}
<form method="POST" action="{$smarty.server.PHP_SELF}">
<input type="hidden" name="page" value="{$smarty.request.page}">
<input type="hidden" name="action" value="news_edit">
<input type="hidden" name="id" value="{$NEWS[news].id}">
</form>
{include file="global/block_footer.tpl"}
{/section}
{include file="global/block_footer.tpl"}

View File

@ -0,0 +1,32 @@
{include file="global/block_header.tpl" BLOCK_HEADER="Edit news entry #{$NEWS.id}"}
<form method="POST" action="{$smarty.server.PHP_SELF}">
<input type="hidden" name="page" value="{$smarty.request.page}">
<input type="hidden" name="action" value="{$smarty.request.action}">
<input type="hidden" name="id" value="{$NEWS.id}">
<input type="hidden" name="do" value="save">
<table width="80%">
<tr>
<th>
Active
</th>
<td>
<input type="checkbox" name="active" value="1" id="active" {if $NEWS.active}checked{/if} />
<label for="active"></label>
</td>
</tr>
<tr>
<th>
Header
</th>
<td><input name="header" type="text" size="30" value="{$NEWS.header}" required /></td>
</tr>
<tr>
<th>
Content
</th>
<td><textarea name="content" rows="500" type="text" required>{$NEWS.content}</textarea></td>
</tr>
</table>
<input type="submit" value="Save" class="submit small" />
</form>
{include file="global/block_footer.tpl"}

View File

@ -15,6 +15,7 @@
<ul>
<li><a href="{$smarty.server.PHP_SELF}?page=admin&action=user">User Info</a></li>
<li><a href="{$smarty.server.PHP_SELF}?page=admin&action=wallet">Wallet Info</a></li>
<li><a href="{$smarty.server.PHP_SELF}?page=admin&action=news">News Posts</a></li>
</ul>
</li>
{/if}

View File

@ -1,18 +1,5 @@
<div class="block" style="clear:none;">
<div class="block_head">
<div class="bheadl"></div>
<div class="bheadr"></div>
<h1>News</h1>
</div>
<div class="block_content" style="padding:10px;">
<p>
This is an experimental pool for now. Please use it at your own risk. We haven't had any issues with it so far but please keep us posted if you do have problems that could be solved by the pool owner.
</p>
</div> <!-- nested block ends -->
<div class="bendl"></div>
<div class="bendr"></div>
</div>
{section name=news loop=$NEWS}
{include file="global/block_header.tpl" BLOCK_HEADER="{$NEWS[news].header}"}
{$NEWS[news].content}
{include file="global/block_footer.tpl"}
{/section}