Compare commits
8 Commits
04176ef92f
...
b6e6390dde
Author | SHA1 | Date |
---|---|---|
Robbie Antenesse | b6e6390dde | |
Robbie Antenesse | f8ae41bca6 | |
Robbie Antenesse | fcfc25e114 | |
Robbie Antenesse | a833cfa160 | |
Robbie Antenesse | a4358a7658 | |
Robbie Antenesse | f642519125 | |
Robbie Antenesse | 8a11f4a6b1 | |
Robbie Antenesse | 9a12f560c2 |
|
@ -8,7 +8,7 @@
|
||||||
"license": "UNLICENCED",
|
"license": "UNLICENCED",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "concurrently \"npm run watch-js\" \"npm run watch-php\"",
|
"start": "concurrently \"npm run watch-js\" \"npm run watch-php\"",
|
||||||
"watch-js": "parcel watch index.html",
|
"watch-js": "parcel watch index.html --public-url ./",
|
||||||
"watch-php": "cpx src/php/**/* dist -v -w",
|
"watch-php": "cpx src/php/**/* dist -v -w",
|
||||||
"bundle": "parcel build index.html && cpx src/php/**/* dist",
|
"bundle": "parcel build index.html && cpx src/php/**/* dist",
|
||||||
"serve-frontend-only": "parcel index.html",
|
"serve-frontend-only": "parcel index.html",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export function request (data = {}, success = () => {}, error = () => {}, fail = () => {}) {
|
export function request (data = {}, success = () => {}, error = () => {}/* , fail = () => {} */) {
|
||||||
fetch('./account/', {
|
return fetch('./api/', {
|
||||||
method: 'POST', // or 'PUT'
|
method: 'POST', // or 'PUT'
|
||||||
body: JSON.stringify(data), // data can be `string` or {object}!
|
body: JSON.stringify(data), // data can be `string` or {object}!
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -10,12 +10,8 @@ export function request (data = {}, success = () => {}, error = () => {}, fail =
|
||||||
.then(response => {
|
.then(response => {
|
||||||
console.log('Success:', JSON.stringify(response));
|
console.log('Success:', JSON.stringify(response));
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
error(response);
|
return error(response.data);
|
||||||
}
|
}
|
||||||
success(response);
|
return success(response.data);
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.error('Request Error:', err);
|
|
||||||
fail(err);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import { request } from "./helpers";
|
import { request } from "./helpers";
|
||||||
|
import { addMessage } from "../utilities";
|
||||||
|
|
||||||
export function logIn() {
|
export function logIn() {
|
||||||
const email = document.getElementById('loginEmail').value.trim(),
|
const email = document.getElementById('loginEmail').value.trim(),
|
||||||
|
@ -22,4 +23,67 @@ export function logIn() {
|
||||||
password,
|
password,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createAccount() {
|
||||||
|
const email = document.getElementById('createNewEmail').value.trim(),
|
||||||
|
password = document.getElementById('createNewPassword').value.trim(),
|
||||||
|
confirm = document.getElementById('createNewConfirm').value.trim(),
|
||||||
|
publicName = document.getElementById('createNewPublicName').value.trim(),
|
||||||
|
allowEmail = document.getElementById('createNewAllowEmails').checked;
|
||||||
|
const createAccountErrorMessages = document.getElementById('createAccountErrorMessages');
|
||||||
|
let errorHTML = '';
|
||||||
|
|
||||||
|
if (email === '') {
|
||||||
|
errorHTML += '<p class="bold red">Please enter an email address.</p>';
|
||||||
|
} else if (!/.+@.+\..+/.test(email)) {
|
||||||
|
errorHTML += '<p class="bold red">Please double-check your email address.</p>';
|
||||||
|
}
|
||||||
|
if (password === '') {
|
||||||
|
errorHTML += '<p class="bold red">Please enter a password.</p>';
|
||||||
|
} else if (confirm !== password) {
|
||||||
|
errorHTML += '<p class="bold red">The password you entered to confirm did not match the password you entered.</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
createAccountErrorMessages.innerHTML = errorHTML;
|
||||||
|
if (errorHTML === '') {
|
||||||
|
request({
|
||||||
|
action: 'check-email',
|
||||||
|
email,
|
||||||
|
}, emailExists => {
|
||||||
|
if (emailExists) {
|
||||||
|
errorHTML += '<p class="bold red">The email address you entered already exists.</p>';
|
||||||
|
}
|
||||||
|
}, errorData => {
|
||||||
|
console.error(errorData);
|
||||||
|
errorHTML += `<p class="bold red">${errorData}</p>`;
|
||||||
|
}).then(() => {
|
||||||
|
createAccountErrorMessages.innerHTML = errorHTML;
|
||||||
|
if (errorHTML === '') {
|
||||||
|
console.log('creating account');
|
||||||
|
request({
|
||||||
|
action: 'create-account',
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
userData: {
|
||||||
|
publicName,
|
||||||
|
allowEmail,
|
||||||
|
},
|
||||||
|
}, responseData => {
|
||||||
|
return responseData;
|
||||||
|
}, errorData => {
|
||||||
|
errorHTML += `<p class="bold red">${errorData}</p>`;
|
||||||
|
}).then(responseData => {
|
||||||
|
console.log(responseData);
|
||||||
|
createAccountErrorMessages.innerHTML = errorHTML;
|
||||||
|
if (errorHTML === '') {
|
||||||
|
const loginModal = document.getElementById('loginModal');
|
||||||
|
loginModal.parentElement.removeChild(loginModal);
|
||||||
|
addMessage('Account Created Successfully!');
|
||||||
|
addMessage(`Welcome${publicName !== '' ? ', ' + publicName : ''}! You are logged in.`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch(err => console.error(err));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -40,6 +40,7 @@ export function renderLoginForm() {
|
||||||
<label>Allow Emails
|
<label>Allow Emails
|
||||||
<input type="checkbox" id="createNewAllowEmails">
|
<input type="checkbox" id="createNewAllowEmails">
|
||||||
</label>
|
</label>
|
||||||
|
<section id="createAccountErrorMessages"></section>
|
||||||
<a id="createAccountSubmit" class="button">Create Account</a>
|
<a id="createAccountSubmit" class="button">Create Account</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { logIn } from "./login";
|
import { logIn, createAccount } from "./login";
|
||||||
|
|
||||||
export function setupLoginModal(modal) {
|
export function setupLoginModal(modal) {
|
||||||
const closeElements = modal.querySelectorAll('.modal-background, .close-button');
|
const closeElements = modal.querySelectorAll('.modal-background, .close-button');
|
||||||
|
@ -9,4 +9,5 @@ export function setupLoginModal(modal) {
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('loginSubmit').addEventListener('click', logIn);
|
document.getElementById('loginSubmit').addEventListener('click', logIn);
|
||||||
|
document.getElementById('createAccountSubmit').addEventListener('click', createAccount);
|
||||||
}
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
class Db {
|
||||||
|
private $dbh;
|
||||||
|
public $last_error_info;
|
||||||
|
function __construct() {
|
||||||
|
$this->dbh = new PDO('mysql:host=localhost;dbname=lexiconga;charset=utf8', 'root', '');
|
||||||
|
$this->dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||||
|
$this->last_error_info = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute ($query, $params = array()) {
|
||||||
|
// Run a query that doesn't require a result to be returned
|
||||||
|
$stmt = $this->dbh->prepare($query);
|
||||||
|
if ($stmt->execute($params)) {
|
||||||
|
$this->last_error_info = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
$this->last_error_info = $stmt->errorInfo();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function query ($query, $params = array()) {
|
||||||
|
// Run a query that returns results
|
||||||
|
$stmt = $this->dbh->prepare($query);
|
||||||
|
$stmt->execute($params);
|
||||||
|
$this->last_error_info = $stmt->errorInfo();
|
||||||
|
return $stmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function lastInsertId () {
|
||||||
|
return $this->dbh->lastInsertId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function errorInfo () {
|
||||||
|
return $this->dbh->errorInfo();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,275 @@
|
||||||
|
<?php
|
||||||
|
require_once('./Db.php');
|
||||||
|
require_once('./Token.php');
|
||||||
|
|
||||||
|
class Dictionary {
|
||||||
|
private $db;
|
||||||
|
private $token;
|
||||||
|
private $defaults;
|
||||||
|
function __construct () {
|
||||||
|
$this->db = new Db();
|
||||||
|
$this->token = new Token();
|
||||||
|
|
||||||
|
$this->defaults = array(
|
||||||
|
'partsOfSpeech' => array("Noun","Adjective","Verb"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function checkIfIdExists ($id) {
|
||||||
|
$query = "SELECT id FROM dictionaries WHERE id=?";
|
||||||
|
$results = $this->db->query($query, array($id))->fetchAll();
|
||||||
|
return count($results) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create ($user) {
|
||||||
|
$new_id = mt_rand(1000, 999999999);
|
||||||
|
$id_exists = $this->checkIfIdExists($new_id);
|
||||||
|
while ($id_exists) {
|
||||||
|
$new_id = mt_rand(1000, 999999999);
|
||||||
|
$id_exists = $this->checkIfIdExists($new_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
$insert_dictionary_query = "INSERT INTO dictionaries (id, user, created_on) VALUES (?, ?, ?)";
|
||||||
|
$insert_dictionary = $this->db->execute($insert_dictionary_query, array($new_id, $user, time()));
|
||||||
|
|
||||||
|
if ($insert_dictionary === true) {
|
||||||
|
$insert_linguistics_query = "INSERT INTO dictionary_linguistics (dictionary, parts_of_speech)
|
||||||
|
VALUES ($new_id, ?)";
|
||||||
|
$insert_linguistics = $this->db->execute($insert_linguistics_query, array(
|
||||||
|
json_encode($this->defaults['partsOfSpeech']),
|
||||||
|
));
|
||||||
|
|
||||||
|
if ($insert_linguistics === true) {
|
||||||
|
return $this->changeCurrent($user, $new_id);
|
||||||
|
} else {
|
||||||
|
return array(
|
||||||
|
'error' => '"INSERT INTO dictionary_linguistics" failed: ' . $this->db->last_error_info[2],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'error' => '"INSERT INTO dictionaries" failed: ' . $this->db->last_error_info[2],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function changeCurrent ($user, $dictionary) {
|
||||||
|
$update_query = 'UPDATE users SET current_dictionary=? WHERE id=?';
|
||||||
|
$update = $this->db->query($update_query, array($dictionary, $user));
|
||||||
|
if ($update->rowCount() > 0) {
|
||||||
|
return $dictionary;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAllNames ($user) {
|
||||||
|
$query = "SELECT id, name, specification FROM dictionaries WHERE user=$user";
|
||||||
|
$results = $this->db->query($query)->fetchAll();
|
||||||
|
if ($results) {
|
||||||
|
return array_map(function($result) {
|
||||||
|
return array(
|
||||||
|
'id' => $result['id'],
|
||||||
|
'name' => $result['name'] . ' ' . $result['specification'],
|
||||||
|
);
|
||||||
|
}, $results);
|
||||||
|
}
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDetails ($user, $dictionary) {
|
||||||
|
$query = "SELECT * FROM dictionaries JOIN dictionary_linguistics ON dictionary = id WHERE user=$user AND id=$dictionary";
|
||||||
|
$result = $this->db->query($query)->fetch();
|
||||||
|
if ($result) {
|
||||||
|
// Default json values in case they are somehow not created by front end first
|
||||||
|
$partsOfSpeech = $result['parts_of_speech'] !== '' ? json_decode($result['parts_of_speech']) : $this->defaults['partsOfSpeech'];
|
||||||
|
$phonology = $result['phonology'] !== '' ? json_decode($result['phonology']) : $this->defaults['phonology'];
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'id' => $result['id'],
|
||||||
|
'name' => $result['name'],
|
||||||
|
'specification' => $result['specification'],
|
||||||
|
'description' => $result['description'],
|
||||||
|
'partsOfSpeech' => $partsOfSpeech,
|
||||||
|
'details' => array(
|
||||||
|
'phonology' => $phonology,
|
||||||
|
'orthography' => array(
|
||||||
|
'notes' => $result['orthography_notes'],
|
||||||
|
),
|
||||||
|
'grammar' => array(
|
||||||
|
'notes' => $result['grammar_notes'],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'settings' => array(
|
||||||
|
'allowDuplicates' => $result['allow_duplicates'] === '1' ? true : false,
|
||||||
|
'caseSensitive' => $result['case_sensitive'] === '1' ? true : false,
|
||||||
|
'sortByDefinition' => $result['sort_by_definition'] === '1' ? true : false,
|
||||||
|
'isComplete' => $result['is_complete'] === '1' ? true : false,
|
||||||
|
'isPublic' => $result['is_public'] === '1' ? true : false,
|
||||||
|
),
|
||||||
|
'lastUpdated' => is_null($result['last_updated']) ? null : $result['last_updated'],
|
||||||
|
'createdOn' => $result['created_on'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDetails ($user, $dictionary, $dictionary_object) {
|
||||||
|
$query1 = "UPDATE dictionaries
|
||||||
|
SET name=:name,
|
||||||
|
specification=:specification,
|
||||||
|
description=:description,
|
||||||
|
allow_duplicates=:allow_duplicates,
|
||||||
|
case_sensitive=:case_sensitive,
|
||||||
|
sort_by_definition=:sort_by_definition,
|
||||||
|
is_complete=:is_complete,
|
||||||
|
is_public=:is_public,
|
||||||
|
last_updated=:last_updated,
|
||||||
|
created_on=:created_on
|
||||||
|
WHERE user=$user AND id=$dictionary";
|
||||||
|
|
||||||
|
// $result1 = $this->db->query($query1, array(
|
||||||
|
$result1 = $this->db->execute($query1, array(
|
||||||
|
':name' => $dictionary_object['name'],
|
||||||
|
':specification' => $dictionary_object['specification'],
|
||||||
|
':description' => $dictionary_object['description'],
|
||||||
|
':allow_duplicates' => $dictionary_object['settings']['allowDuplicates'],
|
||||||
|
':case_sensitive' => $dictionary_object['settings']['caseSensitive'],
|
||||||
|
':sort_by_definition' => $dictionary_object['settings']['sortByDefinition'],
|
||||||
|
':is_complete' => $dictionary_object['settings']['isComplete'],
|
||||||
|
':is_public' => $dictionary_object['settings']['isPublic'],
|
||||||
|
':last_updated' => $dictionary_object['lastUpdated'],
|
||||||
|
':created_on' => $dictionary_object['createdOn'],
|
||||||
|
));
|
||||||
|
// if ($result1->rowCount() > 0) {
|
||||||
|
if ($result1 === true) {
|
||||||
|
$linguistics = $dictionary_object['details'];
|
||||||
|
$query2 = "UPDATE dictionary_linguistics
|
||||||
|
SET parts_of_speech=:parts_of_speech,
|
||||||
|
phonology=:phonology,
|
||||||
|
orthography_notes=:orthography_notes,
|
||||||
|
grammar_notes=:grammar_notes
|
||||||
|
WHERE dictionary=$dictionary";
|
||||||
|
|
||||||
|
// $result2 = $this->db->query($query2, array(
|
||||||
|
$result2 = $this->db->execute($query2, array(
|
||||||
|
':parts_of_speech' => json_encode($dictionary_object['partsOfSpeech']),
|
||||||
|
':phonology' => json_encode($linguistics['phonology']),
|
||||||
|
':orthography_notes' => $linguistics['orthography']['notes'],
|
||||||
|
':grammar_notes' => $linguistics['grammar']['notes'],
|
||||||
|
));
|
||||||
|
|
||||||
|
// if ($result2->rowCount() > 0) {
|
||||||
|
if ($result2 === true) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// return $result2->errorInfo();
|
||||||
|
}
|
||||||
|
// return $result1->errorInfo();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getWords ($user, $dictionary) {
|
||||||
|
$query = "SELECT words.* FROM words JOIN dictionaries ON id = dictionary WHERE dictionary=$dictionary AND user=$user";
|
||||||
|
$results = $this->db->query($query)->fetchAll();
|
||||||
|
if ($results) {
|
||||||
|
return array_map(function ($row) {
|
||||||
|
return array(
|
||||||
|
'id' => intval($row['word_id']),
|
||||||
|
'name' => $row['name'],
|
||||||
|
'pronunciation' => $row['pronunciation'],
|
||||||
|
'partOfSpeech' => $row['part_of_speech'],
|
||||||
|
'definition' => $row['definition'],
|
||||||
|
'details' => $row['details'],
|
||||||
|
'lastUpdated' => is_null($row['last_updated']) ? null : intval($row['last_updated']),
|
||||||
|
'createdOn' => intval($row['created_on']),
|
||||||
|
);
|
||||||
|
}, $results);
|
||||||
|
}
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDeletedWords ($user, $dictionary) {
|
||||||
|
$query = "SELECT deleted_words.* FROM deleted_words JOIN dictionaries ON id = dictionary WHERE dictionary=$dictionary AND user=$user";
|
||||||
|
$results = $this->db->query($query)->fetchAll();
|
||||||
|
if ($results) {
|
||||||
|
return array_map(function ($row) {
|
||||||
|
return array(
|
||||||
|
'id' => intval($row['word_id']),
|
||||||
|
'deletedOn' => intval($row['deleted_on']),
|
||||||
|
);
|
||||||
|
}, $results);
|
||||||
|
}
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setWords ($user, $dictionary, $words = array()) {
|
||||||
|
$query = 'INSERT INTO words (dictionary, word_id, name, pronunciation, part_of_speech, definition, details, last_updated, created_on) VALUES ';
|
||||||
|
$params = array();
|
||||||
|
$word_ids = array();
|
||||||
|
$most_recent_word_update = 0;
|
||||||
|
foreach($words as $word) {
|
||||||
|
$last_updated = is_null($word['lastUpdated']) ? $word['createdOn'] : $word['lastUpdated'];
|
||||||
|
if ($most_recent_word_update < $last_updated) {
|
||||||
|
$most_recent_word_update = $last_updated;
|
||||||
|
}
|
||||||
|
$word_ids[] = $word['id'];
|
||||||
|
$query .= "(?, ?, ?, ?, ?, ?, ?, ?, ?), ";
|
||||||
|
$params[] = $dictionary;
|
||||||
|
$params[] = $word['id'];
|
||||||
|
$params[] = $word['name'];
|
||||||
|
$params[] = $word['pronunciation'];
|
||||||
|
$params[] = $word['partOfSpeech'];
|
||||||
|
$params[] = $word['definition'];
|
||||||
|
$params[] = $word['details'];
|
||||||
|
$params[] = $last_updated;
|
||||||
|
$params[] = $word['createdOn'];
|
||||||
|
}
|
||||||
|
$query = trim($query, ', ') . ' ON DUPLICATE KEY UPDATE
|
||||||
|
name=VALUES(name),
|
||||||
|
pronunciation=VALUES(pronunciation),
|
||||||
|
part_of_speech=VALUES(part_of_speech),
|
||||||
|
definition=VALUES(definition),
|
||||||
|
details=VALUES(details),
|
||||||
|
last_updated=VALUES(last_updated)';
|
||||||
|
|
||||||
|
$results = $this->db->execute($query, $params);
|
||||||
|
|
||||||
|
// if ($results) {
|
||||||
|
// $database_words = $this->getWords($user, $dictionary);
|
||||||
|
// $database_ids = array_map(function($database_word) { return $database_word['id']; }, $database_words);
|
||||||
|
// $words_to_delete = array_filter($database_ids, function($database_id) use($word_ids) { return !in_array($database_id, $word_ids); });
|
||||||
|
// if ($words_to_delete) {
|
||||||
|
// $delete_results = $this->deleteWords($dictionary, $words_to_delete);
|
||||||
|
// return $delete_results;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteWords ($dictionary, $word_ids) {
|
||||||
|
$insert_query = 'INSERT INTO deleted_words (dictionary, word_id, deleted_on) VALUES ';
|
||||||
|
$insert_params = array();
|
||||||
|
$delete_query = 'DELETE FROM words WHERE dictionary=? AND word_id IN (';
|
||||||
|
$delete_params = array($dictionary);
|
||||||
|
foreach($word_ids as $word_id) {
|
||||||
|
$insert_query .= "(?, ?, ?), ";
|
||||||
|
$insert_params[] = $dictionary;
|
||||||
|
$insert_params[] = $word_id;
|
||||||
|
$insert_params[] = time();
|
||||||
|
|
||||||
|
$delete_query .= '?, ';
|
||||||
|
$delete_params[] = $word_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$insert_query = trim($insert_query, ', ') . ' ON DUPLICATE KEY UPDATE deleted_on=VALUES(deleted_on)';
|
||||||
|
$delete_query = trim($delete_query, ', ') . ')';
|
||||||
|
|
||||||
|
$insert_results = $this->db->execute($insert_query, $insert_params);
|
||||||
|
if ($insert_results) {
|
||||||
|
$delete_results = $this->db->execute($delete_query, $delete_params);
|
||||||
|
return $delete_results;
|
||||||
|
}
|
||||||
|
return $insert_results;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,249 @@
|
||||||
|
<?php
|
||||||
|
require_once('./Db.php');
|
||||||
|
require_once('./Token.php');
|
||||||
|
require_once('./Dictionary.php');
|
||||||
|
|
||||||
|
class User {
|
||||||
|
private $db;
|
||||||
|
private $token;
|
||||||
|
function __construct () {
|
||||||
|
$this->db = new Db();
|
||||||
|
$this->token = new Token();
|
||||||
|
$this->dictionary = new Dictionary();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function logIn ($email, $password) {
|
||||||
|
$query = 'SELECT * FROM users WHERE email=:email';
|
||||||
|
$user = $this->db->query($query, array(':email' => $email))->fetch();
|
||||||
|
if ($user) {
|
||||||
|
if ($user['old_password'] !== null) {
|
||||||
|
if ($user['old_password'] === crypt($password, $email)) {
|
||||||
|
if ($this->upgradePassword($password)) {
|
||||||
|
return $this->logIn($email, $password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (password_verify($password, $user['password'])) {
|
||||||
|
$this->db->execute('UPDATE users SET last_login=' . time() . ' WHERE id=' . $user['id']);
|
||||||
|
setcookie('token', $this->generateUserToken($user['id'], $user['current_dictionary']));
|
||||||
|
return array(
|
||||||
|
'user' => $this->getUserData($user['id']),
|
||||||
|
'dictionary' => $this->token->hash($user['current_dictionary']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function emailExists ($email) {
|
||||||
|
$query = 'SELECT * FROM users WHERE email=?';
|
||||||
|
$user = $this->db->query($query, array($email));
|
||||||
|
return $user->rowCount() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create ($email, $password, $user_data) {
|
||||||
|
$insert_user_query = 'INSERT INTO users (email, password, public_name, allow_email, created_on)
|
||||||
|
VALUES (?, ?, ?, ?, ?)';
|
||||||
|
$password_hash = password_hash($password, PASSWORD_DEFAULT);
|
||||||
|
|
||||||
|
$insert_user = $this->db->execute($insert_user_query, array(
|
||||||
|
$email,
|
||||||
|
$password_hash,
|
||||||
|
$user_data['publicName'] !== '' ? $user_data['publicName'] : null,
|
||||||
|
$user_data['allowEmail'] ? 1 : 0,
|
||||||
|
time(),
|
||||||
|
));
|
||||||
|
if ($insert_user === true) {
|
||||||
|
$new_user_id = $this->db->lastInsertId();
|
||||||
|
|
||||||
|
$new_dictionary = $this->dictionary->create($new_user_id);
|
||||||
|
|
||||||
|
if (isset($new_dictionary['error'])) {
|
||||||
|
return $new_dictionary;
|
||||||
|
} else {
|
||||||
|
setcookie('token', $this->generateUserToken($new_user_id, $new_dictionary));
|
||||||
|
return array(
|
||||||
|
'user' => $this->getUserData($new_user_id),
|
||||||
|
'dictionary' => $this->token->hash($new_dictionary),
|
||||||
|
'debug' => [
|
||||||
|
'newUserId' => $new_user_id,
|
||||||
|
'newDictionary' => $new_dictionary,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'error' => '"INSERT INTO users" failed: ' . $this->db->last_error_info[2],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUserData ($token, $user_data) {
|
||||||
|
$token_data = $this->token->decode($token);
|
||||||
|
if ($token_data !== false) {
|
||||||
|
$user_id = $token_data->id;
|
||||||
|
$query = 'UPDATE users SET email=?, public_name=?, allow_email=? WHERE id=?';
|
||||||
|
$properties = array(
|
||||||
|
$user_data['email'],
|
||||||
|
$user_data['publicName'],
|
||||||
|
$user_data['allowEmails'],
|
||||||
|
$user_id,
|
||||||
|
);
|
||||||
|
$update_success = $this->db->execute($query, $properties);
|
||||||
|
if ($update_success) {
|
||||||
|
return array(
|
||||||
|
'token' => $token,
|
||||||
|
'userData' => $user_data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserData ($user_id) {
|
||||||
|
$query = 'SELECT email, public_name, allow_emails FROM users WHERE id=?';
|
||||||
|
$stmt = $this->db->query($query, array($user_id));
|
||||||
|
$user = $stmt->fetch();
|
||||||
|
if ($stmt && $user) {
|
||||||
|
return array(
|
||||||
|
'email' => $user['email'],
|
||||||
|
'publicName' => $user['public_name'],
|
||||||
|
'allowEmails' => $user['allow_email'] == 1 ? true : false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createNewDictionary ($token) {
|
||||||
|
$user_data = $this->token->decode($token);
|
||||||
|
if ($user_data !== false) {
|
||||||
|
$id = $user_data->id;
|
||||||
|
$new_dictionary = $this->dictionary->create($id);
|
||||||
|
if (!isset($new_dictionary['error'])) {
|
||||||
|
$new_token = $this->generateUserToken($id, $new_dictionary);
|
||||||
|
return array(
|
||||||
|
'token' => $new_token,
|
||||||
|
'dictionary' => $this->getCurrentDictionary($new_token),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return $new_dictionary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array(
|
||||||
|
'error' => 'invalid token',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function changeCurrentDictionary ($token, $dictionary_hash) {
|
||||||
|
$user_data = $this->token->decode($token);
|
||||||
|
if ($user_data !== false) {
|
||||||
|
$id = $user_data->id;
|
||||||
|
$dictionary_id = $this->token->unhash($dictionary_hash);
|
||||||
|
if ($dictionary_id !== false) {
|
||||||
|
$changed_dictionary = $this->dictionary->changeCurrent($id, $dictionary_id);
|
||||||
|
if ($changed_dictionary !== false) {
|
||||||
|
return array(
|
||||||
|
'token' => $this->generateUserToken($id, $changed_dictionary),
|
||||||
|
'dictionary' => $this->getCurrentDictionary($token),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function listAllDictionaryNames ($token) {
|
||||||
|
$user_data = $this->token->decode($token);
|
||||||
|
if ($user_data !== false) {
|
||||||
|
$id = $user_data->id;
|
||||||
|
return $this->dictionary->getAllNames($id);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCurrentDictionary ($token) {
|
||||||
|
$user_data = $this->token->decode($token);
|
||||||
|
if ($user_data !== false) {
|
||||||
|
$user = $user_data->id;
|
||||||
|
$dictionary = $user_data->dictionary;
|
||||||
|
return array(
|
||||||
|
'details' => $this->dictionary->getDetails($user, $dictionary),
|
||||||
|
'words' => $this->dictionary->getWords($user, $dictionary),
|
||||||
|
'deletedWords' => $this->dictionary->getDeletedWords($user, $dictionary),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveWholeCurrentDictionary ($token, $dictionary_data) {
|
||||||
|
$user_data = $this->token->decode($token);
|
||||||
|
if ($user_data !== false) {
|
||||||
|
$user = $user_data->id;
|
||||||
|
$dictionary = $user_data->dictionary;
|
||||||
|
$details_updated = $this->dictionary->setDetails($user, $dictionary, $dictionary_data['details']);
|
||||||
|
$words_updated = $this->dictionary->setWords($dictionary, $dictionary_data['words']);
|
||||||
|
return $details_updated && $words_updated;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateCurrentDictionaryDetails ($token, $dictionary_details) {
|
||||||
|
$user_data = $this->token->decode($token);
|
||||||
|
if ($user_data !== false) {
|
||||||
|
$user = $user_data->id;
|
||||||
|
$dictionary = $user_data->dictionary;
|
||||||
|
return $this->dictionary->setDetails($user, $dictionary, $dictionary_details);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateOrAddWordsToCurrentDictionary ($token, $words) {
|
||||||
|
// Useful even for just one word
|
||||||
|
$user_data = $this->token->decode($token);
|
||||||
|
if ($user_data !== false) {
|
||||||
|
$dictionary = $user_data->dictionary;
|
||||||
|
$user = $user_data->id;
|
||||||
|
$updated_words = $this->dictionary->setWords($user, $dictionary, $words);
|
||||||
|
if ($updated_words) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteWordsFromCurrentDictionary ($token, $word_ids) {
|
||||||
|
// Useful even for just one word
|
||||||
|
$user_data = $this->token->decode($token);
|
||||||
|
if ($user_data !== false) {
|
||||||
|
$dictionary = $user_data->dictionary;
|
||||||
|
$user = $user_data->id;
|
||||||
|
$deleted_word = $this->dictionary->deleteWords($dictionary, $word_ids);
|
||||||
|
if ($deleted_word) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateUserToken ($user_id, $dictionary_id) {
|
||||||
|
$user_data = array(
|
||||||
|
'id' => intval($user_id),
|
||||||
|
'isMember' => $this->hasMembership($user_id),
|
||||||
|
'dictionary' => intval($dictionary_id),
|
||||||
|
);
|
||||||
|
return $this->token->encode($user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function hasMembership ($id) {
|
||||||
|
$current_membership = "SELECT * FROM memberships WHERE user=$id AND start_date>=CURRENT_TIMESTAMP AND CURRENT_TIMESTAMP<expire_date";
|
||||||
|
return $this->db->query($current_membership)->rowCount() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function upgradePassword ($password) {
|
||||||
|
$new_password = password_hash($password, PASSWORD_DEFAULT);
|
||||||
|
$update_query = 'UPDATE users SET old_password=NULL, password=? WHERE id=' . $user['id'];
|
||||||
|
$stmt = $this->db->query($update_query, array($new_password));
|
||||||
|
return $stmt->rowCount() === 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,26 +1,291 @@
|
||||||
<?php
|
<?php
|
||||||
require_once('./Response.php');
|
require_once('./Response.php');
|
||||||
require_once('./Token.php');
|
require_once('./User.php');
|
||||||
|
|
||||||
$inputJSON = file_get_contents('php://input');
|
$inputJSON = file_get_contents('php://input');
|
||||||
$request= json_decode($inputJSON, true);
|
$request= json_decode($inputJSON, true);
|
||||||
|
|
||||||
$action = isset($request['action']) ? $request['action'] : '';
|
$action = isset($request['action']) ? $request['action'] : '';
|
||||||
|
$token = isset($_COOKIE['token']) ? $_COOKIE['token'] : false;
|
||||||
|
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case 'login': {
|
case 'login': {
|
||||||
if (isset($request['email']) && isset($request['password'])) {
|
if (isset($request['email']) && isset($request['password'])) {
|
||||||
$token = new Token();
|
$user = new User();
|
||||||
$token = $token->encode([
|
$user_data = $user->logIn($request['email'], $request['password']);
|
||||||
'email' => $request['email'],
|
if ($user_data !== false) {
|
||||||
'password' => $request['password'],
|
return Response::json(array(
|
||||||
]);
|
'data' => $user_data,
|
||||||
setcookie('token', $token);
|
'error' => false,
|
||||||
return Response::json([
|
), 200);
|
||||||
'data' => 'cookie saved',
|
}
|
||||||
'error' => false,
|
return Response::json(array(
|
||||||
], 200);
|
'data' => 'Could not log in: incorrect data',
|
||||||
|
'error' => true,
|
||||||
|
), 401);
|
||||||
}
|
}
|
||||||
break;
|
return Response::json(array(
|
||||||
|
'data' => 'Could not log in: required information missing',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
}
|
}
|
||||||
}
|
case 'create-account': {
|
||||||
|
if (isset($request['email']) && isset($request['password'])) {
|
||||||
|
$user = new User();
|
||||||
|
if (!$user->emailExists($request['email'])) {
|
||||||
|
$user_data = $user->create($request['email'], $request['password'], $request['userData']);
|
||||||
|
if (!isset($user_data['error'])) {
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => $user_data,
|
||||||
|
'error' => false,
|
||||||
|
), 201);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not create account: ' . $user_data['error'],
|
||||||
|
'error' => true,
|
||||||
|
), 500);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not create account: duplicate email',
|
||||||
|
'error' => true,
|
||||||
|
), 403);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not create account: required information missing',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
case 'check-email': {
|
||||||
|
if (isset($request['email'])) {
|
||||||
|
$user = new User();
|
||||||
|
$email_exists = $user->emailExists($request['email']);
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => $email_exists,
|
||||||
|
'error' => false,
|
||||||
|
), 200);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not check: required information missing',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
case 'check-username': {
|
||||||
|
if (isset($request['username'])) {
|
||||||
|
$user = new User();
|
||||||
|
$username_exists = $user->usernameExists($request['username']);
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => $username_exists,
|
||||||
|
'error' => false,
|
||||||
|
), 200);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not check: required information missing',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
case 'get-all-dictionary-names': {
|
||||||
|
if ($token !== false) {
|
||||||
|
$user = new User();
|
||||||
|
$all_dictionaries = $user->listAllDictionaryNames($token);
|
||||||
|
if ($all_dictionaries !== false) {
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => $all_dictionaries,
|
||||||
|
'error' => false,
|
||||||
|
), 200);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not get dictionaries: invalid token',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not get dictionaries: no token provided',
|
||||||
|
'error' => true,
|
||||||
|
), 403);
|
||||||
|
}
|
||||||
|
case 'set-user-data': {
|
||||||
|
if ($token !== false && isset($request['userData'])) {
|
||||||
|
$user = new User();
|
||||||
|
$updated_user = $user->setUserData($token, $request['userData']);
|
||||||
|
if ($updated_user !== false) {
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => $updated_user,
|
||||||
|
'error' => false,
|
||||||
|
), 200);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not set user data: missing data',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not get dictionaries: no token provided',
|
||||||
|
'error' => true,
|
||||||
|
), 403);
|
||||||
|
}
|
||||||
|
case 'create-new-dictionary': {
|
||||||
|
if ($token !== false) {
|
||||||
|
$user = new User();
|
||||||
|
$new_data = $user->createNewDictionary($token);
|
||||||
|
if (!isset($new_data['error'])) {
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => $new_data,
|
||||||
|
'error' => false,
|
||||||
|
), 200);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not create dictionary: ' . $new_data['error'],
|
||||||
|
'error' => true,
|
||||||
|
), 401);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not create dictionary: no token provided',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
case 'change-dictionary': {
|
||||||
|
if ($token !== false && isset($request['dictionary'])) {
|
||||||
|
$user = new User();
|
||||||
|
$new_data = $user->changeCurrentDictionary($token, $request['dictionary']);
|
||||||
|
if ($new_data !== false) {
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => $new_data,
|
||||||
|
'error' => false,
|
||||||
|
), 200);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not create dictionary: incorrect data',
|
||||||
|
'error' => true,
|
||||||
|
), 401);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not create dictionary: no token provided',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
case 'get-current-dictionary': {
|
||||||
|
if ($token !== false) {
|
||||||
|
$user = new User();
|
||||||
|
$dictionary_data = $user->getCurrentDictionary($token);
|
||||||
|
if ($dictionary_data !== false) {
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => $dictionary_data,
|
||||||
|
'error' => false,
|
||||||
|
), 200);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not get dictionary: invalid token',
|
||||||
|
'error' => true,
|
||||||
|
), 401);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not get dictionary: no token provided',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
case 'set-whole-current-dictionary': {
|
||||||
|
if ($token !== false && isset($request['dictionary'])) {
|
||||||
|
$user = new User();
|
||||||
|
$dictionary_data = $user->saveWholeCurrentDictionary($token, $request['dictionary']);
|
||||||
|
if ($dictionary_data !== false) {
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Updated successfully',
|
||||||
|
'error' => false,
|
||||||
|
), 200);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not set dictionary: invalid token',
|
||||||
|
'error' => true,
|
||||||
|
), 401);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not set dictionary: required data missing',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
case 'set-dictionary-details': {
|
||||||
|
if ($token !== false && isset($request['details'])) {
|
||||||
|
$user = new User();
|
||||||
|
$update_details_success = $user->updateCurrentDictionaryDetails($token, $request['details']);
|
||||||
|
if ($update_details_success !== false) {
|
||||||
|
return Response::json(array(
|
||||||
|
// 'data' => 'Updated successfully',
|
||||||
|
'data' => $update_details_success,
|
||||||
|
'error' => false,
|
||||||
|
), 200);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not set dictionary: invalid token',
|
||||||
|
'error' => true,
|
||||||
|
), 401);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not set dictionary: required data missing',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
case 'set-dictionary-words': {
|
||||||
|
if ($token !== false && isset($request['words'])) {
|
||||||
|
$user = new User();
|
||||||
|
$update_words_success = $user->updateOrAddWordsToCurrentDictionary($token, $request['words']);
|
||||||
|
if ($update_words_success !== false) {
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Updated successfully',
|
||||||
|
'error' => false,
|
||||||
|
), 200);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not set words: invalid token',
|
||||||
|
'error' => true,
|
||||||
|
), 401);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not set words: required data missing',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
case 'delete-word': {
|
||||||
|
if ($token !== false && isset($request['word'])) {
|
||||||
|
$user = new User();
|
||||||
|
$delete_word_success = $user->deleteWordsFromCurrentDictionary($token, array($request['word']));
|
||||||
|
if ($delete_word_success !== false) {
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Deleted successfully',
|
||||||
|
'error' => false,
|
||||||
|
), 200);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not delete word: invalid token',
|
||||||
|
'error' => true,
|
||||||
|
), 401);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not delete word: required data missing',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
case 'delete-words': {
|
||||||
|
if ($token !== false && isset($request['words'])) {
|
||||||
|
$user = new User();
|
||||||
|
$delete_word_success = $user->deleteWordsFromCurrentDictionary($token, $request['words']);
|
||||||
|
if ($delete_word_success !== false) {
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Deleted successfully',
|
||||||
|
'error' => false,
|
||||||
|
), 200);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not delete words: invalid token',
|
||||||
|
'error' => true,
|
||||||
|
), 401);
|
||||||
|
}
|
||||||
|
return Response::json(array(
|
||||||
|
'data' => 'Could not delete words: required data missing',
|
||||||
|
'error' => true,
|
||||||
|
), 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
return Response::html('Hi!');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||||
|
SET time_zone = "+00:00";
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `deleted_words` (
|
||||||
|
`dictionary` int(11) NOT NULL,
|
||||||
|
`word_id` int(11) NOT NULL,
|
||||||
|
`deleted_on` int(11) NOT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `dictionaries` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`user` int(11) NOT NULL,
|
||||||
|
`name` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'New',
|
||||||
|
`specification` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Dictionary',
|
||||||
|
`description` text COLLATE utf8_unicode_ci NOT NULL DEFAULT 'A new dicitonary.' COMMENT 'Markdown',
|
||||||
|
`allow_duplicates` tinyint(1) NOT NULL DEFAULT 0,
|
||||||
|
`case_sensitive` tinyint(1) NOT NULL DEFAULT 0,
|
||||||
|
`sort_by_definition` tinyint(1) NOT NULL DEFAULT 0,
|
||||||
|
`is_complete` tinyint(1) NOT NULL DEFAULT 0,
|
||||||
|
`is_public` tinyint(1) NOT NULL DEFAULT 0,
|
||||||
|
`last_updated` int(11) DEFAULT NULL,
|
||||||
|
`created_on` int(11) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=MyISAM AUTO_INCREMENT=500 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE TRIGGER IF NOT EXISTS `delete_dictionary_parts` AFTER DELETE ON `dictionaries` FOR EACH ROW BEGIN
|
||||||
|
DELETE FROM words WHERE words.dictionary=old.id;
|
||||||
|
DELETE FROM dictionary_linguistics WHERE dictionary_linguistics.dictionary=old.id;
|
||||||
|
DELETE FROM deleted_words WHERE deleted_words.dictionary=old.id;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `dictionary_linguistics` (
|
||||||
|
`dictionary` int(11) NOT NULL,
|
||||||
|
`parts_of_speech` text NOT NULL DEFAULT '' COMMENT 'JSON array',
|
||||||
|
`consonants` text NOT NULL DEFAULT '' COMMENT 'JSON array',
|
||||||
|
`vowels` text NOT NULL DEFAULT '' COMMENT 'JSON array',
|
||||||
|
`blends` text NOT NULL DEFAULT '' COMMENT 'JSON array',
|
||||||
|
`onset` text NOT NULL DEFAULT '' COMMENT 'JSON array',
|
||||||
|
`nucleus` text NOT NULL DEFAULT '' COMMENT 'JSON array',
|
||||||
|
`coda` text NOT NULL DEFAULT '' COMMENT 'JSON array',
|
||||||
|
`exceptions` text NOT NULL DEFAULT '' COMMENT 'Markdown',
|
||||||
|
`orthography_notes` text NOT NULL DEFAULT '' COMMENT 'Markdown',
|
||||||
|
`grammar_notes` text NOT NULL DEFAULT '' COMMENT 'Markdown',
|
||||||
|
UNIQUE KEY `dictionary` (`dictionary`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `memberships` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`user` int(11) NOT NULL,
|
||||||
|
`start_date` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`expire_date` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `users` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`email` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
|
||||||
|
`old_password` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`password` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`public_name` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Someone',
|
||||||
|
`current_dictionary` int(11) DEFAULT NULL,
|
||||||
|
`allow_email` tinyint(1) NOT NULL DEFAULT 1,
|
||||||
|
`last_login` int(11) DEFAULT NULL,
|
||||||
|
`password_reset_code` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||||
|
`password_reset_date` int(11) DEFAULT NULL,
|
||||||
|
`created_on` int(11) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `email` (`email`)
|
||||||
|
) ENGINE=MyISAM AUTO_INCREMENT=200 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE TRIGGER IF NOT EXISTS `Delete_User_Dictionaries` AFTER DELETE ON `users` FOR EACH ROW DELETE FROM dictionaries WHERE dictionaries.user = old.id
|
||||||
|
$$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `words` (
|
||||||
|
`dictionary` int(11) NOT NULL,
|
||||||
|
`word_id` int(11) NOT NULL,
|
||||||
|
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||||
|
`pronunciation` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||||
|
`part_of_speech` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||||
|
`definition` text COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
|
||||||
|
`details` text COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT 'Markdown',
|
||||||
|
`last_updated` int(11) DEFAULT NULL,
|
||||||
|
`created_on` int(11) NOT NULL,
|
||||||
|
UNIQUE KEY `unique_index` (`dictionary`,`word_id`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
Loading…
Reference in New Issue