initial
This commit is contained in:
commit
c9b643e112
11 files changed
+778
No files matched your search
@@ -0,0 +1,49 @@
|
||||
# Flashy - Just another simple vocabulary trainer
|
||||
|
||||
This is a single-file php application for training writing using flash cards sorted into boxes.
|
||||
The UI is optimized for mobile viewing. Added cards are automatically sorted into different boxes based on successfully typing in the correct answer or not.
|
||||
|
||||
The provided database contains cards for learning German for english speakers but it can be adapted to learn anything. Editing is also possible throug the UI (except for word classes) so adding an empty database is also an option. Please tweak db.sql before creating the sqlite3 database.
|
||||
|
||||
## Why built it?
|
||||
I wrote this small application to help my wife learn german but then thought of publishing it in case someone else is looking for a simple solution. I know there are plenty of language learning programs out there but i wanted something offline and with boxes the cards are sorted into the traditional way. Contributions and improvements are most welcome.
|
||||
|
||||
## Screenshots
|
||||

|
||||

|
||||
|
||||
### Test
|
||||

|
||||
|
||||
### Vocabulary Boxes
|
||||

|
||||
|
||||
### Editor
|
||||

|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
- php 7.4 or higher
|
||||
- php-sqlite3 extension
|
||||
|
||||
## Installation
|
||||
Create a database from the provided db.sql file:
|
||||
```
|
||||
sqlite db.db < db.sql
|
||||
```
|
||||
|
||||
## Edit index.php
|
||||
Find following user/password lines and edit as needed.
|
||||
```
|
||||
class Auth {
|
||||
private $user = 'username';
|
||||
private $pass = 'password';
|
||||
```
|
||||
|
||||
You can also comment out the line
|
||||
|
||||
```
|
||||
new Auth();
|
||||
```
|
||||
at the bottom to disable basic authentication completely.
|
||||
@@ -0,0 +1,134 @@
|
||||
PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE boxes (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL
|
||||
);
|
||||
INSERT INTO boxes VALUES(0,'Failed Thrice');
|
||||
INSERT INTO boxes VALUES(1,'Failed Twice');
|
||||
INSERT INTO boxes VALUES(2,'Failed Once');
|
||||
INSERT INTO boxes VALUES(3,'New');
|
||||
INSERT INTO boxes VALUES(4,'Correct Once');
|
||||
INSERT INTO boxes VALUES(5,'Correct Twice');
|
||||
INSERT INTO boxes VALUES(6,'Correct Thrice');
|
||||
INSERT INTO boxes VALUES(7,'Mastered');
|
||||
CREATE TABLE classes (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL
|
||||
);
|
||||
INSERT INTO classes VALUES(0,'Pronoun');
|
||||
INSERT INTO classes VALUES(1,'Noun');
|
||||
INSERT INTO classes VALUES(2,'Verb (Infinitive)');
|
||||
INSERT INTO classes VALUES(3,'Verb (Praesens)');
|
||||
INSERT INTO classes VALUES(4,'Verb (Perfekt)');
|
||||
INSERT INTO classes VALUES(5,'Verb (Praeteritum)');
|
||||
INSERT INTO classes VALUES(6,'Verb (Plusquamperfekt)');
|
||||
INSERT INTO classes VALUES(7,'Verb (Futur)');
|
||||
INSERT INTO classes VALUES(8,'Verb (Futur II)');
|
||||
INSERT INTO classes VALUES(9,'Adjective');
|
||||
INSERT INTO classes VALUES(10,'Adverb');
|
||||
CREATE TABLE cards (
|
||||
id INTEGER PRIMARY KEY,
|
||||
box_id INTEGER DEFAULT 3,
|
||||
class_id INTEGER NOT NULL,
|
||||
front TEXT NOT NULL,
|
||||
back TEXT NOT NULL,
|
||||
FOREIGN KEY(box_id) REFERENCES boxes(id) ON UPDATE CASCADE,
|
||||
FOREIGN KEY(class_id) REFERENCES classes(id) ON UPDATE CASCADE
|
||||
);
|
||||
INSERT INTO cards VALUES(1,3,1,'the house','das Haus');
|
||||
INSERT INTO cards VALUES(2,3,1,'my house','mein Haus');
|
||||
INSERT INTO cards VALUES(3,3,1,'your house','dein Haus');
|
||||
INSERT INTO cards VALUES(4,3,1,'his house','sein Haus');
|
||||
INSERT INTO cards VALUES(5,3,1,'her house','ihr Haus');
|
||||
INSERT INTO cards VALUES(6,3,1,'our house','unser Haus');
|
||||
INSERT INTO cards VALUES(7,3,1,'your house (plural)','euer Haus');
|
||||
INSERT INTO cards VALUES(8,3,1,'their house','ihr Haus');
|
||||
INSERT INTO cards VALUES(9,3,1,'the child','das Kind');
|
||||
INSERT INTO cards VALUES(10,3,1,'my child','mein Kind');
|
||||
INSERT INTO cards VALUES(11,3,1,'your child','dein Kind');
|
||||
INSERT INTO cards VALUES(12,3,1,'his child','sein Kind');
|
||||
INSERT INTO cards VALUES(13,3,1,'her child','ihr Kind');
|
||||
INSERT INTO cards VALUES(14,3,1,'our child','unser Kind');
|
||||
INSERT INTO cards VALUES(15,3,1,'your child (plural)','euer Kind');
|
||||
INSERT INTO cards VALUES(16,3,1,'their child','ihr Kind');
|
||||
INSERT INTO cards VALUES(17,3,2,'to eat','essen');
|
||||
INSERT INTO cards VALUES(18,3,3,'i eat','ich esse');
|
||||
INSERT INTO cards VALUES(19,3,3,'you eat (singular)','du isst');
|
||||
INSERT INTO cards VALUES(20,3,3,'he eats','er isst');
|
||||
INSERT INTO cards VALUES(21,3,3,'she eats','sie isst');
|
||||
INSERT INTO cards VALUES(22,3,3,'we eat','wir essen');
|
||||
INSERT INTO cards VALUES(23,3,3,'you eat (plural)','ihr esst');
|
||||
INSERT INTO cards VALUES(24,3,3,'they eat','sie essen');
|
||||
INSERT INTO cards VALUES(25,3,4,'i ate','ich ass');
|
||||
INSERT INTO cards VALUES(26,3,4,'you ate','du asst');
|
||||
INSERT INTO cards VALUES(27,3,4,'he ate','er ass');
|
||||
INSERT INTO cards VALUES(28,3,4,'she ate','sie ass');
|
||||
INSERT INTO cards VALUES(29,3,4,'we ate','wir assen');
|
||||
INSERT INTO cards VALUES(30,3,4,'you ate (plural)','ihr asst');
|
||||
INSERT INTO cards VALUES(31,3,4,'they ate','sie assen');
|
||||
INSERT INTO cards VALUES(32,3,1,'the baker','der Bäcker');
|
||||
INSERT INTO cards VALUES(33,3,1,'the children','die Kinder');
|
||||
INSERT INTO cards VALUES(34,3,1,'my children','meine Kinder');
|
||||
INSERT INTO cards VALUES(35,3,1,'your children','deine Kinder');
|
||||
INSERT INTO cards VALUES(36,3,1,'his children','seine Kinder');
|
||||
INSERT INTO cards VALUES(37,3,1,'her children','ihre Kinder');
|
||||
INSERT INTO cards VALUES(38,3,1,'our children','unsere Kinder');
|
||||
INSERT INTO cards VALUES(39,3,1,'your children (plural)','eure Kinder');
|
||||
INSERT INTO cards VALUES(40,3,1,'their children','ihre Kinder');
|
||||
INSERT INTO cards VALUES(41,3,1,'the bakers','die Bäcker');
|
||||
INSERT INTO cards VALUES(42,3,9,'ruthless','rücksichtslos');
|
||||
INSERT INTO cards VALUES(43,3,4,'it ate','es ass');
|
||||
INSERT INTO cards VALUES(46,3,1,'the mountain','der Berg');
|
||||
INSERT INTO cards VALUES(47,3,2,'to fit','passen');
|
||||
INSERT INTO cards VALUES(48,3,1,'river','Fluss');
|
||||
INSERT INTO cards VALUES(49,3,1,'the stage','die Bühne');
|
||||
INSERT INTO cards VALUES(50,3,2,'to find','finden');
|
||||
INSERT INTO cards VALUES(51,3,2,'to take','nehmen');
|
||||
INSERT INTO cards VALUES(52,3,2,'to taste','schmecken');
|
||||
INSERT INTO cards VALUES(53,3,1,'really','wirklick');
|
||||
INSERT INTO cards VALUES(54,3,2,'to pay','Zahlen');
|
||||
INSERT INTO cards VALUES(55,3,2,'to bring','bringen');
|
||||
INSERT INTO cards VALUES(56,3,1,'bill','Die Rechnung');
|
||||
INSERT INTO cards VALUES(57,3,1,'the waiter','Der Kellner');
|
||||
INSERT INTO cards VALUES(58,3,2,'to order','bestellen');
|
||||
INSERT INTO cards VALUES(59,3,2,'to wish','wünschen');
|
||||
INSERT INTO cards VALUES(60,3,2,'to get','bekommen');
|
||||
INSERT INTO cards VALUES(61,3,1,'exactly ','genau');
|
||||
INSERT INTO cards VALUES(62,3,1,'something','etwas');
|
||||
INSERT INTO cards VALUES(63,3,2,'to climb','klettern');
|
||||
INSERT INTO cards VALUES(64,3,2,'to desire','begehren');
|
||||
INSERT INTO cards VALUES(65,3,1,'the pub','Die Kneipe');
|
||||
INSERT INTO cards VALUES(66,3,1,'again','wieder');
|
||||
INSERT INTO cards VALUES(67,3,1,'open','geöffnet');
|
||||
INSERT INTO cards VALUES(68,3,2,'to open','öffnen');
|
||||
INSERT INTO cards VALUES(69,3,1,'closed','geschlossen');
|
||||
INSERT INTO cards VALUES(70,3,2,'to close','schliessen');
|
||||
INSERT INTO cards VALUES(71,3,1,'the resident','der Einwohner');
|
||||
INSERT INTO cards VALUES(72,3,2,'to freeze','frieren');
|
||||
INSERT INTO cards VALUES(73,3,1,'the desire','die Lust');
|
||||
INSERT INTO cards VALUES(74,3,1,'the passenger','der Fahrgast');
|
||||
INSERT INTO cards VALUES(75,3,1,'at','bei');
|
||||
INSERT INTO cards VALUES(76,3,1,'all','alle');
|
||||
INSERT INTO cards VALUES(77,3,1,'the area (surface)','die Fläche');
|
||||
INSERT INTO cards VALUES(78,3,2,'to lie down','liegen');
|
||||
INSERT INTO cards VALUES(79,3,1,'high','hoch');
|
||||
INSERT INTO cards VALUES(80,3,1,'the border','die Grenze');
|
||||
INSERT INTO cards VALUES(81,3,1,'the main train station','der Hauptbahnhof');
|
||||
INSERT INTO cards VALUES(82,3,1,'the harbour','der Hafen');
|
||||
INSERT INTO cards VALUES(83,3,1,'the Opera','die Oper');
|
||||
INSERT INTO cards VALUES(84,3,1,'the church','die Kirche');
|
||||
INSERT INTO cards VALUES(85,3,2,'last','dauern');
|
||||
INSERT INTO cards VALUES(86,3,2,'to get there','hingelangen');
|
||||
INSERT INTO cards VALUES(87,3,1,'the play','das Stück');
|
||||
INSERT INTO cards VALUES(88,3,1,'the ticket','das Ticket');
|
||||
INSERT INTO cards VALUES(89,3,1,'the fridge','der Kühlschrank');
|
||||
INSERT INTO cards VALUES(90,3,1,'afterwards','nachher');
|
||||
INSERT INTO cards VALUES(91,3,1,'rarely','selten');
|
||||
INSERT INTO cards VALUES(92,3,2,'to cut','schneiden');
|
||||
INSERT INTO cards VALUES(93,3,1,'both','beide');
|
||||
INSERT INTO cards VALUES(94,3,2,'to sit','sitzen');
|
||||
INSERT INTO cards VALUES(95,3,2,'to sit down','sich hinsetzen');
|
||||
INSERT INTO cards VALUES(96,3,2,'to fetch','holen');
|
||||
INSERT INTO cards VALUES(97,3,1,'the surface','die Oberfläche');
|
||||
COMMIT;
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
@@ -0,0 +1,360 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Flashy</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="static/reset.css">
|
||||
<link rel="stylesheet" href="static/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
class Auth {
|
||||
private $user = 'username';
|
||||
private $pass = 'password';
|
||||
|
||||
public function __construct() {
|
||||
if (!isset($_SERVER['PHP_AUTH_USER']) ||
|
||||
$_SERVER['PHP_AUTH_USER'] != $this->user ||
|
||||
!isset($_SERVER['PHP_AUTH_PW']) ||
|
||||
$_SERVER['PHP_AUTH_PW'] != $this->pass
|
||||
) {
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
header('WWW-Authenticate: Basic realm="Flashy"');
|
||||
echo 'You are not authorized to access this site. Please log in.';
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Card {
|
||||
public $id, $boxID, $classID, $front, $back;
|
||||
public function __construct($id, $boxID, $classID, $front, $back) {
|
||||
$this->id=$id;
|
||||
$this->boxID=$boxID;
|
||||
$this->classID=$classID;
|
||||
$this->front=$front;
|
||||
$this->back=$back;
|
||||
}
|
||||
|
||||
public static function createFromDBRow($row) {
|
||||
return new Card($row['id'], $row['box_id'], $row['class_id'], $row['front'], $row['back']);
|
||||
}
|
||||
}
|
||||
|
||||
class DB {
|
||||
private $db;
|
||||
|
||||
public function __construct() {
|
||||
$this->db = new PDO('sqlite:db.db');
|
||||
$this->db->query("PRAGMA foreign_keys = ON");
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
$db = null;
|
||||
}
|
||||
|
||||
public function getClasses() {
|
||||
return $this->db->query("SELECT * FROM classes");
|
||||
}
|
||||
|
||||
public function getBoxes() {
|
||||
return $this->db->query("SELECT * FROM boxes");
|
||||
}
|
||||
|
||||
public function getBoxNameByID($boxID) {
|
||||
return $this->db->query("SELECT name FROM boxes WHERE id='".$boxID."' LIMIT 1")->fetchColumn();
|
||||
}
|
||||
|
||||
public function getClassNameByID($classID) {
|
||||
return $this->db->query("SELECT name FROM classes WHERE id='".$classID."' LIMIT 1")->fetchColumn();
|
||||
}
|
||||
|
||||
public function getNumBoxes() {
|
||||
return $this->db->query("SELECT COUNT(*) FROM boxes")->fetchColumn();
|
||||
}
|
||||
|
||||
public function getFirstCardByBoxID($boxID) {
|
||||
$res = $this->db->query("SELECT * FROM cards WHERE box_id = '" . $boxID . "' LIMIT 1")->fetchAll();
|
||||
if (count($res) > 0) {
|
||||
$row = $res[0];
|
||||
return Card::createFromDBRow($row);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function getCardByID($card_id) {
|
||||
$res = $this->db->query("SELECT * FROM cards WHERE id = '" . $card_id . "' LIMIT 1")->fetchAll();
|
||||
if (count($res) > 0) {
|
||||
$row = $res[0];
|
||||
return Card::createFromDBRow($row);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function getNumCardsByBoxID($boxID) {
|
||||
return $this->db->query("SELECT COUNT(*) FROM cards where box_id='" . $boxID . "'")->fetchColumn();
|
||||
}
|
||||
|
||||
public function getNumCards() {
|
||||
return $this->db->query("SELECT COUNT(*) FROM cards")->fetchColumn();
|
||||
}
|
||||
|
||||
public function updateCard($card) {
|
||||
$origCard = $this->getCardByID($card->id);
|
||||
if($origCard->boxID != $card->boxID) {
|
||||
$res = $this->db->query("UPDATE cards SET box_id='".$card->boxID."' WHERE id='".$card->id."'");
|
||||
}
|
||||
if($origCard->classID != $card->classID) {
|
||||
$res = $this->db->query("UPDATE cards SET class_id='".$card->classID."' WHERE id='".$card->id."'");
|
||||
}
|
||||
if($origCard->front != $card->front) {
|
||||
$res = $this->db->query("UPDATE cards SET front='".$card->front."' WHERE id='".$card->id."'");
|
||||
}
|
||||
if($origCard->back != $card->back) {
|
||||
$res = $this->db->query("UPDATE cards SET back='".$card->back."' WHERE id='".$card->id."'");
|
||||
}
|
||||
}
|
||||
|
||||
public function createCard($card) {
|
||||
if($card->classID != null && $card->front != null && $card->back != null) {
|
||||
$res = $this->db->query("INSERT INTO cards (box_id,class_id,front,back) VALUES(3,".$card->classID.",'".$card->front."','".$card->back."')");
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteCard($cardID) {
|
||||
if($cardID != null) {
|
||||
$res = $this->db->query("DELETE FROM cards WHERE id='".$cardID."'");
|
||||
}
|
||||
}
|
||||
|
||||
public function getRandomCardByBoxID($boxID) {}
|
||||
public function getAllCardsByBoxID($boxID) {}
|
||||
}
|
||||
|
||||
class App {
|
||||
private $db,
|
||||
$selectedCard,
|
||||
$selectedBoxID,
|
||||
$testInput,
|
||||
$message,
|
||||
$checkCase = true;
|
||||
|
||||
public function __construct() {
|
||||
$this->db = new DB();
|
||||
|
||||
$this->handleInput();
|
||||
|
||||
// Select random card from selected box since none is selected yet:
|
||||
if($this->selectedBoxID != null && $this->selectedCard == null) {
|
||||
$this->selectNewCard();
|
||||
/*
|
||||
if($this->selectedCard != null) {
|
||||
// Give the user some info...
|
||||
$this->message = $this->selectedCard->front.' | '.$this->db->getClassNameByID($this->selectedCard->classID);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Do some evaluation...
|
||||
if(isset($this->selectedCard) && $this->testInput != null) {
|
||||
// Case sensitive...
|
||||
if($this->checkCase) {
|
||||
$a = $this->selectedCard->back;
|
||||
$b = $this->testInput;
|
||||
}
|
||||
// Case insensitive...
|
||||
else {
|
||||
$a = strtolower($this->selectedCard->back);
|
||||
$b = strtolower($this->testInput);
|
||||
}
|
||||
//Answer correct:
|
||||
if($a == $b) {
|
||||
if($this->selectedCard->back == $this->testInput) {
|
||||
$this->message = 'Correct';
|
||||
}
|
||||
else {
|
||||
$this->message = 'Almost Correct';
|
||||
}
|
||||
|
||||
if($this->selectedCard->boxID >= 0 && $this->selectedCard->boxID < 3) {
|
||||
$this->selectedCard->boxID = 4;
|
||||
}
|
||||
else if($this->selectedCard->boxID >= 3 && $this->selectedCard->boxID < $this->db->getNumBoxes()-1) {
|
||||
$this->selectedCard->boxID += 1;
|
||||
}
|
||||
}
|
||||
//Answer wrong:
|
||||
else {
|
||||
$this->message = 'Wrong - Correct answer:<br>'.$this->selectedCard->back;
|
||||
if($this->selectedCard->boxID > 0 && $this->selectedCard->boxID <= 3) {
|
||||
$this->selectedCard->boxID -= 1;
|
||||
}
|
||||
else if($this->selectedCard->boxID > 3 && $this->selectedCard->boxID < $this->db->getNumBoxes()) {
|
||||
$this->selectedCard->boxID = 2;
|
||||
}
|
||||
}
|
||||
$this->db->updateCard($this->selectedCard);
|
||||
$this->testInput = '';
|
||||
$this->selectNewCard();
|
||||
}
|
||||
|
||||
$this->renderTest();
|
||||
$this->renderBoxes();
|
||||
$this->renderConfigurator();
|
||||
}
|
||||
|
||||
private function renderTest() {
|
||||
echo '<div class="test_view">' . "\n";
|
||||
echo '<div class="std_row">' . $this->message . "</div>\n";
|
||||
echo '<div class="std_row">'.($this->selectedCard == null ? '' : $this->selectedCard->front.' | '.$this->db->getClassNameByID($this->selectedCard->classID))."</div>\n";
|
||||
echo '<form method="POST">' . "\n";
|
||||
echo '<input type="text" name="test_input"'
|
||||
.($this->testInput == null ? '' : ' value="' . $this->testInput . '"')
|
||||
.($this->selectedCard == null ? '' : ' autofocus')
|
||||
.'>'."\n";
|
||||
echo '<input class="btn_row" type="submit" value="Check">' . "\n";
|
||||
echo '<input type="hidden" name="card_id" value="'.($this->selectedCard == null ? '' : $this->selectedCard->id).'">'."\n";
|
||||
echo '</form>' . "\n";
|
||||
echo '<a class="btn_row'.($this->checkCase ? ' selected' : '').'" href="'.$this->createExtendedGetParameterString('check_case', (int)!$this->checkCase).'">Case sensitive</a>' . "\n";
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
private function renderBoxes() {
|
||||
echo '<div class="box_view">'."\n";
|
||||
echo "<ul>\n";
|
||||
foreach ($this->db->getBoxes() as $box) {
|
||||
$this->addGetParameter('box_id', $box['id']);
|
||||
$this->addGetParameter('check_case', $this->checkCase);
|
||||
if (isset($this->selectedBoxID)) {
|
||||
$html_selected = $box['id'] == $this->selectedBoxID ? ' class="selected"' : '';
|
||||
}
|
||||
else {
|
||||
$html_selected = '';
|
||||
}
|
||||
|
||||
echo "<li>\n";
|
||||
echo '<a href="'.$this->createGetParameterString().'"'.$html_selected.'>'.$box['name'].' ('.$this->db->getNumCardsByBoxID($box['id']).")</a>\n";
|
||||
echo "</li>\n";
|
||||
}
|
||||
echo "</ul>\n";
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
private function renderConfigurator() {
|
||||
echo '<div class="configurator_view">' . "\n";
|
||||
echo '<form method="POST">' . "\n";
|
||||
echo '<div><input type="text" name="card_front" value="'.($this->selectedCard != null ? $this->selectedCard->front : 'Front').'"></div>' . "\n";
|
||||
echo '<div><input type="text" name="card_back" value="'. ($this->selectedCard != null ? $this->selectedCard->back : 'Back') .'"></div>' . "\n";
|
||||
echo '<select name="class_id">'."\n";
|
||||
foreach ($this->db->getClasses() as $class) {
|
||||
if($this->selectedCard != null) {
|
||||
$setSelected = $class['id'] == $this->selectedCard->classID ? ' selected="selected"' : '';
|
||||
}
|
||||
else {
|
||||
$setSelected = '';
|
||||
}
|
||||
echo '<option value="'.$class['id'].'"'.$setSelected.'>'.$class['name']."</option>\n";
|
||||
}
|
||||
echo "</select>\n";
|
||||
echo '<div><input class="btn_row" type="submit" name="action_create" value="Create"></div>' . "\n";
|
||||
echo '<div><input class="btn_row" type="submit" name="action_replace" value="Replace"></div>' . "\n";
|
||||
echo '<div><input class="btn_row" type="submit" name="action_delete" value="Delete"></div>' . "\n";
|
||||
echo '<input type="hidden" name="card_id" value="'.($this->selectedCard == null ? '' : $this->selectedCard->id).'">'."\n";
|
||||
echo '</form>' . "\n";
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
private function handleInput() {
|
||||
if (isset($_REQUEST['box_id']) &&
|
||||
$_REQUEST['box_id'] >= 0 &&
|
||||
$_REQUEST['box_id'] < $this->db->getNumBoxes())
|
||||
{
|
||||
$this->selectedBoxID = $_REQUEST['box_id'];
|
||||
}
|
||||
if (isset($_REQUEST['card_id']) &&
|
||||
$_REQUEST['card_id'] >= 0)
|
||||
{
|
||||
$this->selectedCard = $this->db->getCardByID($_REQUEST['card_id']);
|
||||
}
|
||||
if (isset($_REQUEST['check_case']) &&
|
||||
$_REQUEST['check_case'] == 1)
|
||||
{
|
||||
$this->checkCase = true;
|
||||
}
|
||||
else $this->checkCase = false;
|
||||
|
||||
if (isset($_REQUEST['test_input']) && $_REQUEST['test_input'] != '') {
|
||||
$this->testInput = trim($_REQUEST['test_input']);
|
||||
}
|
||||
|
||||
// Create a new Card in the database
|
||||
if (isset($_REQUEST['action_create']) &&
|
||||
isset($_REQUEST['class_id']) && $_REQUEST['class_id'] != null &&
|
||||
isset($_REQUEST['card_front']) && $_REQUEST['card_front'] != null &&
|
||||
isset($_REQUEST['card_back']) && $_REQUEST['card_back'] != null)
|
||||
{
|
||||
$card = new Card(null, 3, $_REQUEST['class_id'], trim($_REQUEST['card_front']), trim($_REQUEST['card_back']));
|
||||
$this->db->createCard($card);
|
||||
}
|
||||
// Modify an existing card in the database
|
||||
else if (isset($_REQUEST['action_replace']) &&
|
||||
isset($_REQUEST['class_id']) && $_REQUEST['class_id'] != null &&
|
||||
isset($_REQUEST['card_front']) && $_REQUEST['card_front'] != null &&
|
||||
isset($_REQUEST['card_back']) && $_REQUEST['card_back'] != null &&
|
||||
$this->selectedCard != null)
|
||||
{
|
||||
$card = new Card($this->selectedCard->id, $this->selectedCard->boxID, $_REQUEST['class_id'], trim($_REQUEST['card_front']), trim($_REQUEST['card_back']));
|
||||
$this->db->updateCard($card);
|
||||
// Reload the updated card
|
||||
$this->selectedCard = $this->db->getCardByID($card->id);
|
||||
}
|
||||
// Delete a card from the database
|
||||
else if (isset($_REQUEST['action_delete']) &&
|
||||
$this->selectedCard != null)
|
||||
{
|
||||
$this->db->deleteCard($this->selectedCard->id);
|
||||
// Make sure the deleted card is no longer selected
|
||||
$this->selectedCard = null;
|
||||
}
|
||||
}
|
||||
|
||||
private function selectNewCard() {
|
||||
$this->selectedCard = $this->db->getFirstCardByBoxID($this->selectedBoxID);
|
||||
}
|
||||
|
||||
private function addGetParameter($parameterName, $parameterValue) {
|
||||
$_GET[$parameterName] = $parameterValue;
|
||||
}
|
||||
|
||||
private function createGetParameterString() {
|
||||
$tmp = '?';
|
||||
foreach($_GET as $key => $value) {
|
||||
$tmp = $tmp . $key . '=' . $value . '&';
|
||||
}
|
||||
return trim($tmp, '&');//substr($tmp, 0, -1);
|
||||
}
|
||||
|
||||
//Add a temporary extra key/value pair to string
|
||||
private function createExtendedGetParameterString($key, $value) {
|
||||
$this->deleteGetParameter($key);
|
||||
$existingParams = $this->createGetParameterString();
|
||||
return $existingParams == '?' ? '?'.$key.'='.$value : $existingParams.'&'.$key.'='.$value;
|
||||
}
|
||||
|
||||
private function deleteGetParameter($key) {
|
||||
unset($_GET[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
new Auth();
|
||||
new App();
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,48 @@
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
body {
|
||||
margin: 0px auto;
|
||||
padding: 0px;
|
||||
background-color: #83bdfc;
|
||||
font-size: 14px;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
input, select {
|
||||
margin: 0 0 20px 0;
|
||||
padding: 10px;
|
||||
border-radius: 15px;
|
||||
border: none;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.box_view {
|
||||
margin: 0;
|
||||
padding: 10px 10px 50px 10px;
|
||||
|
||||
}
|
||||
|
||||
.box_view ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.box_view li {
|
||||
margin: 20px 0;
|
||||
padding: 0;
|
||||
|
||||
}
|
||||
|
||||
.box_view ul li a {
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
background-color: #b4d8ff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.box_view ul li a.selected {
|
||||
background-color: #202020;
|
||||
color: #EEEEEE;
|
||||
}
|
||||
|
||||
.box_view li a:hover {
|
||||
background-color: #202020;
|
||||
color: #EEEEEE;
|
||||
}
|
||||
|
||||
.test_view {
|
||||
margin: 0;
|
||||
padding: 10px 10px 35px 10px;
|
||||
}
|
||||
|
||||
.std_row, .btn_row {
|
||||
margin: 0 0 20px 0;
|
||||
padding: 10px;
|
||||
min-height: 14px;
|
||||
border-radius: 15px;
|
||||
background-color: #b4d8ff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn_row.selected {
|
||||
background-color: #202020;
|
||||
color: #EEEEEE;
|
||||
}
|
||||
|
||||
.btn_row:hover {
|
||||
background-color: #202020;
|
||||
color: #EEEEEE;
|
||||
}
|
||||
|
||||
.configurator_view {
|
||||
padding: 10px 10px 25px 10px;
|
||||
}
|
||||
|
||||
.configurator_view select {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
/*
|
||||
.infos {
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
background-color: #83bdfc;
|
||||
}
|
||||
|
||||
.infos div {
|
||||
margin: 20px 0;
|
||||
padding: 0px;
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,84 @@
|
||||
body {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
color: #EEEEEE;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
input, select {
|
||||
margin: 0;
|
||||
margin-bottom: 20px;
|
||||
padding: 0px 15px;
|
||||
height: 40px;
|
||||
border-radius: 5px;
|
||||
border: none;
|
||||
width: 100%;
|
||||
/*width: inherit;*/
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.box_view {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
width: 100%;
|
||||
background-color: #505050;
|
||||
}
|
||||
|
||||
.box_view #head {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.box_view tr {
|
||||
padding: 15px 10px;
|
||||
}
|
||||
|
||||
.box_view td {
|
||||
padding: inherit;
|
||||
}
|
||||
|
||||
.test_input {
|
||||
background-color: #505050;
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.test_input form {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.test_input div {
|
||||
margin: 0;
|
||||
/*margin-bottom: 20px;*/
|
||||
padding: 0;
|
||||
min-height: 40px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.test_input #feedback {
|
||||
margin: auto;
|
||||
padding: 15px;
|
||||
width: fit-content;
|
||||
text-align: center;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.configurator_input {
|
||||
background-color: #3f3f3f;
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
.infos {
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
background-color: #3f3f3f;
|
||||
}
|
||||
|
||||
.infos div {
|
||||
margin: 20px 0;
|
||||
padding: 0px;
|
||||
}
|
||||
Reference in new issue
Block a user