1ef0d468bSGreg Roach<?php 2ef0d468bSGreg Roach/** 3ef0d468bSGreg Roach * webtrees: online genealogy 4*8fcd0d32SGreg Roach * Copyright (C) 2019 webtrees development team 5ef0d468bSGreg Roach * This program is free software: you can redistribute it and/or modify 6ef0d468bSGreg Roach * it under the terms of the GNU General Public License as published by 7ef0d468bSGreg Roach * the Free Software Foundation, either version 3 of the License, or 8ef0d468bSGreg Roach * (at your option) any later version. 9ef0d468bSGreg Roach * This program is distributed in the hope that it will be useful, 10ef0d468bSGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 11ef0d468bSGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12ef0d468bSGreg Roach * GNU General Public License for more details. 13ef0d468bSGreg Roach * You should have received a copy of the GNU General Public License 14ef0d468bSGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 15ef0d468bSGreg Roach */ 16e7f56f2aSGreg Roachdeclare(strict_types=1); 17e7f56f2aSGreg Roach 1876692c8bSGreg Roachnamespace Fisharebest\Webtrees\Report; 19ef0d468bSGreg Roach 20208e9f76SGreg Roachuse DomainException; 217774ce41SGreg Roachuse Exception; 22299d100dSGreg Roach 23ef0d468bSGreg Roach/** 24ef0d468bSGreg Roach * Class ReportParserBase 25ef0d468bSGreg Roach */ 26c1010edaSGreg Roachclass ReportParserBase 27c1010edaSGreg Roach{ 28ef0d468bSGreg Roach /** @var resource The XML parser */ 29a6f13a4aSGreg Roach protected $xml_parser; 30ef0d468bSGreg Roach 31ef0d468bSGreg Roach /** @var string Text contents of tags */ 32ef0d468bSGreg Roach protected $text = ''; 33ef0d468bSGreg Roach 34ef0d468bSGreg Roach /** 35ef0d468bSGreg Roach * Create a parser for a report 36ef0d468bSGreg Roach * 37ef0d468bSGreg Roach * @param string $report The XML filename 387774ce41SGreg Roach * 397774ce41SGreg Roach * @throws Exception 40ef0d468bSGreg Roach */ 4176f666f4SGreg Roach public function __construct(string $report) 42c1010edaSGreg Roach { 43ef0d468bSGreg Roach $this->xml_parser = xml_parser_create(); 448a4ee39cSGreg Roach 45ef0d468bSGreg Roach xml_parser_set_option($this->xml_parser, XML_OPTION_CASE_FOLDING, false); 468a4ee39cSGreg Roach 478a4ee39cSGreg Roach xml_set_element_handler( 488a4ee39cSGreg Roach $this->xml_parser, 498a4ee39cSGreg Roach function ($parser, string $name, array $attrs) { 508a4ee39cSGreg Roach $this->startElement($parser, $name, $attrs); 518a4ee39cSGreg Roach }, 528a4ee39cSGreg Roach function ($parser, string $name) { 538a4ee39cSGreg Roach $this->endElement($parser, $name); 548a4ee39cSGreg Roach } 558a4ee39cSGreg Roach ); 568a4ee39cSGreg Roach 578a4ee39cSGreg Roach xml_set_character_data_handler( 588a4ee39cSGreg Roach $this->xml_parser, 598a4ee39cSGreg Roach function ($parser, $data) { 608a4ee39cSGreg Roach $this->characterData($parser, $data); 618a4ee39cSGreg Roach } 628a4ee39cSGreg Roach ); 63ef0d468bSGreg Roach 64ef0d468bSGreg Roach $fp = fopen($report, 'r'); 658a4ee39cSGreg Roach 667774ce41SGreg Roach if ($fp === false) { 677774ce41SGreg Roach throw new Exception('Cannot open ' . $report); 687774ce41SGreg Roach } 697774ce41SGreg Roach 70ef0d468bSGreg Roach while (($data = fread($fp, 4096))) { 71ef0d468bSGreg Roach if (!xml_parse($this->xml_parser, $data, feof($fp))) { 72208e9f76SGreg Roach throw new DomainException(sprintf( 73ef0d468bSGreg Roach 'XML error: %s at line %d', 74ef0d468bSGreg Roach xml_error_string(xml_get_error_code($this->xml_parser)), 75ef0d468bSGreg Roach xml_get_current_line_number($this->xml_parser) 76ef0d468bSGreg Roach )); 77ef0d468bSGreg Roach } 78ef0d468bSGreg Roach } 79ef0d468bSGreg Roach 807774ce41SGreg Roach fclose($fp); 817774ce41SGreg Roach 82ef0d468bSGreg Roach xml_parser_free($this->xml_parser); 83ef0d468bSGreg Roach } 84ef0d468bSGreg Roach 85ef0d468bSGreg Roach /** 86ef0d468bSGreg Roach * XML handler for an opening (or self-closing) tag. 87ef0d468bSGreg Roach * 88ef0d468bSGreg Roach * @param resource $parser The resource handler for the xml parser 89ef0d468bSGreg Roach * @param string $name The name of the xml element parsed 90ef0d468bSGreg Roach * @param string[] $attrs An array of key value pairs for the attributes 9118d7a90dSGreg Roach * 9218d7a90dSGreg Roach * @return void 93ef0d468bSGreg Roach */ 94208e9f76SGreg Roach protected function startElement($parser, string $name, array $attrs) 95c1010edaSGreg Roach { 96a6f13a4aSGreg Roach $method = $name . 'StartHandler'; 97208e9f76SGreg Roach 98ef0d468bSGreg Roach if (method_exists($this, $method)) { 99ef0d468bSGreg Roach $this->$method($attrs); 100ef0d468bSGreg Roach } 101ef0d468bSGreg Roach } 102ef0d468bSGreg Roach 103ef0d468bSGreg Roach /** 104ef0d468bSGreg Roach * XML handler for a closing tag. 105ef0d468bSGreg Roach * 106ef0d468bSGreg Roach * @param resource $parser the resource handler for the xml parser 107ef0d468bSGreg Roach * @param string $name the name of the xml element parsed 10818d7a90dSGreg Roach * 10918d7a90dSGreg Roach * @return void 110ef0d468bSGreg Roach */ 111208e9f76SGreg Roach protected function endElement($parser, string $name) 112c1010edaSGreg Roach { 113a6f13a4aSGreg Roach $method = $name . 'EndHandler'; 114208e9f76SGreg Roach 115ef0d468bSGreg Roach if (method_exists($this, $method)) { 116ef0d468bSGreg Roach $this->$method(); 117ef0d468bSGreg Roach } 118ef0d468bSGreg Roach } 119ef0d468bSGreg Roach 120ef0d468bSGreg Roach /** 121ef0d468bSGreg Roach * XML handler for character data. 122ef0d468bSGreg Roach * 123ef0d468bSGreg Roach * @param resource $parser The resource handler for the xml parser 124ef0d468bSGreg Roach * @param string $data The name of the xml element parsed 12518d7a90dSGreg Roach * 12618d7a90dSGreg Roach * @return void 127ef0d468bSGreg Roach */ 128c1010edaSGreg Roach protected function characterData($parser, $data) 129c1010edaSGreg Roach { 130ef0d468bSGreg Roach $this->text .= $data; 131ef0d468bSGreg Roach } 132ef0d468bSGreg Roach} 133