Create Note object, simple database schema, and readonly web view
This commit is contained in:
parent
47539de2d7
commit
841bf184f7
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
vendor
|
||||
settings.php
|
||||
nbproject/private
|
||||
*.sync-conflict*
|
||||
*.sync-conflict*
|
||||
*.bak
|
2
app.php
2
app.php
@ -114,7 +114,7 @@ END;
|
||||
// For mobile app
|
||||
echo "<script nonce=\"$SECURE_NONCE\">var navbar_breakpoint = \"$navbar_breakpoint\";</script>"
|
||||
?>
|
||||
<nav class="navbar navbar-expand-<?php echo $navbar_breakpoint; ?> navbar-dark bg-blue fixed-top">
|
||||
<nav class="navbar navbar-expand-<?php echo $navbar_breakpoint; ?> navbar-dark bg-red fixed-top">
|
||||
<button class="navbar-toggler my-0 py-0" type="button" data-toggle="collapse" data-target="#navbar-collapse" aria-controls="navbar-collapse" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<!--<i class="fas fa-bars"></i>-->
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
|
@ -1,10 +1,11 @@
|
||||
{
|
||||
"name": "netsyms/business-app-template",
|
||||
"description": "Template for a webapp integrated with an AccountHub server.",
|
||||
"name": "netsyms/notepost",
|
||||
"description": "Note and list organizer.",
|
||||
"type": "project",
|
||||
"require": {
|
||||
"catfan/medoo": "^1.5",
|
||||
"guzzlehttp/guzzle": "^6.2"
|
||||
"guzzlehttp/guzzle": "^6.2",
|
||||
"erusev/parsedown": "^1.7"
|
||||
},
|
||||
"license": "MPL-2.0",
|
||||
"authors": [
|
||||
|
59
composer.lock
generated
59
composer.lock
generated
@ -4,8 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "5c7439c6e041764f2f6b0270a95ab3ae",
|
||||
"content-hash": "e4e700119f47d2f68b0ed82abaf8c5c6",
|
||||
"content-hash": "1aea304797149ba2b5bccc0f6d82c060",
|
||||
"packages": [
|
||||
{
|
||||
"name": "catfan/medoo",
|
||||
@ -64,7 +63,53 @@
|
||||
"sql",
|
||||
"sqlite"
|
||||
],
|
||||
"time": "2018-06-14 18:59:08"
|
||||
"time": "2018-06-14T18:59:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "erusev/parsedown",
|
||||
"version": "1.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/erusev/parsedown.git",
|
||||
"reference": "92e9c27ba0e74b8b028b111d1b6f956a15c01fc1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/erusev/parsedown/zipball/92e9c27ba0e74b8b028b111d1b6f956a15c01fc1",
|
||||
"reference": "92e9c27ba0e74b8b028b111d1b6f956a15c01fc1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Parsedown": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Emanuil Rusev",
|
||||
"email": "hello@erusev.com",
|
||||
"homepage": "http://erusev.com"
|
||||
}
|
||||
],
|
||||
"description": "Parser for Markdown.",
|
||||
"homepage": "http://parsedown.org",
|
||||
"keywords": [
|
||||
"markdown",
|
||||
"parser"
|
||||
],
|
||||
"time": "2018-03-08T01:11:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
@ -129,7 +174,7 @@
|
||||
"rest",
|
||||
"web service"
|
||||
],
|
||||
"time": "2018-04-22 15:46:56"
|
||||
"time": "2018-04-22T15:46:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
@ -180,7 +225,7 @@
|
||||
"keywords": [
|
||||
"promise"
|
||||
],
|
||||
"time": "2016-12-20 10:07:11"
|
||||
"time": "2016-12-20T10:07:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
@ -245,7 +290,7 @@
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"time": "2017-03-20 17:10:46"
|
||||
"time": "2017-03-20T17:10:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
@ -295,7 +340,7 @@
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"time": "2016-08-06 14:39:51"
|
||||
"time": "2016-08-06T14:39:51+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
BIN
database.mwb
Normal file
BIN
database.mwb
Normal file
Binary file not shown.
5
langs/en/notes.json
Normal file
5
langs/en/notes.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"New": "New",
|
||||
"Note": "Note",
|
||||
"Edit": "Edit"
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"home": "Home",
|
||||
"test": "Test"
|
||||
"Notes": "Notes"
|
||||
}
|
||||
|
@ -10,4 +10,10 @@ class IncorrectPasswordException extends Exception {
|
||||
public function __construct(string $message = "Incorrect password.", int $code = 0, \Throwable $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
|
||||
class NoSuchNoteException extends Exception {
|
||||
public function __construct(string $message = "Note ID does not exist.", int $code = 0, \Throwable $previous = null) {
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
195
lib/Note.lib.php
Normal file
195
lib/Note.lib.php
Normal file
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
class Note {
|
||||
|
||||
private $noteid;
|
||||
private $ownerid;
|
||||
private $content = "";
|
||||
private $color = "FFFFFF";
|
||||
|
||||
/**
|
||||
* Create a new Note object.
|
||||
* @param string $content Note content in Markdown
|
||||
* @param string $color Hex color "RRGGBB"
|
||||
* @param int $ownerid The owner's user ID
|
||||
*/
|
||||
public function __construct(string $content, string $color = "FFFFFF", int $ownerid = null, int $noteid = null) {
|
||||
$this->content = $content;
|
||||
$this->color = $color;
|
||||
$this->ownerid = $ownerid;
|
||||
$this->noteid = $noteid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a note from the database and return it.
|
||||
* @global type $database
|
||||
* @param int $noteid
|
||||
* @return \Note
|
||||
* @throws NoSuchNoteException When the note ID isn't found.
|
||||
*/
|
||||
public static function loadNote(int $noteid): Note {
|
||||
global $database;
|
||||
|
||||
if (!$database->has('notes', ['noteid' => $noteid])) {
|
||||
throw new NoSuchNoteException();
|
||||
}
|
||||
|
||||
$notedata = $database->get('notes', ['noteid', 'ownerid', 'color', 'content'], ['noteid' => $noteid]);
|
||||
|
||||
return new Note($notedata['content'], $notedata['color'], $notedata['ownerid'], $notedata['noteid']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the note to the database.
|
||||
* @global type $database
|
||||
* @param bool $saveas If true, save the note under a new ID. Forced to
|
||||
* true if the current note ID is missing or invalid.
|
||||
* @return int The database ID of the saved note
|
||||
* @throws Exception If there is no note owner set.
|
||||
*/
|
||||
public function saveNote(bool $saveas = false): int {
|
||||
global $database;
|
||||
|
||||
$data = [
|
||||
'ownerid' => $this->ownerid,
|
||||
'color' => $this->color,
|
||||
'content' => $this->content
|
||||
];
|
||||
|
||||
// We can't UPDATE the database, so use save as for INSERT
|
||||
if (empty($this->noteid) || !$database->has('notes', ['noteid' => $this->noteid])) {
|
||||
$saveas = true;
|
||||
}
|
||||
|
||||
if (empty($this->ownerid)) {
|
||||
throw new Exception("No owner set.");
|
||||
}
|
||||
|
||||
if ($saveas) {
|
||||
$database->insert('notes', $data);
|
||||
return $database->id();
|
||||
} else {
|
||||
$database->update('notes', $data, ['noteid' => $this->noteid]);
|
||||
return $this->noteid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Markdown content of the note.
|
||||
* @return string
|
||||
*/
|
||||
public function getText(): string {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HTML render of the note.
|
||||
* @param bool $fragment Get just the HTML content, instead of a whole HTML5 file
|
||||
* @return string
|
||||
*/
|
||||
public function getHTML(bool $fragment = true): string {
|
||||
$parsedown = new Parsedown;
|
||||
$parsedown->setSafeMode(true);
|
||||
return $parsedown->text($this->content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the note ID.
|
||||
* @return int
|
||||
*/
|
||||
public function getID(): int {
|
||||
return $this->noteid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the note color as RRGGBB hex.
|
||||
* @return string
|
||||
*/
|
||||
public function getColor(): string {
|
||||
return $this->color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the owner UID
|
||||
* @return int
|
||||
*/
|
||||
public function getOwnerID(): int {
|
||||
return $this->ownerid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the owner as a User object
|
||||
* @return \User
|
||||
*/
|
||||
public function getOwner(): User {
|
||||
return new User($this->ownerid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the note content
|
||||
* @param string $markdown
|
||||
*/
|
||||
public function setText(string $markdown) {
|
||||
$this->content = $markdown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the note color to a hex string
|
||||
* @param string $color "RRGGBB"
|
||||
*/
|
||||
public function setColor(string $color) {
|
||||
$this->color = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the owner by UID
|
||||
* @param int $uid
|
||||
*/
|
||||
public function setOwnerID(int $uid) {
|
||||
$this->ownerid = $uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the owner
|
||||
* @param User $user
|
||||
*/
|
||||
public function setOwner(User $owner) {
|
||||
$this->ownerid = $owner->getUID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this note as an array.
|
||||
* @return string
|
||||
*/
|
||||
public function toArray(): array {
|
||||
$owner = new User($this->ownerid);
|
||||
$arr = [
|
||||
'noteid' => $this->noteid,
|
||||
'color' => $this->color,
|
||||
'content' => $this->content,
|
||||
'owner' => [
|
||||
'uid' => $owner->getUID(),
|
||||
'username' => $owner->getUsername(),
|
||||
'name' => $owner->getName()
|
||||
]
|
||||
];
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an array with the structure from toArray().
|
||||
* @param array $arr
|
||||
* @return \Note A Note constructed from the array data.
|
||||
*/
|
||||
public static function fromArray(array $arr): Note {
|
||||
return new Note($arr['content'], $arr['color'], $arr['owner']['uid'], $arr['noteid']);
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
<type>org.netbeans.modules.php.project</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/php-project/1">
|
||||
<name>BusinessAppTemplate</name>
|
||||
<name>NotePost</name>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
|
@ -7,9 +7,9 @@
|
||||
// List of pages and metadata
|
||||
define("PAGES", [
|
||||
"home" => [
|
||||
"title" => "home",
|
||||
"title" => "Notes",
|
||||
"navbar" => true,
|
||||
"icon" => "fas fa-home"
|
||||
"icon" => "far fa-sticky-note"
|
||||
],
|
||||
"404" => [
|
||||
"title" => "404 error"
|
||||
|
@ -2,5 +2,47 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
$noteids = $database->select('notes', 'noteid', ['ownerid' => $_SESSION['uid']]);
|
||||
|
||||
$notes = [];
|
||||
|
||||
foreach ($noteids as $n) {
|
||||
$notes[] = Note::loadNote($n);
|
||||
}
|
||||
?>
|
||||
<h1>Hello World</h1>
|
||||
|
||||
<style nonce="<?php echo $SECURE_NONCE; ?>">
|
||||
<?php
|
||||
foreach ($notes as $note) {
|
||||
echo "#notecard_" . $note->getID() . " {\n"
|
||||
. " background-color: #" . $note->getColor() . ";\n"
|
||||
. " border: 1px solid #" . $note->getColor() . ";\n"
|
||||
. "}\n";
|
||||
}
|
||||
?>
|
||||
</style>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<?php
|
||||
foreach ($notes as $note) {
|
||||
?>
|
||||
<div class="col-12 col-sm-6 col-md-6 col-lg-4">
|
||||
<div class="card" data-color="<?php echo $note->getColor(); ?>" id="notecard_<?php echo $note->getID(); ?>">
|
||||
<div class="card-body">
|
||||
<?php echo $note->getHTML(); ?>
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<a href="" class="text-body">
|
||||
<i class="fas fa-edit"></i> <?php $Strings->get('Edit'); ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
@ -11,14 +11,14 @@ define("DEBUG", false);
|
||||
// Database connection settings
|
||||
// See http://medoo.in/api/new for info
|
||||
define("DB_TYPE", "mysql");
|
||||
define("DB_NAME", "app");
|
||||
define("DB_NAME", "notepost");
|
||||
define("DB_SERVER", "localhost");
|
||||
define("DB_USER", "app");
|
||||
define("DB_USER", "notepost");
|
||||
define("DB_PASS", "");
|
||||
define("DB_CHARSET", "utf8");
|
||||
|
||||
// Name of the app.
|
||||
define("SITE_TITLE", "Web App Template");
|
||||
define("SITE_TITLE", "NotePost");
|
||||
|
||||
|
||||
// URL of the AccountHub API endpoint
|
||||
|
@ -1,78 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 512.00001 512.00001"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="logo.svg"
|
||||
inkscape:export-filename="/home/skylar/Documents/Projects/Sources/WebAppTemplate/static/img/logo.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<defs
|
||||
id="defs4">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="-493.3276 : 245.89848 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="464.45088 : 245.89848 : 1"
|
||||
inkscape:persp3d-origin="-14.438371 : 160.56515 : 1"
|
||||
id="perspective4236" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.49497475"
|
||||
inkscape:cx="-135.9681"
|
||||
inkscape:cy="352.66131"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-540.36216)">
|
||||
<rect
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.74509804"
|
||||
id="rect4726"
|
||||
width="512"
|
||||
height="512"
|
||||
x="0"
|
||||
y="540.36218"
|
||||
rx="50"
|
||||
ry="50" />
|
||||
<path
|
||||
id="path4348"
|
||||
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:9.87128067;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 132.93564,682.51771 213.96788,-43.14304 0,313.97496 -213.96788,-37.9643 z m 213.96788,-43.14304 0,313.97496 32.16084,-45.18373 0,-217.44396 z m -213.96788,43.14304 213.96788,-43.14304 32.16084,51.34727 -167.21823,22.47784 z m 78.91049,30.68207 167.21823,-22.47784 0,217.44396 -167.21823,-19.77968 z m -78.91049,-30.68207 0,232.86762 78.91049,-26.99911 0,-175.18644 z m 0,232.86762 213.96788,37.9643 32.16084,-45.18373 -167.21823,-19.77968 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="512" height="512" version="1.1" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -540.36)"><rect y="540.36" width="512" height="512" rx="50" ry="50" fill="#fff"/><g stroke="#fff" stroke-width="7.7927"><rect x="233.35" y="641.56" width="233.78" height="233.78" rx="15.585" ry="15.585" fill="#ffeb3b"/><rect x="35.044" y="592.36" width="233.78" height="233.78" rx="15.585" ry="15.585" fill="#ef5350"/><rect x="113.35" y="755.34" width="233.78" height="233.78" rx="15.585" ry="15.585" fill="#ffeb3b"/></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 598 B |
Loading…
x
Reference in New Issue
Block a user