Move wordStats to backend for public view

This commit is contained in:
Robbie Antenesse 2019-07-11 17:16:46 -06:00
parent 59bf9c48e0
commit 6fed4dd4fb
3 changed files with 109 additions and 101 deletions

View File

@ -1,6 +1,6 @@
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';
@ -113,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>

View File

@ -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;

View File

@ -6,9 +6,11 @@ class PublicDictionary {
private $db;
private $token;
private $defaults;
private $original_words;
public $details;
public $words;
function __construct ($dictionary_id, $details_only = false) {
function __construct ($dictionary_id) {
$this->db = new Db();
$this->token = new Token();
@ -17,9 +19,8 @@ class PublicDictionary {
);
$this->details = $this->getPublicDictionaryDetails($dictionary_id);
if (!$details_only) {
$this->words = $this->getPublicDictionaryWords($dictionary_id);
}
$this->words = $this->getPublicDictionaryWords($dictionary_id);
$this->details['wordStats'] = $this->getWordStats();
}
public function getPublicDictionaryDetails ($dictionary) {
@ -77,9 +78,8 @@ class PublicDictionary {
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) {
$words = $this->getWordsAsEntered();
if ($words) {
return array_map(function ($row) use ($dictionary) {
return array(
'name' => $this->translateOrthography($row['name'], $dictionary),
@ -91,7 +91,7 @@ class PublicDictionary {
'createdOn' => intval($row['created_on']),
'wordId' => intval($row['word_id']),
);
}, $this->sortWords($results));
}, $this->sortWords($words));
}
}
return array();
@ -117,8 +117,15 @@ class PublicDictionary {
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) {
$this->details['original_order'] = $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
@ -256,4 +263,95 @@ class PublicDictionary {
}
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;
}
}