Compare commits
12 Commits
0f1a7d2f09
...
2d93a51236
Author | SHA1 | Date |
---|---|---|
Robbie Antenesse | 2d93a51236 | |
Robbie Antenesse | e2066e6168 | |
Robbie Antenesse | 6aef828f42 | |
Robbie Antenesse | 1369fb0fdb | |
Robbie Antenesse | 62dad867e0 | |
Robbie Antenesse | d4d46c7afe | |
Robbie Antenesse | 654bfab004 | |
Robbie Antenesse | 33ac88dd6c | |
Robbie Antenesse | 3666acc426 | |
Robbie Antenesse | cbb4cd07c7 | |
Robbie Antenesse | 59dcdd1694 | |
Robbie Antenesse | c9f456edfb |
22
README.md
22
README.md
|
@ -4,6 +4,24 @@ This is the light-as-possible rewrite of Lexiconga.
|
|||
|
||||
## Installation
|
||||
|
||||
Clone and run `yarn` to install dependencies.
|
||||
1. Clone and run `yarn` and `composer install` to install dependencies.
|
||||
1. Import `src/structure.sql` into a database called 'lexiconga' on your MariaDB server to get the database structure.
|
||||
1. Copy `src/php/api/config.php.changeme` to `src/php/api/config.php` and update the values within to enable connections to your lexiconga database.
|
||||
|
||||
`npm start` bundles and watches frontend changes. For backend stuff, set up a junction link to `dist` from the root of your php-processing server.
|
||||
### Requirements
|
||||
|
||||
* [Yarn](https://yarnpkg.com/) 1.12.3+
|
||||
* [PHP](https://php.net/) 7.2.18+
|
||||
* [Composer](https://getcomposer.org/) 1.8.5+
|
||||
* [MariaDB](https://mariadb.org/) 10.1.37+
|
||||
* [Apache](https://httpd.apache.org/) 2.4+
|
||||
|
||||
## Development
|
||||
|
||||
`npm start` bundles and watches frontend and backend changes. Set up a junction link to `dist` from the root of your php-processing web server.
|
||||
|
||||
It's less useful, but `npm run serve-frontend-only` will bundle and serve _only_ the front end stuff from `localhost:1234`. The bundled files all still get bundled into `dist`.
|
||||
|
||||
## Production
|
||||
|
||||
`npm run bundle` bundles and minifies the frontend stuff and also copies the backend stuff to `dist`. Be sure to run `npm run clear` to delete the contents of `dist` and `.cache` before using `npm run bundle` to make sure you don't get old dev versions of the bundled code included in your upload.
|
|
@ -49,7 +49,7 @@ export const DEFAULT_DICTIONARY = {
|
|||
isComplete: false,
|
||||
isPublic: false,
|
||||
},
|
||||
lastUpdated: null,
|
||||
lastUpdated: getTimestampInSeconds(),
|
||||
createdOn: getTimestampInSeconds(),
|
||||
version: MIGRATE_VERSION,
|
||||
};
|
||||
|
|
|
@ -2,12 +2,17 @@ import './main.scss';
|
|||
|
||||
import setupListeners from './js/setupListeners';
|
||||
import { renderAll } from './js/render';
|
||||
import { generateRandomWords, addMessage } from './js/utilities';
|
||||
import { generateRandomWords, addMessage, hasToken } from './js/utilities';
|
||||
import { loadDictionary } from './js/dictionaryManagement';
|
||||
import { loadSettings } from './js/settings';
|
||||
|
||||
function initialize() {
|
||||
addMessage('Loading...');
|
||||
if (hasToken()) {
|
||||
import('./js/account/index.js').then(account => {
|
||||
account.loginWithToken();
|
||||
});
|
||||
}
|
||||
loadDictionary();
|
||||
loadSettings();
|
||||
// generateRandomWords(100);
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// https://stackoverflow.com/questions/4825683/how-do-i-create-and-read-a-value-from-cookie/4825695#4825695
|
||||
|
||||
export function setCookie (name, value, days) {
|
||||
let expires;
|
||||
if (days) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
expires = '; expires=' + date.toGMTString();
|
||||
}
|
||||
else {
|
||||
expires = '';
|
||||
}
|
||||
document.cookie = name + '=' + value + expires + '; path=/';
|
||||
}
|
||||
|
||||
export function getCookie(c_name) {
|
||||
if (document.cookie.length > 0) {
|
||||
let c_start = document.cookie.indexOf(c_name + '=');
|
||||
if (c_start != -1) {
|
||||
c_start = c_start + c_name.length + 1;
|
||||
let c_end = document.cookie.indexOf(';', c_start);
|
||||
if (c_end == -1) {
|
||||
c_end = document.cookie.length;
|
||||
}
|
||||
return unescape(document.cookie.substring(c_start, c_end));
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { saveEditModal } from "../dictionaryManagement";
|
||||
import { syncDetails } from "./sync";
|
||||
import { addMessage } from "../utilities";
|
||||
|
||||
export function saveEditModalAndSync() {
|
||||
saveEditModal();
|
||||
|
||||
return syncDetails().then(successful => {
|
||||
if (successful) {
|
||||
addMessage('Synced Successfully');
|
||||
} else {
|
||||
addMessage('Could Not Sync');
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
addMessage('Could not connect');
|
||||
});
|
||||
}
|
||||
|
||||
export function saveAndCloseEditModalAndSync() {
|
||||
saveEditModalAndSync().then(() => {
|
||||
document.getElementById('editModal').style.display = 'none';
|
||||
});
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import { setCookie } from "../StackOverflow/cookie";
|
||||
|
||||
export function request (data = {}, success = () => {}, error = () => {}/* , fail = () => {} */) {
|
||||
return fetch('./api/', {
|
||||
method: 'POST', // or 'PUT'
|
||||
|
@ -14,4 +16,8 @@ export function request (data = {}, success = () => {}, error = () => {}/* , fai
|
|||
}
|
||||
return success(response.data);
|
||||
});
|
||||
}
|
||||
|
||||
export function saveToken(token) {
|
||||
setCookie('token', token, 30);
|
||||
}
|
|
@ -1,7 +1,14 @@
|
|||
import '../../scss/Account/main.scss';
|
||||
|
||||
import { renderLoginForm } from "./render";
|
||||
import { triggerLoginChanges } from './login';
|
||||
import { syncDictionary } from './sync';
|
||||
|
||||
export function showLoginForm() {
|
||||
renderLoginForm();
|
||||
}
|
||||
|
||||
export function loginWithToken() {
|
||||
triggerLoginChanges();
|
||||
syncDictionary();
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
import { request } from "./helpers";
|
||||
import { request, saveToken } from "./helpers";
|
||||
import { addMessage } from "../utilities";
|
||||
import { setupLogoutButton } from "./setupListeners";
|
||||
import { setupLogoutButton, setupEditFormButtonOverrides } from "./setupListeners";
|
||||
import { renderAccountSettings } from "./render";
|
||||
import { uploadWholeDictionary } from "./sync";
|
||||
|
||||
export function logIn() {
|
||||
const email = document.getElementById('loginEmail').value.trim(),
|
||||
|
@ -25,6 +26,7 @@ export function logIn() {
|
|||
password,
|
||||
}, successData => {
|
||||
console.log(successData);
|
||||
saveToken(successData.token);
|
||||
}, errorData => {
|
||||
errorHTML += errorData;
|
||||
}).then(() => {
|
||||
|
@ -84,9 +86,14 @@ export function createAccount() {
|
|||
allowEmail,
|
||||
},
|
||||
}, responseData => {
|
||||
return responseData;
|
||||
saveToken(responseData.token);
|
||||
if (responseData.hasOwnProperty('dictionary')) {
|
||||
uploadWholeDictionary(); // Saves external id
|
||||
}
|
||||
return responseData;
|
||||
}, errorData => {
|
||||
errorHTML += `<p class="bold red">${errorData}</p>`;
|
||||
errorHTML += `<p class="bold red">${errorData}</p>`;
|
||||
return errorData;
|
||||
}).then(responseData => {
|
||||
console.log(responseData);
|
||||
createAccountErrorMessages.innerHTML = errorHTML;
|
||||
|
@ -112,6 +119,7 @@ export function triggerLoginChanges() {
|
|||
loginButton.parentElement.appendChild(logoutButton);
|
||||
loginButton.parentElement.removeChild(loginButton);
|
||||
setupLogoutButton(logoutButton);
|
||||
setupEditFormButtonOverrides();
|
||||
|
||||
renderAccountSettings();
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
import { logIn, createAccount } from "./login";
|
||||
import { saveEditModal, saveAndCloseEditModal } from "../dictionaryManagement";
|
||||
import { saveEditModalAndSync, saveAndCloseEditModalAndSync } from "./dictionaryManagement";
|
||||
|
||||
export function setupLoginModal(modal) {
|
||||
const closeElements = modal.querySelectorAll('.modal-background, .close-button');
|
||||
|
@ -19,4 +21,19 @@ export function setupLogoutButton(logoutButton) {
|
|||
document.cookie = 'token=;expires=' + expire.toGMTString() + ';domain=' + document.domain + ';path=' + path; // + in front of `new Date` converts to a number
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
|
||||
export function setupEditFormButtonOverrides() {
|
||||
document.getElementById('editSave').removeEventListener('click', saveEditModal);
|
||||
document.getElementById('editSave').addEventListener('click', saveEditModalAndSync);
|
||||
document.getElementById('editSaveAndClose').removeEventListener('click', saveAndCloseEditModal);
|
||||
document.getElementById('editSaveAndClose').addEventListener('click', saveAndCloseEditModalAndSync);
|
||||
|
||||
// document.getElementById('importDictionaryFile').addEventListener('change', importDictionary);
|
||||
// document.getElementById('importWordsCSV').addEventListener('change', importWords);
|
||||
// document.getElementById('exportDictionaryButton').addEventListener('click', exportDictionary);
|
||||
// document.getElementById('exportWordsButton').addEventListener('click', exportWords);
|
||||
// document.getElementById('deleteDictionaryButton').addEventListener('click', confirmDeleteDictionary);
|
||||
|
||||
// setupMaximizeButtons();
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
import { addMessage } from "../utilities";
|
||||
import { saveDictionary } from "../dictionaryManagement";
|
||||
import { request, saveToken } from "./helpers";
|
||||
|
||||
/* Outline for syncing
|
||||
login
|
||||
-> check local dictionary id
|
||||
(DONE!) ? no id
|
||||
-> upload dictionary
|
||||
-> make new dictionary current
|
||||
? mismatched id
|
||||
-> sync local dictionary (see 'same id' below)
|
||||
-> if no matching remote id, ignore (assume deleted)
|
||||
-> clear local dictionary
|
||||
-> insert downloaded dictionary
|
||||
? same id
|
||||
-> compare detail last updated timestamp
|
||||
? downloaded details are newer
|
||||
-> replace local details
|
||||
? local details are newer
|
||||
-> flag to upload details
|
||||
-> filter deleted words from current words
|
||||
-- check id and compare deletedOn with createdOn
|
||||
-> compare each word and by lastUpdated/createdOn
|
||||
? downloaded word is newer
|
||||
-> update local word
|
||||
? local word is newer
|
||||
-> put word in an array to upload
|
||||
-> upload anything that needs update
|
||||
*/
|
||||
|
||||
export function syncDictionary() {
|
||||
if (!window.currentDictionary.hasOwnProperty('externalId')) {
|
||||
uploadWholeDictionary(true);
|
||||
} else {
|
||||
addMessage('Syncing...');
|
||||
request({
|
||||
action: 'get-current-dictionary',
|
||||
}, remote => {
|
||||
console.log(remote);
|
||||
const detailsSynced = syncDetails(remote.details);
|
||||
|
||||
if (detailsSynced === false) {
|
||||
addMessage('Could not sync');
|
||||
} else {
|
||||
detailsSynced.then(success => {
|
||||
if (success) {
|
||||
console.log('Do a word comparison!');
|
||||
}
|
||||
});
|
||||
}
|
||||
}, error => {
|
||||
console.error(error);
|
||||
}).catch(err => console.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
export function uploadWholeDictionary(asNew = false) {
|
||||
let promise;
|
||||
if (asNew) {
|
||||
promise = request({
|
||||
action: 'create-new-dictionary',
|
||||
}, successData => {
|
||||
saveToken(successData.token);
|
||||
}, errorData => {
|
||||
console.error(errorData);
|
||||
});
|
||||
} else {
|
||||
promise = Promise.resolve();
|
||||
}
|
||||
const dictionary = {
|
||||
details: Object.assign({}, window.currentDictionary),
|
||||
words: window.currentDictionary.words,
|
||||
};
|
||||
delete dictionary.details.words; // Ugly way to easily get the data I need.
|
||||
promise.then(() => {
|
||||
request({
|
||||
action: 'set-whole-current-dictionary',
|
||||
dictionary,
|
||||
}, remoteId => {
|
||||
window.currentDictionary.externalId = remoteId;
|
||||
saveDictionary();
|
||||
addMessage('Dictionary Uploaded Successfully');
|
||||
}, errorData => {
|
||||
console.error(errorData);
|
||||
addMessage(errorData);
|
||||
})
|
||||
.catch(err => console.error('set-whole-current-dictionary: ', err));
|
||||
})
|
||||
.catch(err => console.error('create-new-dictionary: ', err));
|
||||
}
|
||||
|
||||
export function syncDetails(remoteDetails = false) {
|
||||
if (remoteDetails === false || remoteDetails.lastUpdated < window.currentDictionary.lastUpdated) {
|
||||
const details = Object.assign({}, window.currentDictionary);
|
||||
delete details.words;
|
||||
return request({
|
||||
action: 'set-dictionary-details',
|
||||
details,
|
||||
}, successful => {
|
||||
addMessage('Saved Details to Server');
|
||||
return successful;
|
||||
}, error => {
|
||||
console.error(error);
|
||||
addMessage('Could not sync dictionary');
|
||||
return false;
|
||||
});
|
||||
} else if (remoteDetails.lastUpdated > window.currentDictionary.lastUpdated) {
|
||||
window.currentDictionary = Object.assign(window.currentDictionary, remoteDetails);
|
||||
saveDictionary();
|
||||
}
|
||||
addMessage('Dictionary details synchronized');
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
export function syncWords(remoteWords, deletedWords) {
|
||||
const words = window.currentDictionary.words.filter(word => {
|
||||
const deleted = deletedWords.find(deletedWord => deletedWord.id === word.wordId);
|
||||
if (deleted) {
|
||||
return deleted.deletedOn < word.createdOn;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
const newLocalWords = words.filter(word => {
|
||||
const remote = remoteWords.find(remoteWord => remoteWord.id === word.wordId);
|
||||
return typeof remote === 'undefined';
|
||||
});
|
||||
remoteWords.forEach(remoteWord => {
|
||||
const localWord = words.find(word => word.wordId === remoteWord.wordId);
|
||||
if (localWord) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import { addWord } from './wordManagement';
|
||||
import { getCookie } from './StackOverflow/cookie';
|
||||
|
||||
export function getNextId() {
|
||||
const lastId = window.currentDictionary.words.reduce((highestId, word) => {
|
||||
|
@ -147,3 +148,7 @@ export function addMessage(messageText, time = 5000) {
|
|||
|
||||
setTimeout(closeMessage, time);
|
||||
}
|
||||
|
||||
export function hasToken() {
|
||||
return getCookie('token') !== '';
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { renderWords } from "./render";
|
||||
import { wordExists, addMessage, getNextId } from "./utilities";
|
||||
import removeDiacritics from "./StackOverflow/removeDiacritics";
|
||||
import { removeTags } from "../helpers";
|
||||
import { removeTags, getTimestampInSeconds } from "../helpers";
|
||||
import { saveDictionary } from "./dictionaryManagement";
|
||||
|
||||
export function validateWord(word, wordId = false) {
|
||||
|
@ -79,6 +79,9 @@ export function clearWordForm() {
|
|||
}
|
||||
|
||||
export function addWord(word, render = true, message = true) {
|
||||
const timestamp = getTimestampInSeconds();
|
||||
word.lastUpdated = timestamp;
|
||||
word.createdOn = timestamp;
|
||||
window.currentDictionary.words.push(word);
|
||||
if (message) {
|
||||
addMessage(`<a href="#${word.wordId}">${word.name}</a> Created Successfully`, 10000);
|
||||
|
@ -103,6 +106,7 @@ export function updateWord(word, wordId) {
|
|||
if (wordIndex < 0) {
|
||||
console.error('Could not find word to update');
|
||||
} else {
|
||||
word.lastUpdated = getTimestampInSeconds();
|
||||
window.currentDictionary.words[wordIndex] = word;
|
||||
addMessage('Word Updated Successfully');
|
||||
sortWords(true);
|
||||
|
|
|
@ -11,7 +11,7 @@ class Dictionary {
|
|||
$this->token = new Token();
|
||||
|
||||
$this->defaults = array(
|
||||
'partsOfSpeech' => array("Noun","Adjective","Verb"),
|
||||
'partsOfSpeech' => 'Noun,Adjective,Verb',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -29,14 +29,17 @@ class Dictionary {
|
|||
$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()));
|
||||
$insert_dictionary_query = "INSERT INTO dictionaries (id, user, description, created_on) VALUES (?, ?, ?, ?)";
|
||||
$insert_dictionary = $this->db->execute($insert_dictionary_query, array($new_id, $user, 'A new dictionary.', time()));
|
||||
|
||||
if ($insert_dictionary === true) {
|
||||
$insert_linguistics_query = "INSERT INTO dictionary_linguistics (dictionary, parts_of_speech)
|
||||
VALUES ($new_id, ?)";
|
||||
$insert_linguistics_query = "INSERT INTO dictionary_linguistics (dictionary, parts_of_speech, exceptions, orthography_notes, grammar_notes)
|
||||
VALUES ($new_id, ?, ?, ?, ?)";
|
||||
$insert_linguistics = $this->db->execute($insert_linguistics_query, array(
|
||||
json_encode($this->defaults['partsOfSpeech']),
|
||||
$this->defaults['partsOfSpeech'],
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
));
|
||||
|
||||
if ($insert_linguistics === true) {
|
||||
|
@ -68,7 +71,7 @@ VALUES ($new_id, ?)";
|
|||
if ($results) {
|
||||
return array_map(function($result) {
|
||||
return array(
|
||||
'id' => $result['id'],
|
||||
'id' => $this->token->hash($result['id']),
|
||||
'name' => $result['name'] . ' ' . $result['specification'],
|
||||
);
|
||||
}, $results);
|
||||
|
@ -81,17 +84,26 @@ VALUES ($new_id, ?)";
|
|||
$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'];
|
||||
$partsOfSpeech = $result['parts_of_speech'] !== '' ? $result['parts_of_speech'] : $this->defaults['partsOfSpeech'];
|
||||
|
||||
return array(
|
||||
'id' => $result['id'],
|
||||
'externalId' => $this->token->hash($result['id']),
|
||||
'name' => $result['name'],
|
||||
'specification' => $result['specification'],
|
||||
'description' => $result['description'],
|
||||
'partsOfSpeech' => $partsOfSpeech,
|
||||
'partsOfSpeech' => explode(',', $partsOfSpeech),
|
||||
'details' => array(
|
||||
'phonology' => $phonology,
|
||||
'phonology' => array(
|
||||
'consonants' => $result['consonants'] !== '' ? explode(' ', $result['consonants']) : array(),
|
||||
'vowels' => $result['vowels'] !== '' ? explode(' ', $result['vowels']) : array(),
|
||||
'blends' => $result['blends'] !== '' ? explode(' ', $result['blends']) : array(),
|
||||
'phonotactics' => array(
|
||||
'onset' => $result['onset'] !== '' ? explode(',', $result['onset']) : array(),
|
||||
'nucleus' => $result['nucleus'] !== '' ? explode(',', $result['nucleus']) : array(),
|
||||
'coda' => $result['coda'] !== '' ? explode(',', $result['coda']) : array(),
|
||||
'exceptions' => $result['parts_of_speech'],
|
||||
),
|
||||
),
|
||||
'orthography' => array(
|
||||
'notes' => $result['orthography_notes'],
|
||||
),
|
||||
|
@ -106,7 +118,7 @@ VALUES ($new_id, ?)";
|
|||
'isComplete' => $result['is_complete'] === '1' ? true : false,
|
||||
'isPublic' => $result['is_public'] === '1' ? true : false,
|
||||
),
|
||||
'lastUpdated' => is_null($result['last_updated']) ? null : $result['last_updated'],
|
||||
'lastUpdated' => is_null($result['last_updated']) ? $results['created_on'] : $result['last_updated'],
|
||||
'createdOn' => $result['created_on'],
|
||||
);
|
||||
}
|
||||
|
@ -132,11 +144,11 @@ WHERE user=$user AND id=$dictionary";
|
|||
':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'],
|
||||
':allow_duplicates' => $dictionary_object['settings']['allowDuplicates'] ? 1 : 0,
|
||||
':case_sensitive' => $dictionary_object['settings']['caseSensitive'] ? 1 : 0,
|
||||
':sort_by_definition' => $dictionary_object['settings']['sortByDefinition'] ? 1 : 0,
|
||||
':is_complete' => $dictionary_object['settings']['isComplete'] ? 1 : 0,
|
||||
':is_public' => $dictionary_object['settings']['isPublic'] ? 1 : 0,
|
||||
':last_updated' => $dictionary_object['lastUpdated'],
|
||||
':created_on' => $dictionary_object['createdOn'],
|
||||
));
|
||||
|
@ -145,15 +157,27 @@ WHERE user=$user AND id=$dictionary";
|
|||
$linguistics = $dictionary_object['details'];
|
||||
$query2 = "UPDATE dictionary_linguistics
|
||||
SET parts_of_speech=:parts_of_speech,
|
||||
phonology=:phonology,
|
||||
consonants=:consonants,
|
||||
vowels=:vowels,
|
||||
blends=:blends,
|
||||
onset=:onset,
|
||||
nucleus=:nucleus,
|
||||
coda=:coda,
|
||||
exceptions=:exceptions,
|
||||
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']),
|
||||
':parts_of_speech' => implode(',', $dictionary_object['partsOfSpeech']),
|
||||
':consonants' => implode(' ', $linguistics['phonology']['consonants']),
|
||||
':vowels' => implode(' ', $linguistics['phonology']['vowels']),
|
||||
':blends' => implode(' ', $linguistics['phonology']['blends']),
|
||||
':onset' => implode(',', $linguistics['phonology']['phonotactics']['onset']),
|
||||
':nucleus' => implode(',', $linguistics['phonology']['phonotactics']['nucleus']),
|
||||
':coda' => implode(',', $linguistics['phonology']['phonotactics']['coda']),
|
||||
':exceptions' => $linguistics['phonology']['phonotactics']['exceptions'],
|
||||
':orthography_notes' => $linguistics['orthography']['notes'],
|
||||
':grammar_notes' => $linguistics['grammar']['notes'],
|
||||
));
|
||||
|
@ -162,10 +186,9 @@ WHERE dictionary=$dictionary";
|
|||
if ($result2 === true) {
|
||||
return true;
|
||||
}
|
||||
// return $result2->errorInfo();
|
||||
}
|
||||
// return $result1->errorInfo();
|
||||
return false;
|
||||
return $this->db->last_error_info;
|
||||
// return false;
|
||||
}
|
||||
|
||||
public function getWords ($user, $dictionary) {
|
||||
|
@ -203,6 +226,10 @@ WHERE dictionary=$dictionary";
|
|||
}
|
||||
|
||||
public function setWords ($user, $dictionary, $words = array()) {
|
||||
if (count($words) < 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$query = 'INSERT INTO words (dictionary, word_id, name, pronunciation, part_of_speech, definition, details, last_updated, created_on) VALUES ';
|
||||
$params = array();
|
||||
$word_ids = array();
|
||||
|
@ -244,7 +271,12 @@ last_updated=VALUES(last_updated)';
|
|||
// }
|
||||
// }
|
||||
|
||||
return $results;
|
||||
if ($results) {
|
||||
return $results;
|
||||
}
|
||||
return array(
|
||||
'error' => $this->db->last_error_info,
|
||||
);
|
||||
}
|
||||
|
||||
public function deleteWords ($dictionary, $word_ids) {
|
||||
|
|
|
@ -24,10 +24,10 @@ class User {
|
|||
}
|
||||
} 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']));
|
||||
$token = $this->generateUserToken($user['id'], $user['current_dictionary']);
|
||||
return array(
|
||||
'token' => $token,
|
||||
'user' => $this->getUserData($user['id']),
|
||||
'dictionary' => $this->token->hash($user['current_dictionary']),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -60,14 +60,10 @@ VALUES (?, ?, ?, ?, ?)';
|
|||
if (isset($new_dictionary['error'])) {
|
||||
return $new_dictionary;
|
||||
} else {
|
||||
setcookie('token', $this->generateUserToken($new_user_id, $new_dictionary));
|
||||
$token = $this->generateUserToken($new_user_id, $new_dictionary);
|
||||
return array(
|
||||
'token' => $token,
|
||||
'user' => $this->getUserData($new_user_id),
|
||||
'dictionary' => $this->token->hash($new_dictionary),
|
||||
'debug' => [
|
||||
'newUserId' => $new_user_id,
|
||||
'newDictionary' => $new_dictionary,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +97,7 @@ VALUES (?, ?, ?, ?, ?)';
|
|||
}
|
||||
|
||||
public function getUserData ($user_id) {
|
||||
$query = 'SELECT email, public_name, allow_emails FROM users WHERE id=?';
|
||||
$query = 'SELECT email, public_name, allow_email FROM users WHERE id=?';
|
||||
$stmt = $this->db->query($query, array($user_id));
|
||||
$user = $stmt->fetch();
|
||||
if ($stmt && $user) {
|
||||
|
@ -183,7 +179,12 @@ VALUES (?, ?, ?, ?, ?)';
|
|||
$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;
|
||||
if ($details_updated === true && $words_updated === true) {
|
||||
return $this->token->hash($dictionary);
|
||||
}
|
||||
return array(
|
||||
'error' => ($details_updated !== true ? $details_updated . ' ' : '') . ($words_updated !== true ? $words_updated : ''),
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -193,7 +194,13 @@ VALUES (?, ?, ?, ?, ?)';
|
|||
if ($user_data !== false) {
|
||||
$user = $user_data->id;
|
||||
$dictionary = $user_data->dictionary;
|
||||
return $this->dictionary->setDetails($user, $dictionary, $dictionary_details);
|
||||
$details_updated = $this->dictionary->setDetails($user, $dictionary, $dictionary_details);
|
||||
if ($details_updated === true) {
|
||||
return true;
|
||||
}
|
||||
return array(
|
||||
'error' => $details_updated,
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -3,8 +3,17 @@ require_once('./Response.php');
|
|||
require_once('./User.php');
|
||||
|
||||
$inputJSON = file_get_contents('php://input');
|
||||
$inputJSON = strip_tags($inputJSON);
|
||||
$request= json_decode($inputJSON, true);
|
||||
|
||||
if (!$request) {
|
||||
// If malformed/unparseable JSON, fail.
|
||||
return Response::json(array(
|
||||
'data' => 'Malformed request data',
|
||||
'error' => true,
|
||||
), 400);
|
||||
}
|
||||
|
||||
$action = isset($request['action']) ? $request['action'] : '';
|
||||
$token = isset($_COOKIE['token']) ? $_COOKIE['token'] : false;
|
||||
|
||||
|
@ -187,12 +196,18 @@ switch ($action) {
|
|||
if ($token !== false && isset($request['dictionary'])) {
|
||||
$user = new User();
|
||||
$dictionary_data = $user->saveWholeCurrentDictionary($token, $request['dictionary']);
|
||||
if ($dictionary_data !== false) {
|
||||
if ($dictionary_data !== false && !isset($dictionary_data['error'])) {
|
||||
return Response::json(array(
|
||||
'data' => 'Updated successfully',
|
||||
'data' => $dictionary_data,
|
||||
'error' => false,
|
||||
), 200);
|
||||
}
|
||||
if (isset($dictionary_data['error'])) {
|
||||
return Response::json(array(
|
||||
'data' => $dictionary_data['message'],
|
||||
'error' => true,
|
||||
), 500);
|
||||
}
|
||||
return Response::json(array(
|
||||
'data' => 'Could not set dictionary: invalid token',
|
||||
'error' => true,
|
||||
|
@ -207,13 +222,19 @@ switch ($action) {
|
|||
if ($token !== false && isset($request['details'])) {
|
||||
$user = new User();
|
||||
$update_details_success = $user->updateCurrentDictionaryDetails($token, $request['details']);
|
||||
if ($update_details_success !== false) {
|
||||
if ($update_details_success === true) {
|
||||
return Response::json(array(
|
||||
// 'data' => 'Updated successfully',
|
||||
'data' => $update_details_success,
|
||||
'error' => false,
|
||||
), 200);
|
||||
}
|
||||
if (isset($update_details_success['error'])) {
|
||||
return Response::json(array(
|
||||
'data' => $update_details_success['error'],
|
||||
'error' => true,
|
||||
), 500);
|
||||
}
|
||||
return Response::json(array(
|
||||
'data' => 'Could not set dictionary: invalid token',
|
||||
'error' => true,
|
||||
|
|
Loading…
Reference in New Issue