db = $db; $this->man = $man; $this->page = $this->man->Route(); $qry = "SELECT l.ID,l.Bezeichnung,l.Hauptblock,b.Css,b.Breite,b.Höhe FROM sys_print_layouts l " ."LEFT JOIN sys_print_blocks b ON l.Hauptblock=b.ID WHERE Seite=? ORDER BY l.Bevorzugt DESC, l.Bezeichnung ASC"; if ($stmt = $this->db->prepare($qry)) { $stmt->bind_param("s", $this->page); $stmt->execute(); $res = $stmt->get_result(); while ($row = $res->fetch_assoc()) { $this->prints[] = [ "ID" => strval($row["ID"]), "Bezeichnung" => $row["Bezeichnung"], "Hauptblock" => $row["Hauptblock"], "Css" => $row["Css"], "Breite" => $row["Breite"], "Höhe" => $row["Höhe"], ]; } } } public function GetPrints() { return $this->prints; } public function CreateHtml($printID) { // Find requested layout $layout = null; foreach ($this->prints as $key => $print) { if (strval($printID)==$print["ID"]) { $layout = $print; break; } } // Breakoff if layout doesn't exist if (null == $layout) { $this->responseCode = 400; return; } // Get content $content = $this->man->Output()["content"]; $block = [ "ID" => $layout["Hauptblock"], "Bezeichnung" => $layout["Bezeichnung"], "Css" => $layout["Css"], "Breite" => $layout["Breite"], "Höhe" => $layout["Höhe"], "Links" => 0, "Oben" => 0 ]; $entries = $this->prepareEntries($content); $this->printBlock($block, $entries); $this->html.= $this->joinHtml($entries); $this->responseCode = 200; } public function GetHtml() { return $this->html; } public function ResponseCode() { return $this->responseCode; } /******************** Private functions *************************/ private function prepareEntries($content) { $ret = []; $selectionExists = sizeof($this->man->selected)>0; foreach ($content as $group) { foreach ($group["ENTRIES"] as $entry) { if (!$selectionExists || in_array($entry["ID"], $this->man->selected)) { $ret[$entry["ID"]] = [ "html" => "", "floating" => [], "content" => $entry, ]; } } } return $ret; } private function joinHtml($entries) { $ret = ""; foreach ($entries as $entry) { $ret.= $entry["html"]; } return $ret; } private function printBlock($block, &$entries) { // Initialize block $div = "
"; foreach ($entries as &$entry) { $entry["html"].= $div; } unset($entry); // $entry was used as a reference, so it needs to be unset // Fetch sub-blocks $qry = "SELECT spb.*,sph.Links,sph.Oben FROM sys_print_hierarchy sph LEFT JOIN sys_print_blocks spb ON spb.ID=sph.Kindblock WHERE sph.Block=".$block["ID"]; $res = $this->db->query($qry); while ($subblock = $res->fetch_assoc()) { $this->printBlock($subblock, $entries); } // Fetch block elements $elements = []; if ($res = $this->db->query("SELECT * FROM sys_print_elements WHERE Block=".$block["ID"]." ORDER BY Reihenfolge ASC")) { while ($element = $res->fetch_assoc()) { $this->printEntryElement($element, $entries); //$elements[] = $row; } } // Finalize block foreach ($entries as &$entry) { $entry["html"].= "
"; } unset($entry); } private function printEntryElement($element, &$entries) { foreach ($entries as &$entry) { $do_print = false; $cond = explode("|", $element["Bedingung"]); if ($element["Parameter"]=="") { $element["Parameter"] = "{}"; } $params = json_decode($element["Parameter"], true); switch ($cond[0]) { case null: case "": case "0": //Print always $do_print = true; //echo " - Print always"; break; case "1": //Field has to be NOT null, not false and not empty text //echo " - Print if NOT null/false/empty"; if (sizeof($cond)>1 && ($this->getContent($entry["content"], $cond[1])!==null && ( $this->getContent($entry["content"], $cond[1])!==false || $this->getContent($entry["content"], $cond[1], true)!="" ) ) ) { $do_print = true; } break; case "2": //Field has to be null, false or empty text //echo " - Print if null/false/empty"; if (sizeof($cond)>1 && ($this->getContent($entry["content"], $cond[1])===null || $this->getContent($entry["content"], $cond[1])===false || $this->getContent($entry["content"], $cond[1], true)=="")) $do_print = true; break; case "3": //Field has to be value (second parameter) or include value if is link if (sizeof($cond)>2) { // UNTESTED //echo " - Print if has/includes value ".$cond[2]; $result = $this->getContent($entry["content"], $cond[1]); $arr = is_array($result); $do_print = ($arr && in_array($cond[2], $result)) || (!$arr && $cond[2]==$result); } break; case "4": //Field has to be NOT value (second parameter) or DONT include value if is link if (sizeof($cond)>2) { // UNTESTED //echo " - Print if has/includes NOT value ".$cond[2]; $result = $this->getContent($entry["content"], $cond[1]); $arr = is_array($result); $do_print = ($arr && !in_array($cond[2], $result)) || (!$arr && $cond[2]!=$result); } break; case "5": //Field has to be text (second parameter) or include text if it is link if (sizeof($cond)>2) { //echo " - Print if has/includes text ".$cond[2]; $result = $this->getContent($entry["content"], $cond[1], 1); $testtexts = explode(",", $cond[2]); if (is_array($result)) { $do_print = true; foreach ($testtexts as $testtext) { if (!in_array($testtext, $result)) { $do_print = false; break; } } } else { $do_print = $cond[2]==$result; } } break; case "6": //Field has to be NOT text (second parameter) or DONT include text if it is link if (sizeof($cond)>2) { // UNTESTED //echo " - Print if has/includes NOT text ".$cond[2]; $result = $this->getContent($entry["content"], $cond[1], 1); $testtexts = explode(",", $cond[2]); if (is_array($result)) { $do_print = true; foreach ($testtexts as $testtext) { if (in_array($testtext, $result)) { $do_print = false; break; } } } else { $do_print = $cond[2]!=$result; } } break; } $print_count = 0; if ($do_print) { $print_count = $params["repeat"] ?? 1; } while ($print_count>0) { //echo " - Printing"; $print_count--; $border = array(); $border["top"] = isset($params["border-top"]) ? $params["border-top"] : (isset($params["border"]) ? $params["border"] : "0"); $border["bottom"] = isset($params["border-bottom"]) ? $params["border-bottom"] : (isset($params["border"]) ? $params["border"] : "0"); $border["left"] = isset($params["border-left"]) ? $params["border-left"] : (isset($params["border"]) ? $params["border"] : "0"); $border["right"] = isset($params["border-right"]) ? $params["border-right"] : (isset($params["border"]) ? $params["border"] : "0"); $border["color"] = isset($params["border-color"]) ? $params["border-color"] : "#000000"; $border["string"] = ""; if ($border["left"]!="0") { $border["string"].= "border-left: 1px solid ".$border["color"]."; "; } if ($border["right"]!="0") { $border["string"].= "border-right: 1px solid ".$border["color"]."; "; } if ($border["top"]!="0") { $border["string"].= "border-top: 1px solid ".$border["color"]."; "; } if ($border["bottom"]!="0") { $border["string"].= "border-bottom: 1px solid ".$border["color"]."; "; } /*if (isset($params["border"])) { $border["string"] = "border: 1px solid ".$border["color"].";"; }*/ $cnt = $element["Inhalt"]; $fields = array(); if (preg_match_all("/#([^#\[\]]+)(?:\[(\d*):(\d*)\])?#/", $cnt, $matches, PREG_SET_ORDER)) { foreach ($matches as $match) { $replace = ""; $fields[] = $match[1]; $replace = $this->getContent($entry["content"], $match[1], 1); if (sizeof($match)>3) { if ($match[3]!="") { $replace = substr($replace, 0, intval($match[3])); } if ($match[2]!="") { $replace = substr($replace, intval($match[2])); } } $cnt = str_replace($match[0], $replace, $cnt); } } $left = $element["Links"]/10; $top = $element["Oben"]/10; $width = $element["Breite"]/10; if ($width == 0) { $width = 10; } $height = $element["Höhe"]/10; if ($height == 0) { $height = 10; } $this->moveIfOverlap($entry["floating"], $left, $top, $width, $height, isset($params["float"]) ? $params["float"] : "none"); $position = "position:absolute;"; if (isset($params["position"])) { $position = "position:".$params["position"].";"; } $position.= "z-index:".$element["Reihenfolge"].";"; switch ($element["Art"]) { case "img": if (isset($params["aspect"]) && $params["aspect"]=="keep") { $imgsize = "max-width: ".$width."mm; max-height: ".$height."mm; width: auto; height: auto; "; } if (isset($params["aspect"]) && $params["aspect"]=="height") { $imgsize = "height: ".$height."mm; width: auto; "; } else { $imgsize = "width: ".$width."mm; height: ".$height."mm; "; } $path = $cnt; if (count($fields)) { $path = $cnt; } //if (file_exists($path)) { $entry["html"].= ""; //} break; case "text": $rotate = ""; if (isset($params["rotate"]) && $params["rotate"]=="1") { $rotate = "transform: rotate(-90deg); "; $left = "calc(".($left + ($height - $width)/2)."mm - ".$border["left"]."px); "; $top = "calc(".($top + ($width - $height)/2)."mm - ".$border["top"]."px); "; } else { $left.= "mm; "; $top.= "mm; "; } $font = "font-family: ".(isset($params["font"]) && $params["font"]=="narrow" ? "Calibri, Carlito, Arial Narrow, Liberation Sans Narrow, Arial, Liberation Sans; " : "Arial, Liberation Sans; "); $font.= "font-size: ".(isset($params["size"]) ? $params["size"] : $height)."mm; "; if (isset($params["weight"])) { $font.= "font-weight: ".$params["weight"]."; "; } if (isset($params["align"])) { $font.= "text-align: ".$params["align"]."; "; } if (isset($params["color"])) { $font.= "color: ".$params["color"]."; "; } $entry["html"].= "".$cnt.""; break; case "circle": $left.= "mm; "; $top.= "mm; "; $display = "display: inline-flex; align-items: center; justify-content: space-around; "; $font = "font-family: ".(isset($params["font"]) && $params["font"]=="narrow" ? "Calibri, Carlito, Arial Narrow, Liberation Sans Narrow, Arial, Liberation Sans; " : "Arial, Liberation Sans; "); $font.= "font-size: ".(isset($params["size"]) ? $params["size"] : $height)."mm; "; if (isset($params["weight"])) { $font.= "font-weight: ".$params["weight"]."; "; } if (isset($params["color"])) { $font.= "color: ".$params["color"]."; "; } $font.= "text-align: center; "; $background = isset($params["background"]) ? "background-color: ".$params["background"].";" : ""; $entry["html"].= "".$cnt.""; break; case "quartercircle": $left.= "mm; "; $top.= "mm; "; $background = isset($params["background"]) ? "background-color: ".$params["background"].";" : ""; $border_radius = isset($params["corner"]) ? "border-".$params["corner"]."-radius:100%;" : "border-top-left-radius:100%;"; $entry["html"].= "".$cnt.""; break; } } } unset($entry); } private function getTextFromReference($ref, $getText) { if (1==$getText && array_key_exists("KÜRZEL", $ref)) { return $ref["KÜRZEL"]; } elseif (1<=$getText && array_key_exists("NAME", $ref)) { return $ref["NAME"]; } elseif (array_key_exists("ID", $ref)) { return $ref["ID"]; } return ""; } // $entry Content-array of entry ([ID, MAIN, SUB]) // $key Requested field // $getText 0 = ID is sufficient, 1 = Kürzel (prio.) or Name desired, 2 = Name desired private function getContent($entry, $key, $getText = 0) { // Check if requested field are actually nested keys separated by dots $dotPos = strpos($key, "."); if ($dotPos!==false) { $subkey = substr($key, 0, $dotPos); if (array_key_exists($subkey, $entry)) { return $this->getContent($entry[$subkey], substr($key, $dotPos+1, strlen($key)-$dotPos-1)); } } // Check if requested field exists if (array_key_exists($key, $entry)) { // Check if requested field is an array (which means it was selected through a foreign reference or link table) if (is_array($entry[$key])) { // Check if array is size 0 -> This means an unset reference, i.e. NULL if (0==sizeof($entry[$key])) { return null; } elseif (array_key_exists("ID", $entry[$key])) { // Check if requested field is a normal foreign reference -> It will have the ID field then. // Foreign reference with ID, NAME and maybe KÜRZEL return $this->getTextFromReference($entry[$key], $getText); } else { // If not, we assume to have an sequential array which means a n:m-link-table $ret = []; foreach ($entry[$key] as $i => $ref) { $ret[] = $this->getTextFromReference($ref, $getText); } return $ret; } } else { // Requested field is a normal value return $entry[$key]; } } elseif (array_key_exists("MAIN", $entry)) { // If we are in the root structure of a content object, we will have sections MAIN and SUB and check those recursively // Search the MAIN-array for field $ret = $this->getContent($entry["MAIN"], $key, $getText); // If only the field name was returned check SUB-array if exists if ($key==$ret && array_key_exists("SUB", $entry)) { $ret = $this->getContent($entry["SUB"], $key, $getText); } return $ret; } else { // Nothing was found, we return the field name return $key; } } private function moveIfOverlap(&$floating, &$left, &$top, $width, $height, $dir = "none", $lastdir = "none") { $moved = false; foreach ($floating as $key => $float) { if ( $left < $float["right"] && $left+$width > $float["left"] && $top < $float["bottom"] && $top+$height > $float["top"] ) { if ($float["dir"]=="left" && $lastdir!="right") { $left = $float["right"]; } else if ($float["dir"]=="right" && $lastdir!="left") { $left = $float["left"] - $width; } else if ($float["dir"]=="up" && $lastdir!="down") { $top = $float["bottom"]; } else if ($float["dir"]=="down" && $lastdir!="up") { $top = $float["top"] - $height; } $lastdir = $float["dir"]; $moved = true; } } if ($moved) { $this->moveIfOverlap($floating, $left, $top, $width, $height, $dir, $lastdir); } else if ($dir!="none") { $floating[] = array( "left" => $left, "right" => $left + $width, "top" => $top, "bottom" => $top + $height, "dir" => $dir ); } } }