Skip to content

Commit 2becc36

Browse files
Merge pull request #822 from sillsdev/develop
Deploy Issue-818
2 parents 41b26f4 + ee1ccac commit 2becc36

File tree

7 files changed

+302
-40
lines changed

7 files changed

+302
-40
lines changed

composer.lock

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wp-resources/plugins/sil-dictionary-webonary/webonary/Webonary_Cloud.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ private static function isValidDictionary($dictionary): bool
3838
return is_object($dictionary) && isset($dictionary->_id);
3939
}
4040

41-
private static function isValidEntry($entry): bool
41+
public static function isValidEntry($entry): bool
4242
{
4343
return is_object($entry) && isset($entry->_id);
4444
}
@@ -292,7 +292,12 @@ private static function validatePermissionToPost($header): stdClass
292292
public static function entryToFakePost($entry): WP_Post
293293
{
294294
$allow_comments = get_option('default_comment_status') == 'open';
295-
$updated_timestamp = strtotime($entry->updatedAt);
295+
296+
if (is_object($entry->updatedAt))
297+
$updated_timestamp = intval($entry->updatedAt->{'$date'}->{'$numberLong'} / 1000);
298+
else
299+
$updated_timestamp = strtotime($entry->updatedAt);
300+
296301
$post_date = date('Y-m-d H:i:s', $updated_timestamp);
297302
$post_title = $entry->mainheadword[0]->value ?? '';
298303

@@ -775,6 +780,7 @@ public static function resetDictionary($dictionaryId): array
775780
$language = $dictionary->mainLanguage;
776781
update_option('languagecode', $language->lang);
777782
update_option('totalConfiguredEntries', $language->entriesCount);
783+
update_option('mongo_sem_domain', false);
778784

779785
if (!empty($language->letters))
780786
update_option('vernacular_alphabet', self::filterLetterList($language->letters, true));
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
<?php
2+
3+
use MongoDB\Client;
4+
use MongoDB\Database;
5+
use MongoDB\Driver\ServerApi;
6+
use MongoDB\Model\BSONDocument;
7+
8+
class Webonary_MongoDB
9+
{
10+
private static ?Database $database = null;
11+
private static ?string $sem_domain_abbrev_field = null;
12+
private static ?string $site_collection_name = null;
13+
14+
private const DB_COLLATION_LOCALES = [
15+
'af',
16+
'sq',
17+
'am',
18+
'ar',
19+
'hy',
20+
'as',
21+
'az',
22+
'be',
23+
'bn',
24+
'bs',
25+
'bg',
26+
'my',
27+
'ca',
28+
'chr',
29+
'zh',
30+
'zh_Hant',
31+
'hr',
32+
'cs',
33+
'da',
34+
'nl',
35+
'dz',
36+
'en',
37+
'en_US',
38+
'en_US_POSIX',
39+
'eo',
40+
'et',
41+
'ee',
42+
'fo',
43+
'fil',
44+
'fr',
45+
'fr_CA',
46+
'gl',
47+
'ka',
48+
'de',
49+
'de_AT',
50+
'el',
51+
'gu',
52+
'ha',
53+
'haw',
54+
'he',
55+
'hi',
56+
'hu',
57+
'is',
58+
'ig',
59+
'smn',
60+
'id',
61+
'ga',
62+
'it',
63+
'ja',
64+
'kl',
65+
'kn',
66+
'kk',
67+
'kok',
68+
'ko',
69+
'ky',
70+
'lkt',
71+
'lo',
72+
'lv',
73+
'ln',
74+
'lt',
75+
'dsb',
76+
'lb',
77+
'mk',
78+
'ms',
79+
'ml',
80+
'mt',
81+
'mr',
82+
'mn',
83+
'ne',
84+
'se',
85+
'nb',
86+
'nn',
87+
'or',
88+
'om',
89+
'ps',
90+
'fa',
91+
'fa_AF',
92+
'pl',
93+
'pt',
94+
'pa',
95+
'ro',
96+
'ru',
97+
'sr',
98+
'sr_Latn',
99+
'si',
100+
'sk',
101+
'sl',
102+
'es',
103+
'sw',
104+
'sv',
105+
'ta',
106+
'te',
107+
'th',
108+
'bo',
109+
'to',
110+
'tr',
111+
'uk',
112+
'hsb',
113+
'ur',
114+
'ug',
115+
'vi',
116+
'wae',
117+
'cy',
118+
'yi',
119+
'yo',
120+
'zu',
121+
];
122+
private const STRENGTH_CI_AI = 1;
123+
private const STRENGTH_CI_AS = 2;
124+
private const STRENGTH_CS_AS = 3;
125+
126+
/**
127+
* @return Database
128+
* @noinspection DuplicatedCode
129+
*/
130+
public static function GetMongoDB(): Database
131+
{
132+
if (!is_null(self::$database))
133+
return self::$database;
134+
135+
$settings = WEBONARY_MONGO;
136+
$catalog = $settings['cat'];
137+
138+
$uri = "mongodb+srv://{$settings['usr']}:{$settings['pwd']}@{$settings['url']}/?retryWrites=true&w=majority&appName=Cluster0";
139+
140+
// set the version of the Stable API on the client
141+
$api_version = new ServerApi(ServerApi::V1);
142+
143+
// create a new client and connect to the server
144+
$client = new Client($uri, [], ['serverApi' => $api_version]);
145+
146+
self::$database = $client->$catalog;
147+
148+
return self::$database;
149+
}
150+
151+
private static function GetSiteCollectionName(): string
152+
{
153+
if (is_null(self::$site_collection_name))
154+
self::$site_collection_name = 'webonaryEntries_' . Webonary_Cloud::getBlogDictionaryId();
155+
156+
return self::$site_collection_name;
157+
}
158+
159+
private static function GetSemDomainAbbrevField(): string
160+
{
161+
if (!is_null(self::$sem_domain_abbrev_field))
162+
return self::$sem_domain_abbrev_field;
163+
164+
$found = get_option('mongo_sem_domain');
165+
166+
if (!empty($found['value']) && $found['expires'] > time()) {
167+
self::$sem_domain_abbrev_field = $found['value'];
168+
return self::$sem_domain_abbrev_field;
169+
}
170+
171+
$db = self::GetMongoDB();
172+
$collection = self::GetSiteCollectionName();
173+
174+
/** @var BSONDocument $doc */
175+
$doc = $db->$collection->findOne(
176+
['senses.semanticdomains' =>
177+
[
178+
'$ne' => null
179+
]
180+
],
181+
['projection' => ['_id' => 1, 'senses.semanticdomains' => 1]]
182+
);
183+
184+
$keys = array_keys((array)$doc->senses[0]->semanticdomains[0]);
185+
$abbrev = array_find($keys, function($val) { return str_starts_with($val, 'abbrev'); });
186+
self::$sem_domain_abbrev_field = $abbrev;
187+
188+
// remember this for 24 hours
189+
update_option('mongo_sem_domain', ['value' => $abbrev, 'expires' => time() + (60 * 60 * 24)]);
190+
191+
return self::$sem_domain_abbrev_field;
192+
}
193+
194+
/**
195+
* @param string $sem_domain_text
196+
* @param string $sem_domain_code
197+
* @param int $page_num
198+
* @param int $posts_per_page
199+
* @return array
200+
* @throws Exception
201+
*/
202+
public static function DoSemanticDomainSearch(string $sem_domain_text, string $sem_domain_code, int $page_num, int $posts_per_page): array
203+
{
204+
$db = self::GetMongoDB();
205+
$collection = self::GetSiteCollectionName();
206+
207+
// 'senses.semanticdomains.name.value'
208+
if (empty($sem_domain_code)) {
209+
$find = ['senses.semanticdomains.name.value' => $sem_domain_text];
210+
}
211+
else {
212+
$find = [
213+
'senses.semanticdomains.' . self::GetSemDomainAbbrevField() . '.value' =>
214+
[
215+
'$in' => [
216+
$sem_domain_code,
217+
new MongoDB\BSON\Regex('^' . preg_quote($sem_domain_code, '/'), 'i')
218+
]
219+
]
220+
];
221+
}
222+
223+
$count = $db->$collection->countDocuments($find);
224+
$posts = [];
225+
226+
/** @var BSONDocument[] $docs */
227+
$docs = $db->$collection->find(
228+
$find,
229+
[
230+
'projection' => [
231+
'_id' => 1,
232+
'dictionaryId' => 1,
233+
'guid' => 1,
234+
'updatedAt' => 1,
235+
'mainheadword' => 1,
236+
'displayXhtml' => 1
237+
],
238+
'limit' => $posts_per_page,
239+
'skip' => $posts_per_page * ($page_num - 1),
240+
// 'collation' => [
241+
// 'locale' => self::GetLocale($lang_code),
242+
// 'strength' => self::STRENGTH_CI_AI
243+
// ]
244+
]
245+
)->toArray();
246+
247+
foreach (json_decode(json_encode($docs), false) as $key => $entry) {
248+
if (Webonary_Cloud::isValidEntry($entry)) {
249+
$post = Webonary_Cloud::entryToFakePost($entry);
250+
$posts[$key] = $post;
251+
}
252+
}
253+
return [
254+
$count,
255+
$posts
256+
];
257+
}
258+
259+
private static function GetLocale($lang_code): string
260+
{
261+
return in_array($lang_code, self::DB_COLLATION_LOCALES) ? $lang_code : 'vi';
262+
}
263+
}

0 commit comments

Comments
 (0)