Skip to content
Snippets Groups Projects
class.forms.php 76.8 KiB
Newer Older
  • Learn to ignore specific revisions
  •         $data = $this->field->getSource();
    
            $config = $this->field->getConfiguration();
            if ($datetime = parent::getValue()) {
    
                $datetime = is_int($datetime) ? $datetime :
                    strtotime($datetime);
    
                if ($datetime && isset($data[$this->name . ':time'])) {
    
                    list($hr, $min) = explode(':', $data[$this->name . ':time']);
                    $datetime += $hr * 3600 + $min * 60;
                }
    
                if ($datetime && $config['gmt']) {
                    // Convert to GMT time
                    $tz = new DateTimeZone($cfg->getTimezone());
                    $D = DateTime::createFromFormat('U', $datetime);
                    $datetime -= $tz->getOffset($D);
                }
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $datetime;
        }
    }
    
    
    class SectionBreakWidget extends Widget {
    
        function render($mode=false) {
    
            ?><div class="form-header section-break"><h3><?php
            echo Format::htmlchars($this->field->get('label'));
            ?></h3><em><?php echo Format::htmlchars($this->field->get('hint'));
            ?></em></div>
            <?php
        }
    }
    
    class ThreadEntryWidget extends Widget {
    
        function render($client=null) {
            global $cfg;
    
    
            $object_id = false;
            if (!$client) {
                $namespace = 'ticket.staff';
            }
            else {
                $namespace = 'ticket.client';
                $object_id = substr(session_id(), -12);
            }
            list($draft, $attrs) = Draft::getDraftAndDataAttrs($namespace, $object_id, $this->value);
    
            <textarea style="width:100%;" name="<?php echo $this->field->get('name'); ?>"
    
                placeholder="<?php echo Format::htmlchars($this->field->get('hint')); ?>"
    
                class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
                    ?> draft draft-delete" <?php echo $attrs; ?>
    
                cols="21" rows="8" style="width:80%;"><?php echo
    
                $draft ?: Format::htmlchars($this->value); ?></textarea>
    
            $config = $this->field->getConfiguration();
            if (!$config['attachments'])
                return;
    
            $attachments = $this->getAttachments($config);
    
            print $attachments->render($client);
            foreach ($attachments->getMedia() as $type=>$urls) {
                foreach ($urls as $url)
                    Form::emitMedia($url, $type);
    
    
        function getAttachments($config=false) {
            if (!$config)
                $config = $this->field->getConfiguration();
    
    
            $field = new FileUploadField(array(
    
                'name'=>'attach:' . $this->field->get('id'),
    
            $field->setForm($this->field->getForm());
            return $field;
    
    class FileUploadWidget extends Widget {
        static $media = array(
            'css' => array(
                '/css/filedrop.css',
            ),
        );
    
        function render($how) {
            $config = $this->field->getConfiguration();
            $name = $this->field->getFormName();
    
            $id = substr(md5(spl_object_hash($this)), 10);
    
            $attachments = $this->field->getFiles();
    
            $mimetypes = array_filter($config['__mimetypes'],
                function($t) { return strpos($t, '/') !== false; }
            );
    
            $files = array();
    
            foreach ($this->value ?: array() as $fid) {
    
                $found = false;
                foreach ($attachments as $f) {
    
                        $files[] = $f;
                        $found = true;
                        break;
                    }
                }
    
                if (!$found && ($file = AttachmentFile::lookup($fid))) {
    
                    $files[] = array(
                        'id' => $file->getId(),
                        'name' => $file->getName(),
                        'type' => $file->getType(),
                        'size' => $file->getSize(),
                    );
                }
            }
    
                ?>" class="filedrop"><div class="files"></div>
                <div class="dropzone"><i class="icon-upload"></i>
    
    Jared Hancock's avatar
    Jared Hancock committed
                <?php echo sprintf(
                    __('Drop files here or %s choose them %s'),
                    '<a href="#" class="manual">', '</a>'); ?>
    
            <input type="file" multiple="multiple"
                id="file-<?php echo $id; ?>" style="display:none;"
    
                accept="<?php echo implode(',', $config['__mimetypes']); ?>"/>
    
            <script type="text/javascript">
    
            $(function(){$('#<?php echo $id; ?> .dropzone').filedropbox({
    
              url: 'ajax.php/form/upload/<?php echo $this->field->get('id') ?>',
    
              link: $('#<?php echo $id; ?>').find('a.manual'),
    
              paramname: 'upload[]',
    
              fallback_id: 'file-<?php echo $id; ?>',
    
              allowedfileextensions: <?php echo JsonDataEncoder::encode(
    
                $config['__extensions'] ?: array()); ?>,
    
              allowedfiletypes: <?php echo JsonDataEncoder::encode(
    
              maxfiles: <?php echo $config['max'] ?: 20; ?>,
    
              maxfilesize: <?php echo ($config['size'] ?: 1048576) / 1048576; ?>,
    
              name: '<?php echo $name; ?>[]',
              files: <?php echo JsonDataEncoder::encode($files); ?>
            });});
            </script>
    <?php
        }
    
        function getValue() {
            $data = $this->field->getSource();
    
            $ids = array();
            // Handle manual uploads (IE<10)
            if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES[$this->name])) {
                foreach (AttachmentFile::format($_FILES[$this->name]) as $file) {
    
                    try {
                        $ids[] = $this->field->uploadFile($file);
                    }
                    catch (FileUploadError $ex) {}
    
                }
                return array_merge($ids, parent::getValue() ?: array());
            }
    
            // If no value was sent, assume an empty list
    
            elseif ($data && is_array($data) && !isset($data[$this->name]))
    
                return array();
    
            return parent::getValue();
        }
    }
    
    
    class FileUploadError extends Exception {}
    
    
    class FreeTextField extends FormField {
        static $widget = 'FreeTextWidget';
    
        function getConfigurationOptions() {
            return array(
                'content' => new TextareaField(array(
    
                    'configuration' => array('html' => true, 'size'=>'large'),
    
                    'label'=>__('Content'), 'required'=>true, 'default'=>'',
                    'hint'=>__('Free text shown in the form, such as a disclaimer'),
                )),
            );
        }
    
        function hasData() {
            return false;
        }
    
        function isBlockLevel() {
            return true;
        }
    }
    
    class FreeTextWidget extends Widget {
        function render($mode=false) {
            $config = $this->field->getConfiguration();
            ?><div class=""><h3><?php
                echo Format::htmlchars($this->field->get('label'));
            ?></h3><em><?php
                echo Format::htmlchars($this->field->get('hint'));
            ?></em><div><?php
                echo Format::viewableImages($config['content']); ?></div>
            </div>
            <?php
        }
    }
    
    
    class VisibilityConstraint {
    
        const HIDDEN =      0x0001;
        const VISIBLE =     0x0002;
    
        var $initial;
        var $constraint;
    
        function __construct($constraint, $initial=self::VISIBLE) {
            $this->constraint = $constraint;
            $this->initial = $initial;
        }
    
        function emitJavascript($field) {
            $func = 'recheck';
            $form = $field->getForm();
    ?>
        <script type="text/javascript">
          !(function() {
            var <?php echo $func; ?> = function() {
    
              var target = $('#field<?php echo $field->getWidget()->id; ?>');
    
    
    <?php   $fields = $this->getAllFields($this->constraint);
            foreach ($fields as $f) {
                $field = $form->getField($f);
                echo sprintf('var %1$s = $("#%1$s");',
    
                    $field->getWidget()->id);
    
            }
            $expression = $this->compileQ($this->constraint, $form);
    ?>
    
              if (<?php echo $expression; ?>)
    
    Peter Rotich's avatar
    Peter Rotich committed
                target.slideDown('fast', function (){
    
                    $(this).trigger('show');
                    });
              else
                target.slideUp('fast', function (){
                    $(this).trigger('hide');
                    });
    
            };
    
    <?php   foreach ($fields as $f) {
                $w = $form->getField($f)->getWidget();
    ?>
    
            $('#<?php echo $w->id; ?>').on('change', <?php echo $func; ?>);
    
            $('#field<?php echo $w->id; ?>').on('show hide', <?php
                    echo $func; ?>);
    
    <?php   } ?>
          })();
        </script><?php
        }
    
        /**
         * Determines if the field was visible when the form was submitted
         */
        function isVisible($field) {
            return $this->compileQPhp($this->constraint, $field);
        }
    
        function compileQPhp(Q $Q, $field) {
            $form = $field->getForm();
            $expr = array();
            foreach ($Q->constraints as $c=>$value) {
                if ($value instanceof Q) {
                    $expr[] = $this->compileQPhp($value, $field);
                }
                else {
                    @list($f, $op) = explode('__', $c, 2);
                    $field = $form->getField($f);
                    $wval = $field->getClean();
                    switch ($op) {
                    case 'eq':
                    case null:
    
                        $expr[] = ($wval == $value && $field->isVisible());
    
                    }
                }
            }
            $glue = $Q->isOred()
                ? function($a, $b) { return $a || $b; }
                : function($a, $b) { return $a && $b; };
            $initial = !$Q->isOred();
            $expression = array_reduce($expr, $glue, $initial);
            if ($Q->isNegated)
                $expression = !$expression;
            return $expression;
        }
    
        function getAllFields(Q $Q, &$fields=array()) {
            foreach ($Q->constraints as $c=>$value) {
                if ($c instanceof Q) {
                    $this->getAllFields($c, $fields);
                }
                else {
                    list($f, $op) = explode('__', $c, 2);
                    $fields[$f] = true;
                }
            }
            return array_keys($fields);
        }
    
        function compileQ($Q, $form) {
            $expr = array();
            foreach ($Q->constraints as $c=>$value) {
                if ($value instanceof Q) {
                    $expr[] = $this->compileQ($value, $form);
                }
                else {
                    list($f, $op) = explode('__', $c, 2);
    
                    $widget = $form->getField($f)->getWidget();
                    $id = $widget->id;
    
                    switch ($op) {
                    case 'eq':
    
                        $expr[] = sprintf('(%s.is(":visible") && %s)',
                                $id,
                                sprintf('%s == %s',
                                    sprintf($widget->getJsValueGetter(), $id),
                                    JsonDataEncoder::encode($value))
                                );
    
                    }
                }
            }
            $glue = $Q->isOred() ? ' || ' : ' && ';
            $expression = implode($glue, $expr);
            if (count($expr) > 1)
                $expression = '('.$expression.')';
            if ($Q->isNegated)
                $expression = '!'.$expression;
            return $expression;
        }
    }