Skip to content
Snippets Groups Projects
Commit d71f1dff authored by Jared Hancock's avatar Jared Hancock
Browse files

orm: Convert Topic and FaqTopic to be ORM based

parent 512e643d
No related branches found
No related tags found
No related merge requests found
......@@ -63,27 +63,22 @@ class FAQ extends VerySimpleModel {
function getCategory() { return $this->category; }
function getHelpTopicsIds() {
if ($topics=$this->getHelpTopics()) {
return array_keys($topics);
}
return array();
$ids = array();
foreach ($this->getHelpTopics() as $topic)
$ids[] = $topic->getId();
return $ids;
}
function getHelpTopics() {
//XXX: change it to obj (when needed)!
if (!isset($this->topics)) {
$this->topics = array();
$sql='SELECT t.topic_id, CONCAT_WS(" / ", pt.topic, t.topic) as name FROM '.TOPIC_TABLE.' t '
.' INNER JOIN '.FAQ_TOPIC_TABLE.' ft ON(ft.topic_id=t.topic_id AND ft.faq_id='.db_input($this->getId()).') '
.' LEFT JOIN '.TOPIC_TABLE.' pt ON(pt.topic_id=t.topic_pid) '
.' ORDER BY t.topic';
if (($res=db_query($sql)) && db_num_rows($res)) {
while(list($id,$name) = db_fetch_row($res))
$this->topics[$id]=$name;
}
$this->topics = Topic::objects()->filter(array(
'topic_id__in' => FaqTopic::objects()->filter(array(
'faq_id' => $this->getId(),
))->values('topic_id'),
));
}
return $this->topics;
}
......@@ -384,4 +379,24 @@ class FAQ extends VerySimpleModel {
}
}
FAQ::_inspect();
class FaqTopic extends VerySimpleModel {
static $meta = array(
'table' => FAQ_TOPIC_TABLE,
'pk' => array('faq_id', 'topic_id'),
'joins' => array(
'faq' => array(
'constraint' => array(
'faq_id' => 'FAQ.faq_id',
),
),
'topic' => array(
'constraint' => array(
'topic_id' => 'Topic.topic_id',
),
),
),
);
}
?>
......@@ -55,7 +55,7 @@ class Internationalization {
'list.yaml' => 'DynamicList::create',
// Note that department, sla, and forms are required for
// help_topic
'help_topic.yaml' => 'Topic::create',
'help_topic.yaml' => 'Topic::__create',
'filter.yaml' => 'Filter::create',
'team.yaml' => 'Team::create',
// Organization
......
......@@ -132,6 +132,7 @@ class VerySimpleModel {
}
function __onload() {}
static function __oninspect() {}
static function _inspect() {
if (!static::$meta['table'])
......@@ -163,6 +164,9 @@ class VerySimpleModel {
$j['fkey'] = explode('.', $foreign);
$j['local'] = $keys[0];
}
// Let the model participate
static::__oninspect();
}
static function objects() {
......
......@@ -16,12 +16,22 @@
require_once INCLUDE_DIR . 'class.sequence.php';
class Topic {
var $id;
class Topic extends VerySimpleModel {
static $meta = array(
'table' => TOPIC_TABLE,
'pk' => array('topic_id'),
'ordering' => array('topic'),
'joins' => array(
'parent' => array(
'list' => false,
'constraint' => array(
'topic_pid' => 'Topic.topic_id',
),
),
),
);
var $ht;
var $parent;
var $page;
var $form;
......@@ -31,39 +41,13 @@ class Topic {
const FLAG_CUSTOM_NUMBERS = 0x0001;
function Topic($id) {
$this->id=0;
$this->load($id);
}
function load($id=0) {
static function __oninspect() {
global $cfg;
if(!$id && !($id=$this->getId()))
return false;
$sql='SELECT ht.* '
.' FROM '.TOPIC_TABLE.' ht '
.' WHERE ht.topic_id='.db_input($id);
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();
}
return true;
}
function reload() {
return $this->load();
}
function asVar() {
......@@ -71,22 +55,23 @@ class Topic {
}
function getId() {
return $this->id;
return $this->topic_id;
}
function getPid() {
return $this->ht['topic_pid'];
return $this->topic_pid;
}
function getParent() {
if(!$this->parent && $this->getPid())
$this->parent = self::lookup($this->getPid());
return $this->parent;
}
function getName() {
return $this->ht['topic'];
return $this->topic;
}
function getLocalName() {
return $this->getLocal('name');
}
function getFullName() {
......@@ -99,31 +84,31 @@ class Topic {
}
function getDeptId() {
return $this->ht['dept_id'];
return $this->dept_id;
}
function getSLAId() {
return $this->ht['sla_id'];
return $this->sla_id;
}
function getPriorityId() {
return $this->ht['priority_id'];
return $this->priority_id;
}
function getStatusId() {
return $this->ht['status_id'];
return $this->status_id;
}
function getStaffId() {
return $this->ht['staff_id'];
return $this->staff_id;
}
function getTeamId() {
return $this->ht['team_id'];
return $this->team_id;
}
function getPageId() {
return $this->ht['page_id'];
return $this->page_id;
}
function getPage() {
......@@ -134,7 +119,7 @@ class Topic {
}
function getFormId() {
return $this->ht['form_id'];
return $this->form_id;
}
function getForm() {
......@@ -149,7 +134,7 @@ class Topic {
}
function autoRespond() {
return (!$this->ht['noautoresp']);
return !$this->noautoresp;
}
function isEnabled() {
......@@ -170,7 +155,7 @@ class Topic {
* there is a loop in the ancestry
*/
function isActive(array $chain=array()) {
if (!$this->ht['isactive'])
if (!$this->isactive)
return false;
if (!isset($chain[$this->getId()]) && ($p = $this->getParent())) {
......@@ -178,12 +163,12 @@ class Topic {
return $p->isActive($chain);
}
else {
return $this->ht['isactive'];
return $this->isactive;
}
}
function isPublic() {
return ($this->ht['ispublic']);
return ($this->ispublic);
}
function getHashtable() {
......@@ -197,7 +182,7 @@ class Topic {
}
function hasFlag($flag) {
return $this->ht['flags'] & $flag != 0;
return $this->flags & $flag != 0;
}
function getNewTicketNumber() {
......@@ -206,17 +191,17 @@ class Topic {
if (!$this->hasFlag(self::FLAG_CUSTOM_NUMBERS))
return $cfg->getNewTicketNumber();
if ($this->ht['sequence_id'])
$sequence = Sequence::lookup($this->ht['sequence_id']);
if ($this->sequence_id)
$sequence = Sequence::lookup($this->sequence_id);
if (!$sequence)
$sequence = new RandomSequence();
return $sequence->next($this->ht['number_format'] ?: '######',
return $sequence->next($this->number_format ?: '######',
array('Ticket', 'isTicketNumberUnique'));
}
function getTranslateTag($subtag) {
return _H(sprintf('topic.%s.%s', $subtag, $this->id));
return _H(sprintf('topic.%s.%s', $subtag, $this->getId()));
}
function getLocal($subtag) {
$tag = $this->getTranslateTag($subtag);
......@@ -225,42 +210,47 @@ class Topic {
}
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);
if ($i != $this->sort) {
$this->sort = $i;
return $this->save();
}
// Noop
return true;
}
function update($vars, &$errors) {
if(!$this->save($this->getId(), $vars, $errors))
return false;
$this->reload();
return true;
}
function delete() {
global $cfg;
if ($this->getId() == $cfg->getDefaultTopicId())
return false;
$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()));
if (parent::delete()) {
self::objects()->filter(array(
'topic_pid' => $this->getId()
))->update(array(
'topic_pid' => 0
));
FaqTopic::objects()->filter(array(
'topic_id' => $this->getId()
))->delete();
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;
return true;
}
/*** Static functions ***/
function create($vars, &$errors) {
return self::save(0, $vars, $errors);
static function create($vars=array()) {
$topic = parent::create($vars);
$topic->created = SqlFunction::NOW();
return $topic;
}
static function __create($vars, &$errors) {
$topic = self::create();
$topic->save($vars, $errors);
return $topic;
}
static function getHelpTopics($publicOnly=false, $disabled=false, $localize=true) {
......@@ -269,15 +259,18 @@ class Topic {
// If localization is specifically requested, then rebuild the list.
if (!$names || $localize) {
$sql = 'SELECT topic_id, topic_pid, ispublic, isactive, topic FROM '.TOPIC_TABLE
. ' ORDER BY `sort`';
$res = db_query($sql);
$objects = self::objects()->values_flat(
'topic_id', 'topic_pid', 'ispublic', 'isactive', 'topic'
)
->order_by('sort');
// Fetch information for all topics, in declared sort order
$topics = array();
while (list($id, $pid, $pub, $act, $topic) = db_fetch_row($res))
foreach ($objects as $T) {
list($id, $pid, $pub, $act, $topic) = $T;
$topics[$id] = array('pid'=>$pid, 'public'=>$pub,
'disabled'=>!$act, 'topic'=>$topic);
}
$localize_this = function($id, $default) use ($localize) {
if (!$localize)
......@@ -329,42 +322,38 @@ class Topic {
return $requested_names;
}
function getPublicHelpTopics() {
static function getPublicHelpTopics() {
return self::getHelpTopics(true);
}
function getAllHelpTopics($localize=false) {
static function getAllHelpTopics($localize=false) {
return self::getHelpTopics(false, true, $localize);
}
function getIdByName($name, $pid=0) {
$sql='SELECT topic_id FROM '.TOPIC_TABLE
.' WHERE topic='.db_input($name)
.' AND topic_pid='.db_input($pid);
if(($res=db_query($sql)) && db_num_rows($res))
list($id) = db_fetch_row($res);
static function getIdByName($name, $pid=0) {
$list = self::objects()->filter(array(
'topic'=>$name,
'topic_pid'=>$pid,
))->values_flat('topic_id')->one();
return $id;
if ($list)
return $list[0];
}
static function lookup($id) {
return ($id && is_numeric($id) && ($t= new Topic($id)) && $t->getId()==$id)?$t:null;
}
function save($id, $vars, &$errors) {
function update($vars, &$errors) {
global $cfg;
$vars['topic']=Format::striptags(trim($vars['topic']));
$vars['topic'] = Format::striptags(trim($vars['topic']));
if($id && $id!=$vars['id'])
if (isset($this->topic_id) && $this->getId() != $vars['id'])
$errors['err']=__('Internal error occurred');
if(!$vars['topic'])
if (!$vars['topic'])
$errors['topic']=__('Help topic name is required');
elseif(strlen($vars['topic'])<5)
elseif (strlen($vars['topic'])<5)
$errors['topic']=__('Topic is too short. Five characters minimum');
elseif(($tid=self::getIdByName($vars['topic'], $vars['topic_pid'])) && $tid!=$id)
elseif (($tid=self::getIdByName($vars['topic'], $vars['topic_pid']))
&& $tid!=$this->getId())
$errors['topic']=__('Topic already exists');
if (!is_numeric($vars['dept_id']))
......@@ -374,60 +363,53 @@ class Topic {
$errors['number_format'] =
'Ticket number format requires at least one hash character (#)';
if($errors) return false;
foreach (array('sla_id','form_id','page_id','topic_pid') as $f)
if (!isset($vars[$f]))
$vars[$f] = 0;
$sql=' updated=NOW() '
.',topic='.db_input($vars['topic'])
.',topic_pid='.db_input($vars['topic_pid'])
.',dept_id='.db_input($vars['dept_id'])
.',priority_id='.db_input($vars['priority_id'])
.',status_id='.db_input($vars['status_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'])
.',sequence_id='.db_input($vars['custom-numbers'] ? $vars['sequence_id'] : 0)
.',number_format='.db_input($vars['custom-numbers'] ? $vars['number_format'] : '')
.',flags='.db_input($vars['custom-numbers'] ? self::FLAG_CUSTOM_NUMBERS : 0)
.',noautoresp='.db_input(isset($vars['noautoresp']) && $vars['noautoresp']?1:0)
.',notes='.db_input(Format::sanitize($vars['notes']));
if ($errors)
return false;
$this->topic = $vars['topic'];
$this->topic_pid = $vars['topic_pid'] ?: 0;
$this->dept_id = $vars['dept_id'];
$this->priority_id = $vars['priority_id'] ?: 0;
$this->status_id = $vars['status_id'] ?: 0;
$this->sla_id = $vars['sla_id'] ?: 0;
$this->form_id = $vars['form_id'] ?: 0;
$this->page_id = $vars['page_id'] ?: 0;
$this->isactive = !!$vars['isactive'];
$this->ispublic = !!$vars['ispublic'];
$this->sequence_id = $vars['custom-numbers'] ? $vars['sequence_id'] : 0;
$this->number_format = $vars['custom-numbers'] ? $vars['number_format'] : '';
$this->flags = $vars['custom-numbers'] ? self::FLAG_CUSTOM_NUMBERS : 0;
$this->noautoresp = !!$vars['noautoresp'];
$this->notes = Format::sanitize($vars['notes']);
//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']));
elseif($vars['assign'] && $vars['assign'][0]=='t')
$sql.=',staff_id=0, team_id='.db_input(preg_replace("/[^0-9]/", "", $vars['assign']));
else
$sql.=',staff_id=0, team_id=0 '; //no auto-assignment!
if ($vars['assign'] && $vars['assign'][0] == 's') {
$this->team_id = 0;
$this->staff_id = preg_replace("/[^0-9]/", "", $vars['assign']);
}
elseif ($vars['assign'] && $vars['assign'][0] == 't') {
$this->staff_id = 0;
$this->team_id = preg_replace("/[^0-9]/", "", $vars['assign']);
}
else {
$this->staff_id = 0;
$this->team_id = 0;
}
$rv = false;
if ($id) {
$sql='UPDATE '.TOPIC_TABLE.' SET '.$sql.' WHERE topic_id='.db_input($id);
if (!($rv = db_query($sql)))
$errors['err']=sprintf(__('Unable to update %s.'), __('this help topic'))
.' '.__('Internal error occurred');
} else {
if (isset($vars['topic_id']))
$sql .= ', topic_id='.db_input($vars['topic_id']);
// If in manual sort mode, place the new item directly below the
// parent item
if ($vars['topic_pid'] && $cfg && $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['topic_pid']))));
if ($this->__new__) {
if (isset($this->topic_pid)
&& ($parent = Topic::lookup($this->topic_pid))) {
$this->sort = ($parent->sort ?: 0) + 1;
}
$sql='INSERT INTO '.TOPIC_TABLE.' SET '.$sql.',created=NOW()';
if (db_query($sql) && ($id = db_insert_id()))
$rv = $id;
else
if (!($rv = $this->save())) {
$errors['err']=sprintf(__('Unable to create %s.'), __('this help topic'))
.' '.__('Internal error occurred');
}
}
elseif (!($rv = $this->save())) {
$errors['err']=sprintf(__('Unable to update %s.'), __('this help topic'))
.' '.__('Internal error occurred');
}
if (!$cfg || $cfg->getTopicSortMode() == 'a') {
static::updateSortOrder();
......@@ -435,6 +417,12 @@ class Topic {
return $rv;
}
function save($refetch=false) {
if ($this->dirty)
$this->updated = SqlFunction::NOW();
return parent::save($refetch || $this->dirty);
}
static function updateSortOrder() {
global $cfg;
......
......@@ -35,7 +35,8 @@ if($_POST){
}
break;
case 'create':
if(($id=Topic::create($_POST,$errors))){
$topic = Topic::create();
if ($topic->update($_POST, $errors)) {
$msg=sprintf(__('Successfully added %s'), Format::htmlchars($_POST['topic']));
$_REQUEST['a']=null;
}elseif(!$errors['err']){
......@@ -58,10 +59,13 @@ if($_POST){
switch(strtolower($_POST['a'])) {
case 'enable':
$sql='UPDATE '.TOPIC_TABLE.' SET isactive=1 '
.' WHERE topic_id IN ('.implode(',', db_input($_POST['ids'])).')';
$num = Topic::objects()->filter(array(
'topic_id__in' => $_POST['ids'],
))->update(array(
'isactive' => true,
));
if(db_query($sql) && ($num=db_affected_rows())) {
if ($num > 0) {
if($num==$count)
$msg = sprintf(__('Successfully enabled %s'),
_N('selected help topic', 'selected help topics', $count));
......@@ -74,10 +78,14 @@ if($_POST){
}
break;
case 'disable':
$sql='UPDATE '.TOPIC_TABLE.' SET isactive=0 '
.' WHERE topic_id IN ('.implode(',', db_input($_POST['ids'])).')'
.' AND topic_id <> '.db_input($cfg->getDefaultTopicId());
if(db_query($sql) && ($num=db_affected_rows())) {
$num = Topic::objects()->filter(array(
'topic_id__in'=>$_POST['ids'],
))->exclude(array(
'topic_id'=>$cfg->getDefaultTopicId(),
))->update(array(
'isactive' => false,
));
if ($num > 0) {
if($num==$count)
$msg = sprintf(__('Successfully diabled %s'),
_N('selected help topic', 'selected help topics', $count));
......@@ -90,11 +98,9 @@ if($_POST){
}
break;
case 'delete':
$i=0;
foreach($_POST['ids'] as $k=>$v) {
if(($t=Topic::lookup($v)) && $t->delete())
$i++;
}
$i = Topic::objects()->filter(array(
'topic_id__in'=>$_POST['ids']
))->delete();
if($i && $i==$count)
$msg = sprintf(__('Successfully deleted %s'),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment