Compare commits
3 Commits
389b4d9015
...
6fed4dd4fb
Author | SHA1 | Date |
---|---|---|
Robbie Antenesse | 6fed4dd4fb | |
Robbie Antenesse | 59bf9c48e0 | |
Robbie Antenesse | e490ef08d3 |
|
@ -1,10 +1,9 @@
|
|||
import md from 'marked';
|
||||
import { removeTags, slugify } from '../../helpers';
|
||||
import { getWordsStats, getHomonymnNumber } from './utilities';
|
||||
import { getHomonymnNumber } from './utilities';
|
||||
import { getMatchingSearchWords, highlightSearchTerm, getSearchFilters, getSearchTerm } from './search';
|
||||
import { showSection } from './displayToggles';
|
||||
import { renderAd } from '../ads';
|
||||
import { sortWords } from './wordManagement';
|
||||
import { setupInfoModal } from '../setupListeners/modals';
|
||||
import { setupSearchFilters } from '../setupListeners/search';
|
||||
|
||||
|
@ -13,7 +12,6 @@ export function renderAll() {
|
|||
renderCustomCSS();
|
||||
renderDictionaryDetails();
|
||||
renderPartsOfSpeech();
|
||||
sortWords();
|
||||
renderWords();
|
||||
}
|
||||
|
||||
|
@ -115,7 +113,7 @@ export function renderDetails() {
|
|||
}
|
||||
|
||||
export function renderStats() {
|
||||
const wordStats = getWordsStats();
|
||||
const { wordStats } = window.currentDictionary;
|
||||
const numberOfWordsHTML = `<p><strong>Number of Words</strong><br>${wordStats.numberOfWords.map(stat => `<span><span class="tag">${stat.name}</span><span class="tag">${stat.value}</span></span>`).join(' ')}</p>`;
|
||||
const wordLengthHTML = `<p><strong>Word Length</strong><br><span><span class="tag">Shortest</span><span class="tag">${wordStats.wordLength.shortest}</span></span>
|
||||
<span><span class="tag">Longest</span><span class="tag">${wordStats.wordLength.longest}</span></span>
|
||||
|
|
|
@ -1,93 +1,3 @@
|
|||
export function getWordsStats() {
|
||||
const {words, partsOfSpeech} = window.currentDictionary;
|
||||
const {caseSensitive} = window.currentDictionary.settings;
|
||||
|
||||
const wordStats = {
|
||||
numberOfWords: [
|
||||
{
|
||||
name: 'Total',
|
||||
value: words.length,
|
||||
},
|
||||
],
|
||||
wordLength: {
|
||||
shortest: 0,
|
||||
longest: 0,
|
||||
average: 0,
|
||||
},
|
||||
letterDistribution: [
|
||||
/* {
|
||||
letter: '',
|
||||
number: 0,
|
||||
percentage: 0.00,
|
||||
} */
|
||||
],
|
||||
totalLetters: 0,
|
||||
};
|
||||
|
||||
partsOfSpeech.forEach(partOfSpeech => {
|
||||
const wordsWithPartOfSpeech = words.filter(word => word.partOfSpeech === partOfSpeech);
|
||||
wordStats.numberOfWords.push({
|
||||
name: partOfSpeech,
|
||||
value: wordsWithPartOfSpeech.length,
|
||||
});
|
||||
});
|
||||
|
||||
wordStats.numberOfWords.push({
|
||||
name: 'Unclassified',
|
||||
value: words.filter(word => !partsOfSpeech.includes(word.partOfSpeech)).length,
|
||||
});
|
||||
|
||||
let totalLetters = 0;
|
||||
const numberOfLetters = {};
|
||||
|
||||
words.forEach(word => {
|
||||
const shortestWord = wordStats.wordLength.shortest;
|
||||
const longestWord = wordStats.wordLength.longest;
|
||||
const wordLetters = word.name.split('');
|
||||
const lettersInWord = wordLetters.length;
|
||||
|
||||
totalLetters += lettersInWord;
|
||||
|
||||
if (shortestWord === 0 || lettersInWord < shortestWord) {
|
||||
wordStats.wordLength.shortest = lettersInWord;
|
||||
}
|
||||
|
||||
if (longestWord === 0 || lettersInWord > longestWord) {
|
||||
wordStats.wordLength.longest = lettersInWord;
|
||||
}
|
||||
|
||||
wordLetters.forEach(letter => {
|
||||
const letterToUse = caseSensitive ? letter : letter.toLowerCase();
|
||||
if (!numberOfLetters.hasOwnProperty(letterToUse)) {
|
||||
numberOfLetters[letterToUse] = 1;
|
||||
} else {
|
||||
numberOfLetters[letterToUse]++;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
wordStats.totalLetters = totalLetters;
|
||||
wordStats.wordLength.average = words.length > 0 ? Math.round(totalLetters / words.length) : 0;
|
||||
|
||||
for (const letter in numberOfLetters) {
|
||||
if (numberOfLetters.hasOwnProperty(letter)) {
|
||||
const number = numberOfLetters[letter];
|
||||
wordStats.letterDistribution.push({
|
||||
letter,
|
||||
number,
|
||||
percentage: number / totalLetters,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
wordStats.letterDistribution.sort((a, b) => {
|
||||
if (a.percentage === b.percentage) return 0;
|
||||
return (a.percentage > b.percentage) ? -1 : 1;
|
||||
});
|
||||
|
||||
return wordStats;
|
||||
}
|
||||
|
||||
export function getHomonymnIndexes(word) {
|
||||
const { currentDictionary } = window;
|
||||
const { caseSensitive } = currentDictionary.settings;
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
import removeDiacritics from "../StackOverflow/removeDiacritics";
|
||||
|
||||
export function sortWords() {
|
||||
const { sortByDefinition } = window.currentDictionary.settings;
|
||||
const sortBy = sortByDefinition ? 'definition' : 'name';
|
||||
|
||||
window.currentDictionary.words.sort((wordA, wordB) => {
|
||||
if (removeDiacritics(wordA[sortBy]).toLowerCase() === removeDiacritics(wordB[sortBy]).toLowerCase()) return 0;
|
||||
return removeDiacritics(wordA[sortBy]).toLowerCase() > removeDiacritics(wordB[sortBy]).toLowerCase() ? 1 : -1;
|
||||
});
|
||||
}
|
|
@ -90,187 +90,6 @@ VALUES ($new_id, ?, ?, ?, ?, ?, ?)";
|
|||
return array();
|
||||
}
|
||||
|
||||
public function getPublicDictionaryDetails ($dictionary) {
|
||||
if (is_numeric($dictionary)) {
|
||||
$query = "SELECT d.*, dl.*, u.public_name FROM dictionaries d JOIN dictionary_linguistics dl ON dl.dictionary = d.id JOIN users u ON u.id = d.user WHERE d.id=? AND d.is_public=1";
|
||||
$result = $this->db->query($query, array($dictionary))->fetch();
|
||||
if ($result) {
|
||||
// Default json values in case they are somehow not created by front end first
|
||||
$partsOfSpeech = $result['parts_of_speech'] !== '' ? $result['parts_of_speech'] : $this->defaults['partsOfSpeech'];
|
||||
|
||||
return array(
|
||||
'externalID' => $result['id'],
|
||||
'name' => $result['name'],
|
||||
'specification' => $result['specification'],
|
||||
'description' => $this->parseReferences(strip_tags($result['description']), $result['id']),
|
||||
'createdBy' => $result['public_name'],
|
||||
'partsOfSpeech' => explode(',', $partsOfSpeech),
|
||||
'alphabeticalOrder' => $result['alphabetical_order'] !== '' ? explode(' ', $result['alphabetical_order']) : array(),
|
||||
'details' => array(
|
||||
'phonology' => array(
|
||||
'consonants' => $result['consonants'] !== '' ? explode(' ', $result['consonants']) : array(),
|
||||
'vowels' => $result['vowels'] !== '' ? explode(' ', $result['vowels']) : array(),
|
||||
'blends' => $result['blends'] !== '' ? explode(' ', $result['blends']) : array(),
|
||||
'notes' => $result['phonology_notes'],
|
||||
),
|
||||
'phonotactics' => array(
|
||||
'onset' => $result['onset'] !== '' ? explode(',', $result['onset']) : array(),
|
||||
'nucleus' => $result['nucleus'] !== '' ? explode(',', $result['nucleus']) : array(),
|
||||
'coda' => $result['coda'] !== '' ? explode(',', $result['coda']) : array(),
|
||||
'notes' => $result['phonotactics_notes'],
|
||||
),
|
||||
'orthography' => array(
|
||||
'translations' => $result['translations'] !== '' ? explode(PHP_EOL, $result['translations']) : 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,
|
||||
'theme' => $result['theme'],
|
||||
'customCSS' => $result['custom_css'],
|
||||
'isPublic' => $result['is_public'] === '1' ? true : false,
|
||||
),
|
||||
'lastUpdated' => is_null($result['last_updated']) ? $result['created_on'] : $result['last_updated'],
|
||||
'createdOn' => $result['created_on'],
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getPublicDictionaryWords ($dictionary) {
|
||||
if (is_numeric($dictionary)) {
|
||||
$query = "SELECT words.* FROM words JOIN dictionaries ON id = dictionary WHERE dictionary=? AND is_public=1";
|
||||
$results = $this->db->query($query, array($dictionary))->fetchAll();
|
||||
if ($results) {
|
||||
return array_map(function ($row) use ($dictionary) {
|
||||
return array(
|
||||
'name' => $this->translateOrthography($row['name'], $dictionary),
|
||||
'pronunciation' => $row['pronunciation'],
|
||||
'partOfSpeech' => $row['part_of_speech'],
|
||||
'definition' => $row['definition'],
|
||||
'details' => $this->parseReferences(strip_tags($row['details']), $dictionary),
|
||||
'lastUpdated' => is_null($row['last_updated']) ? intval($row['created_on']) : intval($row['last_updated']),
|
||||
'createdOn' => intval($row['created_on']),
|
||||
'wordId' => intval($row['word_id']),
|
||||
);
|
||||
}, $results);
|
||||
}
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getSpecificPublicDictionaryWord ($dictionary, $word) {
|
||||
if (is_numeric($dictionary) && is_numeric($word)) {
|
||||
$query = "SELECT words.* FROM words JOIN dictionaries ON id = dictionary WHERE dictionary=? AND word_id=? AND is_public=1";
|
||||
$result = $this->db->query($query, array($dictionary, $word))->fetch();
|
||||
if ($result) {
|
||||
return array(
|
||||
'name' => $this->translateOrthography($result['name'], $dictionary),
|
||||
'pronunciation' => $result['pronunciation'],
|
||||
'partOfSpeech' => $result['part_of_speech'],
|
||||
'definition' => $result['definition'],
|
||||
'details' => $this->parseReferences(strip_tags($result['details']), $dictionary),
|
||||
'lastUpdated' => is_null($result['last_updated']) ? intval($result['created_on']) : intval($result['last_updated']),
|
||||
'createdOn' => intval($result['created_on']),
|
||||
'wordId' => intval($result['word_id']),
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function parseReferences($details, $dictionary_id) {
|
||||
$details = strip_tags($details);
|
||||
if (preg_match_all('/\{\{.+?\}\}/', $details, $references) !== false) {
|
||||
$references = array_unique($references[0]);
|
||||
foreach($references as $reference) {
|
||||
$word_to_find = preg_replace('/\{\{|\}\}/', '', $reference);
|
||||
$homonymn = 0;
|
||||
|
||||
if (strpos($word_to_find, ':') !== false) {
|
||||
$separator = strpos($word_to_find, ':');
|
||||
$homonymn = substr($word_to_find, $separator + 1);
|
||||
$word_to_find = substr($word_to_find, 0, $separator);
|
||||
if ($homonymn && trim($homonymn) && intval(trim($homonymn)) > 0) {
|
||||
$homonymn = intval(trim($homonymn));
|
||||
} else {
|
||||
$homonymn = false;
|
||||
}
|
||||
}
|
||||
|
||||
$target_id = false;
|
||||
$reference_ids = $this->getWordIdsWithName($dictionary_id, $word_to_find);
|
||||
|
||||
if (count($reference_ids) > 0) {
|
||||
if ($homonymn !== false && $homonymn > 0) {
|
||||
if (isset($reference_ids[$homonymn - 1])) {
|
||||
$target_id = $reference_ids[$homonymn - 1];
|
||||
}
|
||||
} else if ($homonymn !== false) {
|
||||
$target_id = $reference_ids[0];
|
||||
}
|
||||
|
||||
if ($target_id !== false) {
|
||||
if ($homonymn < 1) {
|
||||
$homonymn = 1;
|
||||
}
|
||||
$homonymn_sub_html = count($reference_ids) > 1 && $homonymn - 1 >= 0 ? '<sub>' . $homonymn . '</sub>' : '';
|
||||
$site_root = substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], $dictionary_id));
|
||||
$markdown_link = '<span class="word-reference"><a href="' . $site_root . $dictionary_id . '/' . $target_id .'" target="_blank" title="Link to Reference">'
|
||||
. '<span class="orthographic-translation">' . $this->translateOrthography($word_to_find, $dictionary_id) . '</span>' . $homonymn_sub_html
|
||||
. '</a></span>';
|
||||
$details = str_replace($reference, $markdown_link, $details);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $details;
|
||||
}
|
||||
|
||||
private function getWordIdsWithName($dictionary, $word_name) {
|
||||
if (is_numeric($dictionary)) {
|
||||
$query = "SELECT word_id FROM words WHERE dictionary=? AND name=?";
|
||||
$results = $this->db->query($query, array($dictionary, $word_name))->fetchAll();
|
||||
if ($results) {
|
||||
return array_map(function ($row) {
|
||||
return intval($row['word_id']);
|
||||
}, $results);
|
||||
}
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
private function translateOrthography($word, $dictionary) {
|
||||
if (!isset($this->translations)) {
|
||||
$this->translations = $this->getTranslations($dictionary);
|
||||
}
|
||||
foreach($this->translations as $translation) {
|
||||
$translation = array_map('trim', explode('=', $translation));
|
||||
if (count($translation) > 1 && $translation[0] !== '' && $translation[1] !== '') {
|
||||
$word = str_replace($translation[0], $translation[1], $word);
|
||||
}
|
||||
};
|
||||
return $word;
|
||||
}
|
||||
|
||||
private function getTranslations($dictionary) {
|
||||
if (is_numeric($dictionary)) {
|
||||
$query = "SELECT translations FROM dictionary_linguistics WHERE dictionary=?";
|
||||
$result = $this->db->query($query, array($dictionary))->fetch();
|
||||
if ($result) {
|
||||
return explode(PHP_EOL, $result['translations']);
|
||||
}
|
||||
}
|
||||
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();
|
||||
|
|
|
@ -0,0 +1,357 @@
|
|||
<?php
|
||||
require_once(realpath(dirname(__FILE__) . '/./Db.php'));
|
||||
require_once(realpath(dirname(__FILE__) . '/./Token.php'));
|
||||
|
||||
class PublicDictionary {
|
||||
private $db;
|
||||
private $token;
|
||||
private $defaults;
|
||||
private $original_words;
|
||||
public $details;
|
||||
public $words;
|
||||
|
||||
function __construct ($dictionary_id) {
|
||||
$this->db = new Db();
|
||||
$this->token = new Token();
|
||||
|
||||
$this->defaults = array(
|
||||
'partsOfSpeech' => 'Noun,Adjective,Verb',
|
||||
);
|
||||
|
||||
$this->details = $this->getPublicDictionaryDetails($dictionary_id);
|
||||
$this->words = $this->getPublicDictionaryWords($dictionary_id);
|
||||
$this->details['wordStats'] = $this->getWordStats();
|
||||
}
|
||||
|
||||
public function getPublicDictionaryDetails ($dictionary) {
|
||||
if (is_numeric($dictionary)) {
|
||||
$query = "SELECT d.*, dl.*, u.public_name FROM dictionaries d JOIN dictionary_linguistics dl ON dl.dictionary = d.id JOIN users u ON u.id = d.user WHERE d.id=? AND d.is_public=1";
|
||||
$result = $this->db->query($query, array($dictionary))->fetch();
|
||||
if ($result) {
|
||||
// Default json values in case they are somehow not created by front end first
|
||||
$partsOfSpeech = $result['parts_of_speech'] !== '' ? $result['parts_of_speech'] : $this->defaults['partsOfSpeech'];
|
||||
|
||||
return array(
|
||||
'externalID' => $result['id'],
|
||||
'name' => $result['name'],
|
||||
'specification' => $result['specification'],
|
||||
'description' => $this->parseReferences(strip_tags($result['description']), $result['id']),
|
||||
'createdBy' => $result['public_name'],
|
||||
'partsOfSpeech' => explode(',', $partsOfSpeech),
|
||||
'alphabeticalOrder' => $result['alphabetical_order'] !== '' ? explode(' ', $result['alphabetical_order']) : array(),
|
||||
'details' => array(
|
||||
'phonology' => array(
|
||||
'consonants' => $result['consonants'] !== '' ? explode(' ', $result['consonants']) : array(),
|
||||
'vowels' => $result['vowels'] !== '' ? explode(' ', $result['vowels']) : array(),
|
||||
'blends' => $result['blends'] !== '' ? explode(' ', $result['blends']) : array(),
|
||||
'notes' => $result['phonology_notes'],
|
||||
),
|
||||
'phonotactics' => array(
|
||||
'onset' => $result['onset'] !== '' ? explode(',', $result['onset']) : array(),
|
||||
'nucleus' => $result['nucleus'] !== '' ? explode(',', $result['nucleus']) : array(),
|
||||
'coda' => $result['coda'] !== '' ? explode(',', $result['coda']) : array(),
|
||||
'notes' => $result['phonotactics_notes'],
|
||||
),
|
||||
'orthography' => array(
|
||||
'translations' => $result['translations'] !== '' ? explode(PHP_EOL, $result['translations']) : 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,
|
||||
'theme' => $result['theme'],
|
||||
'customCSS' => $result['custom_css'],
|
||||
'isPublic' => $result['is_public'] === '1' ? true : false,
|
||||
),
|
||||
'lastUpdated' => is_null($result['last_updated']) ? $result['created_on'] : $result['last_updated'],
|
||||
'createdOn' => $result['created_on'],
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getPublicDictionaryWords ($dictionary) {
|
||||
if (is_numeric($dictionary)) {
|
||||
$words = $this->getWordsAsEntered();
|
||||
if ($words) {
|
||||
return array_map(function ($row) use ($dictionary) {
|
||||
return array(
|
||||
'name' => $this->translateOrthography($row['name'], $dictionary),
|
||||
'pronunciation' => $row['pronunciation'],
|
||||
'partOfSpeech' => $row['part_of_speech'],
|
||||
'definition' => $row['definition'],
|
||||
'details' => $this->parseReferences(strip_tags($row['details']), $dictionary),
|
||||
'lastUpdated' => is_null($row['last_updated']) ? intval($row['created_on']) : intval($row['last_updated']),
|
||||
'createdOn' => intval($row['created_on']),
|
||||
'wordId' => intval($row['word_id']),
|
||||
);
|
||||
}, $this->sortWords($words));
|
||||
}
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getSpecificPublicDictionaryWord ($dictionary, $word) {
|
||||
if (is_numeric($dictionary) && is_numeric($word)) {
|
||||
$query = "SELECT words.* FROM words JOIN dictionaries ON id = dictionary WHERE dictionary=? AND word_id=? AND is_public=1";
|
||||
$result = $this->db->query($query, array($dictionary, $word))->fetch();
|
||||
if ($result) {
|
||||
return array(
|
||||
'name' => $this->translateOrthography($result['name'], $dictionary),
|
||||
'pronunciation' => $result['pronunciation'],
|
||||
'partOfSpeech' => $result['part_of_speech'],
|
||||
'definition' => $result['definition'],
|
||||
'details' => $this->parseReferences(strip_tags($result['details']), $dictionary),
|
||||
'lastUpdated' => is_null($result['last_updated']) ? intval($result['created_on']) : intval($result['last_updated']),
|
||||
'createdOn' => intval($result['created_on']),
|
||||
'wordId' => intval($result['word_id']),
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getWordsAsEntered() {
|
||||
if (!isset($this->original_words)) {
|
||||
$query = "SELECT words.* FROM words JOIN dictionaries ON id = dictionary WHERE dictionary=? AND is_public=1";
|
||||
$this->original_words = $this->db->query($query, array($this->details['externalID']))->fetchAll();
|
||||
}
|
||||
return $this->original_words;
|
||||
}
|
||||
|
||||
private function sortWords($words) {
|
||||
$sort_by = isset($this->details['settings']) && isset($this->details['settings']['sortByDefinition']) && $this->details['settings']['sortByDefinition'] === true
|
||||
? 'definition' : 'name';
|
||||
// Transliterator settings from https://stackoverflow.com/a/35178027
|
||||
$transliterator = Transliterator::createFromRules(':: Latin-ASCII; :: NFD; :: [:Nonspacing Mark:] Remove; :: Lower(); :: NFC;', Transliterator::FORWARD);
|
||||
usort($words, function($a, $b) use($transliterator, $sort_by) {
|
||||
$word_a = $transliterator->transliterate($a[$sort_by]);
|
||||
$word_b = $transliterator->transliterate($b[$sort_by]);
|
||||
return strcasecmp($word_a, $word_b);
|
||||
});
|
||||
|
||||
if (isset($this->details['alphabeticalOrder']) && count($this->details['alphabeticalOrder']) > 0) {
|
||||
$ordering = array();
|
||||
for ($i = 0; $i < count($this->details['alphabeticalOrder']); $i++) {
|
||||
$ordering[$this->details['alphabeticalOrder'][$i]] = $i + 1;
|
||||
}
|
||||
usort($words, function($word_a, $word_b) use($sort_by, $ordering) {
|
||||
if ($word_a[$sort_by] === $word_b[$sort_by]) return 0;
|
||||
|
||||
$a_letters = str_split($word_a[$sort_by]);
|
||||
$b_letters = str_split($word_b[$sort_by]);
|
||||
|
||||
for ($i = 0; $i < count($a_letters); $i++) {
|
||||
$a = $a_letters[$i];
|
||||
if (!isset($b_letters[$i])) {
|
||||
return 1;
|
||||
}
|
||||
$b = $b_letters[$i];
|
||||
if (!isset($ordering[$a]) && !isset($ordering[$b])) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($ordering[$a])) {
|
||||
return 1;
|
||||
}
|
||||
if (!isset($ordering[$b])) {
|
||||
return -1;
|
||||
}
|
||||
if ($ordering[$a] === $ordering[$b]) {
|
||||
if (count($a_letters) < count($b_letters) && $i === count($a_letters) - 1) {
|
||||
return -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return $ordering[$a] - $ordering[$b];
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
return $words;
|
||||
}
|
||||
|
||||
private function parseReferences($details, $dictionary_id) {
|
||||
$details = strip_tags($details);
|
||||
if (preg_match_all('/\{\{.+?\}\}/', $details, $references) !== false) {
|
||||
$references = array_unique($references[0]);
|
||||
foreach($references as $reference) {
|
||||
$word_to_find = preg_replace('/\{\{|\}\}/', '', $reference);
|
||||
$homonymn = 0;
|
||||
|
||||
if (strpos($word_to_find, ':') !== false) {
|
||||
$separator = strpos($word_to_find, ':');
|
||||
$homonymn = substr($word_to_find, $separator + 1);
|
||||
$word_to_find = substr($word_to_find, 0, $separator);
|
||||
if ($homonymn && trim($homonymn) && intval(trim($homonymn)) > 0) {
|
||||
$homonymn = intval(trim($homonymn));
|
||||
} else {
|
||||
$homonymn = false;
|
||||
}
|
||||
}
|
||||
|
||||
$target_id = false;
|
||||
$reference_ids = $this->getWordIdsWithName($dictionary_id, $word_to_find);
|
||||
|
||||
if (count($reference_ids) > 0) {
|
||||
if ($homonymn !== false && $homonymn > 0) {
|
||||
if (isset($reference_ids[$homonymn - 1])) {
|
||||
$target_id = $reference_ids[$homonymn - 1];
|
||||
}
|
||||
} else if ($homonymn !== false) {
|
||||
$target_id = $reference_ids[0];
|
||||
}
|
||||
|
||||
if ($target_id !== false) {
|
||||
if ($homonymn < 1) {
|
||||
$homonymn = 1;
|
||||
}
|
||||
$homonymn_sub_html = count($reference_ids) > 1 && $homonymn - 1 >= 0 ? '<sub>' . $homonymn . '</sub>' : '';
|
||||
$site_root = substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], $dictionary_id));
|
||||
$markdown_link = '<span class="word-reference"><a href="' . $site_root . $dictionary_id . '/' . $target_id .'" target="_blank" title="Link to Reference">'
|
||||
. '<span class="orthographic-translation">' . $this->translateOrthography($word_to_find, $dictionary_id) . '</span>' . $homonymn_sub_html
|
||||
. '</a></span>';
|
||||
$details = str_replace($reference, $markdown_link, $details);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $details;
|
||||
}
|
||||
|
||||
private function getWordIdsWithName($dictionary, $word_name) {
|
||||
if (is_numeric($dictionary)) {
|
||||
$query = "SELECT word_id FROM words WHERE dictionary=? AND name=?";
|
||||
$results = $this->db->query($query, array($dictionary, $word_name))->fetchAll();
|
||||
if ($results) {
|
||||
return array_map(function ($row) {
|
||||
return intval($row['word_id']);
|
||||
}, $results);
|
||||
}
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
private function translateOrthography($word, $dictionary) {
|
||||
if (!isset($this->translations)) {
|
||||
$this->translations = $this->getTranslations($dictionary);
|
||||
}
|
||||
foreach($this->translations as $translation) {
|
||||
$translation = array_map('trim', explode('=', $translation));
|
||||
if (count($translation) > 1 && $translation[0] !== '' && $translation[1] !== '') {
|
||||
$word = str_replace($translation[0], $translation[1], $word);
|
||||
}
|
||||
};
|
||||
return $word;
|
||||
}
|
||||
|
||||
private function getTranslations($dictionary) {
|
||||
if (is_numeric($dictionary)) {
|
||||
$query = "SELECT translations FROM dictionary_linguistics WHERE dictionary=?";
|
||||
$result = $this->db->query($query, array($dictionary))->fetch();
|
||||
if ($result) {
|
||||
return explode(PHP_EOL, $result['translations']);
|
||||
}
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
private function getWordStats() {
|
||||
$words = $this->getWordsAsEntered();
|
||||
$word_stats = array(
|
||||
'numberOfWords' => array(
|
||||
array(
|
||||
'name' => 'Total',
|
||||
'value' => count($words),
|
||||
),
|
||||
),
|
||||
'wordLength' => array(
|
||||
'shortest' => 0,
|
||||
'longest' => 0,
|
||||
'average' => 0,
|
||||
),
|
||||
'letterDistribution' => array(
|
||||
/* array(
|
||||
'letter' => '',
|
||||
'number' => 0,
|
||||
'percentage' => 0.00,
|
||||
) */
|
||||
),
|
||||
'totalLetters' => 0,
|
||||
);
|
||||
|
||||
foreach($this->details['partsOfSpeech'] as $part_of_speech) {
|
||||
$words_with_part_of_speech = array_filter($words, function ($word) use($part_of_speech) {
|
||||
return $word['part_of_speech'] === $part_of_speech;
|
||||
});
|
||||
$word_stats['numberOfWords'][] = array(
|
||||
'name' => $part_of_speech,
|
||||
'value' => count($words_with_part_of_speech),
|
||||
);
|
||||
};
|
||||
|
||||
$word_stats['numberOfWords'][] = array(
|
||||
'name' => 'Unclassified',
|
||||
'value' => count(array_filter($words, function ($word) {
|
||||
return !in_array($word['part_of_speech'], $this->details['partsOfSpeech']);
|
||||
})),
|
||||
);
|
||||
|
||||
$total_letters = 0;
|
||||
$number_of_letters = array();
|
||||
|
||||
foreach($words as $word) {
|
||||
$shortest_word = $word_stats['wordLength']['shortest'];
|
||||
$longest_word = $word_stats['wordLength']['longest'];
|
||||
$word_letters = str_split($word['name']);
|
||||
$letters_in_word = count($word_letters);
|
||||
|
||||
$total_letters += $letters_in_word;
|
||||
|
||||
if ($shortest_word === 0 || $letters_in_word < $shortest_word) {
|
||||
$word_stats['wordLength']['shortest'] = $letters_in_word;
|
||||
}
|
||||
|
||||
if ($longest_word === 0 || $letters_in_word > $longest_word) {
|
||||
$word_stats['wordLength']['longest'] = $letters_in_word;
|
||||
}
|
||||
|
||||
foreach($word_letters as $letter) {
|
||||
$letterToUse = $this->details['settings']['caseSensitive'] ? $letter : strtolower($letter);
|
||||
if (!isset($number_of_letters[$letterToUse])) {
|
||||
$number_of_letters[$letterToUse] = 1;
|
||||
} else {
|
||||
$number_of_letters[$letterToUse]++;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
$word_stats['totalLetters'] = $total_letters;
|
||||
$word_stats['wordLength']['average'] = count($words) > 0 ? round($total_letters / count($words)) : 0;
|
||||
|
||||
foreach ($number_of_letters as $letter => $number) {
|
||||
if (isset($number_of_letters[$letter])) {
|
||||
$word_stats['letterDistribution'][] = array(
|
||||
'letter' => $letter,
|
||||
'number' => $number,
|
||||
'percentage' => $number / $total_letters,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
usort($word_stats['letterDistribution'], function ($a, $b) {
|
||||
if ($a['percentage'] === $b['percentage']) return 0;
|
||||
return ($a['percentage'] > $b['percentage']) ? -1 : 1;
|
||||
});
|
||||
|
||||
return $word_stats;
|
||||
}
|
||||
}
|
|
@ -14,11 +14,11 @@ switch ($view) {
|
|||
$html = file_get_contents(realpath(dirname(__FILE__) . '/./template-view.html'));
|
||||
$dict = isset($_GET['dict']) ? $_GET['dict'] : false;
|
||||
if ($dict !== false) {
|
||||
require_once(realpath(dirname(__FILE__) . '/./api/Dictionary.php'));
|
||||
$dictionary = new Dictionary();
|
||||
$dictionary_data = $dictionary->getPublicDictionaryDetails($dict);
|
||||
require_once(realpath(dirname(__FILE__) . '/./api/PublicDictionary.php'));
|
||||
$dictionary = new PublicDictionary($dict);
|
||||
$dictionary_data = $dictionary->details;
|
||||
if ($dictionary_data !== false) {
|
||||
$dictionary_data['words'] = $dictionary->getPublicDictionaryWords($dict);
|
||||
$dictionary_data['words'] = $dictionary->words;
|
||||
$html = str_replace('{{dict}}', $dict, $html);
|
||||
$html = str_replace('{{dict_name}}', $dictionary_data['name'] . ' ' . $dictionary_data['specification'], $html);
|
||||
$html = str_replace('{{public_name}}', $dictionary_data['createdBy'], $html);
|
||||
|
@ -39,9 +39,9 @@ switch ($view) {
|
|||
$dict = isset($_GET['dict']) ? $_GET['dict'] : false;
|
||||
$word = isset($_GET['word']) ? $_GET['word'] : false;
|
||||
if ($dict !== false && $word !== false) {
|
||||
require_once(realpath(dirname(__FILE__) . '/./api/Dictionary.php'));
|
||||
$dictionary = new Dictionary();
|
||||
$dictionary_data = $dictionary->getPublicDictionaryDetails($dict);
|
||||
require_once(realpath(dirname(__FILE__) . '/./api/PublicDictionary.php'));
|
||||
$dictionary = new PublicDictionary($dict, true);
|
||||
$dictionary_data = $dictionary->details;
|
||||
if ($dictionary_data !== false) {
|
||||
$dictionary_name = $dictionary_data['name'] . ' ' . $dictionary_data['specification'];
|
||||
$word_data = $dictionary->getSpecificPublicDictionaryWord($dict, $word);
|
||||
|
@ -119,7 +119,7 @@ switch ($view) {
|
|||
oldLoad && oldLoad();
|
||||
if (UpUp) {
|
||||
UpUp.start({
|
||||
'cache-version': '2.0.2',
|
||||
'cache-version': '2.1.0',
|
||||
'content-url': 'offline.html',
|
||||
'assets': [
|
||||
\"" . implode('","', $files) . "\"
|
||||
|
|
Loading…
Reference in New Issue