Create Note object, simple database schema, and readonly web view

master
Skylar Ittner 5 yıl önce
ebeveyn 47539de2d7
işleme 841bf184f7

3
.gitignore sağlanmış

@ -1,4 +1,5 @@
vendor
settings.php
nbproject/private
*.sync-conflict*
*.sync-conflict*
*.bak

@ -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 üretilen

@ -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": [],

İkili dosya gösterilmiyor.

@ -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);
}
}

@ -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>

Önce

Genişlik:  |  Yükseklik:  |  Boyut: 2.9 KiB

Sonra

Genişlik:  |  Yükseklik:  |  Boyut: 598 B

Yükleniyor…
İptal
Kaydet