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

    Forms models built on the VerySimpleModel paradigm. Allows for arbitrary
    data to be associated with tickets. Eventually this model can be
    extended to associate arbitrary data with registered clients and thread
    entries.

    Jared Hancock <jared@osticket.com>
    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:
**********************************************************************/
require_once(INCLUDE_DIR . 'class.orm.php');
require_once(INCLUDE_DIR . 'class.forms.php');
require_once(INCLUDE_DIR . 'class.list.php');
require_once(INCLUDE_DIR . 'class.filter.php');
require_once(INCLUDE_DIR . 'class.signal.php');
Jared Hancock's avatar
Jared Hancock committed

/**
 * Form template, used for designing the custom form and for entering custom
 * data for a ticket
 */
class DynamicForm extends VerySimpleModel {
Jared Hancock's avatar
Jared Hancock committed

    static $meta = array(
        'table' => FORM_SEC_TABLE,
        'ordering' => array('title'),
        'pk' => array('id'),
        'joins' => array(
            'fields' => array(
                'reverse' => 'DynamicFormField.form',
            ),
        ),
    // Registered form types
    static $types = array(
        'T' => 'Ticket Information',
        'U' => 'User Information',
        'O' => 'Organization Information',
Jared Hancock's avatar
Jared Hancock committed
    const FLAG_DELETABLE    = 0x0001;
    const FLAG_DELETED      = 0x0002;

Jared Hancock's avatar
Jared Hancock committed
    var $_fields;
    var $_has_data = false;
    var $_dfields;
    function getInfo() {
        $base = $this->ht;
        unset($base['fields']);
        return $base;
    }
    function getId() {
        return $this->id;
    }

    /**
     * Fetch a list of field implementations for the fields defined in this
     * form. This method should *always* be preferred over
     * ::getDynamicFields() to avoid caching confusion
     */
    function getFields() {
        if (!$this->_fields) {
            $this->_fields = new ListObject();
Jared Hancock's avatar
Jared Hancock committed
            foreach ($this->getDynamicFields() as $f)
                $this->_fields->append($f->getImpl($f));
    /**
     * Fetch the dynamic fields associated with this dynamic form. Do not
     * use this list for data processing or validation. Use ::getFields()
     * for that.
     */
Jared Hancock's avatar
Jared Hancock committed
    function getDynamicFields() {
        return $this->fields;
    // Multiple inheritance -- delegate methods not defined to a forms API
    // Form
    function __call($what, $args) {
        $delegate = array($this->getForm(), $what);
        if (!is_callable($delegate))
            throw new Exception(sprintf(__('%s: Call to non-existing function'), $what));
        return call_user_func_array($delegate, $args);
    function getTitle() {
        return $this->getLocal('title');
    function getInstructions() {
        return $this->getLocal('instructions');
    /**
     * Drop field errors clean info etc. Useful when replacing the source
     * content of the form. This is necessary because the field listing is
     * cached under some circumstances.
     */
    function reset() {
        foreach ($this->getFields() as $f)
            $f->reset();
        return $this;
    }

    function getForm($source=false) {
        if ($source)
            $this->reset();
        $fields = $this->getFields();
Peter Rotich's avatar
Peter Rotich committed
        $form = new SimpleForm($fields, $source, array(
            'title' => $this->getLocal('title'),
            'instructions' => $this->getLocal('instructions'))
        );
    function isDeletable() {
Jared Hancock's avatar
Jared Hancock committed
        return $this->flags & self::FLAG_DELETABLE;
    }

    function setFlag($flag) {
        $this->flags |= $flag;
    function hasAnyVisibleFields($user=false) {
        global $thisstaff, $thisclient;
        $user = $user ?: $thisstaff ?: $thisclient;
        $visible = 0;
        $isstaff = $user instanceof Staff;
        foreach ($this->getFields() as $F) {
            if ($isstaff) {
                if ($F->isVisibleToStaff())
                    $visible++;
            }
            elseif ($F->isVisibleToUsers()) {
                $visible++;
            }
        }
        return $visible > 0;
    }

    function instanciate($sort=1, $data=null) {
        $inst = DynamicFormEntry::create(
            array('form_id'=>$this->get('id'), 'sort'=>$sort)
        );
            $inst->setSource($data);
        return $inst;
    function disableFields(array $ids) {
        foreach ($this->getFields() as $F) {
            if (in_array($F->get('id'), $ids)) {
                $F->disable();
            }
        }
    }

    function getTranslateTag($subtag) {
        return _H(sprintf('form.%s.%s', $subtag, $this->id));
    }
    function getLocal($subtag) {
        $tag = $this->getTranslateTag($subtag);
        $T = CustomDataTranslation::translate($tag);
        return $T != $tag ? $T : $this->get($subtag);
    }

    function save($refetch=false) {
Jared Hancock's avatar
Jared Hancock committed
        if (count($this->dirty))
            $this->set('updated', new SqlFunction('NOW'));
Jared Hancock's avatar
Jared Hancock committed
        // XXX: This should go to an update routine
        if (isset($this->dirty['notes']))
            $this->notes = Format::sanitize($this->notes);
        if ($rv = parent::save($refetch | $this->dirty))
            return $this->saveTranslations();
        return $rv;
        if (!$this->isDeletable())
            return false;
        // Soft Delete: Mark the form as deleted.
Jared Hancock's avatar
Jared Hancock committed
        $this->setFlag(self::FLAG_DELETED);
        return $this->save();
Loading
Loading full blame...