You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
369 lines
11 KiB
369 lines
11 KiB
<?php
|
|
/*********************************************************************
|
|
class.page.php
|
|
|
|
Page class
|
|
|
|
Copyright (c) 2006-2013 osTicket
|
|
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 Page extends VerySimpleModel {
|
|
|
|
static $meta = array(
|
|
'table' => PAGE_TABLE,
|
|
'pk' => array('id'),
|
|
'ordering' => array('name'),
|
|
'defer' => array('body'),
|
|
'joins' => array(
|
|
'topics' => array(
|
|
'reverse' => 'Topic.page',
|
|
),
|
|
'attachments' => array(
|
|
'constraint' => array(
|
|
"'P'" => 'Attachment.type',
|
|
'id' => 'Attachment.object_id',
|
|
),
|
|
'list' => true,
|
|
'null' => true,
|
|
'broker' => 'GenericAttachments',
|
|
),
|
|
),
|
|
);
|
|
|
|
var $_local;
|
|
|
|
function getId() {
|
|
return $this->id;
|
|
}
|
|
|
|
function getHashtable() {
|
|
$base = $this->ht;
|
|
unset($base['topics']);
|
|
unset($base['attachments']);
|
|
return $base;
|
|
}
|
|
|
|
function getType() {
|
|
return $this->type;
|
|
}
|
|
|
|
function getName() {
|
|
return $this->name;
|
|
}
|
|
function getLocalName($lang=false) {
|
|
return $this->_getLocal('name', $lang);
|
|
}
|
|
function getNameAsSlug() {
|
|
return urlencode(Format::slugify($this->name));
|
|
}
|
|
|
|
function getBody() {
|
|
return $this->body;
|
|
}
|
|
function getLocalBody($lang=false) {
|
|
return $this->_getLocal('body', $lang);
|
|
}
|
|
function getBodyWithImages() {
|
|
return Format::viewableImages($this->getLocalBody(), ['type' => 'P']);
|
|
}
|
|
|
|
function _getLocal($what, $lang=false) {
|
|
if (!$lang) {
|
|
$lang = Internationalization::getCurrentLanguage();
|
|
}
|
|
$translations = $this->getAllTranslations();
|
|
foreach ($translations as $t) {
|
|
if ($lang == $t->lang) {
|
|
$data = $t->getComplex();
|
|
if (isset($data[$what]))
|
|
return $data[$what];
|
|
}
|
|
}
|
|
return $this->ht[$what];
|
|
}
|
|
|
|
function getAllTranslations() {
|
|
if (!isset($this->_local)) {
|
|
$tag = $this->getTranslateTag('name:body');
|
|
$this->_local = CustomDataTranslation::allTranslations($tag, 'article');
|
|
}
|
|
return $this->_local;
|
|
}
|
|
|
|
function getNotes() {
|
|
return $this->notes;
|
|
}
|
|
|
|
function isActive() {
|
|
return ($this->isactive);
|
|
}
|
|
|
|
function isInUse() {
|
|
global $cfg;
|
|
|
|
return ($this->getNumTopics()
|
|
|| in_array($this->getId(), $cfg->getDefaultPages()));
|
|
}
|
|
|
|
|
|
function getCreateDate() {
|
|
return $this->created;
|
|
}
|
|
|
|
function getUpdateDate() {
|
|
return $this->updated;
|
|
}
|
|
|
|
function getNumTopics() {
|
|
return $this->topics->count();
|
|
}
|
|
|
|
function getTranslateTag($subtag) {
|
|
return _H(sprintf('page.%s.%s', $subtag, $this->getId()));
|
|
}
|
|
function getLocal($subtag) {
|
|
$tag = $this->getTranslateTag($subtag);
|
|
$T = CustomDataTranslation::translate($tag);
|
|
return $T != $tag ? $T : $this->ht[$subtag];
|
|
}
|
|
|
|
function disable() {
|
|
|
|
if(!$this->isActive())
|
|
return true;
|
|
|
|
if($this->isInUse())
|
|
return false;
|
|
|
|
|
|
$this->isactive = 0;
|
|
return $this->save();
|
|
}
|
|
|
|
function delete() {
|
|
|
|
if ($this->isInUse())
|
|
return false;
|
|
|
|
if (!parent::delete())
|
|
return false;
|
|
|
|
$type = array('type' => 'deleted');
|
|
Signal::send('object.deleted', $this, $type);
|
|
return true;
|
|
}
|
|
|
|
function save($refetch=false) {
|
|
if ($this->dirty)
|
|
$this->updated = SqlFunction::NOW();
|
|
return parent::save($refetch || $this->dirty);
|
|
}
|
|
|
|
/* ------------------> Static methods <--------------------- */
|
|
|
|
static function create($vars=false) {
|
|
$page = new static($vars);
|
|
$page->created = SqlFunction::NOW();
|
|
return $page;
|
|
}
|
|
|
|
function add($vars, &$errors) {
|
|
if(!($id=self::create($vars, $errors)))
|
|
return false;
|
|
|
|
return self::lookup($id);
|
|
}
|
|
|
|
static function getPages($criteria=array()) {
|
|
$pages = self::objects();
|
|
if(isset($criteria['active']))
|
|
$pages = $pages->filter(array('isactive'=>$criteria['active']));
|
|
if(isset($criteria['type']))
|
|
$pages = $pages->filter(array('type'=>$criteria['type']));
|
|
|
|
return $pages;
|
|
}
|
|
|
|
static function getActivePages($criteria=array()) {
|
|
|
|
$criteria = array_merge($criteria, array('active'=>true));
|
|
|
|
return self::getPages($criteria);
|
|
}
|
|
|
|
static function getActiveThankYouPages() {
|
|
return self::getActivePages(array('type' => 'thank-you'));
|
|
}
|
|
|
|
static function lookup($id, $lang=false) {
|
|
try {
|
|
$qs = self::objects()->filter(is_array($id) ? $id : array('id'=>$id));
|
|
if ($lang)
|
|
$qs = $qs->filter(array('lang'=>$lang));
|
|
return $qs->one();
|
|
}
|
|
catch (DoesNotExist $ex) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
static function getIdByName($name, $lang=false) {
|
|
try {
|
|
$qs = self::objects()->filter(array('name'=>$name))
|
|
->values_flat('id');
|
|
list($id) = $qs->one();
|
|
return $id;
|
|
}
|
|
catch (DoesNotExist $ex) {
|
|
return null;
|
|
}
|
|
catch (InconsistentModelException $ex) {
|
|
// This largely happens on upgrades, and may specifically cause
|
|
// the staff login box to crash
|
|
return null;
|
|
}
|
|
}
|
|
|
|
static function lookupByType($type, $lang=false) {
|
|
try {
|
|
return self::objects()->filter(array('type'=>$type))->one();
|
|
}
|
|
catch (DoesNotExist $ex) {
|
|
return null;
|
|
}
|
|
catch (InconsistentModelException $ex) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function update($vars, &$errors, $allowempty=false) {
|
|
//Cleanup.
|
|
$vars['name']=Format::striptags(trim($vars['name']));
|
|
|
|
//validate
|
|
if (isset($this->id) && !$vars['isactive'] && $this->isInUse()) {
|
|
$errors['err'] = __('A page currently in-use CANNOT be disabled!');
|
|
$errors['isactive'] = __('Page is in-use!');
|
|
}
|
|
|
|
if (isset($this->id) && $this->getId() != $vars['id'])
|
|
$errors['err'] = sprintf('%s - %s', __('Internal error occurred'), __('Please try again!'));
|
|
|
|
if(!$vars['type'])
|
|
$errors['type'] = __('Type is required');
|
|
|
|
if(!$vars['name'])
|
|
$errors['name'] = __('Name is required');
|
|
elseif(($pid=self::getIdByName($vars['name'])) && $pid!=$this->getId())
|
|
$errors['name'] = __('Name already exists');
|
|
|
|
if(!$vars['body'] && !$allowempty)
|
|
$errors['body'] = __('Page body is required');
|
|
|
|
if($errors) return false;
|
|
|
|
$this->type = $vars['type'];
|
|
$this->name = $vars['name'];
|
|
$this->body = Format::sanitize($vars['body']);
|
|
$this->isactive = (bool) $vars['isactive'];
|
|
$this->notes = Format::sanitize($vars['notes']);
|
|
|
|
$isnew = !isset($this->id);
|
|
$rv = $this->save();
|
|
if (!$isnew)
|
|
$rv = $this->saveTranslations($vars, $errors);
|
|
|
|
// Attach inline attachments from the editor
|
|
$keepers = Draft::getAttachmentIds($vars['body']);
|
|
$keepers = array_flip(array_map(function($i) { return $i['id']; }, $keepers));
|
|
$this->attachments->keepOnlyFileIds($keepers, true);
|
|
|
|
if ($rv)
|
|
return $rv;
|
|
|
|
$errors['err']=sprintf(__('Unable to update %s.'), __('this site page'));
|
|
return false;
|
|
}
|
|
|
|
function saveTranslations($vars, &$errors) {
|
|
global $thisstaff;
|
|
|
|
$tag = $this->getTranslateTag('name:body');
|
|
$translations = CustomDataTranslation::allTranslations($tag, 'article');
|
|
foreach ($translations as $t) {
|
|
$title = @$vars['trans'][$t->lang]['title'];
|
|
$body = @$vars['trans'][$t->lang]['body'];
|
|
if (!$title && !$body)
|
|
continue;
|
|
|
|
// Content is not new and shouldn't be added below
|
|
unset($vars['trans'][$t->lang]['title']);
|
|
unset($vars['trans'][$t->lang]['body']);
|
|
$content = array('name' => $title, 'body' => Format::sanitize($body));
|
|
|
|
// Don't update content which wasn't updated
|
|
if ($content == $t->getComplex())
|
|
continue;
|
|
|
|
$t->text = $content;
|
|
$t->agent_id = $thisstaff->getId();
|
|
$t->updated = SqlFunction::NOW();
|
|
if (!$t->save())
|
|
return false;
|
|
}
|
|
// New translations (?)
|
|
foreach ($vars['trans'] ?: array() as $lang=>$parts) {
|
|
$content = array('name' => @$parts['title'], 'body' => Format::sanitize(@$parts['body']));
|
|
if (!array_filter($content))
|
|
continue;
|
|
$t = CustomDataTranslation::create(array(
|
|
'type' => 'article',
|
|
'object_hash' => $tag,
|
|
'lang' => $lang,
|
|
'text' => $content,
|
|
'revision' => 1,
|
|
'agent_id' => $thisstaff->getId(),
|
|
'updated' => SqlFunction::NOW(),
|
|
));
|
|
if (!$t->save())
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static function getContext($type) {
|
|
$context = array(
|
|
'thank-you' => array('ticket'),
|
|
'registration-staff' => array(
|
|
// 'token' => __('Special authentication token'),
|
|
'staff' => array('class' => 'Staff', 'desc' => __('Message recipient')),
|
|
'recipient' => array('class' => 'Staff', 'desc' => __('Message recipient')),
|
|
'link',
|
|
),
|
|
'pwreset-staff' => array(
|
|
'staff' => array('class' => 'Staff', 'desc' => __('Message recipient')),
|
|
'recipient' => array('class' => 'Staff', 'desc' => __('Message recipient')),
|
|
'link',
|
|
),
|
|
'registration-client' => array(
|
|
// 'token' => __('Special authentication token'),
|
|
'recipient' => array('class' => 'User', 'desc' => __('Message recipient')),
|
|
'link', 'user',
|
|
),
|
|
'pwreset-client' => array(
|
|
'recipient' => array('class' => 'User', 'desc' => __('Message recipient')),
|
|
'link', 'user',
|
|
),
|
|
'access-link' => array('ticket', 'recipient'),
|
|
);
|
|
|
|
return $context[$type];
|
|
}
|
|
}
|
|
?>
|