Skip to content
Snippets Groups Projects
class.topic.php 10 KiB
Newer Older
Jared Hancock's avatar
Jared Hancock committed
<?php
/*********************************************************************
    class.topic.php

    Help topic helper

    Peter Rotich <peter@osticket.com>
    Copyright (c)  2006-2013 osTicket
Jared Hancock's avatar
Jared Hancock committed
    http://www.osticket.com

    Released under the GNU General Public License WITHOUT ANY WARRANTY.
    See LICENSE.TXT for details.

    vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/

class Topic {
    var $id;
Jared Hancock's avatar
Jared Hancock committed
    var $ht;
    var $parent;
    var $form;
    function Topic($id) {
Jared Hancock's avatar
Jared Hancock committed
        $this->id=0;
        $this->load($id);
    }

    function load($id=0) {
Jared Hancock's avatar
Jared Hancock committed

        if(!$id && !($id=$this->getId()))
            return false;

        $sql='SELECT ht.* '
            .' FROM '.TOPIC_TABLE.' ht '
            .' WHERE ht.topic_id='.db_input($id);

Jared Hancock's avatar
Jared Hancock committed
        if(!($res=db_query($sql)) || !db_num_rows($res))
            return false;

        $this->ht = db_fetch_array($res);
        $this->id = $this->ht['topic_id'];

        $this->page = $this->form = null;
        // Handle upgrade case where sort has not yet been defined
        if (!$this->ht['sort'] && $cfg->getTopicSortMode() == 'a') {
            static::updateSortOrder();
        }
Jared Hancock's avatar
Jared Hancock committed
        return true;
    }
Jared Hancock's avatar
Jared Hancock committed
    function reload() {
        return $this->load();
    }

    function asVar() {
        return $this->getName();
    }
    function getId() {
Jared Hancock's avatar
Jared Hancock committed
        return $this->id;
    }

    function getPid() {
        return $this->ht['topic_pid'];
    }

    function getParent() {
        if(!$this->parent && $this->getPid())
            $this->parent = self::lookup($this->getPid());

        return $this->parent;
    }

    function getName() {
        return $this->ht['topic'];
    function getFullName() {
        return self::getTopicName($this->getId());
    }

    static function getTopicName($id) {
        $names = static::getHelpTopics(false, true);
    function getDeptId() {
Jared Hancock's avatar
Jared Hancock committed
        return $this->ht['dept_id'];
    }

    function getSLAId() {
Jared Hancock's avatar
Jared Hancock committed
        return $this->ht['sla_id'];
    }

    function getPriorityId() {
Jared Hancock's avatar
Jared Hancock committed
        return $this->ht['priority_id'];
    }

    function getStaffId() {
Jared Hancock's avatar
Jared Hancock committed
        return $this->ht['staff_id'];
    }

    function getTeamId() {
Jared Hancock's avatar
Jared Hancock committed
        return $this->ht['team_id'];
    }

    function getPageId() {
        return $this->ht['page_id'];
    }

    function getPage() {
        if(!$this->page && $this->getPageId())
            $this->page = Page::lookup($this->getPageId());

        return $this->page;
    }

    function getFormId() {
        return $this->ht['form_id'];
    }

    function getForm() {
        if(!$this->form && $this->getFormId())
            $this->form = DynamicForm::lookup($this->getFormId());

        return $this->form;
    }

Jared Hancock's avatar
Jared Hancock committed
    function autoRespond() {
        return (!$this->ht['noautoresp']);
    }

    function isEnabled() {
         return ($this->ht['isactive']);
    }

    function isActive() {
Jared Hancock's avatar
Jared Hancock committed
        return $this->isEnabled();
    }

    function isPublic() {
Jared Hancock's avatar
Jared Hancock committed
        return ($this->ht['ispublic']);
    }

    function getHashtable() {
        return $this->ht;
    }

    function getInfo() {
        return $this->getHashtable();
    }

    function setSortOrder($i) {
        if ($i != $this->ht['sort']) {
            $sql = 'UPDATE '.TOPIC_TABLE.' SET `sort`='.db_input($i)
                .' WHERE `topic_id`='.db_input($this->getId());
            return (db_query($sql) && db_affected_rows() == 1);
        }
        // Noop
        return true;
    }

    function update($vars, &$errors) {
        if(!$this->save($this->getId(), $vars, $errors))
            return false;

        $this->reload();
        return true;
    function delete() {

Jared Hancock's avatar
Jared Hancock committed
        $sql='DELETE FROM '.TOPIC_TABLE.' WHERE topic_id='.db_input($this->getId()).' LIMIT 1';
        if(db_query($sql) && ($num=db_affected_rows())) {
            db_query('UPDATE '.TOPIC_TABLE.' SET topic_pid=0 WHERE topic_pid='.db_input($this->getId()));
Jared Hancock's avatar
Jared Hancock committed
            db_query('UPDATE '.TICKET_TABLE.' SET topic_id=0 WHERE topic_id='.db_input($this->getId()));
            db_query('DELETE FROM '.FAQ_TOPIC_TABLE.' WHERE topic_id='.db_input($this->getId()));
        }

        return $num;
    }
    /*** Static functions ***/
    function create($vars, &$errors) {
        return self::save(0, $vars, $errors);
    static function getHelpTopics($publicOnly=false, $disabled=false) {
        static $topics, $names;

        if (!$names) {
            $sql = 'SELECT topic_id, topic_pid, ispublic, isactive, topic FROM '.TOPIC_TABLE
            $res = db_query($sql);

            // Fetch information for all topics, in declared sort order
            $topics = array();
            while (list($id, $pid, $pub, $act, $topic) = db_fetch_row($res))
                $topics[$id] = array('pid'=>$pid, 'public'=>$pub,
                    'disabled'=>!$act, 'topic'=>$topic);

            // Resolve parent names
            foreach ($topics as $id=>$info) {
                $name = $info['topic'];
                $loop = array($id=>true);
                while ($info['pid'] && ($info = $topics[$info['pid']])) {
                    $name = sprintf('%s / %s', $info['topic'], $name);
                    if (isset($loop[$info['pid']]))
                        break;
                    $loop[$info['pid']] = true;
                }
                $names[$id] = $name;
            }
        }
        if ($disabled && !$publicOnly)
            return $names;
        // Apply requested filters
        $requested_names = array();
        foreach ($names as $id=>$n) {
            $info = $topics[$id];
            if ($publicOnly && !$info['public'])
                continue;
            if (!$disabled && $info['disabled'])
                continue;
            $requested_names[$id] = $n;
        return $requested_names;
    function getPublicHelpTopics() {
        return self::getHelpTopics(true);
    }

    function getIdByName($name, $pid=0) {

        $sql='SELECT topic_id FROM '.TOPIC_TABLE
            .' WHERE topic='.db_input($name)
            .' AND topic_pid='.db_input($pid);
Jared Hancock's avatar
Jared Hancock committed
        if(($res=db_query($sql)) && db_num_rows($res))
            list($id) = db_fetch_row($res);
    static function lookup($id) {
Jared Hancock's avatar
Jared Hancock committed
        return ($id && is_numeric($id) && ($t= new Topic($id)) && $t->getId()==$id)?$t:null;
    }

    function save($id, $vars, &$errors) {
Jared Hancock's avatar
Jared Hancock committed

        $vars['topic']=Format::striptags(trim($vars['topic']));

        if($id && $id!=$vars['id'])
            $errors['err']='Internal error. Try again';

        if(!$vars['topic'])
            $errors['topic']='Help topic required';
        elseif(strlen($vars['topic'])<5)
            $errors['topic']='Topic is too short. 5 chars minimum';
        elseif(($tid=self::getIdByName($vars['topic'], $vars['pid'])) && $tid!=$id)
Jared Hancock's avatar
Jared Hancock committed
            $errors['topic']='Topic already exists';

        if (!is_numeric($vars['dept_id']))
Jared Hancock's avatar
Jared Hancock committed
            $errors['dept_id']='You must select a department';
Jared Hancock's avatar
Jared Hancock committed
        if($errors) return false;
        foreach (array('sla_id','form_id','page_id','pid') as $f)
            if (!isset($vars[$f]))
                $vars[$f] = 0;
        $sql=' updated=NOW() '
            .',topic='.db_input($vars['topic'])
            .',topic_pid='.db_input($vars['pid'])
            .',dept_id='.db_input($vars['dept_id'])
            .',priority_id='.db_input($vars['priority_id'])
            .',sla_id='.db_input($vars['sla_id'])
            .',form_id='.db_input($vars['form_id'])
            .',page_id='.db_input($vars['page_id'])
            .',isactive='.db_input($vars['isactive'])
            .',ispublic='.db_input($vars['ispublic'])
            .',noautoresp='.db_input(isset($vars['noautoresp']) && $vars['noautoresp']?1:0)
            .',notes='.db_input(Format::sanitize($vars['notes']));
Jared Hancock's avatar
Jared Hancock committed

        //Auto assign ID is overloaded...
        if($vars['assign'] && $vars['assign'][0]=='s')
             $sql.=',team_id=0, staff_id='.db_input(preg_replace("/[^0-9]/", "", $vars['assign']));
Jared Hancock's avatar
Jared Hancock committed
        elseif($vars['assign'] && $vars['assign'][0]=='t')
            $sql.=',staff_id=0, team_id='.db_input(preg_replace("/[^0-9]/", "", $vars['assign']));
Jared Hancock's avatar
Jared Hancock committed
        else
            $sql.=',staff_id=0, team_id=0 '; //no auto-assignment!
Jared Hancock's avatar
Jared Hancock committed
            $sql='UPDATE '.TOPIC_TABLE.' SET '.$sql.' WHERE topic_id='.db_input($id);
            if (!($rv = db_query($sql)))
                $errors['err']='Unable to update topic. Internal error occurred';
        } else {
            if (isset($vars['topic_id']))
                $sql .= ', topic_id='.db_input($vars['topic_id']);
            if ($vars['pid'] && $cfg->getTopicSortMode() != 'a') {
                $sql .= ', `sort`='.db_input(
                    db_result(db_query('SELECT COALESCE(`sort`,0)+1 FROM '.TOPIC_TABLE
                        .' WHERE `topic_id`='.db_input($vars['pid']))));
            }
            $sql='INSERT INTO '.TOPIC_TABLE.' SET '.$sql.',created=NOW()';
            if (db_query($sql) && ($id = db_insert_id()))
                $rv = $id;
            else
                $errors['err']='Unable to create the topic. Internal error';
        }
        if ($cfg->getTopicSortMode() == 'a') {
            static::updateSortOrder();
    static function updateSortOrder() {
        // Fetch (un)sorted names
        $names = static::getHelpTopics(false, true);
        uasort($names, function($a, $b) { return strcmp($a, $b); });

        $update = array_keys($names);
        foreach ($update as $idx=>&$id) {
            $id = sprintf("(%s,%s)", db_input($id), db_input($idx+1));
        }
        // Thanks, http://stackoverflow.com/a/3466
        $sql = sprintf('INSERT INTO `%s` (topic_id,`sort`) VALUES %s
            ON DUPLICATE KEY UPDATE `sort`=VALUES(`sort`)',
            TOPIC_TABLE, implode(',', $update));
        db_query($sql);

// Add fields from the standard ticket form to the ticket filterable fields
Filter::addSupportedMatches('Help Topic', array('topicId' => 'Topic ID'), 100);