en_btr_backend/app/Handlers/UlbXmlImportHandler.php

194 lines
5.0 KiB
PHP

<?php
namespace App\Handlers;
use App\Book;
use App\Chapter;
use App\Word;
use App\Verse;
use DOMDocument;
use DOMElement;
/**
* UlbXmlImportHandler.php
*
* @author: Leonard Smith <leonard@acornwebconsultants.com>
* Date: 10/2/20
* Time: 8:04 AM
*/
class UlbXmlImportHandler
{
use BookXmlFilesTrait;
const REPO_FOLDER = '/ulb/';
/**
* @var array
*/
protected $availableFiles = [];
public function run() : void
{
// Collect available xml files
foreach (self::$bookXmlFiles as $name => $filename)
{
$filepath = $this->getBookXmlFilePath(self::REPO_FOLDER, $name);
if (file_exists($filepath)) {
$this->availableFiles[$name] = $filepath;
}
}
$this->loopOverXmlFiles();
}
public function loopOverXmlFiles() : void
{
foreach ($this->availableFiles as $name => $filepath) {
$this->importBook($name, $filepath);
}
}
/**
* @param string $bookTitle
* @param string $filepath
* @return Book
*/
public function importBook(string $bookTitle, string $filepath) : Book
{
/** @var DOMDocument $document */
$document = $this->openBook($filepath);
$book = Book::create([
'id' => strtolower($bookTitle),
'name' => ucfirst($bookTitle),
]);
$chapterCollection = $document->getElementsByTagName('chapter');
foreach ($chapterCollection as $chapterElem) {
$chapter = $this->importChapter($chapterElem, $book->id);
$book->chapters()->save($chapter);
}
return $book;
}
/**
* @param DOMElement $chapterElem
* @return Chapter
*/
public function importChapter(DOMElement $chapterElem, string $book_id) : Chapter
{
$chapterName = $this->parseChapterName($chapterElem);
$chapter = Chapter::create([
'id' => implode('-', [$book_id, $chapterName]),
'name' => $chapterName,
]);
$verseCollection = $chapterElem->getElementsByTagName('verse');
foreach ($verseCollection as $verseElem) {
$verse = $this->importVerse($verseElem, $chapter->id);
$chapter->verses()->save($verse);
}
return $chapter;
}
/**
* @param DOMElement $verseElem
* @return Verse
*/
public function importVerse(DOMElement $verseElem, string $chapter_id) : Verse
{
$verseNumber = $this->parseVerseNumber($verseElem);
$verse = Verse::create([
'id' => implode('-', [$chapter_id, $verseNumber]),
'name' => $verseNumber,
'greek_text' => $verseElem->getElementsByTagName('Greek')[0]->nodeValue,
'ulb_text' => $verseElem->getElementsByTagName('ULB')[0]->nodeValue,
]);
$wordCollection = $verseElem->getElementsByTagName('w');
foreach ($wordCollection as $wordElem) {
$word = $this->importWord($wordElem, $verse->id);
$verse->words()->save($word);
}
return $verse;
}
/**
* @param DOMElement $wordElem
* @return Word
*/
public function importWord(DOMElement $wordElem, string $verse_id) : Word
{
$ognt_sort = $wordElem->getAttribute('OGNTsort');
// NOTE: We have to switch things around a bit as the incoming XML file
// uses lexeme for lemma and lemma for the strongs number
$word = Word::create([
'id' => implode('-', [$verse_id, $ognt_sort]),
'ulb' => $wordElem->nodeValue,
'greek' => $wordElem->getAttribute('text'),
'lemma' => $wordElem->getAttribute('lexeme'),
'morph' => $wordElem->getAttribute('morph'),
'ognt_sort' => $ognt_sort,
'strongs_number' => $this->formatStrongsNumber($wordElem->getAttribute('lemma')),
]);
return $word;
}
/**
* Not all of the strongs numbers coming from the XML files are formatted the same. Let's fix that here.
*
* @param string $strongsNumber
* @return string
*/
protected function formatStrongsNumber(string $strongsNumber)
{
return 'G' . ltrim($strongsNumber, "Gg");
}
/**
* @param DOMElement $chapterElem
* @return string
*/
protected function parseChapterName(DOMElement $chapterElem) : string
{
$osisId = $chapterElem->getAttribute('osisID');
preg_match("|^[A-Za-z1-3]*.([0-9]*)$|", $osisId, $matches);
return $matches[1];
}
/**
* @param DOMElement $verseElem
* @return string
*/
protected function parseVerseNumber(DOMElement $verseElem) : string
{
$string = $verseElem->getAttribute('name');
preg_match("|^[A-Za-z1-3]*\s*[0-9]*:([0-9]*)$|", $string, $matches);
return $matches[1];
}
/**
* @param $filepath
* @return DOMDocument
*/
protected function openBook($filepath) : DOMDocument
{
$document = new \DOMDocument;
$document->load($filepath);
return $document;
}
}