Skip to content

Commit c0e0e16

Browse files
committed
Migrated over from Source Text Parser
This is now running mostly without issues. Still a good amount of work to do before it is ready to really work.
1 parent eb460f3 commit c0e0e16

15 files changed

+2459
-0
lines changed

Controllers/IndexController.php

Lines changed: 363 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,363 @@
1+
<?php
2+
3+
/***********
4+
*
5+
* Source Text Library
6+
* https://developers.urbanmonastic.org/
7+
*
8+
* © Paul Prins
9+
* https://paulprins.net https://paul.build/
10+
*
11+
* Licensed under MIT - For full license, view the LICENSE distributed with this source.
12+
*
13+
***********/
14+
15+
namespace UrbanMonastics\SourceTextLibrary\Controllers;
16+
17+
use UrbanMonastics\SourceTextLibrary\SourceTextLibrary as SourceTextLibrary;
18+
19+
class Index{
20+
// Manage the location, and loading of the various files from the location
21+
protected $VersionFolders = array(); // Which folder abbreviations do we have
22+
protected $PathContents = array();
23+
protected $index;
24+
25+
/* -- Reference to Parent -- */
26+
private $SourceTextLibrary;
27+
private $ActiveVersion;
28+
29+
function __construct( SourceTextLibrary &$SourceTextLibrary ){
30+
$this->SourceTextLibrary = $SourceTextLibrary;
31+
}
32+
33+
34+
public function getIssues(){
35+
if( !is_array( $this->index ) || !array_key_exists( 'Issues', $this->index ) )
36+
return array("There is no index");
37+
38+
return $this->index['Issues'];
39+
}
40+
41+
42+
public function loadLibrary( string $libraryPath ){
43+
if( !is_string( $libraryPath ) || is_null( $libraryPath ) || !file_exists( $libraryPath ) ){
44+
throw new \Exception('loadLibrary - Supplied path is not a valid library location');
45+
}
46+
47+
if( is_null( $this->index ) ){
48+
$this->index = array();
49+
$this->index['Version'] = SourceTextLibrary::version;
50+
$this->index['Sources'] = array();
51+
// ['Abbreviation'] = array('Path' => PathToSourceDirectory, 'Abbreviation', 'Title', 'Type' => null, 'SecondaryType' => null, 'Segments' => , 'Verses', '' )
52+
$this->index['SourceVersions'] = array();
53+
$this->index['Issues'] = array(); // Just a list of issues
54+
}
55+
56+
57+
$libraryPath = rtrim( $libraryPath, '/' ) . '/';
58+
59+
$LibraryLevel = scandir( $libraryPath );
60+
foreach( $LibraryLevel as $TextAbbrv ){
61+
$TextPath = $libraryPath . $TextAbbrv . '/';
62+
63+
if( !is_dir( $TextPath ) || in_array($TextAbbrv, array('.', '..', '.DS_Store') ) ){
64+
continue;
65+
}
66+
67+
// Check and ensure that this directory has a source.json file (or that one already has been indexed).
68+
if( !file_exists( $TextPath . 'source.json' ) && !array_key_exists( $TextAbbrv, $this->index['Sources'] ) ){
69+
throw new \Exception('loadLibrary - Directory is missing the required source.json file: ' . $TextPath);
70+
}
71+
72+
73+
if( file_exists( $TextPath . 'source.json' ) ){
74+
$ThisSource = $this->SourceTextLibrary->_loadJson( $TextPath . 'source.json' );
75+
76+
if( empty( $ThisSource ) ){
77+
throw new \Exception('loadLibrary - Malformed source file found at: \'' . $TextPath . 'source.json\'' );
78+
}
79+
80+
if( $TextAbbrv != $ThisSource['Abbreviation'] ){
81+
$this->index['Issues'][] = "Mismatched abbreviations between folder name and source.json: " . $TextPath;
82+
}
83+
84+
85+
86+
$this->index['Sources'][$TextAbbrv] = array('Path' => $TextPath,
87+
'SourcePath' => $TextPath . 'source.json',
88+
'Abbreviation' => $TextAbbrv,
89+
'Title' => array(),
90+
'Type' => null,
91+
'SecondaryType' => null,
92+
'Segments' => 'None',
93+
'Verses' => false,
94+
'SegmentTitles' => false,
95+
'Versions' => array(),
96+
'VerseCounts' => NULL );
97+
98+
if( array_key_exists( 'Title', $ThisSource ) ){
99+
$this->index['Sources'][$TextAbbrv]['Title'] = (array) $ThisSource['Title'];
100+
}else{
101+
$this->index['Issues'][] = "Source is missing its Title definition: " . $TextPath . "source.json";
102+
}
103+
104+
105+
$allowedSourceTypes = $this->SourceTextLibrary->getAllowedSourceTypes();
106+
$allowedSourceSegments = $this->SourceTextLibrary->getAllowedSourceSegments();
107+
if( array_key_exists( 'Type', $ThisSource ) && in_array( $ThisSource['Type'], $allowedSourceTypes ) ){
108+
$this->index['Sources'][$TextAbbrv]['Type'] = (string) $ThisSource['Type'];
109+
}else{
110+
$this->index['Issues'][] = "Source has an invalid Type definition: " . $TextPath . "source.json";
111+
}
112+
113+
if( array_key_exists( 'SecondaryType', $ThisSource ) && !is_null( $ThisSource['SecondaryType'] ) ){
114+
$this->index['Sources'][$TextAbbrv]['SecondaryType'] = (string) $ThisSource['SecondaryType'];
115+
}
116+
117+
if( array_key_exists( 'Segments', $ThisSource ) && in_array( $ThisSource['Segments'], $allowedSourceSegments ) ){
118+
$this->index['Sources'][$TextAbbrv]['Segments'] = (string) $ThisSource['Segments'];
119+
}else{
120+
$this->index['Issues'][] = "Source has an invalid Segments definition: " . $TextPath . "source.json";
121+
}
122+
123+
124+
if( array_key_exists( 'Verses', $ThisSource ) ){
125+
if( is_bool( $ThisSource['Verses'] ) ){
126+
$this->index['Sources'][$TextAbbrv]['Verses'] = (bool) $ThisSource['Verses'];
127+
128+
if( $ThisSource['Verses'] ){
129+
$this->index['Sources'][$TextAbbrv]['VerseCounts'] = array();
130+
}
131+
}else{
132+
$this->index['Issues'][] = "Source has an invalid Verses definition: " . $TextPath . "source.json";
133+
}
134+
}
135+
136+
if( array_key_exists( 'SegmentTitles', $ThisSource ) ){
137+
if( is_bool( $ThisSource['SegmentTitles'] ) ){
138+
$this->index['Sources'][$TextAbbrv]['SegmentTitles'] = (bool) $ThisSource['SegmentTitles'];
139+
}else{
140+
$this->index['Issues'][] = "Source has an invalid SegmentTitles definition: " . $TextPath . "source.json";
141+
}
142+
}
143+
}
144+
145+
146+
147+
148+
//
149+
//
150+
// Lets index the version directories
151+
$TextLevel = scandir( $TextPath );
152+
foreach( $TextLevel as $VersionAbbrv ){
153+
$VersionPath = $TextPath . $VersionAbbrv . '/';
154+
if( !is_dir( $VersionPath ) || in_array($VersionAbbrv, array('.', '..', '.DS_Store') ) ){
155+
continue;
156+
}
157+
158+
if( !$this->SourceTextLibrary->checkVersion( $VersionAbbrv ) ){
159+
$Issue = "Unknown version found when scanning directories: " . $VersionAbbrv;
160+
if( !in_array( $Issue, $this->index['Issues'] ) ){
161+
$this->index['Issues'][] = $Issue;
162+
}
163+
continue; // This version isn't registered, so lets skip it
164+
}
165+
166+
167+
if( !array_key_exists($VersionAbbrv, $this->index['SourceVersions'] ) ){
168+
$this->index['SourceVersions'][$VersionAbbrv] = array();
169+
}
170+
171+
if( !in_array($TextAbbrv, $this->index['SourceVersions'][$VersionAbbrv] ) ){
172+
$this->index['SourceVersions'][$VersionAbbrv][] = $TextAbbrv;
173+
}
174+
175+
$this->index['SourceVersions'][$VersionAbbrv][] = $TextAbbrv;
176+
177+
$this->index['Sources'][$TextAbbrv]['Versions'][$VersionAbbrv] = array('Path' => $VersionPath,
178+
'Text' => NULL,
179+
'Chapters' => NULL,
180+
'Abbreviations' => NULL );
181+
switch( $this->index['Sources'][$TextAbbrv]['Segments'] ){
182+
case 'None':
183+
$this->index['Sources'][$TextAbbrv]['Versions'][$VersionAbbrv]['Text'] = array();
184+
break;
185+
case 'Chapters':
186+
$this->index['Sources'][$TextAbbrv]['Versions'][$VersionAbbrv]['Chapters'] = array();
187+
break;
188+
case 'Abbreviations':
189+
$this->index['Sources'][$TextAbbrv]['Versions'][$VersionAbbrv]['Abbreviations'] = array();
190+
break;
191+
}
192+
193+
194+
// Sort the Array to ensure it is nicer to read
195+
ksort( $this->index['Sources'][$TextAbbrv]['Versions'] );
196+
197+
198+
199+
$VersionLevel = scandir( $VersionPath );
200+
foreach( $VersionLevel as $FileName ){
201+
$FilePath = $VersionPath . $FileName;
202+
if( !is_file( $FilePath ) || in_array( $FileName, array('.', '..', '.DS_Store', '_template.json') ) ){
203+
continue;
204+
}
205+
206+
// Load the file contents
207+
$FileContents = $this->SourceTextLibrary->_loadJson( $FilePath );
208+
if( !is_array( $FileContents ) ){
209+
$this->index['Issues'][] = "Text file is not valid JSON and cannot be loaded: " . $FilePath;
210+
continue;
211+
}
212+
213+
214+
//
215+
// Lets check for some common issues
216+
if( !array_key_exists( 'TextAbbreviation', $FileContents ) ){
217+
$this->index['Issues'][] = "Text file does not have a TextAbbreviation value: " . $FilePath;
218+
}else if( $FileContents['TextAbbreviation'] !== str_replace('.json', '', $FileName ) ){
219+
$this->index['Issues'][] = "Text file value for TextAbbreviation does not match the filename: '" . $FileContents['TextAbbreviation'] . "' should match '". str_replace('.json', '', $FileName ) . "': " . $FilePath;
220+
}
221+
222+
if( !array_key_exists( 'SourceAbbreviation', $FileContents ) ){
223+
$this->index['Issues'][] = "Text file does not have a SourceAbbreviation value: " . $FilePath;
224+
}else if( $TextAbbrv !== $FileContents['SourceAbbreviation'] ){
225+
$this->index['Issues'][] = "Text file value for SourceAbbreviation does not match the parent directory: '" . $FileContents['SourceAbbreviation'] . "' should match '". $TextAbbrv . "': " . $FilePath;
226+
227+
}
228+
229+
if( $this->index['Sources'][$TextAbbrv]['SegmentTitles'] == false && !empty( $FileContents['Title'] ) ){
230+
$this->index['Issues'][] = "Text file has a Title value when the source does not support this: " . $FilePath;
231+
}
232+
// Lets check for some common issues
233+
//
234+
235+
236+
237+
$TextIndex = array('TextAbbreviation' => $FileContents['TextAbbreviation'],
238+
'FilePath' => $FilePath,
239+
'HasContent' => false);
240+
241+
242+
243+
// Check if it is stored in Text or Verses
244+
$TheseVerses = NULL;
245+
$TextIndex['Verses'] = NULL;
246+
if( $this->index['Sources'][$TextAbbrv]['Verses'] ){
247+
if( array_key_exists('Verses', $FileContents ) ){
248+
$TextIndex['Verses'] = array();
249+
foreach( $FileContents['Verses'] as $v => $c ){
250+
if( strlen( trim( $c ) ) > 0 )
251+
$TextIndex['Verses'][] = (int) $v; // Only list non-empty verses
252+
}
253+
254+
$Max = 0;
255+
if( !empty( $TextIndex['Verses'] ) ){
256+
$Max = max( $TextIndex['Verses'] );
257+
}
258+
259+
if( !array_key_exists( $FileContents['TextAbbreviation'], $this->index['Sources'][$TextAbbrv]['VerseCounts'] ) || $Max > $this->index['Sources'][$TextAbbrv]['VerseCounts'][$FileContents['TextAbbreviation']] ){
260+
if( !empty( $TextIndex['Verses'] ) ){
261+
$this->index['Sources'][$TextAbbrv]['VerseCounts'][$FileContents['TextAbbreviation']] = max( $TextIndex['Verses'] );
262+
}else{
263+
$this->index['Sources'][$TextAbbrv]['VerseCounts'][$FileContents['TextAbbreviation']] = 0;
264+
}
265+
}
266+
267+
ksort( $this->index['Sources'][$TextAbbrv]['VerseCounts'] );
268+
}
269+
270+
if( !empty( $TextIndex['Verses'] ) )
271+
$TextIndex['HasContent'] = true;
272+
}else{
273+
if( !empty( $FileContents['Text'] ) )
274+
$TextIndex['HasContent'] = true;
275+
}
276+
277+
278+
switch( $this->index['Sources'][$TextAbbrv]['Segments'] ){
279+
case 'None':
280+
$this->index['Sources'][$TextAbbrv]['Versions'][$VersionAbbrv]['Text'] = $TextIndex;
281+
break;
282+
283+
case 'Chapters':
284+
$ChapterNumber = ltrim( str_ireplace( array('chapter-', '.json'), array('', ''), $FileName ), '0' );
285+
$this->index['Sources'][$TextAbbrv]['Versions'][$VersionAbbrv]['Chapters'][$ChapterNumber] = $TextIndex;
286+
287+
ksort( $this->index['Sources'][$TextAbbrv]['Versions'][$VersionAbbrv]['Chapters'] );
288+
break;
289+
290+
case 'Abbreviations':
291+
$ThisAbbrv = str_ireplace( '.json', '', $FileName );
292+
$this->index['Sources'][$TextAbbrv]['Versions'][$VersionAbbrv]['Abbreviations'][$ThisAbbrv] = $TextIndex;
293+
294+
ksort( $this->index['Sources'][$TextAbbrv]['Versions'][$VersionAbbrv]['Abbreviations'] );
295+
break;
296+
}
297+
}
298+
299+
300+
}
301+
// Lets index the version directories
302+
303+
304+
305+
}
306+
307+
308+
//
309+
// Lets do some quick source checking
310+
foreach( $this->index as $TextAbrv => $Source ){
311+
// if( ){
312+
// $this->index['Issues'][] = "Text file has a Title value when the source does not support this: " . $FilePath;
313+
// }
314+
}
315+
316+
317+
318+
var_dump( $this->index['Issues'] );
319+
return $this;
320+
}
321+
322+
public function exportIndex(){
323+
$tmp = $this->index;
324+
$tmp['VerificationKey'] = md5( json_encode( $this->index, JSON_UNESCAPED_UNICODE ) );
325+
326+
return $tmp;
327+
}
328+
public function importIndex( array $ExportedIndex ){
329+
//
330+
// First Check - ensure that the Version numbers match
331+
if( !array_key_exists('Version', $ExportedIndex ) || $ExportedIndex['Version'] != SourceTextLibrary::version ){
332+
throw new \Exception('Unable to import the Source Text index. The Version value does not match the library, or is missing');
333+
}
334+
// First Check - Passed
335+
//
336+
337+
//
338+
// Second Check - ensure that the MD5 Hash sum matches
339+
if( !array_key_exists('VerificationKey', $ExportedIndex ) ){
340+
throw new \Exception('Unable to import the Source Text index. The VerificationKey is missing from the index.');
341+
}
342+
343+
$VerificationKey = $ExportedIndex['VerificationKey'];
344+
unset($ExportedIndex['VerificationKey'] );
345+
if( $VerificationKey !== md5( json_encode( $ExportedIndex, JSON_UNESCAPED_UNICODE ) )){
346+
throw new \Exception('Unable to import the Source Text index. The VerificationKey does not match the supplied index.');
347+
}
348+
// Second Check - Passed
349+
//
350+
351+
352+
$this->index = $ExportedIndex;
353+
354+
var_dump("It was verified");
355+
return true;
356+
}
357+
358+
359+
public function clear(){
360+
361+
return $this;
362+
}
363+
}

0 commit comments

Comments
 (0)