Enable creating new dictionaries from frontend
Also change how dictionaries are created, i.e. set random unique id so exposing them without hashing is ok. This is to allow displaying public dictionaries the same way
This commit is contained in:
parent
e6878fd9ec
commit
e6916f0f24
|
@ -26,22 +26,33 @@ class Dictionary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
public function create ($user) {
|
||||||
$insert_dictionary_query = "INSERT INTO dictionaries (user, created_on) VALUES (?, ?)";
|
$new_id = mt_rand(1000, 999999999);
|
||||||
$insert_dictionary = $this->db->execute($insert_dictionary_query, array($user, time()));
|
$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) {
|
if ($insert_dictionary === true) {
|
||||||
$new_dictionary_id = $this->db->lastInsertId();
|
|
||||||
|
|
||||||
$insert_linguistics_query = "INSERT INTO dictionary_linguistics (dictionary, parts_of_speech, phonology)
|
$insert_linguistics_query = "INSERT INTO dictionary_linguistics (dictionary, parts_of_speech, phonology)
|
||||||
VALUES ($new_dictionary_id, ?, ?)";
|
VALUES ($new_id, ?, ?)";
|
||||||
$insert_linguistics = $this->db->execute($insert_linguistics_query, array(
|
$insert_linguistics = $this->db->execute($insert_linguistics_query, array(
|
||||||
json_encode($this->defaults['partsOfSpeech']),
|
json_encode($this->defaults['partsOfSpeech']),
|
||||||
json_encode($this->defaults['phonology']),
|
json_encode($this->defaults['phonology']),
|
||||||
));
|
));
|
||||||
|
|
||||||
if ($insert_linguistics === true) {
|
if ($insert_linguistics === true) {
|
||||||
return $this->changeCurrent($user, $new_dictionary_id);
|
return $this->changeCurrent($user, $new_id);
|
||||||
} else {
|
} else {
|
||||||
return array(
|
return array(
|
||||||
'error' => '"INSERT INTO dictionary_linguistics" failed: ' . $this->db->last_error_info[2],
|
'error' => '"INSERT INTO dictionary_linguistics" failed: ' . $this->db->last_error_info[2],
|
||||||
|
@ -69,7 +80,7 @@ VALUES ($new_dictionary_id, ?, ?)";
|
||||||
if ($results) {
|
if ($results) {
|
||||||
return array_map(function($result) {
|
return array_map(function($result) {
|
||||||
return array(
|
return array(
|
||||||
'id' => $this->token->hash($result['id']),
|
'id' => $result['id'],
|
||||||
'name' => $result['name'] . ' ' . $result['specification'],
|
'name' => $result['name'] . ' ' . $result['specification'],
|
||||||
);
|
);
|
||||||
}, $results);
|
}, $results);
|
||||||
|
@ -86,7 +97,7 @@ VALUES ($new_dictionary_id, ?, ?)";
|
||||||
$phonology = $result['phonology'] !== '' ? json_decode($result['phonology']) : $this->defaults['phonology'];
|
$phonology = $result['phonology'] !== '' ? json_decode($result['phonology']) : $this->defaults['phonology'];
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'id' => $this->token->hash($result['id']),
|
'id' => $result['id'],
|
||||||
'name' => $result['name'],
|
'name' => $result['name'],
|
||||||
'specification' => $result['specification'],
|
'specification' => $result['specification'],
|
||||||
'description' => $result['description'],
|
'description' => $result['description'],
|
||||||
|
|
|
@ -115,9 +115,10 @@ VALUES (?, ?, ?, ?, ?)';
|
||||||
$id = $user_data->id;
|
$id = $user_data->id;
|
||||||
$new_dictionary = $this->dictionary->create($id);
|
$new_dictionary = $this->dictionary->create($id);
|
||||||
if (!isset($new_dictionary['error'])) {
|
if (!isset($new_dictionary['error'])) {
|
||||||
|
$new_token = $this->generateUserToken($id, $new_dictionary);
|
||||||
return array(
|
return array(
|
||||||
'token' => $this->generateUserToken($id, $new_dictionary),
|
'token' => $new_token,
|
||||||
'dictionary' => $this->getCurrentDictionary($token),
|
'dictionary' => $this->getCurrentDictionary($new_token),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return $new_dictionary;
|
return $new_dictionary;
|
||||||
|
|
|
@ -11,6 +11,7 @@ export class MyAccount extends Component {
|
||||||
publicName: PropTypes.string.isRequired,
|
publicName: PropTypes.string.isRequired,
|
||||||
allowEmails: PropTypes.bool.isRequired,
|
allowEmails: PropTypes.bool.isRequired,
|
||||||
userDictionaries: PropTypes.array.isRequired,
|
userDictionaries: PropTypes.array.isRequired,
|
||||||
|
dictionary: PropTypes.object,
|
||||||
sendUserData: PropTypes.func,
|
sendUserData: PropTypes.func,
|
||||||
changeDictionary: PropTypes.func,
|
changeDictionary: PropTypes.func,
|
||||||
}, props, 'prop', 'MyAccount');
|
}, props, 'prop', 'MyAccount');
|
||||||
|
@ -136,15 +137,23 @@ export class MyAccount extends Component {
|
||||||
<div className='column'>
|
<div className='column'>
|
||||||
<h2 className='title'>Account Actions</h2>
|
<h2 className='title'>Account Actions</h2>
|
||||||
|
|
||||||
|
<div className='field'>
|
||||||
|
<div className='control'>
|
||||||
|
<button class="button" onClick={ () => this.props.dictionary.createNew() }>
|
||||||
|
Create New Dictionary
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className='field'>
|
<div className='field'>
|
||||||
<label className='label is-unselectable'>
|
<label className='label is-unselectable'>
|
||||||
<span>Change Dictionary</span>
|
<span>Change Dictionary</span>
|
||||||
</label>
|
</label>
|
||||||
<div className='control'>
|
<div className='control'>
|
||||||
<div className='select'>
|
<div className='select'>
|
||||||
<select>
|
<select value={ this.props.dictionary.id }>
|
||||||
{this.props.userDictionaries.map(item => {
|
{this.props.userDictionaries.map(item => {
|
||||||
return <option value={item.id}>{item.name}</option>;
|
return <option value={item.id}>{item.name}{item.id === this.props.dictionary.id && ' (Current)'}</option>;
|
||||||
})}
|
})}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,6 +17,7 @@ export class AccountManager extends Component {
|
||||||
|
|
||||||
PropTypes.checkPropTypes({
|
PropTypes.checkPropTypes({
|
||||||
updater: PropTypes.object.isRequired,
|
updater: PropTypes.object.isRequired,
|
||||||
|
dictionary: PropTypes.object,
|
||||||
}, props, 'prop', 'AccountManager');
|
}, props, 'prop', 'AccountManager');
|
||||||
|
|
||||||
const userData = store.get('LexicongaUserData');
|
const userData = store.get('LexicongaUserData');
|
||||||
|
@ -163,6 +164,7 @@ export class AccountManager extends Component {
|
||||||
publicName={ userData.publicName }
|
publicName={ userData.publicName }
|
||||||
allowEmails={ userData.allowEmails }
|
allowEmails={ userData.allowEmails }
|
||||||
userDictionaries={ this.state.userDictionaries }
|
userDictionaries={ this.state.userDictionaries }
|
||||||
|
dictionary={ this.props.dictionary }
|
||||||
sendUserData={ this.sendUserData.bind(this) }
|
sendUserData={ this.sendUserData.bind(this) }
|
||||||
changeDictionary={ () => {} } />
|
changeDictionary={ () => {} } />
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -17,6 +17,7 @@ export class Header extends Component {
|
||||||
partsOfSpeech: PropTypes.array.isRequired,
|
partsOfSpeech: PropTypes.array.isRequired,
|
||||||
search: PropTypes.func.isRequired,
|
search: PropTypes.func.isRequired,
|
||||||
updater: PropTypes.object.isRequired,
|
updater: PropTypes.object.isRequired,
|
||||||
|
dictionary: PropTypes.object,
|
||||||
}, props, 'prop', 'Header');
|
}, props, 'prop', 'Header');
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -49,7 +50,9 @@ export class Header extends Component {
|
||||||
<div className={`navbar-menu${ this.state.displayNavMenu ? ' is-active' : '' }`}>
|
<div className={`navbar-menu${ this.state.displayNavMenu ? ' is-active' : '' }`}>
|
||||||
<div className='navbar-end'>
|
<div className='navbar-end'>
|
||||||
<span className='navbar-item has-text-right-touch'>
|
<span className='navbar-item has-text-right-touch'>
|
||||||
<AccountManager updater={ this.props.updater } />
|
<AccountManager
|
||||||
|
updater={ this.props.updater }
|
||||||
|
dictionary={ this.props.dictionary } />
|
||||||
</span>
|
</span>
|
||||||
<span className='navbar-item has-text-right-touch'>
|
<span className='navbar-item has-text-right-touch'>
|
||||||
<Modal buttonText='Help' title='Lexiconga Help'>
|
<Modal buttonText='Help' title='Lexiconga Help'>
|
||||||
|
|
|
@ -209,6 +209,7 @@ class App extends Component {
|
||||||
partsOfSpeech={ this.state.partsOfSpeech }
|
partsOfSpeech={ this.state.partsOfSpeech }
|
||||||
search={ (searchConfig) => this.search(searchConfig) }
|
search={ (searchConfig) => this.search(searchConfig) }
|
||||||
updater={ this.updater }
|
updater={ this.updater }
|
||||||
|
dictionary={ dictionary }
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MainDisplay
|
<MainDisplay
|
||||||
|
|
|
@ -3,6 +3,7 @@ import store from 'store';
|
||||||
import wordDb from './WordDatabase';
|
import wordDb from './WordDatabase';
|
||||||
import idManager from './IDManager';
|
import idManager from './IDManager';
|
||||||
import { DEFAULT_DICTIONARY } from '../Constants';
|
import { DEFAULT_DICTIONARY } from '../Constants';
|
||||||
|
import { request } from "../Helpers";
|
||||||
|
|
||||||
class DictionaryData {
|
class DictionaryData {
|
||||||
constructor () {
|
constructor () {
|
||||||
|
@ -39,6 +40,11 @@ class DictionaryData {
|
||||||
store.set('Lexiconga', updatedValues);
|
store.set('Lexiconga', updatedValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get id () {
|
||||||
|
return this.storedData.id
|
||||||
|
|| null;
|
||||||
|
}
|
||||||
|
|
||||||
get name () {
|
get name () {
|
||||||
return this.storedData.name
|
return this.storedData.name
|
||||||
|| DEFAULT_DICTIONARY.name;
|
|| DEFAULT_DICTIONARY.name;
|
||||||
|
@ -346,6 +352,30 @@ class DictionaryData {
|
||||||
As such, searches on `details` will only allow "contains".
|
As such, searches on `details` will only allow "contains".
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reset(dictionaryDetails = DEFAULT_DICTIONARY) {
|
||||||
|
this.storedData = dictionaryDetails;
|
||||||
|
wordDb.delete().then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('Could not delete words db: ', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createNew () {
|
||||||
|
request('create-new-dictionary', {
|
||||||
|
token: store.get('LexicongaToken'),
|
||||||
|
}, response => {
|
||||||
|
const {data, error} = response;
|
||||||
|
if (error) {
|
||||||
|
console.error(data);
|
||||||
|
} else {
|
||||||
|
console.log(data);
|
||||||
|
store.set('LexicongaToken', data.token);
|
||||||
|
this.reset(data.dictionary.details);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new DictionaryData;
|
export default new DictionaryData;
|
Loading…
Reference in New Issue