Commit 1c39fff7 authored by Malcolm Blaney's avatar Malcolm Blaney

Added Publish method to the module interface, so that all modules

on a page can be alerted when the published status of the page
changes. Invoice->WriteData format was incorrect for only one
group. Post module now displays it's own posts when the Reader
module is not on the page. This allows it to respond to status
changes for the page, whereas Reader module can only aggregate
public feeds. Added a warning to the Purchase module for when
the day is not "co-op-day" and ordering is not being used.
The timezone is now set in the Config module's constructor.
parent e1622978
......@@ -4,6 +4,7 @@ php/modules/Banking.php
php/modules/Browser.php
php/modules/Cart.php
php/modules/Comment.php
php/modules/Contact.php
php/modules/Detail.php
php/modules/Gift.php
php/modules/Graph.php
......@@ -28,6 +29,7 @@ js/dobrado.banking.js
js/dobrado.browser.js
js/dobrado.cart.js
js/dobrado.comment.js
js/dobrado.contact.js
js/dobrado.detail.js
js/dobrado.gift.js
js/dobrado.graph.js
......
......@@ -6,7 +6,7 @@
position:absolute;
top:15px;
left:4px;
z-index:100;
z-index:20;
}
/*
......@@ -52,7 +52,7 @@
width:24px;
height:43px;
display:block;
z-index:101;
z-index:21;
}
#slides .next {
......
......@@ -199,6 +199,10 @@ class Banking extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
// Return if Remove was called for a specific module,
// only want to remove bank details when deleting an account.
......
......@@ -248,6 +248,10 @@ class Browser extends Base {
return "outside";
}
public function Publish($id, $update) {
}
public function Remove($id) {
}
......
......@@ -458,6 +458,10 @@ class Cart extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
// Return if Remove was called for a specific module,
// only want to remove cart settings when deleting an account.
......
......@@ -53,14 +53,14 @@ class Comment extends Base {
$url = $mysqli->escape_string($_POST['url']);
$content = $mysqli->escape_string($_POST['content']);
$time = time();
// Use a select with the insert to get the max comment_id.
$query = 'INSERT INTO comment (user, box_id, comment_id, name, url, '.
'content, timestamp) SELECT user, box_id, MAX(comment_id)+1, "'.
$name.'", "'.$url.'", "'.$content.'", "'.$time.'" FROM comment WHERE '.
'user="'.$this->owner.'" AND box_id="'.$id.'"';
'content, timestamp) SELECT "'.$this->owner.'", '.$id.', '.
'MAX(comment_id) + 1, "'.$name.'", "'.$url.'", "'.$content.'", '.$time.
' FROM comment WHERE user = "'.$this->owner.'" AND box_id = '.$id;
if ($mysqli->query($query)) {
$query = 'SELECT MAX(comment_id) AS comment_id FROM comment WHERE '.
'user="'.$this->owner.'" AND box_id="'.$id.'"';
'user = "'.$this->owner.'" AND box_id = '.$id;
if ($result = $mysqli->query($query)) {
if ($comment = $result->fetch_assoc()) {
$object['content'] = $this->Format($comment['comment_id'],
......@@ -76,8 +76,8 @@ class Comment extends Base {
}
else if ($mode == "remove" && $this->user->canEditPage) {
$comment_id = substr($mysqli->escape_string($_POST['commentId']), 15);
$query = 'DELETE FROM comment WHERE user="'.$this->owner.
'" AND box_id="'.$id.'" AND comment_id="'.$comment_id.'"';
$query = 'DELETE FROM comment WHERE user = "'.$this->owner.
'" AND box_id ='.$id.' AND comment_id = '.$comment_id;
if (!$mysqli->query($query)) {
$this->Log('Comment->Callback 2: '.$mysqli->error);
}
......@@ -104,7 +104,7 @@ class Comment extends Base {
$mysqli = connect_db();
$content = '<div class="comment-list">';
$query = 'SELECT comment_id, name, url, content, timestamp '.
'FROM comment WHERE user="'.$this->owner.'" AND box_id="'.$id.'"';
'FROM comment WHERE user = "'.$this->owner.'" AND box_id = '.$id;
if ($result = $mysqli->query($query)) {
while ($comment = $result->fetch_assoc()) {
$content .= $this->Format($comment['comment_id'], $comment['name'],
......@@ -127,12 +127,14 @@ class Comment extends Base {
if (!$this->Locked($id)) {
$form = '<div class="new-comment-title">Add a comment</div>'.
'<form id="comment-form">'.
'<label id="comment-name-label" for="comment-name">Name: </label>'.
'<input id="comment-name" type="text" name="name" '.
'size="15" maxlength="50"><br>'.
'<label id="comment-url-label" for="comment-url">Website: </label>'.
'<input id="comment-url" type="text" name="url" '.
'size="15" maxlength="200"><br>'.
'<div class="form-spacing">'.
'<label for="comment-name">Name: </label>'.
'<input id="comment-name" size="15" maxlength="50">'.
'</div>'.
'<div class="form-spacing">'.
'<label for="comment-url">Website: </label>'.
'<input id="comment-url" size="15" maxlength="200">'.
'</div>'.
'<textarea id="comment-content"></textarea><br>'.
'<button class="submit">submit</button>'.
'</form>';
......@@ -214,35 +216,43 @@ class Comment extends Base {
'"","#comment-url","margin-top","5px"',
'"","#comment-content","margin-top","5px"',
'"","#comment-content","margin-bottom","5px"',
'"","#comment-content","width","300px"',
'"","#comment-content","height","60px"',
'"","#comment-content","width","400px"',
'"","#comment-content","height","70px"',
'"","","",""');
$this->AddSiteStyle($site_style);
}
public function Placement() {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
$mysqli = connect_db();
if (isset($id)) {
$query = 'DELETE FROM comment WHERE user="'.$this->owner.
'" AND box_id='.$id;
$query = 'DELETE FROM comment WHERE user = "'.$this->owner.
'" AND box_id = '.$id;
if (!$mysqli->query($query)) {
$this->Log('Comment->Remove 1: '.$mysqli->error);
$this->Log("Comment->Remove 1: ".$mysqli->error);
}
$query = 'DELETE FROM comment_settings WHERE user="'.$this->owner.
'" AND box_id='.$id;
$query = 'DELETE FROM comment_settings WHERE user = "'.$this->owner.
'" AND box_id = '.$id;
if (!$mysqli->query($query)) {
$this->Log('Comment->Remove 2: '.$mysqli->error);
$this->Log("Comment->Remove 2: ".$mysqli->error);
}
}
else {
// If a specific id is not set remove all comment data for the user.
$query = 'DELETE FROM comment WHERE user="'.$this->owner.'"';
$query = 'DELETE FROM comment WHERE user = "'.$this->owner.'"';
if (!$mysqli->query($query)) {
$this->Log('Comment->Remove 3: '.$mysqli->error);
$this->Log("Comment->Remove 3: ".$mysqli->error);
}
$query = 'DELETE FROM comment_settings WHERE user="'.$this->owner.'"';
$query = 'DELETE FROM comment_settings WHERE user = "'.$this->owner.'"';
if (!$mysqli->query($query)) {
$this->Log('Comment->Remove 4: '.$mysqli->error);
$this->Log("Comment->Remove 4: ".$mysqli->error);
}
}
$mysqli->close();
......@@ -261,10 +271,6 @@ class Comment extends Base {
$mysqli->close();
}
public function Placement() {
return "middle";
}
public function Update() {
// This is called when the version of the module is updated,
// to provide a way to update or modify tables etc..
......@@ -278,8 +284,8 @@ class Comment extends Base {
private function Format($comment_id, $name, $url, $content, $time) {
if ($url != "") {
$name = '<a href="'.htmlspecialchars(stripslashes($url)).'">'.
htmlspecialchars(stripslashes($name)).'</a>';
$name = '<a href="'.htmlspecialchars($url).'">'.
htmlspecialchars($name).'</a>';
}
$remove = "";
if ($this->user->canEditPage) {
......@@ -288,7 +294,7 @@ class Comment extends Base {
}
return '<div class="comment-wrapper">'.
$remove.'<div class="comment-content">'.
nl2br(htmlspecialchars(stripslashes($content))).'</div>'.
nl2br(htmlspecialchars($content)).'</div>'.
'<div class="comment-name">'.$name.' <span class="comment-time">'.
date('M jS, Y \a\t g:i a', $time).'</span></div></div>';
}
......
......@@ -180,6 +180,10 @@ class Contact extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
$mysqli = connect_db();
if (isset($id)) {
......
......@@ -176,6 +176,10 @@ class Detail extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
// Return if Remove was called for a specific module,
// only want to remove details when deleting an account.
......
......@@ -218,6 +218,10 @@ class Gift extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
}
......
......@@ -241,6 +241,10 @@ class Graph extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
$mysqli = connect_db();
if (isset($id)) {
......
......@@ -76,6 +76,10 @@ class Grid extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
}
......
......@@ -252,6 +252,10 @@ class Invoice extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
}
......@@ -1074,8 +1078,11 @@ class Invoice extends Base {
$files = array();
foreach ($data as $supplier => $product) {
$content = "";
if ($format == "vertical") {
if ($group_list) {
// If there's more than one group, orders can be displayed with group
// totals displayed either in their own columns (horizontally) or
// subtotaled under product groups (vertically).
if ($group_list) {
if ($format == "vertical") {
for ($i = 0; $i < count($product); $i++) {
// First add a title.
if ($i == 0) {
......@@ -1088,30 +1095,32 @@ class Invoice extends Base {
}
}
else {
$content = "Product,Quantity,Price".$extra_column_title."\n";
// First add the title.
$content = "Product,";
for ($j = 0; $j < count($group_list); $j++) {
$content .= ucfirst($group_list[$j]).",";
}
$content .= "Total,Price".$extra_column_title."\n";
foreach ($product as $name => $details) {
$content .= $name.",".$details["quantity"].",".
$details["price"].$extra_column."\n";
$content .= $name.",";
$total = 0;
for ($i = 0; $i < count($group_list); $i++) {
$content .= $details["group"][$group_list[$i]].",";
$total += (float)$details["group"][$group_list[$i]];
}
$content .= $total.",".$details["price"].$extra_column."\n";
}
}
}
// When there is only one group, there is no format distinction.
else {
// First add the title.
$content = "Product,";
for ($j = 0; $j < count($group_list); $j++) {
$content .= ucfirst($group_list[$j]).",";
}
$content .= "Total,Price".$extra_column_title."\n";
$content = "Product,Quantity,Price".$extra_column_title."\n";
foreach ($product as $name => $details) {
$content .= $name.",";
$total = 0;
for ($i = 0; $i < count($group_list); $i++) {
$content .= $details["group"][$group_list[$i]].",";
$total += (float)$details["group"][$group_list[$i]];
}
$content .= $total.",".$details["price"].$extra_column."\n";
$content .= $name.",".$details["quantity"].",".
$details["price"].$extra_column."\n";
}
}
if ($content != "") {
$filename = "/tmp/".$supplier."-".date("j-F-Y").".csv";
$handle = fopen($filename, "w");
......
......@@ -240,6 +240,10 @@ class Manager extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
}
......
......@@ -173,8 +173,8 @@ class Organiser extends Base {
$groups = $this->Children($organisation);
$options = '<option value="'.$organisation.'">all '.$organisation.
' members</option>';
for ($i = 0; $i < count($children); $i++) {
$options .= '<option value="'.$children[$i].'">all '.$children[$i].
for ($i = 0; $i < count($groups); $i++) {
$options .= '<option value="'.$groups[$i].'">all '.$groups[$i].
' members</option>';
}
$options .= '<option value="individual">select individual members</option>';
......@@ -277,6 +277,10 @@ class Organiser extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
}
......
......@@ -381,6 +381,10 @@ class Payment extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
// Return if Remove was called for a specific module,
// only want to remove payments when deleting an account.
......@@ -407,18 +411,6 @@ class Payment extends Base {
public function Update() {
// This is called when the version of the module is updated,
// to provide a way to update or modify tables etc..
$mysqli = connect_db();
$query = 'ALTER TABLE payment_settings ADD COLUMN min_surcharge '.
'DECIMAL(8,2) AFTER surcharge';
if (!$mysqli->query($query)) {
$this->Log('Payment->Update 1: '.$mysqli->error);
}
$query = 'ALTER TABLE payment_settings ADD COLUMN max_surcharge '.
'DECIMAL(8,2) AFTER min_surcharge';
if (!$mysqli->query($query)) {
$this->Log('Payment->Update 1: '.$mysqli->error);
}
$mysqli->close();
}
public function UpdateScript($path) {
......
......@@ -130,6 +130,10 @@ class Player extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
$mysqli = connect_db();
if (isset($id)) {
......
This diff is collapsed.
......@@ -72,8 +72,8 @@ class Purchase extends Base {
$object["data"] = (object)$this->AllData(time(), true);
// Need to find the next co-op date to set to. Due to the way
// relative dates work, need to check if 'this (day)' is in the past,
// otherwise use 'next (day)'.
// relative dates work, need to check if 'this <day>' is in the past,
// otherwise use 'next <day>'.
$co_op_day = $this->Substitute("co-op-day");
$next_co_op = strtotime("this ".$co_op_day);
if ($next_co_op < time()) {
......@@ -250,6 +250,15 @@ class Purchase extends Base {
else {
$_SESSION["purchase-refresh"] = false;
$_SESSION["purchase-order"] = false;
// If today is NOT co-op-day, don't show the volunteer message, and also
// show a warning about orders for next week.
$co_op_day = strtotime($this->Substitute("co-op-day"));
if (time() < $co_op_day - 86400 || time() > $co_op_day + 86400) {
$volunteer = '';
$purchase_next_week = "<div><i><b>Warning:</b> You haven't selected ".
"the order option.</i><br>If you add items with todays date they ".
"will <b>not</b> be added to the orders for this week.<hr></div>";
}
}
$mysqli->close();
......@@ -430,8 +439,8 @@ class Purchase extends Base {
}
$mysqli->close();
$template = array('"purchase-next-week","",'.
'"Please ask them if they are coming next week?"');
$template = array('"purchase-next-week", "", '.
'"Please ask them if they are coming next week?"');
$this->AddTemplate($template);
$site_style = array('"","#purchase-form","background-color","#eeeeee"',
......@@ -458,6 +467,10 @@ class Purchase extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
// Return if Remove was called for a specific module,
// only want to remove purchases when deleting an account.
......@@ -484,13 +497,6 @@ class Purchase extends Base {
public function Update() {
// This is called when the version of the module is updated,
// to provide a way to update or modify tables etc..
$mysqli = connect_db();
$query = 'ALTER TABLE purchase ADD COLUMN supplier VARCHAR(50) NOT NULL '.
'AFTER name';
if (!$mysqli->query($query)) {
$this->Log('Purchase->Update: '.$mysqli->error);
}
$mysqli->close();
}
public function UpdateScript($path) {
......@@ -633,8 +639,8 @@ class Purchase extends Base {
public function PreOrder($user, $timestamp) {
// Need to find the most recent co-op date to copy from. Due to the way
// relative dates work, need to check if 'this (day)' is in the future,
// otherwise use 'last (day)'.
// relative dates work, need to check if 'this <day>' is in the future,
// otherwise use 'last <day>'.
$co_op_day = $this->Substitute("co-op-day");
$start = strtotime("this ".$co_op_day);
if ($start > time()) {
......
......@@ -184,13 +184,26 @@ class Reader extends Base {
if (!$mysqli->query($query)) {
$this->Log('Reader->Install: '.$mysqli->error);
}
$format = '<h4 class="title">!title</h4>'.
'<h5 class="author">By !author on !date</h5>'.
'<div class="description">!description</div>'.
'<div class="options">!category !media</div>';
$template = array('"reader-format", "", "'.
$mysqli->escape_string($format).'"');
$mysqli->close();
$this->AddTemplate($template);
}
public function Placement() {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
$mysqli = connect_db();
if (isset($id)) {
......@@ -231,40 +244,36 @@ class Reader extends Base {
$email = null;
$name = null;
$link = null;
if ($author = $item->get_author()) {
$email = $author->get_email();
$name = $author->get_name();
$link = $author->get_link();
if ($item_author = $item->get_author()) {
$email = $item_author->get_email();
$name = $item_author->get_name();
$link = $item_author->get_link();
}
$category = $item->get_categories();
if ($category !== null) {
$category = "tags: ".$category;
}
$media = $item->get_enclosure();
if ($media !== null) {
$media = "media: ".$media;
}
$categories = $item->get_categories();
$enclosure = $item->get_enclosure();
$permalink = $item->get_permalink();
$date = $item->get_date();
// TODO: use Substitute method here.
if ($title !== null) {
$content .= '<h4 class="reader-title">';
// Link the permalink to the title if it exists.
$content .= $permalink === null ? $title :
'<a href="'.$permalink.'">'.$title.'</a>';
$content .= '</h4>';
}
if ($email !== null) {
$content .= '<h5 class="reader-author">'.$email.'</h5>';
}
else if ($name !== null) {
$content .= '<h5 class="reader-author">'.$name.'</h5>';
$author = $email !== null ? $email : $name !== null ?
$name : $link !== null ? $link : "";
// When there is no title, link the permalink page to the date.
if ($title === null) {
$date = '<a href="'.$this->Url("", $permalink).'">'.$date.'</a>';
}
else if ($link !== null) {
$content .= '<h5 class="reader-author">'.$link.'</h5>';
}
$content .= '<div class="reader-description">'.$description.'</div>'.
'<div class="reader-date">'.$date;
if ($title === null && $permalink !== null) {
$content .= '<a href="'.$permalink.'">#</a>';
else {
$title = '<a href="'.$this->Url("", $permalink).'">'.$title.'</a>';
}
$content .= '</div>';
return $content;
$patterns = array("/!title/", "/!description/", "/!author/", "/!category/",
"/!media/", "/!date/");
$replacements = array($title, $description, $author, $category, $media,
$date);
return $this->Substitute("reader-format", $patterns, $replacements);
}
private function PostsPerRequest() {
......
......@@ -251,6 +251,10 @@ class Roster extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
}
......
......@@ -132,6 +132,10 @@ class Slider extends Base {
return "middle";
}
public function Publish($update) {
}
public function Remove($id) {
$mysqli = connect_db();
if (isset($id)) {
......
......@@ -272,6 +272,10 @@ class Stock extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
// Return if Remove was called for a specific module,
// only want to remove stock when deleting an account.
......
......@@ -119,11 +119,13 @@ class Summary extends Base {
$purchase_page .= "order=true";
$ordered_text = "";
$items = $purchase->Data(time(), strtotime("7 days"));
if (empty($items) && $pre_order_available) {
$ordered_text = "You haven't ordered for next week yet.".
'<br><b>You can <a class="purchase-page-link" href="'.
$purchase_page.'">order here'.'</a> until the '.
$this->Substitute("pre-order-final").' before co-op.</b>';
if (empty($items)) {
if ($pre_order_available) {
$ordered_text = "You haven't ordered for next week yet.".
'<br><b>You can <a class="purchase-page-link" href="'.
$purchase_page.'">order here'.'</a> until the '.
$this->Substitute("pre-order-final").' before co-op.</b>';
}
}
else {
$ordered_text = 'You have items ordered for next week.';
......@@ -210,6 +212,10 @@ class Summary extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
}
......
......@@ -132,6 +132,10 @@ class Turner extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
$mysqli = connect_db();
if (isset($id)) {
......
......@@ -127,6 +127,10 @@ class Writer extends Base {
return "middle";
}
public function Publish($id, $update) {
}
public function Remove($id) {
}
......
......@@ -7,7 +7,7 @@ if (!this.dobrado.purchase) {
'use strict';
// This is a representation of all purchases in json.
var purchase = null;
var purchase = {};
// This is an instance of slick grid, if available on the page.
var purchaseGrid = null;
var purchaseGridId = "";
......@@ -37,10 +37,10 @@ if (!this.dobrado.purchase) {
}
// Check if there is data that needs saving before leaving the page.
window.addEventListener("beforeunload", function (e) {
window.addEventListener("beforeunload", function(event) {
if (purchase.processed && purchase.processed.length !== 0) {
var message = "Please save your orders before leaving the page.";
(e || window.event).returnValue = message;
event.returnValue = message;
return message;
}
});
......
......@@ -17,9 +17,10 @@ if (!this.dobrado.writer) {
$(this).click(showOptions);
});
$("#writer-content").val("Write a new post...").click(showEditor);
$(".writer-post").button({ disabled: true }).click(post);
$(".writer-post").button().click(post);
$("#writer-tags").button().click(toggleTags);
$(".writer .menu").menu();
hideOptions();
});
function hideMenu() {
......@@ -39,6 +40,15 @@ if (!this.dobrado.writer) {
$("." + className).show();