EIOS/rabprog/inc/class_TCPDF.php

420 lines
19 KiB
PHP
Raw Normal View History

2023-12-28 15:39:22 +03:00
<?php
require_once('inc/TCPDF/tcpdf.php');
//error_reporting(E_ALL);
class class_TCPDF {
private $pdf;
function __construct(){
//$this->Footer();
}
function setup(){
$this->pdf->SetCreator(PDF_CREATOR);
$this->pdf->SetAuthor('Яковлев А.Л.');
$this->pdf->SetTitle('РПД заголовок');
$this->pdf->SetSubject('РПД тема');
$this->pdf->SetKeywords('Яковлев, alneo.ru');
//$this->pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 001', PDF_HEADER_STRING, array(0,64,255), array(0,64,128));
//$this->pdf->setFooterData(array(0,64,0), array(0,64,128));
$this->pdf->setPrintHeader(false);
//$this->pdf->setPrintFooter(false);
$this->pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$this->pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
// set default monospaced font
$this->pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
// set margins
//$this->pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$this->pdf->SetMargins(15, 5, 15);
//$this->pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$this->pdf->SetHeaderMargin(2);
//$this->pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
$this->pdf->SetFooterMargin(5);
// set auto page breaks
$this->pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
// set image scale factor
$this->pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$this->pdf->setFontSubsetting(true);
$this->pdf->SetFont('dejavusans', '', 10, '', true);
// set text shadow effect
//$this->pdf->setTextShadow(array('enabled'=>true, 'depth_w'=>0.2, 'depth_h'=>0.2, 'color'=>array(196,196,196), 'opacity'=>1, 'blend_mode'=>'Normal'));
}
function close_HTML_tags($content){
$position = 0;
$open_tags = array();
//теги для игнорирования
$ignored_tags = array('br', 'hr', 'img');
while (($position = strpos($content, '<', $position)) !== FALSE){
//забираем все теги из контента
if (preg_match("|^<(/?)([a-z\d]+)\b[^>]*>|i", substr($content, $position), $match)){
$tag = strtolower($match[2]);
//игнорируем все одиночные теги
if (in_array($tag, $ignored_tags) == FALSE){
//тег открыт
if (isset($match[1]) AND $match[1] == ''){
if (isset($open_tags[$tag]))
$open_tags[$tag]++;
else
$open_tags[$tag] = 1;
}
//тег закрыт
if (isset($match[1]) AND $match[1] == '/'){
if (isset($open_tags[$tag]))
$open_tags[$tag]--;
}
}
$position += strlen($match[0]);
}else $position++;
}
//закрываем все теги
foreach ($open_tags as $tag => $count_not_closed){
$content .= str_repeat("</{$tag}>", $count_not_closed);
}
return $content;
}
function purifierHTML($html){
//https://habr.com/ru/company/smartprogress/blog/202188/
require_once 'inc/htmlpurifier/library/HTMLPurifier.auto.php';
$config = HTMLPurifier_Config::createDefault();
$config->set('Attr.AllowedClasses',array('header')); // или Attr.ForbiddenClasses имеются ввиду CSS классы
$config->set('AutoFormat.RemoveEmpty',true);// удаляет пустые теги, есть исключения*
$config->set('HTML.Doctype','HTML 4.01 Strict'); // обратите внимание как заменился тег <strike>
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify($html);
return $clean_html;
}
function parseHTML($text){
$out = $text;
//echo htmlspecialchars($out).'<hr>';
$m1=array('",="" "','",=""',',="" "','";=""',':=""',';=""',';"=""');
$m2=array('="" ','=""','="" ','="" ','=""','=""','="" ');
$out = str_replace($m1,$m2,$out);
//preg_match_all('/\s(.*)=(.*)\s/i',$out,$arr);
//preg_match_all('/<(.*)>/isU',$out,$arr);
//echo '<pre>'.print_r($arr,1).'</pre>';
$out = preg_replace('/background-color:(.*?);/i','',$out,-1);
$out = preg_replace('/color:(.*?);/i','',$out,-1);
$out = preg_replace('/font-family:(.*?);/i','',$out,-1);
$out = preg_replace('/font-size:(.*?);/i','',$out,-1);
//$out = preg_replace('/<img(.*?)width:(.*?);(.*?)>/i','<img $1 width:200px;$3>',$out,-1);
$out = preg_replace('/<img(.*?)width: 25%;(.*?)>/i','<img $1 width:200px; $2>',$out,-1);
$out = preg_replace('/<img(.*?)width: 50%;(.*?)>/i','<img $1 width:400px; $2>',$out,-1);
$out = preg_replace('/<img(.*?)width: 75%;(.*?)>/i','<img $1 width:500px; $2>',$out,-1);
$out = preg_replace('/<img(.*?)width: 100%;(.*?)>/i','<img $1 width:800px; $2>',$out,-1);
$out = str_replace('https://eios.mkgtu.ru','',$out);
//echo htmlspecialchars($out).'<hr>';
//Закроем все не закрытые тэги HTML <>
$out = preg_replace_callback('|<(.*)<|isU',function ($itt){ if(strpos($itt[1],'>')===false) return '<'.$itt[1].'><'; else return '<'.$itt[1].'<'; },$out);
$out = preg_replace_callback('|="(.*)>|isU',function ($itt){ if(substr_count($itt[1],'"')%2 == 0) return '="' . $itt[1] . '">'; else return '="' . $itt[1] . '>'; },$out);
$out = $this->close_HTML_tags($out);
//echo htmlspecialchars($out).'<hr>';
$out = $this->purifierHTML($out);
$out = str_replace('<table ','<table class="table" ',$out);
$out = str_replace(' border="1"','',$out);
$out = preg_replace('/border:(.*?);/i','',$out,-1);
$out = preg_replace('/border-(.*?):(.*?);/i','',$out,-1);
return $out;
}
function PDF_rpd($DISCIPS,$DISCIP,$rpd,$view=1,$id_disc_sign=0){
GLOBAL $smarty; $out=array();
$this->pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$cQR = new class_QRcode();
$hash = md5('SaLMKGTUYakovlev_'.$rpd['id'].'_');
$out['hash'] = $hash;
$QRfile = $cQR->QR_get('https://eios.mkgtu.ru/rabprog/Q/'.$hash.'/');
$this->pdf->setQRFile($QRfile);
$this->setup();
//$this->pdf->AddPage();
//echo '<pre>'.print_r($rpd,1).'</pre>'; exit();
//echo htmlspecialchars($rpd['razdel1']).'<hr>';
$rpd['razdel1'] = $this->parseHTML($rpd['razdel1']);
$rpd['razdel2'] = $this->parseHTML($rpd['razdel2']);
//echo htmlspecialchars($rpd['razdel7_3']).'<hr>';
$rpd['razdel7_3'] = $this->parseHTML($rpd['razdel7_3']);
//echo $this->purifierHTML($rpd['razdel7_3']);exit();
//echo htmlspecialchars($rpd['razdel7_3']);exit();
$rpd['razdel7_4'] = $this->parseHTML($rpd['razdel7_4']);
$rpd['razdel9'] = $this->parseHTML($rpd['razdel9']);
//echo '<pre>'.print_r($rpd,1).'</pre>';
//echo '<pre>'.print_r($DISCIPS,1).'</pre>';exit();
$this->pdf->SetTitle($DISCIP['DISCIP_name'].' РПД');
$smarty->assign('DISCIPS', $DISCIPS);
$smarty->assign('DISCIP', $DISCIP);
$smarty->assign('save', $rpd);
$class_FAKKAF = new class_FAKKAF();
if(isset($DISCIPS['Очно-заочная'])) $kafname = $DISCIPS['Очно-заочная']['uchebplan']['kaf_name'];
if(isset($DISCIPS['Заочная'])) $kafname = $DISCIPS['Заочная']['uchebplan']['kaf_name'];
if(isset($DISCIPS['Очная'])) $kafname = $DISCIPS['Очная']['uchebplan']['kaf_name'];
$smarty->assign('FAKKAF', $class_FAKKAF->Item_by_kafname($kafname));
//if($view==0) {//сохраняем файл когда все подписали
//Надо собрать подписи всех
$class_RPDSign = new class_RPDSign();
$signs = array_reverse ($class_RPDSign->RPDSignsPDF($id_disc_sign,1,$kafname));
$smarty->assign('signs', $signs);
//}else{ $smarty->assign('signs', array()); }
$cRPD = new class_RPD();
if($cRPD->isRPD_praktik($DISCIP)) {
$html = $smarty->fetch('page_rpd_praktik_pdf.html');
}else {
$html = $smarty->fetch('page_rpd_pdf.html');
}
//echo $html;
//echo '<pre>$id_disc_sign='.$id_disc_sign.'</pre>';
//echo '<pre>$DISCIPS'.print_r($DISCIPS,1).'</pre>';
//echo '<pre>$DISCIP'.print_r($DISCIP,1).'</pre>';
//echo '<pre>$signs'.print_r($signs,1).'</pre>';
//exit();
//echo $html; exit();
//$this->pdf->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, true, '', true);
$delimiter = '<br pagebreak="true" />';
$chunks = explode($delimiter, $html);
$page_orient = 'P';
foreach($chunks as $k => $page){
if(strpos($page,'<!--page_orient=')!==false){
$page_orient='L';
}else{
$page_orient='P';
}
$this->setup();
$this->pdf->AddPage($page_orient);
$this->pdf->writeHTML($this->imgSRC_replacer($page), true, 0, true, 0);
}
//echo $view; exit();
$file_name = '';
if(mb_strlen($DISCIP['DISCIP_name'])<=14) $file_name = $DISCIP['DISCIP_name'];
else $file_name = mb_substr($DISCIP['DISCIP_name'],0,14);
if($view==1) {//отображаем файл
$this->pdf->Output($file_name . '.pdf', 'I');
}else{//сохраняем файл
$path = str_replace('/inc','',__DIR__);
$file = '/upload/pdfs/'.$id_disc_sign.'_'.$file_name . '.pdf';
//echo $file; exit();
$this->pdf->Output($path.$file, 'F');
$out['file'] = '/rabprog'.$file;
}
return $out;
}
function PDF_annotac($DISCIPS,$DISCIP,$rpd,$view=1,$id_disc_sign=0){
GLOBAL $smarty; $out=array();
$this->pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$cQR = new class_QRcode();
$hash = md5('SaLMKGTUYakovlev_'.$rpd['id'].'_');
$out['hash'] = $hash;
$QRfile = $cQR->QR_get('https://eios.mkgtu.ru/rabprog/Q/'.$hash.'/');
$this->pdf->setQRFile($QRfile);
$this->setup();
$rpd['razdel1'] = $this->parseHTML($rpd['razdel1']);
$rpd['razdel2'] = $this->parseHTML($rpd['razdel2']);
$rpd['razdel7_3'] = $this->parseHTML($rpd['razdel7_3']);
$rpd['razdel7_4'] = $this->parseHTML($rpd['razdel7_4']);
$rpd['razdel9'] = $this->parseHTML($rpd['razdel9']);
$this->pdf->SetTitle($DISCIP['DISCIP_name'].' РПД');
$smarty->assign('DISCIPS', $DISCIPS);
$smarty->assign('DISCIP', $DISCIP);
$smarty->assign('save', $rpd);
$class_FAKKAF = new class_FAKKAF();
if(isset($DISCIPS['Очно-заочная'])) $kafname = $DISCIPS['Очно-заочная']['uchebplan']['kaf_name'];
if(isset($DISCIPS['Заочная'])) $kafname = $DISCIPS['Заочная']['uchebplan']['kaf_name'];
if(isset($DISCIPS['Очная'])) $kafname = $DISCIPS['Очная']['uchebplan']['kaf_name'];
$smarty->assign('FAKKAF', $class_FAKKAF->Item_by_kafname($kafname));
$class_RPDSign = new class_RPDSign();
$signs = array_reverse ($class_RPDSign->RPDSignsPDF($id_disc_sign,1,$kafname));
$smarty->assign('signs', $signs);
$cRPD = new class_RPD();
if($cRPD->isRPD_praktik($DISCIP)) {
//$html = $smarty->fetch('page_rpd_praktik_pdf.html');
$html = $smarty->fetch('page_rpd_annotac_pdf.html');
}else {
$html = $smarty->fetch('page_rpd_annotac_pdf.html');
}
$delimiter = '<br pagebreak="true" />';
$chunks = explode($delimiter, $html);
$page_orient = 'P';
foreach($chunks as $k => $page){
if(strpos($page,'<!--page_orient=')!==false){
$page_orient='L';
}else{
$page_orient='P';
}
$this->setup();
$this->pdf->AddPage($page_orient);
$this->pdf->writeHTML($this->imgSRC_replacer($page), true, 0, true, 0);
//echo $k.'::'.$page.'<br>';
}
//echo $view; exit();
if($view==1) {//отображаем файл
$this->pdf->Output($DISCIP['DISCIP_name'] . '.pdf', 'I');
}else{//сохраняем файл
if($view==2){
$out['html'] = $html;
}else {
$path = str_replace('/inc', '', __DIR__);
$file = '/upload/pdfs/' . $id_disc_sign . '_' . $DISCIP['DISCIP_name'] . '.pdf';
//echo $file; exit();
$this->pdf->Output($path . $file, 'F');
$out['file'] = '/rabprog' . $file;
}
}
return $out;
}
function PDF_fos($DISCIPS,$DISCIP,$rpd,$view=1,$id_disc_sign=0){
GLOBAL $smarty; $out=array();
$this->pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$cQR = new class_QRcode();
$hash = md5('SaLMKGTUYakovlev_'.$rpd['id'].'_');
$out['hash'] = $hash;
$QRfile = $cQR->QR_get('https://eios.mkgtu.ru/rabprog/Q/'.$hash.'/');
$this->pdf->setQRFile($QRfile);
$this->setup();
$rpd['razdel1'] = $this->parseHTML($rpd['razdel1']);
$rpd['razdel2'] = $this->parseHTML($rpd['razdel2']);
$rpd['razdel7_3'] = $this->parseHTML($rpd['razdel7_3']);
$rpd['razdel7_4'] = $this->parseHTML($rpd['razdel7_4']);
$rpd['razdel9'] = $this->parseHTML($rpd['razdel9']);
$this->pdf->SetTitle($DISCIP['DISCIP_name'].' РПД');
$smarty->assign('DISCIPS', $DISCIPS);
$smarty->assign('DISCIP', $DISCIP);
$smarty->assign('save', $rpd);
$class_FAKKAF = new class_FAKKAF();
if(isset($DISCIPS['Очно-заочная'])) $kafname = $DISCIPS['Очно-заочная']['uchebplan']['kaf_name'];
if(isset($DISCIPS['Заочная'])) $kafname = $DISCIPS['Заочная']['uchebplan']['kaf_name'];
if(isset($DISCIPS['Очная'])) $kafname = $DISCIPS['Очная']['uchebplan']['kaf_name'];
$smarty->assign('FAKKAF', $class_FAKKAF->Item_by_kafname($kafname));
$class_RPDSign = new class_RPDSign();
$signs = array_reverse ($class_RPDSign->RPDSignsPDF($id_disc_sign,1,$kafname));
$smarty->assign('signs', $signs);
$cRPD = new class_RPD();
if($cRPD->isRPD_praktik($DISCIP)) {
//$html = $smarty->fetch('page_rpd_praktik_pdf.html');
$html = $smarty->fetch('page_rpd_fos_pdf.html');
}else {
$html = $smarty->fetch('page_rpd_fos_pdf.html');
}
$delimiter = '<br pagebreak="true" />';
$chunks = explode($delimiter, $html);
$page_orient = 'P';
foreach($chunks as $k => $page){
if(strpos($page,'<!--page_orient=')!==false){
$page_orient='L';
}else{
$page_orient='P';
}
$this->setup();
$this->pdf->AddPage($page_orient);
try {
$this->pdf->writeHTML($this->imgSRC_replacer($page), true, 0, true, 0);
} catch (Error $e) {
//echo 'Now you can catch me!';
}
//echo $k.'::'.$page.'<br>';
}
//echo $view; exit();
try {
if ($view == 1) {//отображаем файл
//echo $DISCIP['DISCIP_name'].'<br>';
$this->pdf->Output($DISCIP['DISCIP_name'] . '.pdf', 'I');
} else {//сохраняем файл
if ($view == 2) {
$out['html'] = $html;
} else {
$path = str_replace('/inc', '', __DIR__);
$file = '/upload/pdfs/' . $id_disc_sign . '_' . $DISCIP['DISCIP_name'] . '.pdf';
//echo $file; //exit();
$this->pdf->Output($path . $file, 'F');
$out['file'] = '/rabprog' . $file;
}
}
} catch (Error $e) {
//echo 'Now you can catch me!';
}
return $out;
}
function PDF_statPUR($data){
GLOBAL $smarty; $out=array();
$this->pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$this->setup();
$this->pdf->AddPage();
$smarty->assign('data', $data);
$html = $smarty->fetch('page_statpur_pdf.html');
$this->pdf->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, true, '', true);
$this->pdf->Output('statpur_'.date('Hi_dmY').'.pdf', 'I');
return $out;
}
/**
* Заменяет в тексте ссылки на локальные ссылки, реализовано только SVG
* @param $page
* @return array|mixed|string|string[]
*/
function imgSRC_replacer($page){
//echo htmlspecialchars($page);
//<img alt="{\displaystyle {\mathsf {R{\text{-}}H+HO{\text{-}}SO_{3}H\rightarrow R{\text{-}}SO_{3}H+H_{2}O}}}" src="https://wikimedia.org/api/rest_v1/media/math/render/svg/b010cb30e90abff579eeb0f64c3fdd0f5f15076d" style="padding:0px;margin:0px;vertical-align:middle;height:auto;">
preg_match_all('|<img.*src="(.*)".*>|isU',$page,$out);
if(count($out[1])){
$dirm = 'tmp/pdf_imgs/';
foreach($out[1] as $k => $url){
$pi = pathinfo($url);
$fname = md5($url);
if(isset($pi['extension'])&&$pi['extension']!=''){
//copy($url,$dirm.$fname.$pi['extension']);
//$page = str_replace($url,$dirm.$fname.$pi['extension'],$page);
}else{//svg
$content = file_get_contents($url);
$page = str_replace($out[0][$k],$content,$page);
}
}
//echo '<pre>'.print_r($out,1).'</pre>';
//Array(
//[1] => Array(
// [0] => https://wikimedia.org/api/rest_v1/media/math/render/svg/b010cb30e90abff579eeb0f64c3fdd0f5f15076d
// [1] => https://wikimedia.org/api/rest_v1/media/math/render/svg/b010cb30e90abff579eeb0f64c3fdd0f5f15076d
//)
}
return $page;
}
}
class MYPDF extends TCPDF {
private $QRFile = "";
/**
* @param string $QRFile
*/
public function setQRFile($QRFile){
$this->QRFile = $QRFile;
}
//Page header
public function Header() {
//// Logo
//$image_file = K_PATH_IMAGES.'logo_example.jpg';
//$this->Image($image_file, 10, 10, 15, '', 'JPG', '', 'T', false, 300, '', false, false, 0, false, false, false);
//// Set font
//$this->SetFont('helvetica', 'B', 20);
//// Title
//$this->Cell(0, 15, '<< TCPDF Example 003 >>', 0, false, 'C', 0, '', 0, false, 'M', 'M');
}
// Page footer
public function Footer() {
// Position at 15 mm from bottom
$this->SetY(-15);
$this->Cell(0, 10, ''.$this->getAliasNumPage().'/'.$this->getAliasNbPages(), 0, false, 'R', 0, '', 0, false, 'T', 'M');
$this->Image($this->QRFile, 10, 272, 15, '', 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);
}
}