<?php
/**
 * @author     Thomas Meyer
 * @licence    http://creativecommons.org/licenses/by-nc-sa/2.5/
 * @package    yana
 * @subpackage plugins
 */

/**
 * @access     public
 * @package    yana
 * @subpackage plugins
 */
class plugin_guestbook extends plugin
{

    /* private mixed */           var $database;
    /* private readonly String */ var $ACTION_SHOW          = "guestbook_read_read";
    /* private readonly String */ var $ACTION_DETAILS       = "guestbook_read_read_seperated";
    /* private readonly String */ var $ACTION_NEW           = "guestbook_default_new";
    /* private readonly String */ var $ACTION_NEW_WRITE     = "guestbook_write_new";
    /* private readonly String */ var $ACTION_DELETE        = "guestbook_write_delete";
    /* private readonly String */ var $ACTION_EDIT          = "guestbook_read_edit";
    /* private readonly String */ var $ACTION_EDIT_WRITE    = "guestbook_write_edit";
    /* private readonly String */ var $ACTION_COMMENT       = "guestbook_default_comment";
    /* private readonly String */ var $ACTION_COMMENT_WRITE = "guestbook_write_comment";

    /* constructor */ function plugin_guestbook($name)
    {
        settype($name,"string");
        global $YANA;

        $this->name = $name;
        $this->database = $YANA->connect('guestbook');

        /* Plugin-specific addities */
        $url = $YANA->getVar("SETTINGS.CSS");
        if (!empty($url)) {
            $YANA->setVar("CSS", DisplayUtility::css($url));
        }

        $YANA->setVar("ACTION_SHOW"         , $this->ACTION_SHOW);
        $YANA->setVar("ACTION_DETAILS"      , $this->ACTION_DETAILS);
        $YANA->setVar("ACTION_NEW"          , $this->ACTION_NEW);
        $YANA->setVar("ACTION_NEW_WRITE"    , $this->ACTION_NEW_WRITE);
        $YANA->setVar("ACTION_DELETE"       , $this->ACTION_DELETE);
        $YANA->setVar("ACTION_EDIT"         , $this->ACTION_EDIT);
        $YANA->setVar("ACTION_EDIT_WRITE"   , $this->ACTION_EDIT_WRITE);
        $YANA->setVar("ACTION_COMMENT"      , $this->ACTION_COMMENT);
        $YANA->setVar("ACTION_COMMENT_WRITE", $this->ACTION_COMMENT_WRITE);
    }

