]> 91.132.146.200 Git - insipid.git/commitdiff
better intend and updated tag class
authorBanana <mail@bananas-playground.net>
Mon, 11 Sep 2023 10:06:15 +0000 (12:06 +0200)
committerBanana <mail@bananas-playground.net>
Mon, 11 Sep 2023 10:06:15 +0000 (12:06 +0200)
webroot/lib/simple-imap.class.php
webroot/lib/snapshot.class.php
webroot/lib/summoner.class.php
webroot/lib/tag.class.php

index bc570c4fba0894a121a67045e131ca5ded5194c5..8b9a914498982a20f535be1c3c7843facb5c6ab1 100644 (file)
  */
 class SimpleImap {
 
-       private IMAP\Connection $_connection;
-
-       private string $_server = EMAIL_SERVER;
-       private string $_user = EMAIL_SERVER_USER;
-       private string $_pass = EMAIL_SERVER_PASS;
-       private int $_port = EMAIL_SERVER_PORT_IMAP;
-       private string $_mailbox = EMAIL_SERVER_MAILBOX;
-
-       private string $_connectionstring = '';
-
-       /**
-        * SimpleImap constructor.
-        */
-       function __construct() {
-           # create the mailboxstring
-           $this->_connectionstring = '{'.$this->_server.':'.$this->_port.'/imap/ssl/novalidate-cert}';
-       }
-
-       /**
-        *
-        */
-       function __destruct() {
-           //imap_close($this->_connection);
-       }
-
-       /**
-        * connect to the e-mail server
-        * with this code SSL/TLS only
-        *
-        * @see http://ca.php.net/manual/en/function.imap-open.php
-        * @throws Exception
-        */
-       public function connect(): void {
-
-           if(empty($this->_server)) {
-               throw new Exception('Missing EMAIL_SERVER');
-           }
-           if(empty($this->_port)) {
-               throw new Exception('Missing EMAIL_SERVER_PORT');
-           }
-           if(empty($this->_user)) {
-               throw new Exception('Missing EMAIL_SERVER_USER');
-           }
+    private IMAP\Connection $_connection;
+
+    private string $_server = EMAIL_SERVER;
+    private string $_user = EMAIL_SERVER_USER;
+    private string $_pass = EMAIL_SERVER_PASS;
+    private int $_port = EMAIL_SERVER_PORT_IMAP;
+    private string $_mailbox = EMAIL_SERVER_MAILBOX;
+
+    private string $_connectionstring = '';
+
+    /**
+     * SimpleImap constructor.
+     */
+    function __construct() {
+        # create the mailboxstring
+        $this->_connectionstring = '{'.$this->_server.':'.$this->_port.'/imap/ssl/novalidate-cert}';
+    }
+
+    /**
+     *
+     */
+    function __destruct() {
+        //imap_close($this->_connection);
+    }
+
+    /**
+     * connect to the e-mail server
+     * with this code SSL/TLS only
+     *
+     * @see http://ca.php.net/manual/en/function.imap-open.php
+     * @throws Exception
+     */
+    public function connect(): void {
+
+        if(empty($this->_server)) {
+            throw new Exception('Missing EMAIL_SERVER');
+        }
+        if(empty($this->_port)) {
+            throw new Exception('Missing EMAIL_SERVER_PORT');
+        }
+        if(empty($this->_user)) {
+            throw new Exception('Missing EMAIL_SERVER_USER');
+        }
 
         # create the connection
-           $this->_connection = imap_open($this->_connectionstring.$this->_mailbox, $this->_user, $this->_pass);
-
-               if(!$this->_connection) {
-                   throw new Exception('Failed IMAP connection: '.var_export(imap_last_error(),true));
-               }
-       }
-
-       /**
-        * process the given mailbox and check for the special messages
-        * return the body and headers from the found message
-        *
-        * @param string $subjectmarker
-        * @return array emailId => array(body, header);
-        * @throws Exception
-        */
-       function messageWithValidSubject(string $subjectmarker): array {
-           $ret = array();
-
-           $messagecount = imap_num_msg($this->_connection);
-
-           if($messagecount === false) {
-               throw new Exception('Can not read the messages in given mailbox');
-           }
-
-           $processedmessagescount = 0;
-           for($i = 1; $i <= $messagecount; $i++) {
-               $subject = $this->_extractSubject($i);
-
-               if(!empty($subject)) {
-                   # check the special stuff
-                   $markerextract = substr($subject, 0, strlen($subjectmarker));
-                   if($markerextract == $subjectmarker) {
-                       $processedmessagescount++;
-                       # valid message
-                       # get the body
-                       $ret[$i]['body'] = $this->_extractBody($i);
-                                       $ret[$i]['header'] = $this->emailHeaders($i);
-                                       $ret[$i]['header_rfc822'] = $this->emailHeaders_rfc822($i);
-                                       $ret[$i]['header_array'] = $this->emailHeadersAsArray($i);
-                                       # @see https://www.php.net/manual/en/function.imap-uid.php
+        $this->_connection = imap_open($this->_connectionstring.$this->_mailbox, $this->_user, $this->_pass);
+
+        if(!$this->_connection) {
+            throw new Exception('Failed IMAP connection: '.var_export(imap_last_error(),true));
+        }
+    }
+
+    /**
+     * process the given mailbox and check for the special messages
+     * return the body and headers from the found message
+     *
+     * @param string $subjectmarker
+     * @return array emailId => array(body, header);
+     * @throws Exception
+     */
+    function messageWithValidSubject(string $subjectmarker): array {
+        $ret = array();
+
+        $messagecount = imap_num_msg($this->_connection);
+
+        if($messagecount === false) {
+            throw new Exception('Can not read the messages in given mailbox');
+        }
+
+        $processedmessagescount = 0;
+        for($i = 1; $i <= $messagecount; $i++) {
+            $subject = $this->_extractSubject($i);
+
+            if(!empty($subject)) {
+                # check the special stuff
+                $markerextract = substr($subject, 0, strlen($subjectmarker));
+                if($markerextract == $subjectmarker) {
+                    $processedmessagescount++;
+                    # valid message
+                    # get the body
+                    $ret[$i]['body'] = $this->_extractBody($i);
+                    $ret[$i]['header'] = $this->emailHeaders($i);
+                    $ret[$i]['header_rfc822'] = $this->emailHeaders_rfc822($i);
+                    $ret[$i]['header_array'] = $this->emailHeadersAsArray($i);
+                    # @see https://www.php.net/manual/en/function.imap-uid.php
                     $ret[$i]['uid'] = imap_uid($this->_connection,$i);
-                   }
-               }
-           }
+                }
+            }
+        }
 
-           # log messages processed to all messages
+        # log messages processed to all messages
         Summoner::sysLog("INFO Read ".$messagecount." messages");
         Summoner::sysLog("INFO Processed ".$processedmessagescount." messages");
 
-           return $ret;
-
-       }
+        return $ret;
 
-       /**
-        * the current status about the mail connection and INBOX
-        * kinda debug only
-        *
-        * @see http://ca.php.net/manual/en/function.imap-status.php
-        */
-       public function mailboxStatus(): void {
-           if($this->_connection !== false) {
-               $status = imap_status($this->_connection, $this->_connectionstring.$this->_mailbox, SA_ALL);
+    }
 
-               if(DEBUG === true) {
+    /**
+     * the current status about the mail connection and INBOX
+     * kinda debug only
+     *
+     * @see http://ca.php.net/manual/en/function.imap-status.php
+     */
+    public function mailboxStatus(): void {
+        if($this->_connection !== false) {
+            $status = imap_status($this->_connection, $this->_connectionstring.$this->_mailbox, SA_ALL);
+
+            if(DEBUG === true) {
                 Summoner::sysLog("messages " . $status->messages);
                 Summoner::sysLog("recent " . $status->recent);
                 Summoner::sysLog("unseen " . $status->unseen);
@@ -151,108 +151,108 @@ class SimpleImap {
                 Summoner::sysLog("uidvalidity " . $status->uidvalidity);
             }
 
-               $list = imap_getmailboxes($this->_connection, $this->_connectionstring, "*");
-               if (is_array($list)) {
-                   foreach ($list as $key => $val) {
-                       echo "($key) ";
-                       echo imap_utf7_decode($val->name) . ",";
-                       echo "'" . $val->delimiter . "',";
-                       echo $val->attributes . "<br />\n";
-                   }
-               } else {
+            $list = imap_getmailboxes($this->_connection, $this->_connectionstring, "*");
+            if (is_array($list)) {
+                foreach ($list as $key => $val) {
+                    echo "($key) ";
+                    echo imap_utf7_decode($val->name) . ",";
+                    echo "'" . $val->delimiter . "',";
+                    echo $val->attributes . "<br />\n";
+                }
+            } else {
                 Summoner::sysLog("ERROR imap_getmailboxes failed: ".var_export(imap_last_error()));
-               }
-           }
-       }
-
-       /**
-        * This function causes a fetch of the complete, unfiltered RFC2822 format header of the specified message.
-        *
-        * @param integer $messagenum
-        * @return string
-        */
-       public function emailHeaders(int $messagenum): string {
-               return imap_fetchheader($this->_connection, $messagenum);
-       }
-
-       /**
-        * return the email headers by given emailid
-        *
-        * @param integer $messagenum
-        * @return object
-        */
-       public function emailHeaders_rfc822(int $messagenum): object {
-               return imap_rfc822_parse_headers($this->emailHeaders($messagenum));
-       }
-
-       /**
-        * Email headers parsed as an array
-        *
-        * @param integer $messagenum
-        * @return array
-        */
-       public function emailHeadersAsArray(int $messagenum): array {
-               preg_match_all('/([^: ]+): (.+?(?:\r\n\s(?:.+?))*)\r\n/m', $this->emailHeaders($messagenum), $matches );
-               return array_combine( $matches[1], $matches[2]);
-       }
-
-       /**
-        * Move given message to given folder
-        *
-        * @param integer $messageUid This is the message Uid as an int
-        * @param string $folder This is the target folder. Default is EMAIL_ARCHIVE_FOLDER
-        */
-       public function moveMessage(int $messageUid, string $folder=EMAIL_ARCHIVE_FOLDER): void {
-           if(!empty($messageUid) && !empty($folder)) {
-               $messageUid = (string)$messageUid;
-               imap_setflag_full($this->_connection,$messageUid,"\SEEN", ST_UID);
+            }
+        }
+    }
+
+    /**
+     * This function causes a fetch of the complete, unfiltered RFC2822 format header of the specified message.
+     *
+     * @param integer $messagenum
+     * @return string
+     */
+    public function emailHeaders(int $messagenum): string {
+        return imap_fetchheader($this->_connection, $messagenum);
+    }
+
+    /**
+     * return the email headers by given emailid
+     *
+     * @param integer $messagenum
+     * @return object
+     */
+    public function emailHeaders_rfc822(int $messagenum): object {
+        return imap_rfc822_parse_headers($this->emailHeaders($messagenum));
+    }
+
+    /**
+     * Email headers parsed as an array
+     *
+     * @param integer $messagenum
+     * @return array
+     */
+    public function emailHeadersAsArray(int $messagenum): array {
+        preg_match_all('/([^: ]+): (.+?(?:\r\n\s(?:.+?))*)\r\n/m', $this->emailHeaders($messagenum), $matches );
+        return array_combine( $matches[1], $matches[2]);
+    }
+
+    /**
+     * Move given message to given folder
+     *
+     * @param integer $messageUid This is the message Uid as an int
+     * @param string $folder This is the target folder. Default is EMAIL_ARCHIVE_FOLDER
+     */
+    public function moveMessage(int $messageUid, string $folder=EMAIL_ARCHIVE_FOLDER): void {
+        if(!empty($messageUid) && !empty($folder)) {
+            $messageUid = (string)$messageUid;
+            imap_setflag_full($this->_connection,$messageUid,"\SEEN", ST_UID);
             imap_mail_move($this->_connection, $messageUid, $folder,CP_UID);
             imap_expunge($this->_connection);
         }
     }
 
-       /**
-        * extract the subject from the email headers and decode
-        * A subject can be split into multiple parts...
-        *
-        * @param int $messagenum
-        * @return string
-        */
-       private function _extractSubject(int $messagenum): string {
-           $ret = '';
-
-           $headerinfo = $this->emailHeaders_rfc822($messagenum);
-           $subjectArr = imap_mime_header_decode($headerinfo->subject);
-           foreach ($subjectArr as $el) {
-               $ret .= $el->text;
-           }
-
-           return $ret;
-       }
-
-       /**
-        * extract the body of the given message
-        *
-        * @see http://php.net/manual/en/function.imap-fetchstructure.php
-        *
-        * @param int $messagenum
-        * @return string
-        */
-       private function _extractBody(int $messagenum): string {
-           $ret = '';
-
-           $emailstructure = imap_fetchstructure($this->_connection, $messagenum);
-
-           # simple or multipart?
-           if(isset($emailstructure->parts)) {
-               exit("multipart todo");
-           }
-           else {
-               $body = imap_body($this->_connection, $messagenum);
-           }
-
-           # encoding
-       switch ($emailstructure->encoding) {
+    /**
+     * extract the subject from the email headers and decode
+     * A subject can be split into multiple parts...
+     *
+     * @param int $messagenum
+     * @return string
+     */
+    private function _extractSubject(int $messagenum): string {
+        $ret = '';
+
+        $headerinfo = $this->emailHeaders_rfc822($messagenum);
+        $subjectArr = imap_mime_header_decode($headerinfo->subject);
+        foreach ($subjectArr as $el) {
+            $ret .= $el->text;
+        }
+
+        return $ret;
+    }
+
+    /**
+     * extract the body of the given message
+     *
+     * @see http://php.net/manual/en/function.imap-fetchstructure.php
+     *
+     * @param int $messagenum
+     * @return string
+     */
+    private function _extractBody(int $messagenum): string {
+        $ret = '';
+
+        $emailstructure = imap_fetchstructure($this->_connection, $messagenum);
+
+        # simple or multipart?
+        if(isset($emailstructure->parts)) {
+            exit("multipart todo");
+        }
+        else {
+            $body = imap_body($this->_connection, $messagenum);
+        }
+
+        # encoding
+        switch ($emailstructure->encoding) {
             case ENC8BIT: # 1 8BIT
                 $ret = quoted_printable_decode(imap_8bit($body));
             break;
@@ -270,7 +270,7 @@ class SimpleImap {
             break;
 
             case ENC7BIT: # 0 7BIT
-                               // imap_qprint($body); does throws notices
+                // imap_qprint($body); does throws notices
                 $ret = quoted_printable_decode($body);
             break;
 
@@ -280,13 +280,13 @@ class SimpleImap {
                 $ret = $body;
         }
 
-           return $ret;
-       }
+        return $ret;
+    }
 
-       /**
-        * close the imap connection
-        */
-       function close(): void {
-           imap_close($this->_connection);
-       }
+    /**
+     * close the imap connection
+     */
+    function close(): void {
+        imap_close($this->_connection);
+    }
 }
index cc920d2ca9b4c00fa9c7853c5675ca860c786506..13ebce88c30da5bf2437032887c6b3b426c84e4c 100644 (file)
  * right now it uses google pagespeedonline.
  */
 class Snapshot {
-       /**
-        * @var string
-        */
-       private string $_googlePageSpeed = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=';
+    /**
+     * @var string
+     */
+    private string $_googlePageSpeed = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=';
 
-       /**
-        * @var string
-        */
-       private string $_wkhtmltoimageOptions = '--load-error-handling ignore --quality 80 --quiet --width 1900';
+    /**
+     * @var string
+     */
+    private string $_wkhtmltoimageOptions = '--load-error-handling ignore --quality 80 --quiet --width 1900';
 
-       /**
-        * Snapshot constructor
-        */
-       public function __constructor(): void {}
+    /**
+     * Snapshot constructor
+     */
+    public function __constructor(): void {}
 
-       /**
-        * call given url with google PageSpeed API
-        * to receive image data
-        *
-        * @param String $url URL to take a thumbnail from
-        * @param string $filename
-        * @return boolean
-        */
-       public function doSnapshot(string $url, string $filename): bool {
-               $ret = false;
+    /**
+     * call given url with google PageSpeed API
+     * to receive image data
+     *
+     * @param String $url URL to take a thumbnail from
+     * @param string $filename
+     * @return boolean
+     */
+    public function doSnapshot(string $url, string $filename): bool {
+        $ret = false;
 
-               if(!empty($url) && is_writable(dirname($filename))) {
-                       if(DEBUG) {
+        if(!empty($url) && is_writable(dirname($filename))) {
+            if(DEBUG) {
                 Summoner::sysLog("[DEBUG] try to save to $filename with $this->_googlePageSpeed for $url");
-                       }
-                       $theCall = Summoner::curlCall($this->_googlePageSpeed.urlencode($url).'&screenshot=true');
-                       if(!empty($theCall)) {
-                               $jsonData = json_decode($theCall,true);
-                               if(DEBUG) {
+            }
+            $theCall = Summoner::curlCall($this->_googlePageSpeed.urlencode($url).'&screenshot=true');
+            if(!empty($theCall)) {
+                $jsonData = json_decode($theCall,true);
+                if(DEBUG) {
                     Summoner::sysLog("[DEBUG] Call result data: ".var_export($jsonData, true));
-                               }
-                               if(!empty($jsonData) && isset($jsonData['lighthouseResult']['audits']['full-page-screenshot']['details']['screenshot']['data'])) {
-                                       $imageData = $jsonData['lighthouseResult']['audits']['full-page-screenshot']['details']['screenshot']['data'];
+                }
+                if(!empty($jsonData) && isset($jsonData['lighthouseResult']['audits']['full-page-screenshot']['details']['screenshot']['data'])) {
+                    $imageData = $jsonData['lighthouseResult']['audits']['full-page-screenshot']['details']['screenshot']['data'];
 
-                                       $source = fopen($imageData, 'r');
-                                       $destination = fopen($filename, 'w');
-                                       if(stream_copy_to_stream($source, $destination)) {
-                                               $ret = $filename;
-                                       }
-                                       fclose($source);
-                                       fclose($destination);
-                               } elseif(DEBUG) {
+                    $source = fopen($imageData, 'r');
+                    $destination = fopen($filename, 'w');
+                    if(stream_copy_to_stream($source, $destination)) {
+                        $ret = $filename;
+                    }
+                    fclose($source);
+                    fclose($destination);
+                } elseif(DEBUG) {
                     Summoner::sysLog("[DEBUG] invalid json data. Path ['lighthouseResult']['audits']['full-page-screenshot']['details']['screenshot']['data'] not found in : ".var_export($jsonData, true));
-                               }
-                       } elseif(DEBUG) {
+                }
+            } elseif(DEBUG) {
                 Summoner::sysLog("[DEBUG] curl call failed");
-                       }
-               }
+            }
+        }
 
-               return $ret;
-       }
+        return $ret;
+    }
 
-       /**
-        * use configured COMPLETE_PAGE_SCREENSHOT_COMMAND to create a whole page screenshot
-        * of the given link and store it locally
-        *
-        * @TODO: TBD
-        *
-        * @param String $url URL to take the screenshot from
-        * @param string $filename
-        * @return boolean
-        */
-       public function wholePageSnapshot(string $url, string $filename): bool {
-               $ret = false;
+    /**
+     * use configured COMPLETE_PAGE_SCREENSHOT_COMMAND to create a whole page screenshot
+     * of the given link and store it locally
+     *
+     * @TODO: TBD
+     *
+     * @param String $url URL to take the screenshot from
+     * @param string $filename
+     * @return boolean
+     */
+    public function wholePageSnapshot(string $url, string $filename): bool {
+        $ret = false;
 
-               require_once 'lib/shellcommand.class.php';
+        require_once 'lib/shellcommand.class.php';
 
-               if(!empty($url) && is_writable(dirname($filename))) {
-                       $cmd = COMPLETE_PAGE_SCREENSHOT_COMMAND;
-                       $params = $this->_wkhtmltoimageOptions." ".$url." ".$filename;
-                       $command = new ShellCommand($cmd." ".$params);
-                       if ($command->execute()) {
-                           $ret = $command->getOutput();
-                       } else {
-                               error_log($command->getError());
-                               $ret = $command->getExitCode();
-                       }
-               }
+        if(!empty($url) && is_writable(dirname($filename))) {
+            $cmd = COMPLETE_PAGE_SCREENSHOT_COMMAND;
+            $params = $this->_wkhtmltoimageOptions." ".$url." ".$filename;
+            $command = new ShellCommand($cmd." ".$params);
+            if ($command->execute()) {
+                $ret = $command->getOutput();
+            } else {
+                error_log($command->getError());
+                $ret = $command->getExitCode();
+            }
+        }
 
-               return $ret;
-       }
+        return $ret;
+    }
 }
index 184153d6bcce5bbc8e8d4069196f08018b6f30de..bb6a693e2bac31e8b7185e9caebcfb83b656df5d 100644 (file)
  */
 class Summoner {
 
-       private const BROWSER_AGENT_STRING = 'Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0';
-
-       /**
-        * validate the given string with the given type. Optional check the string
-        * length
-        *
-        * @param string $input The string to check
-        * @param string $mode How the string should be checked
-        * @param int $limit If int given the string is checked for length
-        *
-        * @see http://de.php.net/manual/en/regexp.reference.unicode.php
-        * http://www.sql-und-xml.de/unicode-database/#pc
-        *
-        * the pattern replaces all that is allowed. the correct result after
-        * the replace should be empty, otherwise are there chars which are not
-        * allowed
-        *
-        * @return bool
-        */
-       static function validate(string $input, string $mode='text', int $limit=0): bool {
-               // check if we have input
-               $input = trim($input);
-
-               if($input == "") return false;
-
-               $ret = false;
-
-               switch ($mode) {
-                       case 'mail':
-                               if(filter_var($input,FILTER_VALIDATE_EMAIL) === $input) {
-                                       return true;
-                               }
-                               else {
-                                       return false;
-                               }
-                       break;
-
-                       case 'url':
-                               if(filter_var($input,FILTER_VALIDATE_URL) === $input) {
-                                       return true;
-                               }
-                               else {
-                                       return false;
-                               }
-                       break;
-
-                       case 'nospace':
-                               // text without any whitespace and special chars
-                               $pattern = '/[\p{L}\p{N}]/u';
-                       break;
-
-                       case 'nospaceP':
-                               // text without any whitespace and special chars
-                               // but with Punctuation other
-                               # http://www.sql-und-xml.de/unicode-database/po.html
-                               $pattern = '/[\p{L}\p{N}\p{Po}\-_]/u';
-                       break;
-
-                       case 'digit':
-                               // only numbers and digit
-                               // warning with negative numbers...
-                               $pattern = '/[\p{N}\-]/';
-                       break;
-
-                       case 'pageTitle':
-                               // text with whitespace and without special chars
-                               // but with Punctuation
-                               $pattern = '/[\p{L}\p{N}\p{Po}\p{Z}\s\-_]/u';
-                       break;
-
-                       # strange. the \p{M} is needed.. don't know why..
-                       case 'filename':
-                               $pattern = '/[\p{L}\p{N}\p{M}\-_\.\p{Zs}]/u';
-                       break;
-
-                       case 'text':
-                       default:
-                               $pattern = '/[\p{L}\p{N}\p{P}\p{S}\p{Z}\p{M}\s]/u';
-               }
-
-               $value = preg_replace($pattern, '', $input);
-
-               if($value === "") {
-                       $ret = true;
-               }
-
-               if(!empty($limit)) {
-                       # isset starts with 0
-                       if(isset($input[$limit])) {
-                               # too long
-                               $ret = false;
-                       }
-               }
-
-               return $ret;
-       }
-
-
-       /**
-        * execute a curl call to the given $url
-        *
-        * @param string $url The request url
-        * @param int $port
-        * @return string
-        */
-       static function curlCall(string $url, int $port=0): string {
-               $ret = '';
-
-               $ch = curl_init();
-
-               curl_setopt($ch, CURLOPT_URL, $url);
-               curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-               curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
-               curl_setopt($ch, CURLOPT_TIMEOUT, 30);
-               curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
-               curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
-               curl_setopt($ch, CURLOPT_USERAGENT,self::BROWSER_AGENT_STRING);
-
-               // curl_setopt($ch, CURLOPT_VERBOSE, true);
-               // curl_setopt($ch, CURLOPT_HEADER, true);
-
-               if(!empty($port)) {
-                 curl_setopt($ch, CURLOPT_PORT, $port);
-               }
-
-               $do = curl_exec($ch);
-
-               if(is_string($do) === true) {
-                       $ret = $do;
-               }
-               else {
-                       error_log('ERROR '.var_export(curl_error($ch),true));
-               }
-
-               curl_close($ch);
-
-               return $ret;
-       }
-
-       /**
-        * Download given url to given file
-        *
-        * @param string $url
-        * @param string $whereToStore
-        * @param int $port
-        * @return bool
-        */
-       static function downloadFile(string $url, string $whereToStore, int $port=0): bool {
-               $fh = fopen($whereToStore, 'w+');
-
-               $ret = false;
-
-               if($fh !== false) {
-                       $ch = curl_init($url);
-                       curl_setopt($ch, CURLOPT_FILE, $fh);
-
-                       curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
-                       curl_setopt($ch, CURLOPT_TIMEOUT, 30);
-                       curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
-                       curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
-                       curl_setopt($ch, CURLOPT_USERAGENT, self::BROWSER_AGENT_STRING);
-
-                       if(!empty($port)) {
-                               curl_setopt($ch, CURLOPT_PORT, $port);
-                       }
-                       curl_exec($ch);
-                       curl_close($ch);
-
-                       $ret = true;
-               }
-
-               fclose($fh);
-
-               return $ret;
-       }
-
-       /**
-        * simulate the Null coalescing operator in php5
-        * this only works with arrays and checking if the key is there and echo/return it.
-        * http://php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op
-        *
-        * @param array $array
-        * @param string $key
-        * @return mixed
-        */
-       static function ifset(array $array, string $key): mixed {
-               return $array[$key] ?? false;
-       }
-
-       /**
-        * try to gather meta information from given URL
-        *
-        * @param string $url
-        * @return array
-        */
-       static function gatherInfoFromURL(string $url): array {
-               $ret = array();
-
-               if(self::validate($url,'url')) {
-                       $data = self::curlCall($url);
-                       if(!empty($data)) {
-                               $ret = self::socialMetaInfos($data);
-                       }
-               }
-
-               return $ret;
-       }
-
-       /**
-        * get as much as possible social meta infos from given string
-        * the string is usually a HTML source
-        *
-        * @param string $string
-        * @return array
-        */
-       static function socialMetaInfos(string $string): array {
-               #http://www.w3bees.com/2013/11/fetch-facebook-og-meta-tags-with-php.html
-               #http://www.9lessons.info/2014/01/social-meta-tags-for-google-twitter-and.html
-               #http://ogp.me/
-               #https://moz.com/blog/meta-data-templates-123
-
-               $dom = new DomDocument;
-               # surpress invalid html warnings
-               @$dom->loadHTML($string);
-
-               $xpath = new DOMXPath($dom);
-               $metas = $xpath->query('//*/meta');
-
-               $mediaInfos = array();
-
-               # meta tags
-               foreach($metas as $meta) {
-                       if($meta->getAttribute('property')) {
-                               $prop = $meta->getAttribute('property');
-                               $prop = mb_strtolower($prop);
-
-                               # minimum required information
-                               # http://ogp.me/#metadata
-                               if($prop == "og:title") {
-
-                                       $mediaInfos['title'] = $meta->getAttribute('content');
-                               }
-                               elseif($prop == "og:image") {
-                                       $mediaInfos['image'] = $meta->getAttribute('content');
-                               }
-                               elseif($prop == "og:url") {
-                                       $mediaInfos['link'] = $meta->getAttribute('content');
-                               }
-                               elseif($prop == "og:description") {
-                                       $mediaInfos['description'] = $meta->getAttribute('content');
-                               }
-                       }
-                       elseif($meta->getAttribute('name')) {
-                               $name = $meta->getAttribute('name');
-                               $name = mb_strtolower($name);
-
-                               # twitter
-                               # https://dev.twitter.com/cards/overview
-
-                               if($name == "twitter:title") {
-                                       $mediaInfos['title'] = $meta->getAttribute('content');
-                               }
-                               elseif($name == "twitter:description") {
-                                       $mediaInfos['description'] = $meta->getAttribute('content');
-                               }
-                               elseif($name == "twitter:image") {
-                                       $mediaInfos['image'] = $meta->getAttribute('content');
-                               }
-                               elseif($name == "description") {
-                                       $mediaInfos['description'] = $meta->getAttribute('content');
-                               }
-
-                       }
-                       elseif($meta->getAttribute('itemprop')) {
-                               $itemprop = $meta->getAttribute('itemprop');
-                               $itemprop = mb_strtolower($itemprop);
-
-                               # google plus
-                               if($itemprop == "name") {
-                                       $mediaInfos['title'] = $meta->getAttribute('content');
-                               }
-                               elseif($itemprop == "description") {
-                                       $mediaInfos['description'] = $meta->getAttribute('content');
-                               }
-                               elseif($itemprop == "image") {
-                                       $mediaInfos['image'] = $meta->getAttribute('content');
-                               }
-
-                       }
-               }
-
-
-               if(!isset($mediaInfos['title'])) {
-                       $titleDom = $xpath->query('//title');
-                       $mediaInfos['title'] = $titleDom->item(0)->nodeValue;
-               }
-
-               return $mediaInfos;
-       }
-
-       /**
-        * at creation a category or tag can be a string with multiple values.
-        * separated with space or ,
-        * category and tag is a single string without any separators
-        *
-        * @param string $string
-        * @return array
-        */
-       static function prepareTagOrCategoryStr(string $string): array {
-               $ret = array();
+    private const BROWSER_AGENT_STRING = 'Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0';
+
+    /**
+     * validate the given string with the given type. Optional check the string
+     * length
+     *
+     * @param string $input The string to check
+     * @param string $mode How the string should be checked
+     * @param int $limit If int given the string is checked for length
+     *
+     * @see http://de.php.net/manual/en/regexp.reference.unicode.php
+     * http://www.sql-und-xml.de/unicode-database/#pc
+     *
+     * the pattern replaces all that is allowed. the correct result after
+     * the replace should be empty, otherwise are there chars which are not
+     * allowed
+     *
+     * @return bool
+     */
+    static function validate(string $input, string $mode='text', int $limit=0): bool {
+        // check if we have input
+        $input = trim($input);
+
+        if($input == "") return false;
+
+        $ret = false;
+
+        switch ($mode) {
+            case 'mail':
+                if(filter_var($input,FILTER_VALIDATE_EMAIL) === $input) {
+                    return true;
+                }
+                else {
+                    return false;
+                }
+            break;
+
+            case 'url':
+                if(filter_var($input,FILTER_VALIDATE_URL) === $input) {
+                    return true;
+                }
+                else {
+                    return false;
+                }
+            break;
+
+            case 'nospace':
+                // text without any whitespace and special chars
+                $pattern = '/[\p{L}\p{N}]/u';
+            break;
+
+            case 'nospaceP':
+                // text without any whitespace and special chars
+                // but with Punctuation other
+                # http://www.sql-und-xml.de/unicode-database/po.html
+                $pattern = '/[\p{L}\p{N}\p{Po}\-_]/u';
+            break;
+
+            case 'digit':
+                // only numbers and digit
+                // warning with negative numbers...
+                $pattern = '/[\p{N}\-]/';
+            break;
+
+            case 'pageTitle':
+                // text with whitespace and without special chars
+                // but with Punctuation
+                $pattern = '/[\p{L}\p{N}\p{Po}\p{Z}\s\-_]/u';
+            break;
+
+            # strange. the \p{M} is needed.. don't know why..
+            case 'filename':
+                $pattern = '/[\p{L}\p{N}\p{M}\-_\.\p{Zs}]/u';
+            break;
+
+            case 'text':
+            default:
+                $pattern = '/[\p{L}\p{N}\p{P}\p{S}\p{Z}\p{M}\s]/u';
+        }
+
+        $value = preg_replace($pattern, '', $input);
+
+        if($value === "") {
+            $ret = true;
+        }
+
+        if(!empty($limit)) {
+            # isset starts with 0
+            if(isset($input[$limit])) {
+                # too long
+                $ret = false;
+            }
+        }
+
+        return $ret;
+    }
+
+
+    /**
+     * execute a curl call to the given $url
+     *
+     * @param string $url The request url
+     * @param int $port
+     * @return string
+     */
+    static function curlCall(string $url, int $port=0): string {
+        $ret = '';
+
+        $ch = curl_init();
+
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
+        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+        curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
+        curl_setopt($ch, CURLOPT_USERAGENT,self::BROWSER_AGENT_STRING);
+
+        // curl_setopt($ch, CURLOPT_VERBOSE, true);
+        // curl_setopt($ch, CURLOPT_HEADER, true);
+
+        if(!empty($port)) {
+          curl_setopt($ch, CURLOPT_PORT, $port);
+        }
+
+        $do = curl_exec($ch);
+
+        if(is_string($do) === true) {
+            $ret = $do;
+        }
+        else {
+            error_log('ERROR '.var_export(curl_error($ch),true));
+        }
+
+        curl_close($ch);
+
+        return $ret;
+    }
+
+    /**
+     * Download given url to given file
+     *
+     * @param string $url
+     * @param string $whereToStore
+     * @param int $port
+     * @return bool
+     */
+    static function downloadFile(string $url, string $whereToStore, int $port=0): bool {
+        $fh = fopen($whereToStore, 'w+');
+
+        $ret = false;
+
+        if($fh !== false) {
+            $ch = curl_init($url);
+            curl_setopt($ch, CURLOPT_FILE, $fh);
+
+            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
+            curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+            curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
+            curl_setopt($ch, CURLOPT_USERAGENT, self::BROWSER_AGENT_STRING);
+
+            if(!empty($port)) {
+                curl_setopt($ch, CURLOPT_PORT, $port);
+            }
+            curl_exec($ch);
+            curl_close($ch);
+
+            $ret = true;
+        }
+
+        fclose($fh);
+
+        return $ret;
+    }
+
+    /**
+     * simulate the Null coalescing operator in php5
+     * this only works with arrays and checking if the key is there and echo/return it.
+     * http://php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op
+     *
+     * @param array $array
+     * @param string $key
+     * @return mixed
+     */
+    static function ifset(array $array, string $key): mixed {
+        return $array[$key] ?? false;
+    }
+
+    /**
+     * try to gather meta information from given URL
+     *
+     * @param string $url
+     * @return array
+     */
+    static function gatherInfoFromURL(string $url): array {
+        $ret = array();
+
+        if(self::validate($url,'url')) {
+            $data = self::curlCall($url);
+            if(!empty($data)) {
+                $ret = self::socialMetaInfos($data);
+            }
+        }
+
+        return $ret;
+    }
+
+    /**
+     * get as much as possible social meta infos from given string
+     * the string is usually a HTML source
+     *
+     * @param string $string
+     * @return array
+     */
+    static function socialMetaInfos(string $string): array {
+        #http://www.w3bees.com/2013/11/fetch-facebook-og-meta-tags-with-php.html
+        #http://www.9lessons.info/2014/01/social-meta-tags-for-google-twitter-and.html
+        #http://ogp.me/
+        #https://moz.com/blog/meta-data-templates-123
+
+        $dom = new DomDocument;
+        # surpress invalid html warnings
+        @$dom->loadHTML($string);
+
+        $xpath = new DOMXPath($dom);
+        $metas = $xpath->query('//*/meta');
+
+        $mediaInfos = array();
+
+        # meta tags
+        foreach($metas as $meta) {
+            if($meta->getAttribute('property')) {
+                $prop = $meta->getAttribute('property');
+                $prop = mb_strtolower($prop);
+
+                # minimum required information
+                # http://ogp.me/#metadata
+                if($prop == "og:title") {
+
+                    $mediaInfos['title'] = $meta->getAttribute('content');
+                }
+                elseif($prop == "og:image") {
+                    $mediaInfos['image'] = $meta->getAttribute('content');
+                }
+                elseif($prop == "og:url") {
+                    $mediaInfos['link'] = $meta->getAttribute('content');
+                }
+                elseif($prop == "og:description") {
+                    $mediaInfos['description'] = $meta->getAttribute('content');
+                }
+            }
+            elseif($meta->getAttribute('name')) {
+                $name = $meta->getAttribute('name');
+                $name = mb_strtolower($name);
+
+                # twitter
+                # https://dev.twitter.com/cards/overview
+
+                if($name == "twitter:title") {
+                    $mediaInfos['title'] = $meta->getAttribute('content');
+                }
+                elseif($name == "twitter:description") {
+                    $mediaInfos['description'] = $meta->getAttribute('content');
+                }
+                elseif($name == "twitter:image") {
+                    $mediaInfos['image'] = $meta->getAttribute('content');
+                }
+                elseif($name == "description") {
+                    $mediaInfos['description'] = $meta->getAttribute('content');
+                }
+
+            }
+            elseif($meta->getAttribute('itemprop')) {
+                $itemprop = $meta->getAttribute('itemprop');
+                $itemprop = mb_strtolower($itemprop);
+
+                # google plus
+                if($itemprop == "name") {
+                    $mediaInfos['title'] = $meta->getAttribute('content');
+                }
+                elseif($itemprop == "description") {
+                    $mediaInfos['description'] = $meta->getAttribute('content');
+                }
+                elseif($itemprop == "image") {
+                    $mediaInfos['image'] = $meta->getAttribute('content');
+                }
+
+            }
+        }
+
+
+        if(!isset($mediaInfos['title'])) {
+            $titleDom = $xpath->query('//title');
+            $mediaInfos['title'] = $titleDom->item(0)->nodeValue;
+        }
+
+        return $mediaInfos;
+    }
+
+    /**
+     * at creation a category or tag can be a string with multiple values.
+     * separated with space or ,
+     * category and tag is a single string without any separators
+     *
+     * @param string $string
+     * @return array
+     */
+    static function prepareTagOrCategoryStr(string $string): array {
+        $ret = array();
         $_ret = array();
 
-               $string = trim($string, ", ");
-               if(strstr($string, ",")) {
-                       $_t = explode(",", $string);
-                       foreach($_t as $n) {
-                               $_ret[$n] = $n;
-                       }
-                       unset($_t);
-                       unset($n);
-
-                       foreach($_ret as $e) {
-                               if(strstr($e, " ")) {
-                                       unset($ret[$e]);
-                                       $_t = explode(" ", $e);
-                                       foreach($_t as $new) {
-                                               $new = trim($new);
-                                               $_c = self::validate($new,'nospace');
-                                               if(!empty($new) && $_c === true) {
-                                                       $ret[$new] = $new;
-                                               }
-                                       }
-                               }
-                               else {
+        $string = trim($string, ", ");
+        if(strstr($string, ",")) {
+            $_t = explode(",", $string);
+            foreach($_t as $n) {
+                $_ret[$n] = $n;
+            }
+            unset($_t);
+            unset($n);
+
+            foreach($_ret as $e) {
+                if(strstr($e, " ")) {
+                    unset($ret[$e]);
+                    $_t = explode(" ", $e);
+                    foreach($_t as $new) {
+                        $new = trim($new);
+                        $_c = self::validate($new,'nospace');
+                        if(!empty($new) && $_c === true) {
+                            $ret[$new] = $new;
+                        }
+                    }
+                }
+                else {
                     $new = trim($e);
                     $_c = self::validate($new,'nospace');
                     if(!empty($new) && $_c === true) {
                         $ret[$new] = $new;
                     }
                 }
-                       }
-               }
-               else {
-                       $_t = explode(" ", $string);
-                       foreach($_t as $new) {
-                               $new = trim($new);
+            }
+        }
+        else {
+            $_t = explode(" ", $string);
+            foreach($_t as $new) {
+                $new = trim($new);
                 $_c = self::validate($new,'nospace');
-                               if(!empty($new) && $_c === true) {
-                                  $ret[$new] = $new;
-                               }
-                       }
-               }
-
-
-               return $ret;
-       }
-
-       /**
-        * a very simple HTTP_AUTH authentication.
-        */
-       static function simpleAuth(): void {
-               if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])
-                       || $_SERVER['PHP_AUTH_USER'] !== FRONTEND_USERNAME || $_SERVER['PHP_AUTH_PW'] !== FRONTEND_PASSWORD
-                       ) {
-                       header('WWW-Authenticate: Basic realm="Insipid edit area"');
-                       header('HTTP/1.0 401 Unauthorized');
-                       echo 'No Access.';
-                       exit;
-               }
-       }
-
-       /**
-        * check if we have a valid auth. Nothing more.
-        *
-        * @see Summoner::simpleAuth to trigger the auth
-        * @return bool
-        */
-       static function simpleAuthCheck(): bool {
-               if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])
-                       && $_SERVER['PHP_AUTH_USER'] === FRONTEND_USERNAME && $_SERVER['PHP_AUTH_PW'] === FRONTEND_PASSWORD
-               ) {
-                       return true;
-               }
-
-               return false;
-       }
-
-       /**
-        * Checks if in the given urlstring a scheme is existent. If not add http:// to it
-        *
-        * @param string $urlString
-        * @return string
-        */
-       static function addSchemeToURL(string $urlString): string {
-               $ret = $urlString;
-
-               if(empty(parse_url($ret, PHP_URL_SCHEME))) {
-                       $ret = "http://".$ret;
-               }
-
-               return $ret;
-       }
-
-       /**
-        * retrieve the folder size with its children of given folder path
-        *
-        * @param string $folder
-        * @return int
-        */
-       static function folderSize(string $folder): int {
-               $ret = 0;
-
-               if(file_exists($folder) && is_readable($folder)) {
-                       foreach (glob(rtrim($folder, '/') . '/*', GLOB_NOSORT) as $each) {
-                               $ret += is_file($each) ? filesize($each) : self::folderSize($each);
-                       }
-               }
-
-               return $ret;
-       }
-
-       /**
-        * Calculate the given byte size in more human readable format.
-        *
-        * @param integer $size
-        * @param string $unit
-        * @return string
-        */
-       static function humanFileSize(int $size, string $unit=""): string {
+                if(!empty($new) && $_c === true) {
+                   $ret[$new] = $new;
+                }
+            }
+        }
+
+
+        return $ret;
+    }
+
+    /**
+     * a very simple HTTP_AUTH authentication.
+     */
+    static function simpleAuth(): void {
+        if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])
+            || $_SERVER['PHP_AUTH_USER'] !== FRONTEND_USERNAME || $_SERVER['PHP_AUTH_PW'] !== FRONTEND_PASSWORD
+            ) {
+            header('WWW-Authenticate: Basic realm="Insipid edit area"');
+            header('HTTP/1.0 401 Unauthorized');
+            echo 'No Access.';
+            exit;
+        }
+    }
+
+    /**
+     * check if we have a valid auth. Nothing more.
+     *
+     * @see Summoner::simpleAuth to trigger the auth
+     * @return bool
+     */
+    static function simpleAuthCheck(): bool {
+        if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])
+            && $_SERVER['PHP_AUTH_USER'] === FRONTEND_USERNAME && $_SERVER['PHP_AUTH_PW'] === FRONTEND_PASSWORD
+        ) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if in the given urlstring a scheme is existent. If not add http:// to it
+     *
+     * @param string $urlString
+     * @return string
+     */
+    static function addSchemeToURL(string $urlString): string {
+        $ret = $urlString;
+
+        if(empty(parse_url($ret, PHP_URL_SCHEME))) {
+            $ret = "http://".$ret;
+        }
+
+        return $ret;
+    }
+
+    /**
+     * retrieve the folder size with its children of given folder path
+     *
+     * @param string $folder
+     * @return int
+     */
+    static function folderSize(string $folder): int {
+        $ret = 0;
+
+        if(file_exists($folder) && is_readable($folder)) {
+            foreach (glob(rtrim($folder, '/') . '/*', GLOB_NOSORT) as $each) {
+                $ret += is_file($each) ? filesize($each) : self::folderSize($each);
+            }
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Calculate the given byte size in more human readable format.
+     *
+     * @param integer $size
+     * @param string $unit
+     * @return string
+     */
+    static function humanFileSize(int $size, string $unit=""): string {
         $ret =  number_format($size)." bytes";
 
         if((!$unit && $size >= 1<<30) || $unit == "GB") {
@@ -473,18 +473,18 @@ class Summoner {
         }
 
         return $ret;
-       }
-
-       /**
-        * delete and/or empty a directory
-        *
-        * $empty = true => empty the directory but do not delete it
-        *
-        * @param string $directory
-        * @param boolean $empty
-        * @param int $fTime If not false remove files older then this value in sec.
-        * @return boolean
-        */
+    }
+
+    /**
+     * delete and/or empty a directory
+     *
+     * $empty = true => empty the directory but do not delete it
+     *
+     * @param string $directory
+     * @param boolean $empty
+     * @param int $fTime If not false remove files older then this value in sec.
+     * @return boolean
+     */
     static function recursive_remove_directory(string $directory, bool $empty=false, int $fTime=0): bool {
         if(substr($directory,-1) == '/') {
             $directory = substr($directory,0,-1);
@@ -532,15 +532,15 @@ class Summoner {
         }
     }
 
-       /**
-        * http_build_query with modify array
-        * modify will add: key AND value not empty
-        * modify will remove: only key with no value
-        *
-        * @param array $array
-        * @param array $modify
-        * @return string
-        */
+    /**
+     * http_build_query with modify array
+     * modify will add: key AND value not empty
+     * modify will remove: only key with no value
+     *
+     * @param array $array
+     * @param array $modify
+     * @return string
+     */
     static function createFromParameterLinkQuery(array $array, array $modify=array()): string {
         $ret = '';
 
@@ -562,25 +562,25 @@ class Summoner {
         return $ret;
     }
 
-       /**
-        * Make the input more safe for logging
-        *
-        * @param string $input The string to be made more safe
-        * @return string
-        */
-       static function cleanForLog($input): string {
-               $input = var_export($input, true);
-               $input = preg_replace( "/[\t\n\r]/", " ", $input);
-               return addcslashes($input, "\000..\037\177..\377\\");
-       }
-
-       /**
-        * error_log with a dedicated destination
-        * Uses LOGFILE const
-        *
-        * @param string $msg The string to be written to the log
-        */
-       static function sysLog(string $msg): void {
-               error_log(date("c")." ".$msg."\n", 3, LOGFILE);
-       }
+    /**
+     * Make the input more safe for logging
+     *
+     * @param string $input The string to be made more safe
+     * @return string
+     */
+    static function cleanForLog($input): string {
+        $input = var_export($input, true);
+        $input = preg_replace( "/[\t\n\r]/", " ", $input);
+        return addcslashes($input, "\000..\037\177..\377\\");
+    }
+
+    /**
+     * error_log with a dedicated destination
+     * Uses LOGFILE const
+     *
+     * @param string $msg The string to be written to the log
+     */
+    static function sysLog(string $msg): void {
+        error_log(date("c")." ".$msg."\n", 3, LOGFILE);
+    }
 }
index 2fd46ce8f05a4da418a2a24fe232906b74f862d1..d6a131f5eeaebd38e222319215e3625ca341bc32 100644 (file)
@@ -3,7 +3,7 @@
  * Insipid
  * Personal web-bookmark-system
  *
- * Copyright 2016-2022 Johannes Keßler
+ * Copyright 2016-2023 Johannes Keßler
  *
  * Development starting from 2011: Johannes Keßler
  * https://www.bananas-playground.net/projekt/insipid/
  * Class Tag
  */
 class Tag {
-       /**
-        * the database object
-        *
-        * @var mysqli
-        */
-       private $DB;
-
-       /**
-        * the current loaded tag by DB id
-        *
-        * @var int
-        */
-       private $_id;
-
-       /**
-        * current loaded tag data
-        *
-        * @var array
-        */
-       private $_data;
-
-       /**
-        * Tag constructor.
-        *
-        * @param mysqli $databaseConnectionObject
-        */
-       public function __construct($databaseConnectionObject) {
-               $this->DB = $databaseConnectionObject;
-       }
-
-       /**
-        * by given string load the info from the DB and even create if not existing
-        *
-        * @param string $string
-        * @param bool $doNotCreate
-        * @return int 0=fail, 1=existing, 2=new, 3=newNotCreated
-        */
-       public function initbystring(string $string, $doNotCreate=false): int {
-           $ret = 0;
-               $this->_id = false;
-               if(!empty($string)) {
-                       $queryStr = "SELECT `id`,`name` FROM `".DB_PREFIX."_tag`
-                                                       WHERE `name` = '".$this->DB->real_escape_string($string)."'";
-                       $query = $this->DB->query($queryStr);
-                       if(!empty($query) && $query->num_rows > 0) {
-                               $result = $query->fetch_assoc();
-                               $this->_id = $result['id'];
-                               $this->_data = $result;
-                               $ret = 1;
-                       }
-                       else {
-                           if(!$doNotCreate) {
-                    $queryStr = "INSERT INTO `" . DB_PREFIX . "_tag`
-                                    SET `name` = '" . $this->DB->real_escape_string($string) . "'";
-                    $this->DB->query($queryStr);
-                    if (!empty($this->DB->insert_id)) {
-                        $this->_id = $this->DB->insert_id;
-                        $this->_data['id'] = $this->_id;
-                        $this->_data['name'] = $string;
-                        $ret = 2;
+    /**
+     * the database object
+     *
+     * @var mysqli
+     */
+    private mysqli $DB;
+
+    /**
+     * the current loaded tag by DB id
+     *
+     * @var string
+     */
+    private string $_id;
+
+    /**
+     * current loaded tag data
+     *
+     * @var array
+     */
+    private array $_data;
+
+    /**
+     * Tag constructor.
+     *
+     * @param mysqli $databaseConnectionObject
+     */
+    public function __construct(mysqli $databaseConnectionObject) {
+        $this->DB = $databaseConnectionObject;
+    }
+
+    /**
+     * by given string load the info from the DB and even create if not existing
+     *
+     * @param string $string
+     * @param bool $doNotCreate
+     * @return int 0=fail, 1=existing, 2=new, 3=newNotCreated
+     */
+    public function initbystring(string $string, $doNotCreate=false): int {
+        $ret = 0;
+        $this->_id = false;
+        if(!empty($string)) {
+            $queryStr = "SELECT `id`,`name` FROM `".DB_PREFIX."_tag`
+                            WHERE `name` = '".$this->DB->real_escape_string($string)."'";
+
+            if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
+
+            try {
+                $query = $this->DB->query($queryStr);
+                if(!empty($query) && $query->num_rows > 0) {
+                    $result = $query->fetch_assoc();
+                    $this->_id = $result['id'];
+                    $this->_data = $result;
+                    $ret = 1;
+                }
+                else {
+                    if(!$doNotCreate) {
+                        $queryStr = "INSERT INTO `" . DB_PREFIX . "_tag`
+                                        SET `name` = '" . $this->DB->real_escape_string($string) . "'";
+
+                        if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
+
+                        $this->DB->query($queryStr);
+                        if (!empty($this->DB->insert_id)) {
+                            $this->_id = $this->DB->insert_id;
+                            $this->_data['id'] = $this->_id;
+                            $this->_data['name'] = $string;
+                            $ret = 2;
+                        }
+                    }
+                    else {
+                        $ret=3;
                     }
                 }
-                           else {
-                               $ret=3;
+            } catch (Exception $e) {
+                Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
+            }
+        }
+        return $ret;
+    }
+
+    /**
+     * by given DB table id load all the info we need
+     *
+     * @param int $id
+     * @return int
+     */
+    public function initbyid(int $id): int {
+        $this->_id = 0;
+
+        if(!empty($id)) {
+            $queryStr = "SELECT `id`,`name` FROM `".DB_PREFIX."_tag`
+                            WHERE `id` = '".$this->DB->real_escape_string($id)."'";
+
+            if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
+
+            try {
+                $query = $this->DB->query($queryStr);
+                if(!empty($query) && $query->num_rows > 0) {
+                    $result = $query->fetch_assoc();
+                    $this->_id = $result['id'];
+                    $this->_data = $result;
                 }
-                       }
-               }
-               return $ret;
-       }
-
-       /**
-        * by given DB table id load all the info we need
-        *
-        * @param int $id
-        * @return int
-        */
-       public function initbyid(int $id): int {
-               $this->_id = 0;
-
-               if(!empty($id)) {
-                       $queryStr = "SELECT `id`,`name` FROM `".DB_PREFIX."_tag`
-                                                       WHERE `id` = '".$this->DB->real_escape_string($id)."'";
-                       $query = $this->DB->query($queryStr);
-                       if(!empty($query) && $query->num_rows > 0) {
-                               $result = $query->fetch_assoc();
-                               $this->_id = $result['id'];
-                               $this->_data = $result;
-                       }
-               }
-
-               return $this->_id;
-       }
-
-       /**
-        * return all or data fpr given key on the current loaded tag
-        *
-        * @param bool $key
-        * @return array|string
-        */
-       public function getData($key=false) {
-               $ret = $this->_data;
-
-               if(!empty($key) && isset($this->_data[$key])) {
-                       $ret = $this->_data[$key];
-               }
-
-               return $ret;
-       }
-
-       /**
-        * set the relation to the given link to the loaded tag
-        *
-        * @param int $linkid
-        * @return void
-        */
-       public function setRelation(int $linkid) {
-               if(!empty($linkid) && !empty($this->_id)) {
-                       $queryStr = "INSERT IGNORE INTO `".DB_PREFIX."_tagrelation`
-                                                       SET `linkid` = '".$this->DB->real_escape_string($linkid)."',
-                                                               `tagid` = '".$this->DB->real_escape_string($this->_id)."'";
-                       $this->DB->query($queryStr);
-               }
-       }
+            } catch (Exception $e) {
+                Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
+            }
+        }
+
+        return $this->_id;
+    }
+
+    /**
+     * return all or data fpr given key on the current loaded tag
+     *
+     * @param bool $key
+     * @return array|string
+     */
+    public function getData($key=false) {
+        $ret = $this->_data;
+
+        if(!empty($key) && isset($this->_data[$key])) {
+            $ret = $this->_data[$key];
+        }
+
+        return $ret;
+    }
+
+    /**
+     * set the relation to the given link to the loaded tag
+     *
+     * @param int $linkid
+     * @return void
+     */
+    public function setRelation(int $linkid): void {
+        if(!empty($linkid) && !empty($this->_id)) {
+            $queryStr = "INSERT IGNORE INTO `".DB_PREFIX."_tagrelation`
+                            SET `linkid` = '".$this->DB->real_escape_string($linkid)."',
+                                `tagid` = '".$this->DB->real_escape_string($this->_id)."'";
+            if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
+
+            try {
+                $this->DB->query($queryStr);
+            } catch (Exception $e) {
+                Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
+            }
+        }
+    }
 
     /**
      * Return an array of any linkid related to the current loaded tag
-        *
+     *
      * @return array
      */
-       public function getReleations(): array {
-           $ret = array();
-
-           $queryStr = "SELECT linkid 
-                       FROM `".DB_PREFIX."_tagrelation` 
-                       WHERE tagid = '".$this->DB->real_escape_string($this->_id)."'";
-           $query = $this->DB->query($queryStr);
-        if(!empty($query) && $query->num_rows > 0) {
-            while($result = $query->fetch_assoc()) {
-                $ret[] = $result['linkid'];
+    public function getReleations(): array {
+        $ret = array();
+
+        $queryStr = "SELECT linkid 
+                    FROM `".DB_PREFIX."_tagrelation` 
+                    WHERE tagid = '".$this->DB->real_escape_string($this->_id)."'";
+
+        if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
+
+        try {
+            $query = $this->DB->query($queryStr);
+            if(!empty($query) && $query->num_rows > 0) {
+                while($result = $query->fetch_assoc()) {
+                    $ret[] = $result['linkid'];
+                }
+            }
+        } catch (Exception $e) {
+            Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
+        }
+
+        return $ret;
+    }
+
+    /**
+     * deletes the current loaded tag from db
+     *
+     * @return boolean
+     */
+    public function delete(): bool {
+        $ret = false;
+
+        if(!empty($this->_id)) {
+            $this->DB->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
+
+            try {
+                $queryStr = "DELETE
+                    FROM `".DB_PREFIX."_tagrelation`
+                    WHERE `tagid` = '".$this->DB->real_escape_string($this->_id)."'";
+                $this->DB->query($queryStr);
+
+                $queryStr = "DELETE
+                    FROM `".DB_PREFIX."_tag`
+                    WHERE `id` = '".$this->DB->real_escape_string($this->_id)."'";
+
+                if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
+
+                $this->DB->query($queryStr);
+                $this->DB->commit();
+            } catch (Exception $e) {
+                Summoner::sysLog('[ERROR] Failed to remove tag: '.var_export($e->getMessage(),true));
+
+                $this->DB->rollback();
             }
         }
 
         return $ret;
     }
 
-       /**
-        * deletes the current loaded tag from db
-        *
-        * @return boolean
-        */
-       public function delete(): bool {
-               $ret = false;
-
-               if(!empty($this->_id)) {
-                       $this->DB->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
-
-                       try {
-                               $queryStr = "DELETE
-                                       FROM `".DB_PREFIX."_tagrelation`
-                                       WHERE `tagid` = '".$this->DB->real_escape_string($this->_id)."'";
-                               $this->DB->query($queryStr);
-
-                               $queryStr = "DELETE
-                                       FROM `".DB_PREFIX."_tag`
-                                       WHERE `id` = '".$this->DB->real_escape_string($this->_id)."'";
-                               $this->DB->query($queryStr);
-
-                               $this->DB->commit();
-                       } catch (Exception $e) {
-                               if(DEBUG) {
-                                       var_dump($e->getMessage());
-                               }
-                               error_log('ERROR Failed to remove tag: '.var_export($e->getMessage(),true));
-
-                               $this->DB->rollback();
-                       }
-               }
-
-               return $ret;
-       }
-
-       /**
-        * Rename current loaded tag name
-        *
-        * @param string $newValue
-        * @return void
-        */
-       public function rename(string $newValue) {
-           if(!empty($newValue)) {
-               $queryStr = "UPDATE `".DB_PREFIX."_tag`
-                           SET `name` = '".$this->DB->real_escape_string($newValue)."'
-                           WHERE `id` = '".$this->DB->real_escape_string($this->_id)."'";
-               $this->DB->query($queryStr);
+    /**
+     * Rename current loaded tag name
+     *
+     * @param string $newValue
+     * @return void
+     */
+    public function rename(string $newValue): void {
+        if(!empty($newValue)) {
+            $queryStr = "UPDATE `".DB_PREFIX."_tag`
+                        SET `name` = '".$this->DB->real_escape_string($newValue)."'
+                        WHERE `id` = '".$this->DB->real_escape_string($this->_id)."'";
+
+            if(QUERY_DEBUG) Summoner::sysLog("[QUERY] ".__METHOD__." query: ".Summoner::cleanForLog($queryStr));
+
+            try {
+                $this->DB->query($queryStr);
+            } catch (Exception $e) {
+                Summoner::sysLog("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage());
+            }
             $this->_data['name'] = $newValue;
         }
     }