. */ namespace Fisharebest\Webtrees\Report; use Fisharebest\Webtrees\Auth; use Fisharebest\Webtrees\Database; use Fisharebest\Webtrees\Date; use Fisharebest\Webtrees\Family; use Fisharebest\Webtrees\Filter; use Fisharebest\Webtrees\Functions\Functions; use Fisharebest\Webtrees\Functions\FunctionsDate; use Fisharebest\Webtrees\GedcomRecord; use Fisharebest\Webtrees\GedcomTag; use Fisharebest\Webtrees\I18N; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Log; use Fisharebest\Webtrees\Media; use Fisharebest\Webtrees\Note; use Fisharebest\Webtrees\Place; /** * Class ReportParserGenerate - parse a report.xml file and generate the report. */ class ReportParserGenerate extends ReportParserBase { /** @var bool Are we collecting data from elements */ private $process_footnote = true; /** @var bool Are we currently outputing data? */ private $print_data = false; /** @var bool[] Push-down stack of $print_data */ private $print_data_stack = []; /** @var int Are we processing GEDCOM data */ private $process_gedcoms = 0; /** @var int Are we processing conditionals */ private $process_ifs = 0; /** @var int Are we processing repeats*/ private $process_repeats = 0; /** @var int Quantity of data to repeat during loops */ private $repeat_bytes = 0; /** @var array[] Repeated data when iterating over loops */ private $repeats = []; /** @var array[] Nested repeating data */ private $repeats_stack = []; /** @var ReportBase[] Nested repeating data */ private $wt_report_stack = []; /** @var resource Nested repeating data */ private $parser; /** @var resource[] Nested repeating data */ private $parser_stack = []; /** @var string The current GEDCOM record */ private $gedrec = ''; /** @var string[] Nested GEDCOM records */ private $gedrec_stack = []; /** @var ReportBaseElement The currently processed element */ private $current_element; /** @var ReportBaseElement The currently processed element */ private $footnote_element; /** @var string The GEDCOM fact currently being processed */ private $fact = ''; /** @var string The GEDCOM value currently being processed */ private $desc = ''; /** @var string The GEDCOM type currently being processed */ private $type = ''; /** @var int The current generational level */ private $generation = 1; /** @var array Source data for processing lists */ private $list = []; /** @var int Number of items in lists */ private $list_total = 0; /** @var int Number of items filtered from lists */ private $list_private = 0; /** @var ReportBase A factory for creating report elements */ private $report_root; /** @var ReportBase Nested report elements */ private $wt_report; /** @todo This attribute is public to support the PHP5.3 closure workaround. */ /** @var string[][] Variables defined in the report at run-time */ public $vars; /** * Create a parser for a report * * @param string $report The XML filename * @param ReportBase $report_root * @param string[][] $vars */ public function __construct($report, ReportBase $report_root = null, array $vars = []) { $this->report_root = $report_root; $this->wt_report = $report_root; $this->current_element = new ReportBaseElement; $this->vars = $vars; parent::__construct($report); } /** * XML start element handler * * This function is called whenever a starting element is reached * The element handler will be called if found, otherwise it must be HTML * * @param resource $parser the resource handler for the XML parser * @param string $name the name of the XML element parsed * @param array $attrs an array of key value pairs for the attributes */ protected function startElement($parser, $name, $attrs) { $newattrs = []; foreach ($attrs as $key => $value) { if (preg_match("/^\\$(\w+)$/", $value, $match)) { if ((isset($this->vars[$match[1]]['id'])) && (!isset($this->vars[$match[1]]['gedcom']))) { $value = $this->vars[$match[1]]['id']; } } $newattrs[$key] = $value; } $attrs = $newattrs; if ($this->process_footnote && ($this->process_ifs === 0 || $name === "if") && ($this->process_gedcoms === 0 || $name === "Gedcom") && ($this->process_repeats === 0 || $name === "Facts" || $name === "RepeatTag")) { $start_method = $name . 'StartHandler'; $end_method = $name . 'EndHandler'; if (method_exists($this, $start_method)) { $this->$start_method($attrs); } elseif (!method_exists($this, $end_method)) { $this->htmlStartHandler($name, $attrs); } } } /** * XML end element handler * * This function is called whenever an ending element is reached * The element handler will be called if found, otherwise it must be HTML * * @param resource $parser the resource handler for the XML parser * @param string $name the name of the XML element parsed */ protected function endElement($parser, $name) { if (($this->process_footnote || $name === "Footnote") && ($this->process_ifs === 0 || $name === "if") && ($this->process_gedcoms === 0 || $name === "Gedcom") && ($this->process_repeats === 0 || $name === "Facts" || $name === "RepeatTag" || $name === "List" || $name === "Relatives")) { $start_method = $name . 'StartHandler'; $end_method = $name . 'EndHandler'; if (method_exists($this, $end_method)) { $this->$end_method(); } elseif (!method_exists($this, $start_method)) { $this->htmlEndHandler($name); } } } /** * XML character data handler * * @param resource $parser the resource handler for the XML parser * @param string $data the name of the XML element parsed */ protected function characterData($parser, $data) { if ($this->print_data && $this->process_gedcoms === 0 && $this->process_ifs === 0 && $this->process_repeats === 0) { $this->current_element->addText($data); } } /** * XML