    /* public void */ function _default(/* String */ $event, /* Hashtable */ $ARGS)
    {
        /* check input data */
        settype($event, "string");
        settype($ARGS, "array");
        $event = strtolower($event);

        global $YANA;

        switch ($event) {

/* BEGIN auto-generated Event-handlers */

             /* Type: read, Permission: 75, Templates:  GUESTBOOK_EDIT */
             case $this->ACTION_EDIT:
                 $YANA->setVar("BESCHREIBUNG", '%LANGUAGE.DESCR_SHOW%');
                 $DB_SRC = $this->database->structure->getStructure();
                 $DB_SRC = changeCaseArray($DB_SRC,CASE_UPPER);
                 $YANA->setVar('DATABASE', $DB_SRC);
                 /* Create search request */
                 $url_where = "";
                 if (empty($ARGS['where'])) {

                     $ARGS['where'] = "";
                     foreach ($DB_SRC['TABLES']['GUESTBOOK']['CONTENT'] as $NAME => $CURRENT)
                     {
                         $NAME = strtolower($NAME);
                         if (!empty($ARGS["search_".$NAME]))
                         {
                             if (!empty($ARGS['where']))
                             {
                                 $ARGS['where'] .= ',';
                                 $url_where     .= ',';
                             }
                             $ARGS['where']   .= $NAME.'='.htmlentities($ARGS["search_".$NAME]);
                             $url_where       .= $NAME.'='.urlencode(htmlentities($ARGS["search_".$NAME]));
                         }
                     }

                 } else {
                     $url_where = $ARGS['where'];
                 }
                 /* commit request */
                 $YANA->setVar('DATABASE', $DB_SRC);
                 $YANA->setVar('WHERE', $url_where);
                 $YANA->setVar('ROWS', $this->_get_table($ARGS, "guestbook"));
                 return true;
             break;


             /* Type: write, Permission: 75, Templates: MESSAGE  */
             case $this->ACTION_EDIT_WRITE:
                 /* convert raw form data into arrays */
                 $ENTRIES = array();
                 foreach($ARGS as $a => $b)
                 {
                     if (preg_match("/^guestbook\/([^\/]+)\/(.+)$/i", $a, $m))
                     {
                         /* before doing anything, check if entry exists */
                         if (!$this->database->exists("guestbook.".strtolower($m[1])))
                         {
                             $YANA->report(new alert("ungueltige_eingabe"));
                             $YANA->report(new log("SQL-ERROR: table guestbook.".strtolower($m[1])." does not exist!"));
                             return false;
                         } else {
                             $ENTRIES[strtolower($m[1])][strtolower($m[2])] = $b;
                         }
                     }
                 }
                 /* now update the entries */
                 foreach($ENTRIES as $primary_key => $entry)
                 {
                     /* change entry only if it has been marked */
                     if (!empty($ARGS["marker/$primary_key"]))
                     {
                         /* update the row */
                         plugin_guestbook::_untaintInput($entry);
                         $this->database->insert("guestbook.$primary_key", $entry);
                     }
                 }
                 /* don't forget to save your recent changes ;-) */
                 if ($this->database->write()) {
                     return true;
                 } else {
                     return false;
                 }
             break;


             /* Type: write, Permission: 75, Templates: MESSAGE  */
             case $this->ACTION_DELETE:
                 /* find any previously marked entries and mark them for removal */
                 foreach($ARGS as $a => $b)
                 {
                     if (preg_match("/^MARKER\//i", $a) && !empty($b))
                     {
                         /* before deleting, check if entry exists */
                         if (!$this->database->exists("guestbook.".strtolower($b)))
                         {
                             $YANA->report(new alert('ungueltige_eingabe', 'The selected entry '.strtolower($b).' does not exist!'));
                             return false;
                         } else {
                             if (!$this->database->remove("guestbook.".strtolower($b))) return false;
                         }
                     }
                 }
                 /* now delete those entries */
                 if ($this->database->write()) {
                     return true;
                 } else {
                     return false;
                 }
             break;


             /* Type: default, Permission: 0, Templates:  GUESTBOOK_NEW */
             case $this->ACTION_NEW:
                 if ($this->_securityCheck() === false) {
                     return false;
                 }
                 $YANA->setVar("SECURITY_IMAGE_INDEX", rand(1,9));
                 $YANA->setVar("BESCHREIBUNG", '%LANGUAGE.DESCR_NEW%');
                 return true;
             break;


             /* Type: write, Permission: 0, Templates: MESSAGE  */
             case $this->ACTION_NEW_WRITE:
                 if ($this->_securityCheck() === false) {
                     return false;
                 }

                 $permission = $YANA->getVar("PERMISSION");
                 /* avoid spamming */
                 if (!is_int($permission) || $permission < 1) {
                     if ($YANA->getVar("PROFILE.GUESTBOOK.SPAMPROTECT") === true && !$YANA->handle("security_check_image", $ARGS)) {
                         $YANA->report(new alert('ungueltige_eingabe', 'Security check failed!'));
                         $YANA->report(new log('SPAM: CAPTCHA not solved, entry has not been created.'));
                         return false;
                     }
                 }

                 /* get values from form fields to create new entry */
                 $NEW_ENTRY = array();
                 $profile_id = $YANA->getVar("PROFILE.GUESTBOOK.PROFILE");
                 if (!empty($profile_id))                  $NEW_ENTRY['profile_id']          = $profile_id;
                 else if (!empty($ARGS['id']))             $NEW_ENTRY['profile_id']          = $ARGS['id'];
                 else                                      $NEW_ENTRY['profile_id']          = 'default';
                 if (!empty($ARGS['guestbook_ip']))        $NEW_ENTRY['guestbook_ip']        = $ARGS['guestbook_ip'];
                 if (!empty($ARGS['guestbook_name']))      $NEW_ENTRY['guestbook_name']      = $ARGS['guestbook_name'];
                 if (!empty($ARGS['guestbook_message']))   $NEW_ENTRY['guestbook_message']   = $ARGS['guestbook_message'];
                 if (!empty($ARGS['guestbook_mail']))      $NEW_ENTRY['guestbook_mail']      = $ARGS['guestbook_mail'];
                 if (!empty($ARGS['guestbook_hometown']))  $NEW_ENTRY['guestbook_hometown']  = $ARGS['guestbook_hometown'];
                 if (!empty($ARGS['guestbook_homepage']))  $NEW_ENTRY['guestbook_homepage']  = $ARGS['guestbook_homepage'];
                 if (!empty($ARGS['guestbook_messenger'])) $NEW_ENTRY['guestbook_messenger'] = $ARGS['guestbook_messenger'];
                 if (!empty($ARGS['guestbook_msgtyp']))    $NEW_ENTRY['guestbook_msgtyp']    = $ARGS['guestbook_msgtyp'];
                 if (!empty($ARGS['guestbook_opinion']))   $NEW_ENTRY['guestbook_opinion']   = $ARGS['guestbook_opinion'];

                 plugin_guestbook::_untaintInput($NEW_ENTRY);

                 /* mark registered users */
                 if (strcasecmp($YANA->getVar("SESSION_USER_ID"), $ARGS['guestbook_name']) == 0) {
                     $NEW_ENTRY['guestbook_is_registered'] = 1;
                 }

                 /* avoid flooding */
                 $myFlood = $YANA->plugins->get($this->name, "flood");
                 $myFlood->setMax((int)$YANA->getVar("PROFILE.GUESTBOOK.FLOODING"));
                 if ($myFlood->isBlocked()) {
                     $YANA->report(new log('Possibly flooding attempt detected. User request rejected.'));
                     $YANA->report(new alert('flooding'));
                     return false;
                 }
                 $recent_entry = $this->database->get("guestbook.?.guestbook_message");
                 if(!empty($NEW_ENTRY['guestbook_message']) && $recent_entry == $NEW_ENTRY['guestbook_message']) {
                     $YANA->report(new alert('nospam'));
                     return false;
                 } elseif($myFlood->getMax()>0) {
                     $myFlood->set();
                 }

                 /* insert new entry into table */
                 if (!$this->database->insert('guestbook.*',$NEW_ENTRY)) {
                     $YANA->report(new log('Failed to insert entry.', preg_replace('/\s/', ' ', makeConfig($NEW_ENTRY)) ));
                     $YANA->report(new alert('ungueltige_eingabe'));
                     return false;
                 } elseif (!$this->database->write()) {
                     $YANA->report(new log('Unable to submit entry.', preg_replace('/\s/', ' ', makeConfig($NEW_ENTRY)) ));
                     return false;
                 } else {
                     /* send Mail */
                     if (!empty($NEW_ENTRY['guestbook_mail']) && $YANA->getVar("PROFILE.GUESTBOOK.SENDMAIL"))
                     $this->_send_mail($NEW_ENTRY['guestbook_mail'],$YANA->skin->getFile("danke_mail"),$ARGS);
                     if ($YANA->getVar("PROFILE.GUESTBOOK.MAIL") && $YANA->getVar("PROFILE.GUESTBOOK.NOTIFICATION"))
                     $this->_send_mail($YANA->getVar("PROFILE.GUESTBOOK.MAIL"),$YANA->skin->getFile("benachrichtigung_mail"),$ARGS);
                     return true;
                 }
             break;

             /* Type: read, Permission: 0, Templates:  GUESTBOOK_READ */
             case $this->ACTION_SHOW:
                 if ($this->_securityCheck() === false) {
                     return false;
                 }
                 $ARGS['sort']  = "guestbook_date";
                 $ARGS['desc']  = true;
                 $profile_id    = $YANA->getVar("PROFILE.GUESTBOOK.PROFILE");
                 if (empty($profile_id)) $profile_id = ( (!empty($ARGS['id'])) ? $ARGS['id'] : 'default');
                 $ARGS['where'] = "profile_id=$profile_id";
                 $YANA->setVar('DATABASE', changeCaseArray($this->database->structure->getStructure(),CASE_UPPER));
                 $YANA->setVar('ROWS', $this->_get_table($ARGS, "guestbook"));
                 $YANA->setVar("BESCHREIBUNG", '%LANGUAGE.DESCR_SHOW%');
                 return true;
             break;


             /* Type: read, Permission: 0, Templates:  GUESTBOOK_READ_SEPERATED */
             case $this->ACTION_DETAILS:
                 if ($this->_securityCheck() === false) {
                     return false;
                 }
                 $ARGS['sort']  = "guestbook_date";
                 $ARGS['desc']  = true;
                 $profile_id    = $YANA->getVar("PROFILE.GUESTBOOK.PROFILE");
                 if (empty($profile_id)) $profile_id = ( (!empty($ARGS['id'])) ? $ARGS['id'] : 'default');
                 $ARGS['where'] = "profile_id=$profile_id";
                 $YANA->setVar('DATABASE', changeCaseArray($this->database->structure->getStructure(),CASE_UPPER));
                 $YANA->setVar('ROWS', $this->_get_table($ARGS, "guestbook"));
                 $YANA->setVar("BESCHREIBUNG", '%LANGUAGE.DESCR_DETAILS%');
             break;

             /* Type: default, Permission: 30, Templates: GUESTBOOK_DEFAULT_COMMENT  */
             case $this->ACTION_COMMENT:
                if (!is_numeric($ARGS['target'])) {
                    $YANA->message('alert', 'ungueltige_eingabe', $this->ACTION_SHOW);
                    return false;
                } else {
                    settype($ARGS['target'], 'int');
                    $guestbook_comment = $this->database->get('guestbook.'.$ARGS['target'].'.guestbook_comment');
                    if (!empty($guestbook_comment)) {
                         $YANA->setVar('GUESTBOOK_COMMENT', $guestbook_comment);
                    }
                    return true;
                }
             break;


             /* Type: write, Permission: 30, Templates: MESSAGE  */
             case $this->ACTION_COMMENT_WRITE:
                if (!is_numeric($ARGS['target']) || !is_string($ARGS['guestbook_comment'])) {
                    $YANA->message('alert', 'ungueltige_eingabe', $this->ACTION_COMMENT);
                    return false;
                } else if (!$this->database->insert('guestbook.'.$ARGS['target'].'.guestbook_comment', $ARGS['guestbook_comment']) ||
                    !$this->database->write()) {
                    $YANA->report(new log('Unable to insert comment.', $ARGS['guestbook_comment']));
                    return false;
                } else {
                    return true;
                }
             break;

/* END auto-generated Event-handlers */

             default:
                 $YANA->setVar('DATABASE', $this->database->structure->getStructure());
                 return true;
             break;

        } /* end switch */

        return true;
    }

/* BEGIN auto-generated functions */

