rtl = true;
}
// Set the character setting
$this->charset = 'UTF-8';
// Set the Keywords
$this->rkeywords = $META_KEYWORDS;
// Generated By...text
// I18N This is a report footer. %s is the name of the application.
$this->generatedby = i18n::translate('Generated by %s', WT_WEBTREES);
// Only admin should see the version number
if (WT_USER_IS_ADMIN) {
$this->generatedby .= " ".WT_VERSION_TEXT;
}
// For known size pages
if (($this->pagew == 0) AND ($this->pageh == 0)) {
/**
* The current ISO 216 standard was introduced in 1975 and is a direct follow up to the german DIN 476 standard from 1922. ISO 216 is also called EN 20216 in Europe.
* The ISO paper sizes are based on the metric system so everything else is aproxiamte
*
* The Series A is used for Standard Printing and Stationary.
* The Series B is used for Posters, Wall-Charts etc.
* The C series is used for folders, post cards and envelopes. C series envelope is suitable to insert A series sizes.
* ISO also define format series RA and SRA for untrimmed raw paper, where SRA stands for 'supplementary raw format A'.
* Japan has adopted the ISO series A sizes, but its series B sizes are slightly different. These sizes are sometimes called JIS B or JB sizes.
* sun was a unit of length used in Japan and is equal to about 3.03 cm or 1.193 inches
* The United States, Canada, and in part Mexico, are today the only industrialized nations in which the ISO standard paper sizes are not yet widely used.
*
* A0 & A1 Technical drawings, posters
* A1 & A2 Flip charts
* A2 & A3 Drawings, diagrams, large tables
* A4 Letters, magazines, forms, catalogs, laser printer and copying machine output
* A5 Note pads
* A6 Postcards
* B5, A5, B6 A6 Books
* C4, C5, C6 Envelopes for A4 letters: unfolded (C4), folded once (C5), folded twice (C6)
* B4 & A3 Newspapers, supported by most copying machines in addition to A4
* B8 & A8 Playing cards
*
* 1 inch = 72 points
* 1 mm = 2.8346457 points
* 1 inch = 25.4 mm
* 1 point = 0,35278 mm
*/
switch ($this->pageFormat) {
// ISO A series
case "4A0": {$sizes = array(4767.86,6740.79);break;} // ISO 216, 1682 mm x 2378 mm
case "2A0": {$sizes = array(3370.39,4767.86);break;} // ISO 216, 1189 mm x 1682 mm
case "A0": {$sizes = array(2383.94,3370.39);break;} // ISO 216, 841 mm x 1189mm
case "A1": {$sizes = array(1683.78,2383.94);break;} // ISO 216, 594 mm x 841 mm
case "A2": {$sizes = array(1190.55,1683.78);break;} // ISO 216, 420 mm x 594 mm
case "A3": {$sizes = array(841.89,1190.55);break;} // ISO 216, 297 mm x 420 mm
case "A4": default:{ // For unknown Page Size Name
$sizes = array(595.28,841.89); // ISO 216, 210 mm 297 mm
$this->pageFormat = "A4";
break;}
case "A5": {$sizes = array(419.53,595.28);break;} // ISO 216, 148 mm x 210 mm
case "A6": {$sizes = array(297.64,419.53);break;} // ISO 216, 105 mm x 148 mm
case "A7": {$sizes = array(209.76,297.64);break;} // ISO 216, 74 mm x 105 mm
case "A8": {$sizes = array(147.40,209.76);break;} // ISO 216, 52 mm x 74 mm
case "A9": {$sizes = array(104.88,147.40);break;} // ISO 216, 37 mm x 52 mm
case "A10": {$sizes = array(73.70,104.88);break;} // ISO 216, 26 mm x 37 mm
// ISO B series
case "B0": {$sizes = array(2834.65,4008.19);break;} // ISO 216, 1000 mm x 1414 mm
case "B1": {$sizes = array(2004.09,2834.65);break;} // ISO 216, 707 mm x 1000 mm
case "B2": {$sizes = array(1417.32,2004.09);break;} // ISO 216, 500 mm x 707 mm
case "B3": {$sizes = array(1000.63,1417.32);break;} // ISO 216, 353 mm x 500 mm
case "B4": {$sizes = array(708.66,1000.63);break;} // ISO 216, 250 mm x 353 mm
case "B5": {$sizes = array(498.90,708.66);break;} // ISO 216, 176 mm x 250 mm
case "B6": {$sizes = array(354.33,498.90);break;} // ISO 216, 125 mm x 176 mm
case "B7": {$sizes = array(249.45,354.33);break;} // ISO 216, 88 mm x 125 mm
case "B8": {$sizes = array(175.75,249.45);break;} // ISO 216, 62 mm x 88 mm
case "B9": {$sizes = array(124.72,175.75);break;} // ISO 216, 44 mm x 62 mm
case "B10": {$sizes = array(87.87,124.72);break;} // ISO 216, 31 mm x 44 mm
// ISO C series, Envelope
case "C0": {$sizes = array(2599.37,3676.54);break;} // ISO 269, 917 mm x 1297 mm, For flat A0 sheet
case "C1": {$sizes = array(1836.85,2599.37);break;} // ISO 269, 648 mm x 917 mm, For flat A1 sheet
case "C2": {$sizes = array(1298.27,1836.85);break;} // ISO 269, 458 mm x 648 mm, For flat A2 sheet, A1 folded in half
case "C3": {$sizes = array(918.43,1298.27);break;} // ISO 269, 324 mm x 458 mm, For flat A3 sheet, A2 folded in half
case "C4": {$sizes = array(649.13,918.43);break;} // ISO 269, 229 mm x 324 mm, For flat A4 sheet, A3 folded in half
case "C5": {$sizes = array(459.21,649.13);break;} // ISO 269, 162 mm x 229 mm, For flat A5 sheet, A4 folded in half
case "C6/5":{$sizes = array(323.15,649.13);break;} // ISO 269, 114 mm x 229 mm. A5 folded twice = 1/3 A4. Alternative for the DL envelope
case "C6": {$sizes = array(323.15,459.21);break;} // ISO 269, 114 mm x 162 mm, For A5 folded in half
case "C7/6":{$sizes = array(229.61,459.21);break;} // ISO 269, 81 mm x 162 mm, For A5 sheet folded in thirds
case "C7": {$sizes = array(229.61,323.15);break;} // ISO 269, 81 mm x 114 mm, For A5 folded in quarters
case "C8": {$sizes = array(161.57,229.61);break;} // ISO 269, 57 mm x 81 mm
case "C9": {$sizes = array(113.39,161.57);break;} // ISO 269, 40 mm x 57 mm
case "C10": {$sizes = array(79.37,113.39);break;} // ISO 269, 28 mm x 40 mm
case "DL": {$sizes = array(311.81,623.62);break;} // Original DIN 678 but ISO 269 now has this C6/5 , 110 mm x 220 mm, For A4 sheet folded in thirds, A5 in half
// Untrimmed stock sizes for the ISO-A Series - ISO primary range
case "RA0": {$sizes = array(2437.80,3458.27);break;} // ISO 478, 860 mm x 1220 mm
case "RA1": {$sizes = array(1729.13,2437.80);break;} // ISO 478, 610 mm x 860 mm
case "RA2": {$sizes = array(1218.90,1729.13);break;} // ISO 478, 430 mm x 610 mm
case "RA3": {$sizes = array(864.57,1218.90);break;} // ISO 478, 305 mm x 430 mm
case "RA4": {$sizes = array(609.45,864.57);break;} // ISO 478, 215 mm x 305 mm
// Untrimmed stock sizes for the ISO-A Series - ISO supplementary range
case "SRA0": {$sizes = array(2551.18,3628.35);break;} // ISO 593, 900 mm x 1280 mm
case "SRA1": {$sizes = array(1814.17,2551.18);break;} // ISO 593, 640 mm x 900 mm
case "SRA2": {$sizes = array(1275.59,1814.17);break;} // ISO 593, 450 mm x 640 mm
case "SRA3": {$sizes = array(907.09,1275.59);break;} // ISO 593, 320 mm x 450 mm
case "SRA4": {$sizes = array(637.80,907.09);break;} // ISO 593, 225 mm x 320 mm
// ISO size variations
case "A2EXTRA": {$sizes = array(1261.42,1754.65);break;} // ISO 216, 445 mm x 619 mm
case "A2SUPER": {$sizes = array(864.57,1440.00);break;} // ISO 216, 305 mm x 508 mm
case "A3EXTRA": {$sizes = array(912.76,1261.42);break;} // ISO 216, 322 mm x 445 mm
case "SUPERA3": {$sizes = array(864.57,1380.47);break;} // ISO 216, 305 mm x 487 mm
case "A4EXTRA": {$sizes = array(666.14,912.76);break;} // ISO 216, 235 mm x 322 mm
case "A4LONG": {$sizes = array(595.28,986.46);break;} // ISO 216, 210 mm x 348 mm
case "A4SUPER": {$sizes = array(649.13,912.76);break;} // ISO 216, 229 mm x 322 mm
case "SUPERA4": {$sizes = array(643.46,1009.13);break;} // ISO 216, 227 mm x 356 mm
case "A5EXTRA": {$sizes = array(490.39,666.14);break;} // ISO 216, 173 mm x 235 mm
case "SOB5EXTRA": {$sizes = array(572.60,782.36);break;} // ISO 216, 202 mm x 276 mm
// Japanese version of the ISO 216 B series
case "JB0": {$sizes = array(2919.69,4127.24);break;} // JIS P 0138-61, 1030 mm x 1456 mm
case "JB1": {$sizes = array(2063.62,2919.69);break;} // JIS P 0138-61, 728 mm x 1030 mm
case "JB2": {$sizes = array(1459.84,2063.62);break;} // JIS P 0138-61, 515 mm x 728 mm
case "JB3": {$sizes = array(1031.81,1459.84);break;} // JIS P 0138-61, 364 mm x 515 mm
case "JB4": {$sizes = array(728.50,1031.81);break;} // JIS P 0138-61, 257 mm x 364 mm
case "JB5": {$sizes = array(515.91,728.50);break;} // JIS P 0138-61, 182 mm x 257 mm
case "JB6": {$sizes = array(362.83,515.91);break;} // JIS P 0138-61, 128 mm x 182 mm
case "JB7": {$sizes = array(257.95,362.83);break;} // JIS P 0138-61, 91 mm x 128 mm
case "JB8": {$sizes = array(181.42,257.95);break;} // JIS P 0138-61, 64 mm x 91 mm
case "JB9": {$sizes = array(127.56,181.42);break;} // JIS P 0138-61, 45 mm x 64 mm
case "JB10":{$sizes = array(90.71,127.56);break;} // JIS P 0138-61, 32 mm x 45 mm
// US pages
case "EXECUTIVE": {$sizes = array(522.00,756.00); break;} // 7.25 in x 10.5 in
case "FOLIO": {$sizes = array(612.00,936.00); break;} // 8.5 in x 13 in
case "FOOLSCAP":{$sizes = array(972.00,1224.00); break;} // 13.5 in x 17 in
case "LEDGER": {$sizes = array(792.00,1224.00); break;} // 11 in x 17 in
case "LEGAL": {$sizes = array(612.00,1008.00); break;} // 8.5 in x 14 in
case "LETTER": {$sizes = array(612.00,792.00); break;} // 8.5 in x 11 in
case "QUARTO": {$sizes = array(609.12,777.5); break;} // 8.46 in x 10.8 in
case "STATEMENT": {$sizes = array(396.00,612.00); break;} // 5.5 in x 8.5 in
case "USGOVT": {$sizes = array(576.00,792.00); break;} // 8 in x 11 in
}
$this->pagew = $sizes[0];
$this->pageh = $sizes[1];
}
else {
if ($this->pagew < 10) {
die("REPORT ERROR PGVReportBase::setup(): For custom size pages you must set \"customwidth\" larger then this in the XML file");
}
if ($this->pageh < 10) {
die("REPORT ERROR PGVReportBase::setup(): For custom size pages you must set \"customheight\" larger then this in the XML file");
}
}
return 0;
}
/**
* Process the Header , Page header, Body or Footer - PGVReportBase
*
* @param string $p Header (H), Page header (PH), Body (B) or Footer (F)
*/
function setProcessing($p) {
$this->processing = $p;
return 0;
}
/**
* Add the Title when raw character data is used in PGVRTitle - PGVReportBase
*
* @param string $data
*/
function addTitle($data) {
$this->title .= $data;
return 0;
}
/**
* Add the Description when raw character data is used in PGVRDescription - PGVReportBase
*
* @param string $data
*/
function addDescription($data) {
$this->rsubject .= $data;
return 0;
}
/**
* Add Style to PGVRStyles array - PGVReportBase
*
* @see PGVRStyleSHandler()
* @param array $style
*/
function addStyle($style) {
$this->PGVRStyles[$style["name"]] = $style;
return 0;
}
/**
* Get a style from the PGVRStyles array - PGVReportBase
*
* @param string $s Style name
* @return array
*/
function getStyle($s) {
if (!isset($this->PGVRStyles[$s])) {
return current($this->PGVRStyles);
}
return $this->PGVRStyles[$s];
}
// static callback functions to sort data
static function CompareBirthDate($x, $y) {
return GedcomDate::Compare($x->getBirthDate(), $y->getBirthDate());
}
static function CompareDeathDate($x, $y) {
return GedcomDate::Compare($x->getDeathDate(), $y->getDeathDate());
}
/**
* @deprecated
* @todo Is this a deprecated function or a future feature?
*
function get_type() {
// remove this die line only if it's cousing problem - It confirms that it's not used
die("REPORT ERROR PGVReportBase::get_type: It is used");
return "PGVReportBase";
}
*/
}
/**
* Main PGV Report Element class that all other page elements are extended from
*
* @package webtrees
* @subpackage Reports
*/
class PGVRElement {
/**
* @var string
*/
public $text = "";
/**
* Element renderer
* @param &$renderer
*/
function render(&$renderer) {
// print "Nothing rendered. Something bad happened";
// debug_print_backtrace();
//-- to be implemented in inherited classes
return 0;
}
function getHeight(&$renderer) {
return 0;
}
function getWidth(&$renderer) {
return 0;
}
function addText($t) {
global $embed_fonts, $SpecialOrds, $pgvreport, $reportTitle, $reportDescription;
foreach($SpecialOrds as $ord) {
if (strpos($t, chr($ord))!==false) {
$embed_fonts = true;
}
}
$t = trim($t, "\r\n\t");
$t = str_replace(array("
", " "), array("\n", " "), $t);
if (!WT_RNEW) {
$t = strip_tags($t);
$t = unhtmlentities($t);
}
$this->text .= $t;
// Adding the title and description to the Document Properties
if ($reportTitle) {
$pgvreport->addTitle($t);
} elseif ($reportDescription) {
$pgvreport->addDescription($t);
}
return 0;
}
function addNewline() {
$this->text .= "\n";
return 0;
}
function getValue() {
return $this->text;
}
function setWrapWidth($wrapwidth, $cellwidth) {
return 0;
}
function renderFootnote(&$renderer) {
return false;
//-- to be implemented in inherited classes
}
/**
* Get the Class name type
*
* @return string PGVRElementBase
*/
function get_type() {
return "PGVRElementBase";
}
function setText($text) {
$this->text = $text;
return 0;
}
} //-- END PGVRElement
/**
* HTML element class
*
* @package webtrees
* @subpackage Reports
* @todo add info
*/
class PGVRHtml extends PGVRElement {
public $tag;
public $attrs;
public $elements = array();
function PGVRHtml($tag, $attrs) {
$this->tag = $tag;
$this->attrs = $attrs;
return 0;
}
function getStart() {
$str = "<".$this->tag." ";
foreach($this->attrs as $key=>$value) {
$str .= $key."=\"".$value."\" ";
}
$str .= ">";
return $str;
}
function getEnd() {
return "".$this->tag.">";
}
function addElement($element) {
$this->elements[] = $element;
return 0;
}
/**
* Get the class type
* @return string PGVRHtml
*/
function get_type() {
return "PGVRHtml";
}
}
/**
* Cell element class
*
* @package webtrees
* @subpackage Reports
*/
class PGVRCell extends PGVRElement {
/**
* Allows to center or align the text. Possible values are:
- left or empty string: left align
- center: center align
- right: right align
- justify: justification (default value when $ishtml=false)
* @var string
*/
public $align = "";
/**
* Whether or not a border should be printed around this box. 0 = no border, 1 = border. Default is 0.
* Or a string containing some or all of the following characters (in any order):- L: left
- T: top
- R: right
- B: bottom
* @var mixed
*/
public $border;
/**
* Border color in HTML code
* @var string
*/
public $bocolor;
/**
* The HTML color code to fill the background of this cell.
* @var string
*/
public $bgcolor;
/**
* Indicates if the cell background must be painted (1) or transparent (0). Default value: 1.
* If no background color is set then it will not be painted
* @var int
*/
public $fill;
/**
* Cell height DEFAULT 0 (expressed in points)
* The starting height of this cell. If the text wraps the height will automatically be adjusted.
* @var int
*/
public $height;
/**
* Left position in user units (X-position). Default is the current position
* @var mixed
*/
public $left;
/**
* Indicates where the current position should go after the call. Possible values are:- 0: to the right [DEFAULT]
- 1: to the beginning of the next line
- 2: below
* @var int
*/
public $newline;
/**
* The name of the PGVRStyle that should be used to render the text.
* @var string
*/
public $styleName;
/**
* Stretch carachter mode: - 0 = disabled (default)
- 1 = horizontal scaling only if necessary
- 2 = forced horizontal scaling
- 3 = character spacing only if necessary
- 4 = forced character spacing
* @var int
*/
public $stretch;
/**
* Text color in HTML code
* @var string
*/
public $tcolor;
/**
* Top position in user units (Y-position). Default is the current position
* @var mixed
*/
public $top;
/**
* URL address
* @var string
*/
public $url;
/**
* Cell width DEFAULT 0 (expressed in points)
* Setting the width to 0 will make it the width from the current location to the right margin.
* @var int
*/
public $width;
public $reseth;
/**
* CELL - PGVRElement
*
* @param int $width cell width (expressed in points)
* @param int $height cell height (expressed in points)
* @param mixed $border Border style
* @param string $align Text alignement
* @param string $bgcolor Background color code
* @param string $style The name of the text style
* @param int $ln Indicates where the current position should go after the call
* @param mixed $top Y-position
* @param mixed $left X-position
* @param int $fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
* @param int $stretch Stretch carachter mode
* @param string $bocolor Border color
* @param string $tcolor Text color
*/
function PGVRCell($width, $height, $border, $align, $bgcolor, $style, $ln, $top, $left, $fill, $stretch, $bocolor, $tcolor, $reseth) {
$this->align = $align;
$this->border = $border;
$this->bgcolor = $bgcolor;
$this->bocolor = $bocolor;
$this->fill = $fill;
$this->height = $height;
$this->left = $left;
$this->newline = $ln;
$this->styleName = $style;
$this->text = "";
$this->tcolor = $tcolor;
$this->top = $top;
$this->url = "";
$this->stretch = $stretch;
$this->width = $width;
$this->reseth = $reseth;
return 0;
}
/**
* Get the cell height
* @todo add param
* @return float
*/
function getHeight(&$renderer) {
return $this->height;
}
/**
* Sets the current cells URL
* @param string $url The URL address to save
*/
function setUrl($url) {
$this->url = $url;
return 0;
}
/**
* Get the cell width
* @todo add param
* @return float
*/
function getWidth(&$renderer) {
return $this->width;
}
/**
* Get the class type
* @return string PGVRCell
*/
function get_type() {
return "PGVRCell";
}
}
/**
* TextBox element class
*
* @package webtrees
* @subpackage Reports
* @todo add info
*/
class PGVRTextBox extends PGVRElement {
/**
* Array of elements in the TextBox
* @var array
*/
public $elements = array();
/**
* Background color in HTML code
* @var string
*/
public $bgcolor;
/**
* Whether or not paint the background
* @var boolean
*/
public $fill;
/**
* Position the left corner of this box on the page(expressed in points). The default is the current position.
* @var mix
*/
public $left;
/**
* Position the top corner of this box on the page(expressed in points). the default is the current position
* @var mix
*/
public $top;
/**
* After this box is finished rendering, should the next section of text start immediately after the this box or should it start on a new line under this box. 0 = no new line, 1 = force new line. Default is 0
* @var boolean
*/
public $newline;
/**
* @var boolean
*/
public $pagecheck;
/**
* Whether or not a border should be printed around this box. 0 = no border, 1 = border. Default is 0
* @var boolean
*/
public $border;
/**
* Style of rendering
*
*
* - D or empty string: Draw (default).
* - F: Fill.
* - DF or FD: Draw and fill.
* - CNZ: Clipping mode (using the even-odd rule to determine which regions lie inside the clipping path).
*- CEO: Clipping mode (using the nonzero winding number rule to determine which regions lie inside the clipping path).
*
* @var string
*/
public $style;
/**
* @var array $borderstyle Border style of rectangle. Array with keys among the following:
*
* - all: Line style of all borders. Array like for {@link SetLineStyle SetLineStyle}.
* - L, T, R, B or combinations: Line style of left, top, right or bottom border. Array like for {@link SetLineStyle SetLineStyle}.
*
* Not yet in use
var $borderstyle;
*/
/**
* The starting height of this cell. If the text wraps the height will automatically be adjusted
* @var float
*/
public $height;
/**
* Setting the width to 0 will make it the width from the current location to the right margin
* @var float
*/
public $width;
/**
* Use cell padding or not
* @var boolean $padding
*/
public $padding;
/**
* Resets this box last height after it's done
*/
public $reseth;
/**
* TextBox - PGVRElement - Base
*
* @param float $width Text box width
* @param float $height Text box height
* @param boolean $border
* @param string $bgcolor Background color code in HTML
* @param boolean $newline
* @param mixed $left
* @param mixed $top
* @param boolean $pagecheck
* @param string $style
* @param boolean $fill
* @param boolean $padding
* @param boolean $reseth
*/
function PGVRTextBox($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth) {
$this->border = $border;
$this->bgcolor = $bgcolor;
$this->fill= $fill;
$this->height = $height;
$this->left = $left;
$this->newline = $newline;
$this->pagecheck = $pagecheck;
$this->style = $style;
$this->top = $top;
$this->width = $width;
$this->padding = $padding;
$this->reseth = $reseth;
return 0;
}
/**
* Add an element to the TextBox
* @param object|string &$element
*/
function addElement($element) {
$this->elements[] = $element;
return 0;
}
/**
* Get the class type
* @return string PGVRTextBox
*/
function get_type() {
return "PGVRTextBox";
}
}
/**
* Text element class
*
* @package webtrees
* @subpackage Reports
* @todo add info
*/
class PGVRText extends PGVRElement {
/**
* Text color in HTML code
* @var string
*/
public $color;
/**
* Style name
* @var string
*/
public $styleName;
/**
* Remaining width of a cel
* @var int User unit (points)
*/
public $wrapWidthRemaining;
/**
* Original width of a cell
* @var int User unit (points)
*/
public $wrapWidthCell;
/**
* Create a Text class - Base
*
* @param string $style The name of the text style
* @param string $color HTML color code
*/
function PGVRText($style, $color) {
$this->text = "";
$this->color = $color;
$this->wrapWidthRemaining = 0;
$this->styleName = $style;
return 0;
}
function setWrapWidth($wrapwidth, $cellwidth) {
$this->wrapWidthCell = $cellwidth;
if (strpos($this->text, "\n")!==false) {
$this->wrapWidthRemaining = $cellwidth;
} else {
$this->wrapWidthRemaining = $wrapwidth;
}
return $this->wrapWidthRemaining;
}
function getStyleName() {
return $this->styleName;
}
/**
* Get the class type
* @return string PGVRText
*/
function get_type() {
return "PGVRText";
}
}
/**
* Footnote element class
*
* @package webtrees
* @subpackage Reports
* @todo add info
*/
class PGVRFootnote extends PGVRElement {
/**
* The name of the style for this element
* @var string
*/
public $styleName = "";
/**
* Numbers for the links
* @var int
*/
public $num;
/**
* The text that will be printed with the number
* @var string
*/
public $numText = "";
/**
* Remaining width of a cell
* @var float User unit (points)
*/
public $wrapWidthRemaining;
/**
* Original width of a cell
* @var float User unit (points)
*/
public $wrapWidthCell;
public $addlink;
function PGVRFootnote($style="") {
$this->text = "";
if (!empty($style)) {
$this->styleName = $style;
} else {
$this->styleName="footnote";
}
return 0;
}
function rerender($renderer) {
return false;
}
function addText($t) {
global $embed_fonts, $SpecialOrds;
foreach($SpecialOrds as $ord) {
if (strpos($t, chr($ord))!==false) {
$embed_fonts = true;
}
}
$t = trim($t, "\r\n\t");
$t = str_replace(array("
", " "), array("\n", " "), $t);
if (!WT_RNEW) {
$t = strip_tags($t);
$t = unhtmlentities($t);
}
$this->text .= $t;
return 0;
}
function setWrapWidth($wrapwidth, $cellwidth) {
$this->wrapWidthCell = $cellwidth;
if (strpos($this->numText, "\n")!==false) {
$this->wrapWidthRemaining = $cellwidth;
} else {
$this->wrapWidthRemaining = $wrapwidth;
}
return $this->wrapWidthRemaining;
}
function setNum($n) {
$this->num = $n;
//@@ $this->numText = "$n";
$this->numText = "$n "; //@@ source numbers
return 0;
}
function setAddlink($a) {
$this->addlink = $a;
return 0;
}
/**
* Get the class type
* @return string PGVRFootnote
*/
function get_type() {
return "PGVRFootnote";
}
}
/**
* PageHeader element class
*
* @package webtrees
* @subpackage Reports
* @todo add info
*/
class PGVRPageHeader extends PGVRElement {
public $elements = array();
function PGVRTextBox() {
$this->elements = array();
return 0;
}
function PGVRPageHeader() {
$this->elements = array();
return 0;
}
/**
* Add element - PGVRPageHeader
* @param $element
*/
function addElement($element) {
$this->elements[] = $element;
return 0;
}
/**
* Get the class type
* @return string PGVRPageHeader
*/
function get_type() {
return "PGVRPageHeader";
}
}
/**
* Image element class
*
* @package webtrees
* @subpackage Reports
* @todo add info
*/
class PGVRImage extends PGVRElement {
/**
* File name of the image
* @var string
*/
public $file;
/**
* Height of the image
* @var float
*/
public $height;
/**
* Width of the image
* @var float
*/
public $width;
/**
* X-position (left) of the image
* @var float
*/
public $x;
/**
* Y-position (top) of the image
* @var float
*/
public $y;
/**
* Placement fo the image. L: left, C:center, R:right
* @var string
*/
public $align = "";
/**
* T:same line, N:next line
* @var string
*/
public $line = "";
/**
* PGVRImage class function - Base
*
* @param string $file File name of the image
* @param float $x X-position (left) of the image
* @param float $y Y-position (top) of the image
* @param float $w Width of the image
* @param float $h Height of the image
* @param string $align Placement of the image. L: left, C:center, R:right
* @param string $ln T:same line, N:next line
*/
function PGVRImage($file, $x, $y, $w, $h, $align, $ln) {
$this->file = $file;
$this->width = $w;
$this->height = $h;
$this->x = $x;
$this->y = $y;
$this->align = $align;
$this->line = $ln;
return 0;
}
function getHeight(&$renderer) {
return $this->height;
}
function getWidth(&$renderer) {
return $this->width;
}
/**
* Get the class type
* @return string PGVRImage
*/
function get_type() {
return "PGVRImage";
}
}
/**
* Line element class
*
* @package webtrees
* @subpackage Reports
* @todo add info
*/
class PGVRLine extends PGVRElement {
/**
* Start horizontal position, current position (default)
* @var mixed
*/
public $x1 = ".";
/**
* Start vertical position, current position (default)
* @var mixed
*/
public $y1 = ".";
/**
* End horizontal position, maximum width (default)
* @var mixed
*/
public $x2 = ".";
/**
* End vertical position
* @var mixed
*/
public $y2 = ".";
/**
* Create a line class - Base
* @param mixed $x1
* @param mixed $y1
* @param mixed $x2
* @param mixed $y2
*/
function PGVRLine($x1, $y1, $x2, $y2) {
$this->x1 = $x1;
$this->y1 = $y1;
$this->x2 = $x2;
$this->y2 = $y2;
return 0;
}
function getHeight(&$renderer) {
return abs($this->y2 - $this->y1);
}
function getWidth(&$renderer) {
return abs($this->x2 - $this->x1);
}
/**
* Get the class type
* @return string PGVRLine
*/
function get_type() {
return "PGVRLine";
}
}
/**
* element handlers array
*
* Converts XML element names into functions
* @global array $elementHandler
*/
$elementHandler = array();
$elementHandler["br"]["start"] = "brSHandler";
$elementHandler["PGVRBody"]["start"] = "PGVRBodySHandler";
$elementHandler["PGVRCell"]["end"] = "PGVRCellEHandler";
$elementHandler["PGVRCell"]["start"] = "PGVRCellSHandler";
$elementHandler["PGVRDescription"]["end"] = "PGVRDescriptionEHandler";
$elementHandler["PGVRDescription"]["start"] = "PGVRDescriptionSHandler";
$elementHandler["PGVRDoc"]["end"] = "PGVRDocEHandler";
$elementHandler["PGVRDoc"]["start"] = "PGVRDocSHandler";
$elementHandler["PGVReport"]["end"] = "";
$elementHandler["PGVReport"]["start"] = "";
$elementHandler["PGVRFacts"]["end"] = "PGVRFactsEHandler";
$elementHandler["PGVRFacts"]["start"] = "PGVRFactsSHandler";
$elementHandler["PGVRFooter"]["start"] = "PGVRFooterSHandler";
$elementHandler["PGVRFootnote"]["end"] = "PGVRFootnoteEHandler";
$elementHandler["PGVRFootnote"]["start"] = "PGVRFootnoteSHandler";
$elementHandler["PGVRFootnoteTexts"]["start"] = "PGVRFootnoteTextsSHandler";
$elementHandler["PGVRGedcom"]["end"] = "PGVRGedcomEHandler";
$elementHandler["PGVRGedcom"]["start"] = "PGVRGedcomSHandler";
$elementHandler["PGVRGedcomValue"]["start"] = "PGVRGedcomValueSHandler";
$elementHandler["PGVRGeneration"]["start"] = "PGVRGenerationSHandler";
$elementHandler["PGVRGetPersonName"]["start"] = "PGVRGetPersonNameSHandler";
$elementHandler["PGVRHeader"]["start"] = "PGVRHeaderSHandler";
$elementHandler["PGVRHighlightedImage"]["start"]= "PGVRHighlightedImageSHandler";
$elementHandler["PGVRif"]["end"] = "PGVRifEHandler";
$elementHandler["PGVRif"]["start"] = "PGVRifSHandler";
$elementHandler["PGVRImage"]["start"] = "PGVRImageSHandler";
$elementHandler["PGVRInput"]["end"] = "";
$elementHandler["PGVRInput"]["start"] = "";
$elementHandler["PGVRLine"]["start"] = "PGVRLineSHandler";
$elementHandler["PGVRList"]["end"] = "PGVRListEHandler";
$elementHandler["PGVRList"]["start"] = "PGVRListSHandler";
$elementHandler["PGVRListTotal"]["start"] = "PGVRListTotalSHandler";
$elementHandler["PGVRNewPage"]["start"] = "PGVRNewPageSHandler";
$elementHandler["PGVRNow"]["start"] = "PGVRNowSHandler";
$elementHandler["PGVRPageHeader"]["end"] = "PGVRPageHeaderEHandler";
$elementHandler["PGVRPageHeader"]["start"] = "PGVRPageHeaderSHandler";
$elementHandler["PGVRPageNum"]["start"] = "PGVRPageNumSHandler";
$elementHandler["PGVRRelatives"]["end"] = "PGVRRelativesEHandler";
$elementHandler["PGVRRelatives"]["start"] = "PGVRRelativesSHandler";
$elementHandler["PGVRRepeatTag"]["end"] = "PGVRRepeatTagEHandler";
$elementHandler["PGVRRepeatTag"]["start"] = "PGVRRepeatTagSHandler";
$elementHandler["PGVRSetVar"]["start"] = "PGVRSetVarSHandler";
$elementHandler["PGVRStyle"]["start"] = "PGVRStyleSHandler";
$elementHandler["PGVRText"]["end"] = "PGVRTextEHandler";
$elementHandler["PGVRText"]["start"] = "PGVRTextSHandler";
$elementHandler["PGVRTextBox"]["end"] = "PGVRTextBoxEHandler";
$elementHandler["PGVRTextBox"]["start"] = "PGVRTextBoxSHandler";
$elementHandler["PGVRTitle"]["end"] = "PGVRTitleEHandler";
$elementHandler["PGVRTitle"]["start"] = "PGVRTitleSHandler";
$elementHandler["PGVRTotalPages"]["start"] = "PGVRTotalPagesSHandler";
$elementHandler["PGVRvar"]["start"] = "PGVRvarSHandler";
$elementHandler["PGVRvarLetter"]["start"] = "PGVRvarLetterSHandler";
$elementHandler["sp"]["start"] = "spSHandler";
/**
* A new object of the currently used element class
*
* @global object $currentElement
*/
$currentElement = new PGVRElement();
/**
* Should character data be printed
*
* This variable is turned on or off by the element handlers to tell whether the inner character
* Data should be printed
* @global boolean $printData
*/
$printData = false;
/**
* Title collector. Mark it if it has already been used
*
* @global boolean $reportTitle
*/
$reportTitle = false;
/**
* Description collector. Mark it if it has already been used
*
* @global boolean $reportDescription
*/
$reportDescription = false;
/**
* Print data stack
*
* As the XML is being processed there will be times when we need to turn on and off the
* $printData variable as we encounter entinties in the XML. The stack allows us to
* keep track of when to turn $printData on and off.
* @global array $printDataStack
*/
$printDataStack = array();
/**
* @todo add info
* @global array $pgvreportStack
*/
$pgvreportStack = array();
/**
* @todo add info
* @global array $gedrecStack
*/
$gedrecStack = array();
/**
* @todo add info
* @global array $repeatsStack
*/
$repeatsStack = array();
/**
* @todo add info
* @global array $parserStack
*/
$parserStack = array();
/**
* @todo add info
* @global array $repeats
*/
$repeats = array();
/**
* @todo add info
* @global string $gedrec
*/
$gedrec = "";
/**
* @todo add info
* @global ???? $repeatBytes
*/
$repeatBytes = 0;
/**
* @todo add info
* @global resource $parser
*/
$parser = "";
/**
* @todo add info
* @global int $processRepeats
*/
$processRepeats = 0;
/**
* @todo add info
* @global ???? $processIfs
*/
$processIfs = 0;
/**
* @todo add info
* @global ???? $processGedcoms
*/
$processGedcoms = 0;
/**
* Wether or not to print footnote
* true = print, false = don't print
*/
$processFootnote = true;
/**
*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
* @see endElement()
*/
function startElement($parser, $name, $attrs) {
global $elementHandler, $processIfs, $processGedcoms, $processRepeats, $vars;
global $processFootnote;
$newattrs = array();
$match = array();
foreach($attrs as $key=>$value) {
if (preg_match("/^\\$(\w+)$/", $value, $match)) {
if ((isset($vars[$match[1]]["id"]))&&(!isset($vars[$match[1]]["gedcom"]))) {
$value = $vars[$match[1]]["id"];
}
}
$newattrs[$key] = $value;
}
$attrs = $newattrs;
if (($processFootnote)&&($processIfs==0 || $name=="PGVRif")&&($processGedcoms==0 || $name=="PGVRGedcom")&&($processRepeats==0 || $name=="PGVRFacts" || $name=="PGVRRepeatTag")) {
if (isset($elementHandler[$name]["start"])) {
if ($elementHandler[$name]["start"] != "") {
call_user_func($elementHandler[$name]["start"], $attrs);
}
} elseif (!isset($elementHandler[$name]["end"])) {
HTMLSHandler($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
* @see startElement()
*/
function endElement($parser, $name) {
global $elementHandler, $processIfs, $processGedcoms, $processRepeats;
global $processFootnote;
if (($processFootnote || $name=="PGVRFootnote")&&($processIfs==0 || $name=="PGVRif")&&($processGedcoms==0 || $name=="PGVRGedcom")&&($processRepeats==0 || $name=="PGVRFacts" || $name=="PGVRRepeatTag" || $name=="PGVRList" || $name=="PGVRRelatives")) {
if (isset($elementHandler[$name]["end"])) {
if ($elementHandler[$name]["end"]!="") {
call_user_func($elementHandler[$name]["end"]);
}
} elseif (!isset($elementHandler[$name]["start"])) {
HTMLEHandler($name);
}
}
}
/**
* XML character data handler
*
* This function is called whenever raw character data is reached
* just print it to the screen
* @param resource $parser the resource handler for the XML parser
* @param string $data the name of the XML element parsed
* @todo check this
*/
function characterData($parser, $data) {
global $printData, $currentElement, $processGedcoms, $processIfs, $processRepeats, $reportTitle, $pgvreport, $reportDescription;
// global $processFootnote;
if ($printData && ($processGedcoms==0) && ($processIfs==0)&&($processRepeats==0)) {
$currentElement->addText($data);
} elseif ($reportTitle) {
$pgvreport->addTitle($data);
} elseif ($reportDescription) {
$pgvreport->addDescription($data);
}
}
/**
* XML elemnt handler
*
* @param array $attrs an array of key value pairs for the attributes
* @see PGVReportBase::$defaultFont
* @see PGVReportBase::$defaultFontSize
* @see PGVReportBase::addStyle()
* @todo add info - update wiki
*/
function PGVRStyleSHandler($attrs) {
global $pgvreport;
if (empty($attrs["name"])) {
die("REPORT ERROR PGVRStyle: The \"name\" of the style is missing or not set in the XML file.");
}
// array Style that will be passed on
$s = array();
// string Name af the style
$s["name"] = $attrs["name"];
// string Name of the DEFAULT font
$s["font"] = $pgvreport->defaultFont;
if (!empty($attrs["font"])) $s["font"] = $attrs["font"];
// int The size of the font in points
$s["size"] = $pgvreport->defaultFontSize;
if (!empty($attrs["size"])) $s["size"] = (int)$attrs["size"]; // Get it as int to ignore all decimal points or text (if any text then int(0))
// string B: bold, I: italic, U: underline, D: line trough, The default value is regular.
$s["style"] = "";
if (!empty($attrs["style"])) $s["style"] = $attrs["style"];
$pgvreport->addStyle($s);
}
/**
* XML start elemnt handler
*
* Sets up the basics of the document proparties
* @param array $attrs an array of key value pairs for the attributes
* @see PGVRDocEHandler()
* @see PGVReportBase::setup()
* @todo add showGeneratedBy, height, width param to wiki and update the defaults
*/
function PGVRDocSHandler($attrs) {
global $parser, $xml_parser, $pgvreport;
$parser = $xml_parser;
// Custom page width
if (!empty($attrs["customwidth"])) $pgvreport->pagew = (int)$attrs["customwidth"]; // Get it as int to ignore all decimal points or text (if any text then int(0))
// Custom Page height
if (!empty($attrs["customheight"])) $pgvreport->pageh = (int)$attrs["customheight"]; // Get it as int to ignore all decimal points or text (if any text then int(0))
// Left Margin
if (isset($attrs["leftmargin"])) {
if ($attrs["leftmargin"] === "0") $pgvreport->leftmargin = 0;
elseif (!empty($attrs["leftmargin"])) {
$pgvreport->leftmargin = (int)$attrs["leftmargin"]; // Get it as int to ignore all decimal points or text (if any text then int(0))
}
}
// Right Margin
if (isset($attrs["rightmargin"])) {
if ($attrs["rightmargin"] === "0") $pgvreport->rightmargin = 0;
elseif (!empty($attrs["rightmargin"])) {
$pgvreport->rightmargin = (int)$attrs["rightmargin"]; // Get it as int to ignore all decimal points or text (if any text then int(0))
}
}
// Top Margin
if (isset($attrs["topmargin"])) {
if ($attrs["topmargin"] === "0") $pgvreport->topmargin = 0;
elseif (!empty($attrs["topmargin"])) {
$pgvreport->topmargin = (int)$attrs["topmargin"]; // Get it as int to ignore all decimal points or text (if any text then int(0))
}
}
// Bottom Margin
if (isset($attrs["bottommargin"])) {
if ($attrs["bottommargin"] === "0") $pgvreport->bottommargin = 0;
elseif (!empty($attrs["bottommargin"])) {
$pgvreport->bottommargin = (int)$attrs["bottommargin"]; // Get it as int to ignore all decimal points or text (if any text then int(0))
}
}
// Header Margin
if (isset($attrs["headermargin"])) {
if ($attrs["headermargin"] === "0") $pgvreport->headermargin = 0;
elseif (!empty($attrs["headermargin"])) {
$pgvreport->headermargin = (int)$attrs["headermargin"]; // Get it as int to ignore all decimal points or text (if any text then int(0))
}
}
// Footer Margin
if (isset($attrs["footermargin"])) {
if ($attrs["footermargin"] === "0") $pgvreport->footermargin = 0;
elseif (!empty($attrs["footermargin"])) {
$pgvreport->footermargin = (int)$attrs["footermargin"]; // Get it as int to ignore all decimal points or text (if any text then int(0))
}
}
// Page Orientation
if (!empty($attrs["orientation"])) {
if ($attrs["orientation"] == "landscape") $pgvreport->orientation = "landscape";
elseif ($attrs["orientation"] == "portrait") {
$pgvreport->orientation = "portrait";
}
}
// Page Size
if (!empty($attrs["pageSize"])) $pgvreport->pageFormat = strtoupper($attrs["pageSize"]);
// Show Generated By...
if (isset($attrs["showGeneratedBy"])) {
if ($attrs["showGeneratedBy"] === "0") $pgvreport->showGenText = false;
elseif ($attrs["showGeneratedBy"] === "1") {
$pgvreport->showGenText = true;
}
}
$pgvreport->setup();
}
/**
* XML end elemnt handler
*
* @see PGVRDocSHandler()
*/
function PGVRDocEHandler() {
global $pgvreport;
$pgvreport->run();
}
/**
* XML start elemnt handler
*
* @see PGVReportBase::setProcessing()
*/
function PGVRHeaderSHandler() {
global $pgvreport;
// Clear the Header before any new elements are added
$pgvreport->clearHeader();
$pgvreport->setProcessing("H");
}
/**
* XML start elemnt handler
*
* @param array $attrs an array of key value pairs for the attributes
* @see PGVRPageHeaderEHandler()
*/
function PGVRPageHeaderSHandler($attrs) {
global $printDataStack, $printData, $pgvreportStack, $pgvreport, $PGVReportRoot;
array_push($printDataStack, $printData);
$printData = false;
array_push($pgvreportStack, $pgvreport);
$pgvreport = $PGVReportRoot->createPageHeader();
}
/**
* XML end elemnt handler
*
* @see PGVRPageHeaderSHandler()
*/
function PGVRPageHeaderEHandler() {
global $printData, $printDataStack, $pgvreport, $currentElement, $pgvreportStack;
$printData = array_pop($printDataStack);
$currentElement = $pgvreport;
$pgvreport = array_pop($pgvreportStack);
$pgvreport->addElement($currentElement);
}
/**
* XML start elemnt handler
*/
function PGVRBodySHandler() {
global $pgvreport;
$pgvreport->setProcessing("B");
}
/**
* XML start elemnt handler
*/
function PGVRFooterSHandler() {
global $pgvreport;
$pgvreport->setProcessing("F");
}
/**
* XML start elemnt handler
*
* @param array $attrs an array of key value pairs for the attributes
* @see PGVRCellEHandler()
* @see PGVRCell
* @todo defaults to wiki
*/
function PGVRCellSHandler($attrs) {
global $printData, $printDataStack, $currentElement, $PGVReportRoot, $pgvreport;
// string The text alignment of the text in this box.
$align= "";
if (!empty($attrs["align"])) {
$align = $attrs["align"];
// RTL supported left/right alignment
if ($align == "rightrtl") {
if ($pgvreport->rtl) {
$align = "left";
} else {
$align = "right";
}
} elseif ($align == "leftrtl") {
if ($pgvreport->rtl) {
$align = "right";
} else {
$align = "left";
}
}
}
// string The color to fill the background of this cell
$bgcolor = "";
if (!empty($attrs["bgcolor"])) $bgcolor = $attrs["bgcolor"];
// int Whether or not the background should be painted
$fill = 1;
if (isset($attrs["fill"])) {
if ($attrs["fill"] === "0") {
$fill = 0;
} elseif ($attrs["fill"] === "1") {
$fill = 1;
}
}
$reseth = true;
// boolean if true reset the last cell height (default true)
if (isset($attrs["reseth"])) {
if ($attrs["reseth"] === "0") {
$reseth = false;
} elseif ($attrs["reseth"] === "1") {
$reseth = true;
}
}
// mixed Whether or not a border should be printed around this box
$border = 0;
if (!empty($attrs["border"])) $border = $attrs["border"];
// @test Print all borders for testing
// $border = 1;
// string Border color in HTML code
$bocolor = "";
if (!empty($attrs["bocolor"])) $bocolor = $attrs["bocolor"];
// int Cell height (expressed in points) The starting height of this cell. If the text wraps the height will automatically be adjusted.
$height= 0;
if (!empty($attrs["height"])) $height = (int)$attrs["height"];
// int Cell width (expressed in points) Setting the width to 0 will make it the width from the current location to the right margin.
$width = 0;
if (!empty($attrs["width"])) $width = (int)$attrs["width"];
// int Stretch carachter mode
$stretch= 0;
if (!empty($attrs["stretch"])) $stretch = (int)$attrs["stretch"];
// mixed Position the left corner of this box on the page. The default is the current position.
$left = ".";
if (isset($attrs["left"])) {
if ($attrs["left"] === ".") {
$left = ".";
} elseif (!empty($attrs["left"])) {
$left = (int)$attrs["left"];
} elseif ($attrs["left"] === "0") {
$left = 0;
}
}
// mixed Position the top corner of this box on the page. the default is the current position
$top = ".";
if (isset($attrs["top"])) {
if ($attrs["top"] === ".") {
$top = ".";
} elseif (!empty($attrs["top"])) {
$top = (int)$attrs["top"];
} elseif ($attrs["top"] === "0") {
$top = 0;
}
}
// string The name of the PGVRStyle that should be used to render the text.
$style = "";
if (!empty($attrs["style"])) $style = $attrs["style"];
// string Text color in html code
$tcolor = "";
if (!empty($attrs["tcolor"])) $tcolor = $attrs["tcolor"];
// int Indicates where the current position should go after the call.
$ln = 0;
if (isset($attrs["newline"])) {
if (!empty($attrs["newline"])) {
$ln = (int)$attrs["newline"];
} elseif ($attrs["newline"] === "0") {
$ln = 0;
}
}
if ($align=="left") {
$align="L";
} elseif ($align=="right") {
$align="R";
} elseif ($align=="center") {
$align="C";
} elseif ($align=="justify") {
$align="J";
}
array_push($printDataStack, $printData);
$printData = true;
$currentElement = $PGVReportRoot->createCell($width, $height, $border, $align, $bgcolor, $style, $ln, $top, $left, $fill, $stretch, $bocolor, $tcolor, $reseth);
}
/**
* XML end elemnt handler
*
* @see PGVRCellSHandler()
* @final
*/
function PGVRCellEHandler() {
global $printData, $printDataStack, $currentElement, $pgvreport;
$printData = array_pop($printDataStack);
$pgvreport->addElement($currentElement);
}
/**
* XML elemnt handler
*
* @see PGVRElement::addText()
* @final
*/
function PGVRNowSHandler() {
global $currentElement;
$g = timestamp_to_gedcom_date(client_time());
$currentElement->addText($g->Display());
}
/**
* XML elemnt handler
*
* @see PGVRElement::addText()
* @final
*/
function PGVRPageNumSHandler() {
global $currentElement;
$currentElement->addText("#PAGENUM#");
}
/**
* XML elemnt handler
*
* @see PGVRElement::addText()
* @final
*/
function PGVRTotalPagesSHandler() {
global $currentElement;
$currentElement->addText("{{nb}}");
}
/**
* @see PGVRGedcomEHandler()
* @todo add info
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRGedcomSHandler($attrs) {
global $vars, $gedrec, $gedrecStack, $processGedcoms, $fact, $desc, $ged_level;
if ($processGedcoms>0) {
$processGedcoms++;
return;
}
$id = "";
$match = array();
if (preg_match("/0 @(.+)@/", $gedrec, $match)) {
$id = $match[1];
}
$tag = $attrs["id"];
$tag = str_replace("@fact", $fact, $tag);
$tags = explode(":", $tag);
$newgedrec = "";
if (count($tags)<2) {
$newgedrec = find_gedcom_record($attrs["id"], WT_GED_ID);
}
if (empty($newgedrec)) {
$tgedrec = $gedrec;
$newgedrec = "";
foreach($tags as $tag) {
if (preg_match("/\\$(.+)/", $tag, $match)) {
if (isset($vars[$match[1]]["gedcom"])) {
$newgedrec = $vars[$match[1]]["gedcom"];
} else {
$newgedrec = find_gedcom_record($match[1], WT_GED_ID);
}
} else {
if (preg_match("/@(.+)/", $tag, $match)) {
$gmatch = array();
if (preg_match("/\d $match[1] @([^@]+)@/", $tgedrec, $gmatch)) {
$newgedrec = find_gedcom_record($gmatch[1], WT_GED_ID);
$tgedrec = $newgedrec;
} else {
$newgedrec = "";
break;
}
} else {
$temp = explode(" ", trim($tgedrec));
$level = $temp[0] + 1;
if (showFact($tag, $id) && showFactDetails($tag, $id)) {
$newgedrec = get_sub_record($level, "$level $tag", $tgedrec);
$tgedrec = $newgedrec;
} else {
$newgedrec = "";
break;
}
}
}
}
}
if (!empty($newgedrec)) {
$gedObj = new GedcomRecord($newgedrec);
array_push($gedrecStack, array($gedrec, $fact, $desc));
$gedrec = $gedObj->getGedcomRecord();
if (preg_match("/(\d+) (_?[A-Z0-9]+) (.*)/", $gedrec, $match)) {
$ged_level = $match[1];
$fact = $match[2];
$desc = trim($match[3]);
}
} else {
$processGedcoms++;
}
}
/**
* @see PGVRGedcomSHandler()
* @todo add info
*/
function PGVRGedcomEHandler() {
global $gedrec, $gedrecStack, $processGedcoms, $fact, $desc;
if ($processGedcoms>0) {
$processGedcoms--;
} else {
$temp = array_pop($gedrecStack);
$gedrec = $temp[0];
$fact = $temp[1];
$desc = $temp[2];
}
}
/**
* XML start elemnt handler
*
* @param array $attrs an array of key value pairs for the attributes
* @see PGVRTextBoxEHandler()
* @todo defaults to wiki
*/
function PGVRTextBoxSHandler($attrs) {
global $printData, $printDataStack, $pgvreport, $currentElement, $pgvreportStack, $PGVReportRoot;
// string Background color code
$bgcolor = "";
if (!empty($attrs["bgcolor"])) $bgcolor = $attrs["bgcolor"];
// boolean Wether or not fill the background color
$fill = true;
if (isset($attrs["fill"])) {
if ($attrs["fill"] === "0") {
$fill = false;
} elseif ($attrs["fill"] === "1") {
$fill = true;
}
}
// var boolean Whether or not a border should be printed around this box. 0 = no border, 1 = border. Default is 0
$border = false;
if (isset($attrs["border"])) {
if ($attrs["border"] === "1") {
$border = true;
} elseif ($attrs["border"] === "0") {
$border = false;
}
}
// @test Print all borders for testing
// $border = true;
/**
* Border style of rectangle. Array with keys among the following
* - L, T, R, B or combinations: Line style of left, top, right or bottom border.
* @var string
*/
/** not yet in use
$borderstyle = "";
if (!empty($attrs["borderstyle"])) $borderstyle = $attrs["borderstyle"];
*/
// int The starting height of this cell. If the text wraps the height will automatically be adjusted
$height = 0;
if (!empty($attrs["height"])) $height = (int)$attrs["height"];
// int Setting the width to 0 will make it the width from the current location to the margin
$width = 0;
if (!empty($attrs["width"])) $width = (int)$attrs["width"];
// mixed Position the left corner of this box on the page. The default is the current position.
$left = ".";
if (isset($attrs["left"])) {
if ($attrs["left"] === ".") {
$left = ".";
} elseif (!empty($attrs["left"])) {
$left = (int)$attrs["left"];
} elseif ($attrs["left"] === "0") {
$left = 0;
}
}
// mixed Position the top corner of this box on the page. the default is the current position
$top = ".";
if (isset($attrs["top"])) {
if ($attrs["top"] === ".") {
$top = ".";
} elseif (!empty($attrs["top"])) {
$top = (int)$attrs["top"];
} elseif ($attrs["top"] === "0") {
$top = 0;
}
}
// boolean After this box is finished rendering, should the next section of text start immediately after the this box or should it start on a new line under this box. 0 = no new line, 1 = force new line. Default is 0
$newline = false;
if (isset($attrs["newline"])) {
if ($attrs["newline"] === "1") {
$newline = true;
} elseif ($attrs["newline"] === "0") {
$newline = false;
}
}
// boolean
$pagecheck = true;
if (isset($attrs["pagecheck"])) {
if ($attrs["pagecheck"] === "0") {
$pagecheck = false;
} elseif ($attrs["pagecheck"] === "1") {
$pagecheck = true;
}
}
// boolean Cell padding
$padding = true;
if (isset($attrs["padding"])) {
if ($attrs["padding"] === "0") {
$padding = false;
} elseif ($attrs["padding"] === "1") {
$padding = true;
}
}
// boolean Reset this box Height
$reseth = false;
if (isset($attrs["reseth"])) {
if ($attrs["reseth"] === "1") {
$reseth = true;
} elseif ($attrs["reseth"] === "0") {
$reseth = false;
}
}
// string Style of rendering
$style = "";
// fill and border is enought for now for user input
// if (!empty($attrs["style"])) $style = $attrs["style"];
array_push($printDataStack, $printData);
$printData = false;
array_push($pgvreportStack, $pgvreport);
$pgvreport = $PGVReportRoot->createTextBox($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth);
}
/**
* XML end elemnt handler
*
* @see PGVRTextBoxSHandler()
*/
function PGVRTextBoxEHandler() {
global $printData, $printDataStack, $pgvreport, $currentElement, $pgvreportStack;
$printData = array_pop($printDataStack);
$currentElement = $pgvreport;
$pgvreport = array_pop($pgvreportStack);
$pgvreport->addElement($currentElement);
}
/**
* @see PGVRTextEHandler()
* @todo add info to wiki about "color"
* @todo more variables in PGVRText class, check it out
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRTextSHandler($attrs) {
global $printData, $printDataStack, $currentElement, $PGVReportRoot;
array_push($printDataStack, $printData);
$printData = true;
// string The name of the PGVRStyle that should be used to render the text.
$style = "";
if (!empty($attrs["style"])) $style = $attrs["style"];
// string The color of the text - Keep the black color as default
$color = "";
if (!empty($attrs["color"])) $color = $attrs["color"];
$currentElement = $PGVReportRoot->createText($style, $color);
}
/**
* @see PGVRTextSHandler()
*/
function PGVRTextEHandler() {
global $printData, $printDataStack, $pgvreport, $currentElement;
$printData = array_pop($printDataStack);
$pgvreport->addElement($currentElement);
}
/**
* XML start elemnt handler
* Get the name
* 1. id is empty - current GEDCOM record
* 2. id is set with a record id
*
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRGetPersonNameSHandler($attrs) {
// @deprecated
global $currentElement, $vars, $gedrec;
$id = "";
$match = array();
if (empty($attrs["id"])) {
if (preg_match("/0 @(.+)@/", $gedrec, $match)) {
$id = $match[1];
}
} else {
if (preg_match("/\\$(.+)/", $attrs["id"], $match)) {
if (isset($vars[$match[1]]["id"])) {
$id = $vars[$match[1]]["id"];
}
} else {
if (preg_match("/@(.+)/", $attrs["id"], $match)) {
$gmatch = array();
if (preg_match("/\d $match[1] @([^@]+)@/", $gedrec, $gmatch)) {
$id = $gmatch[1];
}
} else {
$id = $attrs["id"];
}
}
}
if (!empty($id)) {
$record = GedcomRecord::getInstance($id);
if (is_null($record)) {
return;
}
if (!$record->canDisplayName()) {
$currentElement->addText(i18n::translate('Private'));
} else {
$name = $record->getFullName();
$name = preg_replace("/(.*)<\/span> ?/", "\\1* ", $name); //restores the * for underlining a given name
if (!WT_RNEW) {
$name = strip_tags($name);
}
if (!empty($attrs["truncate"])) {
//short-circuit with the faster strlen
if (strlen($name)>$attrs["truncate"] && utf8_strlen($name)>$attrs["truncate"]) {
$name = preg_replace("/\(.*\) ?/", "", $name); //removes () and text inbetween - what about ", [ and { etc?
$words = explode(" ", $name);
$name = $words[count($words)-1];
for($i=count($words)-2; $i>=0; $i--) {
$len = utf8_strlen($name);
for($j=count($words)-3; $j>=0; $j--) {
$len += utf8_strlen($words[$j]);
}
if ($len>$attrs["truncate"]) {
$first_letter = utf8_substr($words[$i], 0, 1);
//do not show " of nick-names
if ($first_letter != "\"") $name = utf8_substr($words[$i], 0, 1).". ".$name;
} else {
$name = $words[$i]." ".$name;
}
}
}
} else {
$addname = $record->getAddName();
$addname = preg_replace("/(.*)<\/span> ?/", "\\1* ", $addname); //@@ restores the * for underlining a given name
if (!WT_RNEW) {
$addname = strip_tags($addname);//@@
}
if (!empty($addname)) {
$name .= " ".$addname;
}
}
$currentElement->addText(trim($name));
}
}
}
/**
* XML start elemnt handler
*
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRGedcomValueSHandler($attrs) {
// @deprecated
global $currentElement, $gedrec, $fact, $desc;
$id = "";
$match = array();
if (preg_match("/0 @(.+)@/", $gedrec, $match)) {
$id = $match[1];
}
if (isset($attrs["newline"]) && $attrs["newline"]=="1") {
$useBreak = "1";
} else {
$useBreak = "0";
}
$tag = $attrs["tag"];
if (!empty($tag)) {
if ($tag=="@desc") {
if (showFact($fact, $id) or showFactDetails($fact, $id)) {
$value = $desc;
} else {
$value = "";
}
$value = trim($value);
$currentElement->addText($value);
}
if ($tag=="@id") {
$currentElement->addText($id);
} else {
$tag = str_replace("@fact", $fact, $tag);
if (empty($attrs["level"])) {
$temp = explode(" ", trim($gedrec));
$level = $temp[0];
if ($level==0) {
$level++;
}
} else {
$level = $attrs["level"];
}
$truncate = "";
if (isset($attrs["truncate"])) {
$truncate=$attrs["truncate"];
}
$tags = explode(":", $tag);
//-- check all tags for privacy
foreach($tags as $subtag) {
if (!empty($subtag)) {
if (!showFact($subtag, $id) or !showFactDetails($subtag, $id)) {
return;
}
}
}
if (showFact($fact, $id) or showFactDetails($fact, $id)) {
$value = get_gedcom_value($tag, $level, $gedrec, $truncate);
if ($useBreak == "1") {
// Insert
when multiple dates exist.
// This works around a TCPDF bug that incorrectly wraps RTL dates on LTR pages
$value = str_replace('(', '
(', $value);
$value = str_replace('
', '
', $value);
$value = str_replace('
', '
', $value);
if (substr($value, 0, 6) == '
') {
$value = substr($value, 6);
}
}
$currentElement->addText($value);
}
}
}
}
/**
* XML start elemnt handler
*
* @see PGVRRepeatTagEHandler()
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRRepeatTagSHandler($attrs) {
// @deprecated
// global $repeats, $repeatsStack, $gedrec, $repeatBytes, $parser, $parserStack, $processRepeats, $fact, $desc;
global $repeats, $repeatsStack, $gedrec, $repeatBytes, $parser, $processRepeats, $fact, $desc;
$processRepeats++;
if ($processRepeats>1) return;
array_push($repeatsStack, array($repeats, $repeatBytes));
$repeats = array();
$repeatBytes = xml_get_current_line_number($parser);
$id = "";
$match = array();
if (preg_match("/0 @(.+)@/", $gedrec, $match)) {
$id = $match[1];
}
$tag = "";
if (isset($attrs["tag"])) {
$tag = $attrs["tag"];
}
if (!empty($tag)) {
if ($tag=="@desc") {
if (showFact($fact, $id) and showFactDetails($fact, $id)) {
$value = $desc;
} else {
$value = "";
}
$value = trim($value);
$currentElement->addText($value);
} else {
$tag = str_replace("@fact", $fact, $tag);
$tags = explode(":", $tag);
$temp = explode(" ", trim($gedrec));
$level = $temp[0];
if ($level == 0) {
$level++;
}
$subrec = $gedrec;
$t = $tag;
$count = count($tags);
$i = 0;
while ($i < $count) {
$t = $tags[$i];
if (!empty($t)) {
if (($level==1) && (strpos("CHIL,FAMS,FAMC", $t)===false) and (!showFact($t, $id) or !showFactDetails($t, $id))) {
return;
}
if ($i < ($count-1)) {
$subrec = get_sub_record($level, "$level $t", $subrec);
if (empty($subrec)) {
$level--;
$subrec = get_sub_record($level, "@ $t", $gedrec);
if (empty($subrec)) {
return;
}
}
}
$level++;
}
$i++;
}
$level--;
if ( (($level > 0) or (strpos("CHIL,FAMS,FAMC", $t) !== false)) or ((showFact($t, $id)) or (showFactDetails($t, $id))) ) {
$count = preg_match_all("/$level $t(.*)/", $subrec, $match, PREG_SET_ORDER);
$i = 0;
while ($i < $count) {
// Check for privacy
if (showFact($t, $id) and showFactDetails($t, $id)) {
$rec = get_sub_record($level, "$level $t", $subrec, $i + 1);
$repeats[] = trim($rec);
}
$i++;
}
}
}
}
}
/**
* XML PGVRRepeatTag> end elemnt handler
*
* @see PGVRRepeatTagSHandler()
*/
function PGVRRepeatTagEHandler() {
global $processRepeats, $repeats, $repeatsStack, $repeatBytes;
$processRepeats--;
if ($processRepeats>0) {
return;
}
// Check if there is anything to repeat
if (count($repeats)>0) {
// No need to load them if not used...
global $parser, $parserStack, $report, $gedrec;
// @deprecated
// $line = xml_get_current_line_number($parser)-1;
$lineoffset = 0;
foreach($repeatsStack as $rep) {
$lineoffset += $rep[1];
}
//-- read the xml from the file
$lines = file($report);
while(strpos($lines[$lineoffset + $repeatBytes], "\n";
$line_nr = $lineoffset + $repeatBytes;
// RepeatTag Level counter
$count = 1;
while(0 < $count) {
if (strstr($lines[$line_nr], " element
*
* If the variable is a date and 'date="1"' attribute is set then the date will be reformated
* from Sep to September
*
* @param array $attrs an array of key value pairs for the attributes
* @see PGVRSetVarSHandler()
*/
function PGVRvarSHandler($attrs) {
// @deprecated
global $currentElement, $type, $parser;
// Retrievable variables
global $desc, $fact, $language_settings, $vars;
if (empty($attrs["var"])) {
die("REPORT ERROR PGVRvar: The attribute \"var=\" is missing or not set in the XML file on line: ".xml_get_current_line_number($parser));
}
$var = $attrs["var"];
// PGVRSetVar element preset variables
if (!empty($vars[$var]["id"])) {
$var = $vars[$var]["id"];
} else {
$tfact = $fact;
if (($fact == "EVEN" or $fact == "FACT") and $type != " ") {
// Use :
// n TYPE This text if string
$tfact = $type;
}
$var = str_replace(array("[", "]", "@fact", "@desc"), array("['", "']", $tfact, $desc), $var);
eval("if (!empty(\$$var)) \$var = \$$var;");
$match = array();
if (preg_match("/factarray\['(.*)'\]/", $var, $match)) {
$var = $match[1];
}
}
// Check if variable is set as a date and reformat the date
if (isset($attrs["date"])) {
if ($attrs["date"] === "1") {
$g = new GedcomDate($var);
$var = $g->Display();
}
}
$currentElement->addText($var);
}
/**
* Variable lookup, retrieve the first letter only
*
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRvarLetterSHandler($attrs) {
global $currentElement, $fact, $desc;
if (empty($attrs["var"])) {
die("REPORT ERROR PGVRvarLetter: The attribute \"var=\" is missing or not set in the XML file.");
}
$var = $attrs["var"];
if (!empty($var)) {
$abbrev = substr(strrchr(substr($var, 0, -1), "["), 1);
$tfact = $fact;
$var = str_replace(array("[", "]", "@fact", "@desc"), array("['", "']", $tfact, $desc), $var);
eval("if (!empty(\$$var)) \$var = \$$var;");
$letter = utf8_substr($var, 0, 1);
$currentElement->addText($letter);
}
}
/**
* @todo add info
* @param array $attrs an array of key value pairs for the attributes
* @see PGVRFactsEHandler()
*/
function PGVRFactsSHandler($attrs) {
// @deprecated
// global $repeats, $repeatsStack, $gedrec, $parser, $parserStack, $repeatBytes, $processRepeats, $vars;
global $repeats, $repeatsStack, $gedrec, $parser, $repeatBytes, $processRepeats, $vars;
$processRepeats++;
if ($processRepeats>1) return;
// @todo Why is this here when its not used?
$families = 1;
if (isset($attrs["families"])) {
$families = $attrs["families"];
}
array_push($repeatsStack, array($repeats, $repeatBytes));
$repeats = array();
$repeatBytes = xml_get_current_line_number($parser);
$id = "";
$match = array();
if (preg_match("/0 @(.+)@/", $gedrec, $match)) {
$id = $match[1];
}
$tag = "";
if (isset($attrs["ignore"])) {
$tag .= $attrs["ignore"];
}
if (preg_match("/\\$(.+)/", $tag, $match)) {
$tag = $vars[$match[1]]["id"];
}
if (empty($attrs["diff"]) && !empty($id)) {
$record = GedcomRecord::getInstance($id);
$facts = $record->getFacts(explode(",", $tag));
if (!is_array($facts)) {
$facts = array($facts);
}
sort_facts($facts);
$repeats = array();
foreach($facts as $event) {
if (strpos($tag.",", $event->getTag())===false) {
$repeats[]=$event->getGedComRecord();
}
}
} else {
global $nonfacts;
$nonfacts = preg_split("/[\s,;:]/", $tag);
$record = new GedcomRecord($gedrec);
switch ($record->getType()) {
case "INDI":
$record=new Person($gedrec);
break;
case "FAM":
$record=new Family($gedrec);
break;
case "SOUR":
$record=new Source($gedrec);
break;
case "REPO":
$record=new Repository($gedrec);
break;
case "NOTE":
$record=new Note($gedrec);
break;
}
$oldrecord = GedcomRecord::getInstance($record->getXref());
$oldrecord->diffMerge($record);
$facts = $oldrecord->getFacts();
foreach ($facts as $fact) {
if (strpos($fact->getGedcomRecord(), "WT_NEW")!==false) {
$repeats[]=$fact->getGedcomRecord();
}
}
}
}
/**
* XML PGVRFacts> end elemnt handler
*
* @see PGVRFactsSHandler()
*/
function PGVRFactsEHandler() {
global $repeats, $repeatsStack, $repeatBytes, $parser, $parserStack, $report, $gedrec, $fact, $desc, $type, $processRepeats;
$processRepeats--;
if ($processRepeats>0) {
return;
}
// Check if there is anything to repeat
if (count($repeats) > 0) {
$line = xml_get_current_line_number($parser)-1;
$lineoffset = 0;
foreach($repeatsStack as $rep) {
$lineoffset += $rep[1];
}
//-- read the xml from the file
$lines = file($report);
while(($lineoffset + $repeatBytes > 0) and (strpos($lines[$lineoffset + $repeatBytes], "\n";
$i = $line + $lineoffset;
$line_nr = $repeatBytes + $lineoffset;
while($line_nr < $i) {
$reportxml .= $lines[$line_nr];
$line_nr++;
}
// No need to drag this
unset($lines);
$reportxml .= "\n";
// Save original values
array_push($parserStack, $parser);
$oldgedrec = $gedrec;
$count = count($repeats);
$i = 0;
$match = array();
while($i < $count) {
$gedrec = $repeats[$i];
$fact = "";
$desc = "";
if (preg_match("/1 (\w+)(.*)/", $gedrec, $match)) {
$fact = $match[1];
if ($fact=="EVEN" or $fact=="FACT") {
$tmatch = array();
if (preg_match("/2 TYPE (.+)/", $gedrec, $tmatch)) {
$type = trim($tmatch[1]);
} else {
$type = " ";
}
}
$desc = trim($match[2]);
$desc .= get_cont(2, $gedrec);
}
//-- start the sax parser
$repeat_parser = xml_parser_create();
$parser = $repeat_parser;
//-- make sure everything is case sensitive
xml_parser_set_option($repeat_parser, XML_OPTION_CASE_FOLDING, false);
//-- set the main element handler functions
xml_set_element_handler($repeat_parser, "startElement", "endElement");
//-- set the character data handler
xml_set_character_data_handler($repeat_parser, "characterData");
if (!xml_parse($repeat_parser, $reportxml, true)) {
die(sprintf($reportxml."\nPGVRFactsEHandler XML error: %s at line %d", xml_error_string(xml_get_error_code($repeat_parser)), xml_get_current_line_number($repeat_parser)));
}
xml_parser_free($repeat_parser);
$i++;
}
// Restore original values
$parser = array_pop($parserStack);
$gedrec = $oldgedrec;
}
$temp = array_pop($repeatsStack);
$repeats = $temp[0];
$repeatBytes = $temp[1];
}
/**
* Setting upp or changing variables in the XML
* The XML variable name and value is stored in the global variable $vars
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRSetVarSHandler($attrs) {
global $vars, $gedrec, $fact, $desc, $type, $generation;
if (empty($attrs["name"])) {
die("REPORT ERROR PGVRvar: The attribute \"name=\" is missing or not set in the XML file");
}
$name = $attrs["name"];
$value = $attrs["value"];
$match = array();
// Current GEDCOM record strings
if ($value == "@ID") {
if (preg_match("/0 @(.+)@/", $gedrec, $match)) {
$value = $match[1];
}
} elseif ($value == "@fact") {
$value = $fact;
} elseif ($value == "@desc") {
$value = $desc;
} elseif ($value == "@generation") {
$value = $generation;
} elseif (preg_match("/@(\w+)/", $value, $match)) {
$gmatch = array();
if (preg_match("/\d $match[1] (.+)/", $gedrec, $gmatch)) {
$value = str_replace("@", "", trim($gmatch[1]));
}
}
if (preg_match("/\\$(\w+)/", $name, $match)) {
$name = $vars["'".$match[1]."'"]["id"];
}
// TODO: find an alternative that doesn't use pgv_lang
//if ((substr($value, 0, 10) == "\$pgv_lang[") or (substr($value, 0, 11) == "\$factarray[")) {
// $var = str_replace(array("[", "]"), array("['", "']"), $value);
// eval("\$value = $var;");
//}
//$count = preg_match_all("/\\$(\w+)/", $value, $match, PREG_SET_ORDER);
//$i=0;
//while($i<$count) {
// $t = $vars[$match[$i][1]]["id"];
// $value = preg_replace("/\\$".$match[$i][1]."/", $t, $value, 1);
// $i++;
//}
// Arithmetic functions
if (preg_match("/(\d+)\s*([\-\+\*\/])\s*(\d+)/", $value, $match)) {
switch($match[2]) {
case "+":
$t = $match[1] + $match[3];
$value = preg_replace("/".$match[1]."\s*([\-\+\*\/])\s*".$match[3]."/", $t, $value);
break;
case "-":
$t = $match[1] - $match[3];
$value = preg_replace("/".$match[1]."\s*([\-\+\*\/])\s*".$match[3]."/", $t, $value);
break;
case "*":
$t = $match[1] * $match[3];
$value = preg_replace("/".$match[1]."\s*([\-\+\*\/])\s*".$match[3]."/", $t, $value);
break;
case "/":
$t = $match[1] / $match[3];
$value = preg_replace("/".$match[1]."\s*([\-\+\*\/])\s*".$match[3]."/", $t, $value);
break;
}
}
if (strpos($value, "@")!==false) {
$value="";
}
$vars[$name]["id"]=$value;
}
/**
* XML start element
* @see PGVRifEHandler()
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRifSHandler($attrs) {
global $vars, $gedrec, $processIfs, $fact, $desc, $generation, $POSTAL_CODE;
if ($processIfs>0) {
$processIfs++;
return;
}
$vars["POSTAL_CODE"]["id"] = $POSTAL_CODE;
$condition = $attrs["condition"];
$condition = preg_replace("/\\$(\w+)/", "\$vars[\"$1\"][\"id\"]", $condition);
$condition = str_replace(array(" LT ", " GT "), array("<", ">"), $condition);
// Replace the first accurance only once of @fact:DATE or in any other combinations to the current fact, such as BIRT
$condition = str_replace("@fact", $fact, $condition);
$match = array();
$count = preg_match_all("/@([\w:\.]+)/", $condition, $match, PREG_SET_ORDER);
$i = 0;
while( $i < $count ) {
$id = $match[$i][1];
$value="\"\"";
if ($id=="ID") {
if (preg_match("/0 @(.+)@/", $gedrec, $match)) {
$value = "'".$match[1]."'";
}
} elseif ($id=="fact") {
$value = "\"$fact\"";
} elseif ($id=="desc") {
$value = "\"$desc\"";
} elseif ($id=="generation") {
$value = "\"$generation\"";
} else {
$temp = explode(" ", trim($gedrec));
$level = $temp[0];
if ($level==0) {
$level++;
}
$value = get_gedcom_value($id, $level, $gedrec, "", false);
if (empty($value)) {
$level++;
$value = get_gedcom_value($id, $level, $gedrec, "", false);
}
$value = "\"".str_replace(array("'", '"'), array("\'", '\"'), $value)."\"";
}
$condition = str_replace("@$id", $value, $condition);
$i++;
}
$condition = "if ($condition) return true; else return false;";
$ret = @eval($condition);
if (!$ret) {
$processIfs++;
}
}
/**
* XML end element
* @see PGVRifSHandler()
*/
function PGVRifEHandler() {
global $processIfs;
if ($processIfs>0) $processIfs--;
}
/**
* XML start element
* Collect the Footnote links
* GEDCOM Records that are protected by Privacy setting will be ignore
*
* @param array $attrs an array of key value pairs for the attributes
* @see PGVRFootnoteEHandler()
*/
function PGVRFootnoteSHandler($attrs) {
global $printData, $printDataStack, $currentElement, $footnoteElement, $processFootnote, $gedrec, $PGVReportRoot;
$match = array();
$id="";
$tag="";
if (preg_match("/[0-9] (.+) @(.+)@/", $gedrec, $match)) {
$tag = $match[1];
$id = $match[2];
}
if (displayDetailsById($id, $tag)) {
array_push($printDataStack, $printData);
$printData = true;
$style = "";
if (!empty($attrs["style"])) {
$style=$attrs["style"];
}
$footnoteElement = $currentElement;
$currentElement = $PGVReportRoot->createFootnote($style);
} else {
$printData = false;
$processFootnote = false;
}
}
/**
* XML end element
* Print the collected Footnote data
*
* @see PGVRFootnoteSHandler()
*/
function PGVRFootnoteEHandler() {
// @deprecated
// global $printData, $printDataStack, $currentElement, $footnoteElement, $processFootnote, $gedrec, $pgvreport;
global $printData, $printDataStack, $currentElement, $footnoteElement, $processFootnote, $pgvreport;
if ($processFootnote) {
$printData = array_pop($printDataStack);
$temp = trim($currentElement->getValue());
if (strlen($temp)>3) {
$pgvreport->addElement($currentElement);
}
$currentElement = $footnoteElement;
} else {
$processFootnote = true;
}
}
/**
* XML element
*
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRFootnoteTextsSHandler() {
global $pgvreport;
$temp = "footnotetexts";
$pgvreport->addElement($temp);
}
/**
* XML element Forced line break handler - HTML code
*
*/
function brSHandler() {
global $printData, $currentElement, $processGedcoms;
if ($printData && ($processGedcoms==0)) $currentElement->addText("
");
}
/**
* XML element Forced space handler
*
* @todo add info to wiki - missing function
*/
function spSHandler() {
global $printData, $currentElement, $processGedcoms;
if ($printData && ($processGedcoms==0)) $currentElement->addText(" ");
}
/**
* @todo add info
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRHighlightedImageSHandler($attrs) {
global $gedrec, $pgvreport, $PGVReportRoot;
$id = "";
$match = array();
if (preg_match("/0 @(.+)@/", $gedrec, $match)) {
$id = $match[1];
}
// mixed Position the top corner of this box on the page. the default is the current position
$top = ".";
if (isset($attrs["top"])) {
if ($attrs["top"] === "0") {
$top = 0;
} elseif ($attrs["top"] === ".") {
$top = ".";
} elseif (!empty($attrs["top"])) {
$top = (int)$attrs["top"];
}
}
// mixed Position the left corner of this box on the page. the default is the current position
$left = ".";
if (isset($attrs["left"])) {
if ($attrs["left"] === "0") {
$left = 0;
} elseif ($attrs["left"] === ".") {
$left = ".";
} elseif (!empty($attrs["left"])) {
$left = (int)$attrs["left"];
}
}
// string Align the image in left, center, right
$align = "";
if (!empty($attrs["align"])) $align = $attrs["align"];
// string Next Line should be T:next to the image, N:next line
$ln = "";
if (!empty($attrs["ln"])) $ln = $attrs["ln"];
$width = 0;
$height = 0;
if (!empty($attrs["width"])) $width = (int)$attrs["width"];
if (!empty($attrs["height"])) $height = (int)$attrs["height"];
if (showFact("OBJE", $id)) {
$media = find_highlighted_object($id, WT_GED_ID, $gedrec);
if (!empty($media["file"])) {
if (preg_match("/(jpg)|(jpeg)|(png)$/i", $media["file"])) {
if (file_exists($media["file"])) {
$size = findImageSize($media["file"]);
if (($width>0) and ($height==0)) {
$perc = $width / $size[0];
$height= round($size[1]*$perc);
} elseif (($height>0) and ($width==0)) {
$perc = $height / $size[1];
$width= round($size[0]*$perc);
} else {
$width = $size[0];
$height = $size[1];
}
$image = $PGVReportRoot->createImage($media["file"], $left, $top, $width, $height, $align, $ln);
$pgvreport->addElement($image);
}
}
}
}
}
/**
* @todo add info
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRImageSHandler($attrs) {
global $gedrec, $pgvreport, $MEDIA_DIRECTORY, $PGVReportRoot;
// mixed Position the top corner of this box on the page. the default is the current position
$top = ".";
if (isset($attrs["top"])) {
if ($attrs["top"] === "0") {
$top = 0;
} elseif ($attrs["top"] === ".") {
$top = ".";
} elseif (!empty($attrs["top"])) {
$top = (int)$attrs["top"];
}
}
// mixed Position the left corner of this box on the page. the default is the current position
$left = ".";
if (isset($attrs["left"])) {
if ($attrs["left"] === "0") {
$left = 0;
} elseif ($attrs["left"] === ".") {
$left = ".";
} elseif (!empty($attrs["left"])) {
$left = (int)$attrs["left"];
}
}
// string Align the image in left, center, right
$align = "";
if (!empty($attrs["align"])) $align = $attrs["align"];
// string Next Line should be T:next to the image, N:next line
$ln = "T";
if (!empty($attrs["ln"])) $ln = $attrs["ln"];
$width = 0;
$height = 0;
if (!empty($attrs["width"])) $width = (int)$attrs["width"];
if (!empty($attrs["height"])) $height = (int)$attrs["height"];
$file = "";
if (!empty($attrs["file"])) $file = $attrs["file"];
if ($file=="@FILE") {
$match = array();
if (preg_match("/\d OBJE @(.+)@/", $gedrec, $match)) {
$orec = find_gedcom_record($match[1], WT_GED_ID);
} else {
$orec = $gedrec;
}
if (!empty($orec)) {
$fullpath = extract_fullpath($orec);
$filename = "";
$filename = extract_filename($fullpath);
$filename = $MEDIA_DIRECTORY.$filename;
$filename = trim($filename);
if (!empty($filename)) {
if (preg_match("/(jpg)|(jpeg)|(png)$/i", $filename)) {
if (file_exists($filename)) {
$size = findImageSize($filename);
if (($width > 0) and ($height == 0)) {
$perc = $width / $size[0];
$height= round($size[1]*$perc);
} elseif (($height > 0) and ($width == 0)) {
$perc = $height / $size[1];
$width= round($size[0]*$perc);
} else {
$width = $size[0];
$height = $size[1];
}
$image = $PGVReportRoot->createImage($filename, $left, $top, $width, $height, $align, $ln);
$pgvreport->addElement($image);
}
}
}
}
}
else {
$filename = $file;
if (preg_match("/(jpg)|(jpeg)|(png)|(gif)$/i", $filename)) {
if (file_exists($filename)) {
$size = findImageSize($filename);
if (($width>0) and ($height==0)) {
$perc = $width / $size[0];
$height= round($size[1]*$perc);
} elseif (($height>0) and ($width==0)) {
$perc = $height / $size[1];
$width= round($size[0]*$perc);
} else {
$width = $size[0];
$height = $size[1];
}
$image = $PGVReportRoot->createImage($filename, $left, $top, $width, $height, $align, $ln);
$pgvreport->addElement($image);
}
}
}
}
/**
* XML elemnt handler
*
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRLineSHandler($attrs) {
global $pgvreport, $PGVReportRoot;
// Start horizontal position, current position (default)
$x1 = ".";
if (isset($attrs["x1"])) {
if ($attrs["x1"] === "0") {
$x1 = 0;
} elseif ($attrs["x1"] === ".") {
$x1 = ".";
} elseif (!empty($attrs["x1"])) {
$x1 = (int)$attrs["x1"];
}
}
// Start vertical position, current position (default)
$y1 = ".";
if (isset($attrs["y1"])) {
if ($attrs["y1"] === "0") {
$y1 = 0;
} elseif ($attrs["y1"] === ".") {
$y1 = ".";
} elseif (!empty($attrs["y1"])) {
$y1 = (int)$attrs["y1"];
}
}
// End horizontal position, maximum width (default)
$x2 = ".";
if (isset($attrs["x2"])) {
if ($attrs["x2"] === "0") {
$x2 = 0;
} elseif ($attrs["x2"] === ".") {
$x2 = ".";
} elseif (!empty($attrs["x2"])) {
$x2 = (int)$attrs["x2"];
}
}
// End vertical position
$y2 = ".";
if (isset($attrs["y2"])) {
if ($attrs["y2"] === "0") {
$y2 = 0;
} elseif ($attrs["y2"] === ".") {
$y2 = ".";
} elseif (!empty($attrs["y2"])) {
$y2 = (int)$attrs["y2"];
}
}
$line = $PGVReportRoot->createLine($x1, $y1, $x2, $y2);
$pgvreport->addElement($line);
}
/**
* XML start elemnt handler
*
* @see PGVRListEHandler()
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRListSHandler($attrs) {
global $gedrec, $repeats, $repeatBytes, $list, $repeatsStack, $processRepeats, $parser, $vars, $sortby;
global $GEDCOM, $TBLPREFIX;
$processRepeats++;
if ($processRepeats > 1) return;
$match = array();
if (isset($attrs["sortby"])) {
$sortby = $attrs["sortby"];
if (preg_match("/\\$(\w+)/", $sortby, $match)) {
$sortby = $vars[$match[1]]["id"];
$sortby = trim($sortby);
}
} else {
$sortby = "NAME";
}
if (isset($attrs["list"])) {
$listname=$attrs["list"];
} else {
$listname = "individual";
}
// Some filters/sorts can be applied using SQL, while others require PHP
switch ($listname) {
case "pending":
$rows=WT_DB::prepare(
"SELECT CASE new_gedcom WHEN '' THEN old_gedcom ELSE new_gedcom END AS gedcom".
" FROM {$TBLPREFIX}change".
" WHERE (xref, change_id) IN (".
" SELECT xref, MAX(change_id)".
" FROM {$TBLPREFIX}change".
" WHERE status='pending' AND gedcom_id=?".
" GROUP BY xref".
" )"
)->execute(array(WT_GED_ID))->fetchAll();
$list=array();
foreach ($rows as $row) {
$list[]=new GedcomRecord($row->gedcom);
}
break;
case "individual":
case "family":
$sql_col_prefix=substr($listname, 0, 1)."_"; // i_ for individual, f_ for family, etc.
$sql_join=array();
$sql_where=array($sql_col_prefix."file=".WT_GED_ID);
$sql_order_by=array();
foreach ($attrs as $attr=>$value) {
if ((strpos($attr, "filter")===0) && $value) {
// Substitute global vars
$value=preg_replace('/\$(\w+)/e', '$vars["\\1"]["id"]', $value);
// Convert the various filters into SQL
if (preg_match('/^(\w+):DATE (LTE|GTE) (.+)$/', $value, $match)) {
$sql_join[]="JOIN {$TBLPREFIX}dates AS {$attr} ON ({$attr}.d_file={$sql_col_prefix}file AND {$attr}.d_gid={$sql_col_prefix}id)";
$sql_where[]="{$attr}.d_fact='{$match[1]}'";
$date=new GedcomDate($match[3]);
if ($match[2]=="LTE") {
$sql_where[]="{$attr}.d_julianday2<=".$date->minJD();
} else {
$sql_where[]="{$attr}.d_julianday1>=".$date->minJD();
}
if ($sortby==$match[1]) {
$sortby="";
$sql_order_by[]="{$attr}.d_julianday1";
}
unset($attrs[$attr]); // This filter has been fully processed
} elseif (($listname=="individual") && (preg_match('/^NAME CONTAINS (.*)$/', $value, $match))){
// Do nothing, unless you have to
if (($match[1] != "") or ($sortby=="NAME")){
$sql_join[]="JOIN {$TBLPREFIX}name AS {$attr} ON (n_file={$sql_col_prefix}file AND n_id={$sql_col_prefix}id)";
// Search the DB only if there is any name supplied
if ($match[1] != ""){
$names = explode(" ", $match[1]);
foreach ($names as $name){
$sql_where[]="{$attr}.n_full LIKE ".WT_DB::quote(utf8_strtoupper("%{$name}%"));
}
}
// Let the DB do the name sorting even when no name was entered
if ($sortby=="NAME"){
$sortby="";
$sql_order_by[]="{$attr}.n_sort";
}
}
unset($attrs[$attr]); // This filter has been fully processed
} elseif (($listname=="family") && (preg_match('/^NAME CONTAINS (.+)$/', $value, $match))) {
// Eventually, family "names" will be stored in pgv_name. Until then, an extra is needed....
$sql_join[]="JOIN {$TBLPREFIX}link AS {$attr}a ON ({$attr}a.l_file={$sql_col_prefix}file AND {$attr}a.l_from={$sql_col_prefix}id)";
$sql_join[]="JOIN {$TBLPREFIX}name AS {$attr}b ON ({$attr}b.n_file={$sql_col_prefix}file AND n_id={$sql_col_prefix}id)";
$sql_where[]="{$attr}a.l_type=IN ('HUSB, 'WIFE')";
$sql_where[]="{$attr}.n_full LIKE ".WT_DB::quote(utf8_strtoupper("%{$match[1]}%"));
if ($sortby=="NAME") {
$sortby="";
$sql_order_by[]="{$attr}.n_sort";
}
unset($attrs[$attr]); // This filter has been fully processed
} elseif (preg_match('/^(?:\w+):PLAC CONTAINS (.+)$/', $value, $match)) {
$sql_join[]="JOIN {$TBLPREFIX}places AS {$attr}a ON ({$attr}a.p_file={$sql_col_prefix}file)";
$sql_join[]="JOIN {$TBLPREFIX}placelinks AS {$attr}b ON ({$attr}a.p_file={$attr}b.pl_file AND {$attr}b.pl_p_id={$attr}a.p_id AND {$attr}b.pl_gid={$sql_col_prefix}id)";
$sql_where[]="{$attr}a.p_place LIKE ".WT_DB::quote(utf8_strtoupper("%{$match[1]}%"));
// Don't unset this filter. This is just the first primary PLAC filter to reduce the returned list from the DB
}
/**
* General Purpose DB Filter for Individual and Family Lists
* Place any other filter before these filters because they will pick up any filters that has not been processed
* Also, do not unset() these two filters. These are just the first primary filters to reduce the returned list from the DB
*/
elseif (($listname=="individual") and (preg_match('/^(\w*):*(\w*) CONTAINS (.*)$/', $value, $match))){
$query = "";
// Level 1 tag
if ($match[1] != "") $query .= "%1 {$match[1]}%";
// Level 2 tag
if ($match[2] != "") $query .= "%2 {$match[2]}%";
// Contains what?
if ($match[3] != "") $query .= "%{$match[3]}%";
$sql_where[] = "i_gedcom LIKE ".WT_DB::quote(utf8_strtoupper($query));
unset($query);
} elseif (($listname=="family") and (preg_match('/^(\w*):*(\w*) CONTAINS (.*)$/', $value, $match))){
$query = "";
// Level 1 tag
if ($match[1] != "") $query .= "%1 {$match[1]}%";
// Level 2 tag
if ($match[2] != "") $query .= "%2 {$match[2]}%";
// Contains what?
if ($match[3] != "") $query .= "%{$match[3]}%";
$sql_where[] = "f_gedcom LIKE ".WT_DB::quote(utf8_strtoupper($query));
unset($query);
} else {
// TODO: what other filters can we apply in SQL?
}
}
}
if ($listname=="family") {
$list=search_fams_custom($sql_join, $sql_where, $sql_order_by);
} else {
$list=search_indis_custom($sql_join, $sql_where, $sql_order_by);
}
// Clean up the SQL queries - they will not be used again
unset($sql_join, $sql_where, $sql_order_by);
break;
default:
die("Invalid list name: $listname");
}
$filters = array();
$filters2 = array();
if ((isset($attrs["filter1"])) and (count($list) > 0)) {
foreach($attrs as $key=>$value) {
if (preg_match("/filter(\d)/", $key)) {
$condition = $value;
if (preg_match("/@(\w+)/", $condition, $match)) {
$id = $match[1];
$value="''";
if ($id=="ID") {
if (preg_match("/0 @(.+)@/", $gedrec, $match)) {
$value = "'".$match[1]."'";
}
} elseif ($id=="fact") {
$value = "'$fact'";
} elseif ($id=="desc") {
$value = "'$desc'";
} else {
if (preg_match("/\d $id (.+)/", $gedrec, $match)) {
$value = "'".str_replace("@", "", trim($match[1]))."'";
}
}
$condition = preg_replace("/@$id/", $value, $condition);
}
//-- handle regular expressions
if (preg_match("/([A-Z:]+)\s*([^\s]+)\s*(.+)/", $condition, $match)) {
$tag = trim($match[1]);
$expr = trim($match[2]);
$val = trim($match[3]);
if (preg_match("/\\$(\w+)/", $val, $match)) {
$val = $vars[$match[1]]["id"];
$val = trim($val);
}
$searchstr = "";
$tags = explode(":", $tag);
//-- only limit to a level number if we are specifically looking at a level
if (count($tags)>1) {
$level = 1;
foreach($tags as $t) {
if (!empty($searchstr)) {
$searchstr.="[^\n]*(\n[2-9][^\n]*)*\n";
}
//-- search for both EMAIL and _EMAIL... silly double gedcom standard
if ($t=="EMAIL" || $t=="_EMAIL") {
$t="_?EMAIL";
}
$searchstr .= $level." ".$t;
$level++;
}
} else {
if ($tag=="EMAIL" || $tag=="_EMAIL") {
$tag="_?EMAIL";
}
$t = $tag;
$searchstr = "1 ".$tag;
}
switch ($expr) {
case "CONTAINS":
if ($t=="PLAC") {
$searchstr.="[^\n]*[, ]*".$val;
} else {
$searchstr.="[^\n]*".$val;
}
$filters[] = $searchstr;
break;
default:
if (!empty($val)) {
$filters2[] = array("tag"=>$tag, "expr"=>$expr, "val"=>$val);
}
break;
}
}
}
}
}
//-- apply other filters to the list that could not be added to the search string
if ($filters) {
foreach ($list as $key=>$record) {
foreach ($filters as $filter) {
if (!preg_match("/".$filter."/i", $record->getGedcomRecord())) {
unset($list[$key]);
break;
}
}
}
}
if ($filters2) {
$mylist = array();
foreach($list as $indi) {
$key=$indi->getXref();
$grec=$indi->getGedcomRecord();
$keep = true;
foreach($filters2 as $filter) {
if ($keep) {
$tag = $filter["tag"];
$expr = $filter["expr"];
$val = $filter["val"];
if ($val=="''") {
$val = "";
}
$tags = explode(":", $tag);
$t = end($tags);
$v = get_gedcom_value($tag, 1, $grec, "", false);
//-- check for EMAIL and _EMAIL (silly double gedcom standard :P)
if ($t=="EMAIL" && empty($v)) {
$tag = str_replace("EMAIL", "_EMAIL", $tag);
$tags = explode(":", $tag);
$t = end($tags);
$v = get_sub_record(1, $tag, $grec);
}
$level = count($tags);
switch ($expr) {
case "GTE":
if ($t=="DATE") {
$date1 = new GedcomDate($v);
$date2 = new GedcomDate($val);
$keep = (GedcomDate::Compare($date1, $date2)>=0);
} elseif ($val >= $v) {
$keep=true;
}
break;
case "LTE":
if ($t=="DATE") {
$date1 = new GedcomDate($v);
$date2 = new GedcomDate($val);
$keep = (GedcomDate::Compare($date1, $date2)<=0);
} elseif ($val >= $v) {
$keep=true;
}
break;
case "SUBCONTAINS":
$v = get_sub_record($level, $level." ".$tag, $grec);
if (empty($v) && $tag=="ADDR") {
$v = get_sub_record($level+1, ($level+1)." ".$tag, $grec);
}
if (strripos($v, $val)!==false) {
$keep = true;
} else {
$keep = false;
}
break;
default:
if ($v==$val) {
$keep=true;
} else {
$keep = false;
}
break;
}
}
}
if ($keep) $mylist[$key]=$indi;
}
$list = $mylist;
}
switch ($sortby) {
case "NAME":
uasort($list, array("GedcomRecord", "Compare"));
break;
case "ID":
uasort($list, array("GedcomRecord", "CompareId"));
break;
case "CHAN":
uasort($list, array("GedcomRecord", "CompareChanDate"));
break;
case "BIRT:DATE":
uasort($list, array("Person", "CompareBirtDate"));
break;
case "DEAT:DATE":
uasort($list, array("Person", "CompareDeatDate"));
break;
case "MARR:DATE":
uasort($list, array("Family", "CompareMarrDate"));
break;
default:
// unsorted or already sorted by SQL
break;
}
array_push($repeatsStack, array($repeats, $repeatBytes));
$repeatBytes = xml_get_current_line_number($parser)+1;
}
/**
* XML end elemnt handler
* @see PGVRListSHandler()
*/
function PGVRListEHandler() {
global $list, $repeats, $repeatsStack, $repeatBytes, $parser, $parserStack, $report, $gedrec, $processRepeats, $list_total, $list_private;
$processRepeats--;
if ($processRepeats>0) {
return;
}
// Check if there is any list
if (count($list) > 0) {
// @deprecated
// $line = xml_get_current_line_number($parser)-1;
$lineoffset = 0;
foreach($repeatsStack as $rep) {
$lineoffset += $rep[1];
}
//-- read the xml from the file
$lines = file($report);
while((strpos($lines[$lineoffset + $repeatBytes], " 0)) {
$lineoffset--;
}
$lineoffset++;
$reportxml = "\n";
$line_nr = $lineoffset + $repeatBytes;
// List Level counter
$count = 1;
while(0 < $count) {
if (strpos($lines[$line_nr], "canDisplayDetails()) {
$gedrec = $record->getGedcomRecord();
//-- start the sax parser
$repeat_parser = xml_parser_create();
$parser = $repeat_parser;
//-- make sure everything is case sensitive
xml_parser_set_option($repeat_parser, XML_OPTION_CASE_FOLDING, false);
//-- set the main element handler functions
xml_set_element_handler($repeat_parser, "startElement", "endElement");
//-- set the character data handler
xml_set_character_data_handler($repeat_parser, "characterData");
if (!xml_parse($repeat_parser, $reportxml, true)) {
printf($reportxml."\nPGVRListEHandler XML error: %s at line %d", xml_error_string(xml_get_error_code($repeat_parser)), xml_get_current_line_number($repeat_parser));
print_r($repeatsStack);
debug_print_backtrace();
exit;
}
xml_parser_free($repeat_parser);
}
else $list_private++;
}
// Clean up the GLOBAL list array
unset($list);
$parser = array_pop($parserStack);
$gedrec = $oldgedrec;
}
$temp = array_pop($repeatsStack);
$repeats = $temp[0];
$repeatBytes = $temp[1];
}
/**
* XML elemnt handler
*
* Prints the total number of records in a list
* The total number is collected from
* PGVRList and PGVRRelatives
* @param array $attrs an array of key value pairs for the attributes
*/
function PGVRListTotalSHandler() {
global $list_total, $list_private, $currentElement;
if (empty($list_total)) $list_total = 0;
if ($list_private==0) {
$currentElement->addText($list_total);
} else {
$currentElement->addText(($list_total - $list_private)." / ".$list_total);
}
}
/**
* @todo add info
* @param array $attrs an array of key value pairs for the attributes
* @see PGVRRelativesEHandler()
*/
function PGVRRelativesSHandler($attrs) {
global $repeats, $repeatBytes, $list, $repeatsStack, $processRepeats, $parser, $vars, $sortby;
$processRepeats++;
if ($processRepeats>1) return;
$sortby = "NAME";
if (isset($attrs["sortby"])) $sortby = $attrs["sortby"];
$match = array();
if (preg_match("/\\$(\w+)/", $sortby, $match)) {
$sortby = $vars[$match[1]]["id"];
$sortby = trim($sortby);
}
$maxgen = -1;
if (isset($attrs["maxgen"])) $maxgen = $attrs["maxgen"];
if ($maxgen=="*") $maxgen = -1;
$group = "child-family";
if (isset($attrs["group"])) $group = $attrs["group"];
if (preg_match("/\\$(\w+)/", $group, $match)) {
$group = $vars[$match[1]]["id"];
$group = trim($group);
}
$id = "";
if (isset($attrs["id"])) $id = $attrs["id"];
if (preg_match("/\\$(\w+)/", $id, $match)) {
$id = $vars[$match[1]]["id"];
$id = trim($id);
}
$showempty = false;
if (isset($attrs["showempty"])) $showempty = $attrs["showempty"];
if (preg_match("/\\$(\w+)/", $showempty, $match)) {
$showempty = $vars[$match[1]]["id"];
$showempty = trim($showempty);
}
$list = array();
$person = Person::getInstance($id);
if (!empty($person)) {
$list[$id] = $person;
switch ($group) {
case "child-family":
$famids = $person->getChildFamilies();
foreach($famids as $family) {
$husband = $family->getHusband();
$wife = $family->getWife();
if (!empty($husband)) {
$list[$husband->getXref()] = $husband;
}
if (!empty($wife)) {
$list[$wife->getXref()] = $wife;
}
$children = $family->getChildren();
foreach($children as $child) {
if (!empty($child)) $list[$child->getXref()] = $child;
}
}
break;
case "spouse-family":
$famids = $person->getSpouseFamilies();
foreach($famids as $family) {
$husband = $family->getHusband();
$wife = $family->getWife();
if (!empty($husband)) {
$list[$husband->getXref()] = $husband;
}
if (!empty($wife)) {
$list[$wife->getXref()] = $wife;
}
$children = $family->getChildren();
foreach($children as $child) {
if (!empty($child)) $list[$child->getXref()] = $child;
}
}
break;
case "direct-ancestors":
add_ancestors($list, $id, false, $maxgen, $showempty);
break;
case "ancestors":
add_ancestors($list, $id, true, $maxgen, $showempty);
break;
case "descendants":
$list[$id]->generation = 1;
add_descendancy($list, $id, false, $maxgen);
break;
case "all":
add_ancestors($list, $id, true, $maxgen, $showempty);
add_descendancy($list, $id, true, $maxgen);
break;
}
}
switch ($sortby) {
case "NAME":
uasort($list, array("GedcomRecord", "Compare"));
break;
case "ID":
uasort($list, array("GedcomRecord", "CompareId"));
break;
case "BIRT:DATE":
uasort($list, array("PGVReportBase", "CompareBirthDate"));
break;
case "DEAT:DATE":
uasort($list, array("PGVReportBase", "CompareDeathDate"));
break;
case "generation":
$newarray = array();
reset($list);
$genCounter = 1;
while (count($newarray) < count($list)) {
foreach ($list as $key => $value) {
$generation = $value->generation;
if ($generation == $genCounter) {
$newarray[$key]->generation=$generation;
}
}
$genCounter++;
}
$list = $newarray;
break;
default:
// unsorted
break;
}
array_push($repeatsStack, array($repeats, $repeatBytes));
$repeatBytes = xml_get_current_line_number($parser)+1;
}
/**
* XML PGVRRelatives> end elemnt handler
*
* @see PGVRRelativesSHandler()
*/
function PGVRRelativesEHandler() {
global $list, $repeats, $repeatsStack, $repeatBytes, $parser, $parserStack, $report, $gedrec, $processRepeats, $list_total, $list_private, $generation;
$processRepeats--;
if ($processRepeats>0) {
return;
}
// Check if there is any relatives
if (count($list) > 0) {
// @deprecated
// $line = xml_get_current_line_number($parser)-1;
$lineoffset = 0;
foreach($repeatsStack as $rep) {
$lineoffset += $rep[1];
}
//-- read the xml from the file
$lines = file($report);
while((strpos($lines[$lineoffset + $repeatBytes], " 0)) {
$lineoffset--;
}
$lineoffset++;
$reportxml = "\n";
$line_nr = $lineoffset + $repeatBytes;
// Relatives Level counter
$count = 1;
while(0 < $count) {
if (strpos($lines[$line_nr], " $value) {
if (isset($value->generation)) {
$generation = $value->generation;
}
if (strpos($key, "empty")===0) {
continue; // key can be something like "empty7"
}
$tmp=GedcomRecord::getInstance($key);
$gedrec = $tmp->getGedcomRecord();
//-- start the sax parser
$repeat_parser = xml_parser_create();
$parser = $repeat_parser;
//-- make sure everything is case sensitive
xml_parser_set_option($repeat_parser, XML_OPTION_CASE_FOLDING, false);
//-- set the main element handler functions
xml_set_element_handler($repeat_parser, "startElement", "endElement");
//-- set the character data handler
xml_set_character_data_handler($repeat_parser, "characterData");
if (!xml_parse($repeat_parser, $reportxml, true)) {
printf($reportxml."\nPGVRRelativesEHandler XML error: %s at line %d", xml_error_string(xml_get_error_code($repeat_parser)), xml_get_current_line_number($repeat_parser));
print_r($repeatsStack);
debug_print_backtrace();
exit;
}
xml_parser_free($repeat_parser);
}
// Clean up the GLOBAL list array
unset($list);
$parser = array_pop($parserStack);
$gedrec = $oldgedrec;
}
$temp = array_pop($repeatsStack);
$repeats = $temp[0];
$repeatBytes = $temp[1];
}
/**
* XML elemnt handler
*
* Prints the number of generations
* @todo no info on wiki
* @see PGVRElement::addText()
*/
function PGVRGenerationSHandler() {
global $generation, $currentElement;
if (empty($generation)) $generation = 1;
$currentElement->addText($generation);
}
/**
* XML elemnt handler
*
* Has to be placed in an element (header, pageheader, body or footer)
* @final
* @todo update wiki, this element is missing
*/
function PGVRNewPageSHandler() {
global $pgvreport;
$temp = "addpage";
$pgvreport->addElement($temp);
}
/**
* @todo add info
* @todo not on wiki
* @param array $attrs an array of key value pairs for the attributes
* @param string $tag HTML tag name
* @see HTMLEHandler()
* @see PGVReportBase::createHTML()
*/
function HTMLSHandler($tag, $attrs) {
global $printData, $printDataStack, $pgvreportStack, $pgvreport, $currentElement, $PGVReportRoot;
if ($tag=="tempdoc") return;
array_push($pgvreportStack, $pgvreport);
$pgvreport = $PGVReportRoot->createHTML($tag, $attrs);
$currentElement = $pgvreport;
array_push($printDataStack, $printData);
$printData = true;
}
/**
* @todo add info
* @param array $attrs an array of key value pairs for the attributes
* @see HTMLSHandler()
*/
function HTMLEHandler($tag) {
global $printData, $printDataStack, $pgvreport, $currentElement, $pgvreportStack;
if ($tag=="tempdoc") return;
$printData = array_pop($printDataStack);
$currentElement = $pgvreport;
$pgvreport = array_pop($pgvreportStack);
if (!is_null($pgvreport)) $pgvreport->addElement($currentElement);
else $pgvreport = $currentElement;
}
/**
* XML start elemnt handler
*
* @todo add to wiki
* @see PGVRTitleEHandler()
* @final
*/
function PGVRTitleSHandler() {
global $reportTitle;
$reportTitle = true;
}
/**
* XML end elemnt handler
*
* @see PGVRTitleSHandler()
* @final
*/
function PGVRTitleEHandler() {
global $reportTitle;
$reportTitle = false;
}
/**
* XML start elemnt handler
*
* @todo add to wiki
* @see PGVRDescriptionEHandler()
* @final
*/
function PGVRDescriptionSHandler() {
global $reportDescription;
$reportDescription = true;
}
/**
* XML end elemnt handler
*
* @see PGVRDescriptionSHandler()
* @final
*/
function PGVRDescriptionEHandler() {
global $reportDescription;
$reportDescription = false;
}
?>