1ef0d468bSGreg Roach<?php 2*3976b470SGreg Roach 3ef0d468bSGreg Roach/** 4ef0d468bSGreg Roach * webtrees: online genealogy 58fcd0d32SGreg Roach * Copyright (C) 2019 webtrees development team 6ef0d468bSGreg Roach * This program is free software: you can redistribute it and/or modify 7ef0d468bSGreg Roach * it under the terms of the GNU General Public License as published by 8ef0d468bSGreg Roach * the Free Software Foundation, either version 3 of the License, or 9ef0d468bSGreg Roach * (at your option) any later version. 10ef0d468bSGreg Roach * This program is distributed in the hope that it will be useful, 11ef0d468bSGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 12ef0d468bSGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13ef0d468bSGreg Roach * GNU General Public License for more details. 14ef0d468bSGreg Roach * You should have received a copy of the GNU General Public License 15ef0d468bSGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 16ef0d468bSGreg Roach */ 17e7f56f2aSGreg Roachdeclare(strict_types=1); 18e7f56f2aSGreg Roach 1976692c8bSGreg Roachnamespace Fisharebest\Webtrees\Report; 20ef0d468bSGreg Roach 21208e9f76SGreg Roachuse DomainException; 227774ce41SGreg Roachuse Exception; 23299d100dSGreg Roach 24ef0d468bSGreg Roach/** 25ef0d468bSGreg Roach * Class ReportParserBase 26ef0d468bSGreg Roach */ 27c1010edaSGreg Roachclass ReportParserBase 28c1010edaSGreg Roach{ 29ef0d468bSGreg Roach /** @var resource The XML parser */ 30a6f13a4aSGreg Roach protected $xml_parser; 31ef0d468bSGreg Roach 32ef0d468bSGreg Roach /** @var string Text contents of tags */ 33ef0d468bSGreg Roach protected $text = ''; 34ef0d468bSGreg Roach 35ef0d468bSGreg Roach /** 36ef0d468bSGreg Roach * Create a parser for a report 37ef0d468bSGreg Roach * 38ef0d468bSGreg Roach * @param string $report The XML filename 397774ce41SGreg Roach * 407774ce41SGreg Roach * @throws Exception 41ef0d468bSGreg Roach */ 4276f666f4SGreg Roach public function __construct(string $report) 43c1010edaSGreg Roach { 44ef0d468bSGreg Roach $this->xml_parser = xml_parser_create(); 458a4ee39cSGreg Roach 46ef0d468bSGreg Roach xml_parser_set_option($this->xml_parser, XML_OPTION_CASE_FOLDING, false); 478a4ee39cSGreg Roach 488a4ee39cSGreg Roach xml_set_element_handler( 498a4ee39cSGreg Roach $this->xml_parser, 50af14d238SGreg Roach function ($parser, string $name, array $attrs): void { 518a4ee39cSGreg Roach $this->startElement($parser, $name, $attrs); 528a4ee39cSGreg Roach }, 53af14d238SGreg Roach function ($parser, string $name): void { 548a4ee39cSGreg Roach $this->endElement($parser, $name); 558a4ee39cSGreg Roach } 568a4ee39cSGreg Roach ); 578a4ee39cSGreg Roach 588a4ee39cSGreg Roach xml_set_character_data_handler( 598a4ee39cSGreg Roach $this->xml_parser, 609d454b6bSGreg Roach function ($parser, string $data): void { 618a4ee39cSGreg Roach $this->characterData($parser, $data); 628a4ee39cSGreg Roach } 638a4ee39cSGreg Roach ); 64ef0d468bSGreg Roach 65e364afe4SGreg Roach $fp = fopen($report, 'rb'); 668a4ee39cSGreg Roach 677774ce41SGreg Roach if ($fp === false) { 687774ce41SGreg Roach throw new Exception('Cannot open ' . $report); 697774ce41SGreg Roach } 707774ce41SGreg Roach 71e364afe4SGreg Roach while ($data = fread($fp, 4096)) { 72ef0d468bSGreg Roach if (!xml_parse($this->xml_parser, $data, feof($fp))) { 73208e9f76SGreg Roach throw new DomainException(sprintf( 74ef0d468bSGreg Roach 'XML error: %s at line %d', 75ef0d468bSGreg Roach xml_error_string(xml_get_error_code($this->xml_parser)), 76ef0d468bSGreg Roach xml_get_current_line_number($this->xml_parser) 77ef0d468bSGreg Roach )); 78ef0d468bSGreg Roach } 79ef0d468bSGreg Roach } 80ef0d468bSGreg Roach 817774ce41SGreg Roach fclose($fp); 827774ce41SGreg Roach 83ef0d468bSGreg Roach xml_parser_free($this->xml_parser); 84ef0d468bSGreg Roach } 85ef0d468bSGreg Roach 86ef0d468bSGreg Roach /** 87ef0d468bSGreg Roach * XML handler for an opening (or self-closing) tag. 88ef0d468bSGreg Roach * 89ef0d468bSGreg Roach * @param resource $parser The resource handler for the xml parser 90ef0d468bSGreg Roach * @param string $name The name of the xml element parsed 91ef0d468bSGreg Roach * @param string[] $attrs An array of key value pairs for the attributes 9218d7a90dSGreg Roach * 9318d7a90dSGreg Roach * @return void 94ef0d468bSGreg Roach */ 95af14d238SGreg Roach protected function startElement($parser, string $name, array $attrs): void 96c1010edaSGreg Roach { 97a6f13a4aSGreg Roach $method = $name . 'StartHandler'; 98208e9f76SGreg Roach 99ef0d468bSGreg Roach if (method_exists($this, $method)) { 100ef0d468bSGreg Roach $this->$method($attrs); 101ef0d468bSGreg Roach } 102ef0d468bSGreg Roach } 103ef0d468bSGreg Roach 104ef0d468bSGreg Roach /** 105ef0d468bSGreg Roach * XML handler for a closing tag. 106ef0d468bSGreg Roach * 107ef0d468bSGreg Roach * @param resource $parser the resource handler for the xml parser 108ef0d468bSGreg Roach * @param string $name the name of the xml element parsed 10918d7a90dSGreg Roach * 11018d7a90dSGreg Roach * @return void 111ef0d468bSGreg Roach */ 112af14d238SGreg Roach protected function endElement($parser, string $name): void 113c1010edaSGreg Roach { 114a6f13a4aSGreg Roach $method = $name . 'EndHandler'; 115208e9f76SGreg Roach 116ef0d468bSGreg Roach if (method_exists($this, $method)) { 117ef0d468bSGreg Roach $this->$method(); 118ef0d468bSGreg Roach } 119ef0d468bSGreg Roach } 120ef0d468bSGreg Roach 121ef0d468bSGreg Roach /** 122ef0d468bSGreg Roach * XML handler for character data. 123ef0d468bSGreg Roach * 124ef0d468bSGreg Roach * @param resource $parser The resource handler for the xml parser 125ef0d468bSGreg Roach * @param string $data The name of the xml element parsed 12618d7a90dSGreg Roach * 12718d7a90dSGreg Roach * @return void 128ef0d468bSGreg Roach */ 129af14d238SGreg Roach protected function characterData($parser, $data): void 130c1010edaSGreg Roach { 131ef0d468bSGreg Roach $this->text .= $data; 132ef0d468bSGreg Roach } 133ef0d468bSGreg Roach} 134