    function _get_table($ARGS, $table) 
    {
        global $YANA;

        @settype($table,            "string");
        @settype($ARGS['where'],    "string");
        @settype($ARGS['sort'],     "string");
        @settype($ARGS['page'],     "integer");
        @settype($ARGS['entries'],  "integer");

        /* set up vars */
        $table       = strtolower($table);
        $primary_key = "";
        if (isset($ARGS['desc'])) {
            @settype($ARGS['desc'],   "boolean");
            $desc      = ($ARGS['desc']) ? true : false;
        } else {
            $desc      = true;
        }
        if ($ARGS['page']<0) {
            $page        = 0;
        } else { 
            $page        = (int) $ARGS['page'];
        }
        $entPerPage      = (int) $ARGS['entries'];
        if ($entPerPage<1) {
            $entPerPage  = (int) $YANA->getVar("PROFILE.GUESTBOOK.ENTPERPAGE");
        }
        if ($entPerPage<1) {
            $entPerPage  = 10;
        }
        $primary_key = $this->database->structure->getPrimaryKey($table);
        if (!empty($ARGS['sort'])) {
            $sortBy      = $ARGS['sort'];
        } else {
            $sortBy      = $primary_key;
        }

        $result          = $this->database->get($table, $ARGS['where'], "ORDER BY ".$sortBy.(($desc === true)? ' DESC' : ''), $page, $entPerPage);

        $YANA->setVar('TABLE',       $table);
        $YANA->setVar('PRIMARY_KEY', $primary_key);
        $last_page = $this->database->length($table, $ARGS['where']);
        $YANA->setVar('LAST_PAGE', $last_page);
        $YANA->setVar('SORT', $sortBy);
        $YANA->setVar('WHERE', $ARGS['where']);
        $liste = array();
        if ($last_page > ($entPerPage*2)) {
            $dots = false;
            for($k=0;$k<ceil($last_page/$entPerPage);$k++) 
            {
                $it   = count($liste);
                $first = ($k*$entPerPage);
                $last  = ((($k+1)*$entPerPage < $last_page) ? ($k+1)*$entPerPage : $last_page);
                if ($last_page > 10 * $entPerPage && $k > 1 && $k < ceil($last_page/$entPerPage) - 2 && !($first > $page-$entPerPage-1 && $last < $page+1+(2*$entPerPage))) {
                    if (!$dots) {
                        $dots = true;
                        $liste[$it]['TOO_MANY'] = true;
                    }
                } else {
                    $liste[$it]['FIRST'] = ($first+1);
                    $liste[$it]['LAST']  = $last;
                    if ($first > $page-1 && $last < $page+$entPerPage+1) {
                        $dots = false;
                    }    
                }
            }
        }
        $YANA->setVar('LIST_OF_ENTRIES', $liste);
        $YANA->setVar('ENTRIES_PER_PAGE', $entPerPage);
        $YANA->setVar('DESC', $desc);
        $YANA->setVar('FIRST_PAGE', $page+1);
        $YANA->setVar('OFFSET_PAGE', (($page+$entPerPage>$last_page) ? $last_page : $page+$entPerPage));
        return $result;
    }

/* END auto-generated functions */

