.
*/
namespace Fisharebest\Webtrees\Report;
use Fisharebest\Webtrees\Controller\SimpleController;
use Fisharebest\Webtrees\Functions\FunctionsRtl;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Media;
/**
* Class ReportHtml
*/
class ReportHtml extends ReportBase {
/**
* Cell padding
*
* @var int
*/
public $cPadding = 2;
/**
* Cell height ratio
*
* @var float
*/
public $cellHeightRatio = 1.8;
/**
* Current horizontal position
*
* @var float
*/
public $X = 0.0;
/**
* Current vertical position
*
* @var float
*/
public $Y = 0.0;
/**
* Currently used style name
*
* @var string
*/
public $currentStyle = '';
/**
* Page number counter
*
* @var int
*/
public $pageN = 1;
/**
* Store the page width without left and right margins
*
* In HTML, we don't need this
*
* @var float
*/
public $noMarginWidth = 0.0;
/**
* Last cell height
*
* @var float
*/
public $lastCellHeight = 0.0;
/**
* LTR or RTL alignement; "left" on LTR, "right" on RTL
* Used in
*
* @var string
*/
public $alignRTL = 'left';
/**
* LTR or RTL entity
*
* @var string
*/
public $entityRTL = '';
/**
* Largest Font Height is used by TextBox etc.
*
* Use this to calculate a the text height.
* This makes sure that the text fits into the cell/box when different font sizes are used
*
* @var int
*/
public $largestFontHeight = 0;
/**
* Keep track of the highest Y position
*
* Used with Header div / Body div / Footer div / "addpage" / The bottom of the last image etc.
*
* @var float
*/
public $maxY = 0;
/** @var ReportBaseElement[] Array of elements in the header */
public $headerElements = array();
/** @var ReportBaseElement[] Array of elements in the page header */
public $pageHeaderElements = array();
/** @var ReportBaseElement[] Array of elements in the footer */
public $footerElements = array();
/** @var ReportBaseElement[] Array of elements in the body */
public $bodyElements = array();
/** @var ReportBaseFootnote[] Array of elements in the footer notes */
public $printedfootnotes = array();
/**
* HTML Setup - ReportHtml
*/
public function setup() {
parent::setup();
// Setting up the correct dimensions if Portrait (default) or Landscape
if ($this->orientation == "landscape") {
$tmpw = $this->pagew;
$this->pagew = $this->pageh;
$this->pageh = $tmpw;
}
// Store the pagewidth without margins
$this->noMarginWidth = (int) ($this->pagew - $this->leftmargin - $this->rightmargin);
// If RTL
if ($this->rtl) {
$this->alignRTL = "right";
$this->entityRTL = "";
}
// Change the default HTML font name
$this->defaultFont = "Arial";
if ($this->showGenText) {
// The default style name for Generated by.... is 'genby'
$element = new ReportHtmlCell(0, 10, 0, 'C', '', 'genby', 1, '.', '.', 0, 0, '', '', true);
$element->addText($this->generatedby);
$element->setUrl(parent::WT_URL);
$this->footerElements[] = $element;
}
}
/**
* Add an element.
*
* @param $element
*/
public function addElement($element) {
if ($this->processing == "B") {
$this->bodyElements[] = $element;
} elseif ($this->processing == "H") {
$this->headerElements[] = $element;
} elseif ($this->processing == "F") {
$this->footerElements[] = $element;
}
}
/**
* Generate the page header
*/
public function runPageHeader() {
foreach ($this->pageHeaderElements as $element) {
if (is_object($element)) {
$element->render($this);
} elseif (is_string($element) && $element == "footnotetexts") {
$this->footnotes();
} elseif (is_string($element) && $element == "addpage") {
$this->addPage();
}
}
}
/**
* Generate footnotes
*/
public function footnotes() {
$this->currentStyle = "";
if (!empty($this->printedfootnotes)) {
foreach ($this->printedfootnotes as $element) {
$element->renderFootnote($this);
}
}
}
/**
* Run the report.
*/
public function run() {
$controller = new SimpleController;
$controller
->setPageTitle($this->title)
->pageHeader();
// Setting up the styles
echo '', PHP_EOL;
echo '';
echo '';
echo '';
echo '
';
$this->Y = 0;
$this->maxY = 0;
$this->runPageHeader();
foreach ($this->bodyElements as $element) {
if (is_object($element)) {
$element->render($this);
} elseif (is_string($element) && $element == "footnotetexts") {
$this->footnotes();
} elseif (is_string($element) && $element == "addpage") {
$this->addPage();
}
}
//-- footer
echo '
';
echo '';
echo '
';
echo '';
echo '';
echo '';
}
/**
* Create a new Cell object - ReportHtml
*
* @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
* @param bool $reseth
*
* @return object ReportHtmlCell
*/
public function createCell($width, $height, $border, $align, $bgcolor, $style, $ln, $top, $left, $fill, $stretch, $bocolor, $tcolor, $reseth) {
return new ReportHtmlCell($width, $height, $border, $align, $bgcolor, $style, $ln, $top, $left, $fill, $stretch, $bocolor, $tcolor, $reseth);
}
/**
* Create a text box.
*
* @param $width
* @param $height
* @param $border
* @param $bgcolor
* @param $newline
* @param $left
* @param $top
* @param $pagecheck
* @param $style
* @param $fill
* @param $padding
* @param $reseth
*
* @return ReportHtmlTextbox
*/
public function createTextBox($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth) {
return new ReportHtmlTextbox($width, $height, $border, $bgcolor, $newline, $left, $top, $pagecheck, $style, $fill, $padding, $reseth);
}
/**
* Create a text element.
*
* @param $style
* @param $color
*
* @return ReportHtmlText
*/
public function createText($style, $color) {
return new ReportHtmlText($style, $color);
}
/**
* Create a footnote.
*
* @param string $style
*
* @return ReportHtmlFootnote
*/
public function createFootnote($style = "") {
return new ReportHtmlFootnote($style);
}
/**
* Create a page header.
*
* @return ReportHtmlPageheader
*/
public function createPageHeader() {
return new ReportHtmlPageheader;
}
/**
* Create an image.
*
* @param $file
* @param $x
* @param $y
* @param $w
* @param $h
* @param $align
* @param $ln
*
* @return ReportHtmlImage
*/
public function createImage($file, $x, $y, $w, $h, $align, $ln) {
return new ReportHtmlImage($file, $x, $y, $w, $h, $align, $ln);
}
/**
* Create an image.
*
* @param Media $mediaobject
* @param $x
* @param $y
* @param $w
* @param $h
* @param $align
* @param $ln
*
* @return ReportHtmlImage
*/
public function createImageFromObject(Media $mediaobject, $x, $y, $w, $h, $align, $ln) {
return new ReportHtmlImage($mediaobject->getHtmlUrlDirect('thumb'), $x, $y, $w, $h, $align, $ln);
}
/**
* Create a line.
*
* @param $x1
* @param $y1
* @param $x2
* @param $y2
*
* @return ReportHtmlLine
*/
public function createLine($x1, $y1, $x2, $y2) {
return new ReportHtmlLine($x1, $y1, $x2, $y2);
}
/**
* Create an HTML element.
*
* @param $tag
* @param $attrs
*
* @return ReportHtmlHtml
*/
public function createHTML($tag, $attrs) {
return new ReportHtmlHtml($tag, $attrs);
}
/**
* Clear the Header - ReportHtml
*/
public function clearHeader() {
$this->headerElements = array();
}
/**
* Update the Page Number and set a new Y if max Y is larger - ReportHtml
*/
public function addPage() {
$this->pageN++;
// Add a little margin to max Y "between pages"
$this->maxY += 10;
// If Y is still heigher by any reason...
if ($this->maxY < $this->Y) {
// ... update max Y
$this->maxY = $this->Y;
} // else update Y so that nothing will be overwritten, like images or cells...
else {
$this->Y = $this->maxY;
}
}
/**
* Uppdate max Y to keep track it incase of a pagebreak - ReportHtml
*
* @param float $y
*/
public function addMaxY($y) {
if ($this->maxY < $y) {
$this->maxY = $y;
}
}
/**
* Add a page header.
*
* @param $element
*
* @return int
*/
public function addPageHeader($element) {
$this->pageHeaderElements[] = $element;
return count($this->headerElements) - 1;
}
/**
* Checks the Footnote and numbers them - ReportHtml
*
* @param object $footnote
*
* @return bool false if not numbered before | object if already numbered
*/
public function checkFootnote($footnote) {
$ct = count($this->printedfootnotes);
$i = 0;
$val = $footnote->getValue();
while ($i < $ct) {
if ($this->printedfootnotes[$i]->getValue() == $val) {
// If this footnote already exist then set up the numbers for this object
$footnote->setNum($i + 1);
$footnote->setAddlink($i + 1);
return $this->printedfootnotes[$i];
}
$i++;
}
// If this Footnote has not been set up yet
$footnote->setNum($ct + 1);
$footnote->setAddlink($ct + 1);
$this->printedfootnotes[] = $footnote;
return false;
}
/**
* Clear the Page Header - ReportHtml
*/
public function clearPageHeader() {
$this->pageHeaderElements = array();
}
/**
* Count the number of lines - ReportHtml
*
* @param string $str
*
* @return int Number of lines. 0 if empty line
*/
public function countLines($str) {
if ($str == "") {
return 0;
}
return (substr_count($str, "\n") + 1);
}
/**
* Get the current style.
*
* @return string
*/
public function getCurrentStyle() {
return $this->currentStyle;
}
/**
* Get the current style height.
*
* @return int
*/
public function getCurrentStyleHeight() {
if (empty($this->currentStyle)) {
return $this->defaultFontSize;
}
$style = $this->getStyle($this->currentStyle);
return $style["size"];
}
/**
* Get the current footnotes height.
*
* @param $cellWidth
*
* @return int
*/
public function getFootnotesHeight($cellWidth) {
$h = 0;
foreach ($this->printedfootnotes as $element) {
$h += $element->getFootnoteHeight($this, $cellWidth);
}
return $h;
}
/**
* Get the maximum width from current position to the margin - ReportHtml
*
* @return float
*/
public function getRemainingWidth() {
return $this->noMarginWidth - $this->X;
}
/**
* Get the page height.
*
* @return float
*/
public function getPageHeight() {
return $this->pageh - $this->topmargin;
}
/**
* Get the width of a string.
*
* @param $text
*
* @return int
*/
public function getStringWidth($text) {
$style = $this->getStyle($this->currentStyle);
return mb_strlen($text) * ($style['size'] / 2);
}
/**
* Get a text height in points - ReportHtml
*
* @param $str
*
* @return int
*/
public function getTextCellHeight($str) {
// Count the number of lines to calculate the height
$nl = $this->countLines($str);
// Calculate the cell height
return ceil(($this->getCurrentStyleHeight() * $this->cellHeightRatio) * $nl);
}
/**
* Get the current X position - ReportHtml
*
* @return float
*/
public function getX() {
return $this->X;
}
/**
* Get the current Y position - ReportHtml
*
* @return float
*/
public function getY() {
return $this->Y;
}
/**
* Get the current page number - ReportHtml
*
* @return int
*/
public function pageNo() {
return $this->pageN;
}
/**
* Set the current style.
*
* @param $s
*/
public function setCurrentStyle($s) {
$this->currentStyle = $s;
}
/**
* Set the X position - ReportHtml
*
* @param float $x
*/
public function setX($x) {
$this->X = $x;
}
/**
* Set the Y position - ReportHtml
*
* Also updates Max Y position
*
* @param float $y
*/
public function setY($y) {
$this->Y = $y;
if ($this->maxY < $y) {
$this->maxY = $y;
}
}
/**
* Set the X and Y position - ReportHtml
*
* Also updates Max Y position
*
* @param float $x
* @param float $y
*/
public function setXy($x, $y) {
$this->setX($x);
$this->setY($y);
}
/**
* Wrap text - ReportHtml
*
* @param string $str Text to wrap
* @param int $width Width in points the text has to fit into
*
* @return string
*/
public function textWrap($str, $width) {
// Calculate the line width
$lw = (int) ($width / ($this->getCurrentStyleHeight() / 2));
// Wordwrap each line
$lines = explode("\n", $str);
// Line Feed counter
$lfct = count($lines);
$wraptext = '';
foreach ($lines as $line) {
$wtext = FunctionsRtl::utf8WordWrap($line, $lw, "\n", true);
$wraptext .= $wtext;
// Add a new line as long as it’s not the last line
if ($lfct > 1) {
$wraptext .= "\n";
}
$lfct--;
}
return $wraptext;
}
/**
* Write text - ReportHtml
*
* @param string $text Text to print
* @param string $color HTML RGB color code (Ex: #001122)
* @param bool $useclass
*/
public function write($text, $color = '', $useclass = true) {
$style = $this->getStyle($this->getCurrentStyle());
$htmlcode = '
';
$htmlcode = str_replace(array("\n", '> ', ' <'), array('
', '> ', ' <'), $htmlcode);
echo $htmlcode;
}
}