1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2018 webtrees development team 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16declare(strict_types=1); 17 18namespace Fisharebest\Webtrees\Report; 19 20use DomainException; 21 22/** 23 * Class ReportParserBase 24 */ 25class ReportParserBase 26{ 27 /** @var resource The XML parser */ 28 protected $xml_parser; 29 30 /** @var string Text contents of tags */ 31 protected $text = ''; 32 33 /** 34 * Create a parser for a report 35 * 36 * @param string $report The XML filename 37 */ 38 public function __construct(string $report) 39 { 40 $this->xml_parser = xml_parser_create(); 41 42 xml_parser_set_option($this->xml_parser, XML_OPTION_CASE_FOLDING, false); 43 44 xml_set_element_handler( 45 $this->xml_parser, 46 function ($parser, string $name, array $attrs) { 47 $this->startElement($parser, $name, $attrs); 48 }, 49 function ($parser, string $name) { 50 $this->endElement($parser, $name); 51 } 52 ); 53 54 xml_set_character_data_handler( 55 $this->xml_parser, 56 function ($parser, $data) { 57 $this->characterData($parser, $data); 58 } 59 ); 60 61 $fp = fopen($report, 'r'); 62 63 while (($data = fread($fp, 4096))) { 64 if (!xml_parse($this->xml_parser, $data, feof($fp))) { 65 throw new DomainException(sprintf( 66 'XML error: %s at line %d', 67 xml_error_string(xml_get_error_code($this->xml_parser)), 68 xml_get_current_line_number($this->xml_parser) 69 )); 70 } 71 } 72 73 xml_parser_free($this->xml_parser); 74 } 75 76 /** 77 * XML handler for an opening (or self-closing) tag. 78 * 79 * @param resource $parser The resource handler for the xml parser 80 * @param string $name The name of the xml element parsed 81 * @param string[] $attrs An array of key value pairs for the attributes 82 * 83 * @return void 84 */ 85 protected function startElement($parser, string $name, array $attrs) 86 { 87 $method = $name . 'StartHandler'; 88 89 if (method_exists($this, $method)) { 90 $this->$method($attrs); 91 } 92 } 93 94 /** 95 * XML handler for a closing tag. 96 * 97 * @param resource $parser the resource handler for the xml parser 98 * @param string $name the name of the xml element parsed 99 * 100 * @return void 101 */ 102 protected function endElement($parser, string $name) 103 { 104 $method = $name . 'EndHandler'; 105 106 if (method_exists($this, $method)) { 107 $this->$method(); 108 } 109 } 110 111 /** 112 * XML handler for character data. 113 * 114 * @param resource $parser The resource handler for the xml parser 115 * @param string $data The name of the xml element parsed 116 * 117 * @return void 118 */ 119 protected function characterData($parser, $data) 120 { 121 $this->text .= $data; 122 } 123} 124