     function _securityCheck()
     {
        global $YANA;
        $id = strtolower($YANA->getVar('ID'));
        /* do not show new guestbooks, if Auto-Option is deactivated */
        $dir  = $YANA->registry->get('PROFILEDIR');
        $file = new inputStream($dir->getFilename().$id.'.cfg');
        if ($id !== 'default' && !$file->exists() && !$YANA->getVar("PROFILE.AUTO")) {
            $YANA->report(new log('Access restriction in effect. Access to undefined profile '.$id.' denied.'));
            $YANA->report(new error('4041'));
            return false;
        }
    }

    function _send_mail($empfaenger,$template,$INPUT)
    {
        assert('is_array($INPUT);');
        global $YANA;
        $INPUT = changeCaseArray($INPUT,CASE_UPPER);
        $heute         = getdate();
        $mail          = new mailer($template);
        $mail->subject = $YANA->getVar("LANGUAGE.MAIL_SUBJECT");
        $mail->insert("*", $INPUT);
        $mail->insert("*", $YANA->getVar("*"));
        $mail->insert('DATUM', $heute['mday'] . '.' . $heute['mon'] . '.' . $heute['year']);
        $mail->send($empfaenger);
     }

     function _untaintInput(&$input)
     {
        if (is_array($input)) {
            foreach ($input as $a => $b)
            {
                $input[$a] = untaintInput($b, "string", 0, YANA_ESCAPE_USERTEXT);
            }
        }
     }

}

// © 2006, Thomas Meyer www.All-Community.de
// Copyright Hinweis nicht entfernen!
?>