1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 
<?php
    declare(strict_types=1);
    /**
     *  +------------------------------------------------------------+
     *  | apnscp                                                     |
     *  +------------------------------------------------------------+
     *  | Copyright (c) Apis Networks                                |
     *  +------------------------------------------------------------+
     *  | Licensed under Artistic License 2.0                        |
     *  +------------------------------------------------------------+
     *  | Author: Matt Saladna (msaladna@apisnetworks.com)           |
     *  +------------------------------------------------------------+
     */

    /**
     * Client feedback module from a bygone era
     *
     * @package core
     */
    class Quote_Module extends Module_Skeleton
    {

        private static $CRM_SERVER_HOST = CRM_TICKET_HOST;
        private static $CRM_SERVER_USER = CRM_TICKET_USER;

        // @ignore
        private static $CRM_SERVER_PASSWORD = CRM_TICKET_PASSWORD;
        // @ignore
        private static $CRM_SERVER_DATABASE = CRM_TICKET_DB;
        // @ignore
        public $exportedFunctions = array('*' => PRIVILEGE_SITE);
        // @ignore
        private $_db;
        private $_metaCache = array();

        /**
         * void __construct(void)
         *
         * @ignore
         */
        public function __construct()
        {
            parent::__construct();
        }

        public function __destruct()
        {
            $this->_db = null;
        }

        public function update($quote, $rating = 5, $name = null, $site = null)
        {
            if ($rating < 1 || $rating > 5) {
                return error("invalid rating `$rating'");
            }
            if (!$this->has_quote()) {
                return $this->add($quote, $rating, $name, $site);
            }
            $invoice = $this->billing_get_invoice();
            if (!$invoice) {
                return false;
            }
            $quote = trim($quote);
            if (!$quote) {
                return error('missing quote data');
            }
            $def = array(
                'site'    => $site,
                'name'    => $name,
                'quote'   => Util_HTML_BBCode::clean2HTML($quote),
                'rating'  => $rating,
                'invoice' => $invoice,
            );

            $db = $this->_connect();
            $stmt = $db->prepare('UPDATE quotes
                SET quote = CONCAT(quote,"\r\n\r\nUpdate ", DATE_FORMAT(NOW(), "%M %d, %Y"), ":\r\n", :quote), 
                    name = :name, site = :site, rating = :rating
                WHERE invoice = :invoice');

            return $stmt->execute($def);

        }

        public function has_quote()
        {
            return (bool)$this->get();
        }

        public function get()
        {
            $invoice = $this->billing_get_invoice();
            if (!$invoice) {
                return false;
            }
            $db = $this->_connect();
            $q = "SELECT quote, name, id, rating, site, UNIX_TIMESTAMP(since)
                FROM quotes WHERE invoice = '" . $invoice . "'";
            $rs = $db->query($q);
            if ($rs->rowCount() < 1) {
                return array();
            }

            return $rs->fetch(PDO::FETCH_ASSOC);
        }

        private function _connect()
        {
            if ($this->_db instanceof PDO) {
                return $this->_db;
            }
            Error_Reporter::suppress_php_error('PDO::.*');
            $db = self::$CRM_SERVER_DATABASE;
            $host = self::$CRM_SERVER_HOST;
            $user = self::$CRM_SERVER_USER;
            $password = self::$CRM_SERVER_PASSWORD;
            $dsn = 'mysql:dbname=' . $db . ';host=' . $host;
            try {
                $this->_db = new PDO($dsn, $user, $password);
            } catch (PDOException $e) {
                Error_Reporter::report('unable to connect to quote db - falling back' . $e->getMessage());
                $this->_db = null;

                return error('unable to connect to ticket database - use help@apisnetworks.com');
            }

            return $this->_db;

        }

        /**
         * Add client feedback
         *
         * @param string $quote
         * @param array  $meta
         */
        public function add($quote, $rating = 5, $name = null, $site = null)
        {
            if ($this->auth_is_demo()) {
                return error('cannot add testimonial for demo account');
            }
            if ($rating < 1 || $rating > 5) {
                return error("invalid rating `$rating'");
            }
            $invoice = $this->billing_get_invoice();
            if (!$invoice) {
                return false;
            }
            $quote = trim($quote);
            if (!$quote) {
                return error('missing quote data');
            }
            $def = array(
                'site'    => $site,
                'name'    => $name,
                'since'   => null,
                'quote'   => $quote,
                'invoice' => $invoice,
                'rating'  => $rating
            );
            $def['since'] = $this->billing_get_customer_since();
            $db = $this->_connect();
            $def['quote'] = Util_HTML_BBCode::clean2HTML($def['quote']);
            $stmt = $db->prepare('INSERT INTO quotes
                (id, quote, since, name, rating, site, invoice)
                VALUES
                (null,
                :quote,
                FROM_UNIXTIME(:since),
                :name,
                :rating,
                :site,
                :invoice)');
            Mail::send('matt+feedback@apisnetworks.com', 'Client Testimonial - ' . $site, var_export($def, true));

            return $stmt->execute($def);

        }

        public function get_random()
        {
            $db = $this->_connect();
            $q = 'SELECT id, name, site,
                UNIX_TIMESTAMP(since) AS since, quote ' .
                'FROM quotes ORDER BY RAND() LIMIT 1';
            $rs = $db->query($q);
            if ($rs->rowCount() < 1) {
                return array();
            }

            return $rs->fetch(PDO::FETCH_ASSOC);
        }

        public function get_all()
        {
            $db = $this->_connect();
            if (!$db) {
                return false;
            }
            $quotes = array();
            $q = 'SELECT quote, name, id, rating, site, UNIX_TIMESTAMP(since)
                FROM quotes';
            $rs = $db->query($q);
            if ($rs->rowCount() < 1) {
                return array();
            }
            while (false !== ($r = $rs->fetchObject())) {
                $quotes[] = array(
                    'quote'  => $r->quote,
                    'name'   => $r->name,
                    'id'     => $r->id,
                    'rating' => $r->rating,
                    'site'   => $r->site
                );
            }

            return $quotes;
        }


    }