kind form, need settings[modal_url]
@param  string $name
@param  string $value
@param  array  $settings
@return string
439620
static public function kind($name, $value=null, $settings=[])
    {
        if (strpos($name, '[') === false) {
            $kind_type = $name;
            $name = '_kinds[' . $name . '][]';
        } else {
            $kind_type = preg_replace('/_(kinds\[)?(\w+)\]?\[\]/', '${2}', $name);
        }
        $settings = static::formatSettings($settings);
        $form_type = isset($settings['form_type']) ? trim($settings['form_type']) : 'checkbox_group';
        
        if ($form_type === 'modal') {
            $modal_url = isset($setting['modal_url']) ? $setting['modal_url'] : 'common/data/select/kind?kind_type=' . $kind_type;
            $settings['modal_url'] = Ioc::url($modal_url);
            $str = static::select($name, $value, $settings);
        } elseif ($form_type === 'select') {
            $str = static::select($name, $value, $settings);
        } else {
            $str = static::checkbox_group($name, $value, $settings);
        }
        
        return $str;
    }
1343673
public function set($setting, $value)
    {
        switch ($setting) {
            case self::SETTING_DEFAULT_MODE:
                OptionParser::$defaultMode = $value;
                break;
            default:
                $this->settings[$setting] = $value;
                break;
        }
        return $this;
    }
1109730
public function set($name, $value, array $options = [])
    {
        $options = $this->options($options);
        $value   = parent::set($name, $value, $options);

        return setcookie(
            $this->normalize($name),
            $value,
            $options[self::OPTION_EXPIRE],
            $options[self::OPTION_PATH],
            $options[self::OPTION_DOMAIN],
            false,
            $options[self::OPTION_HTTP_ONLY]
        );
    }
586983
public function bindParams($name, $value=null) {
        
        if (is_array($name)) {
            foreach ($name as $k=>$v) {
                $this->binds[':'.$k]  =   $v;
            }
        } elseif ($value) {
            $this->binds[':'.$name] = $value;
        }
        
        return $this;
    }
455406
static public function location($name=null, $value=null, $settings=[])
    {
        $settings['media_type'] = 'location';
        if (!isset($settings['modal_url'])) {
            $settings['modal_url'] = Ioc::url('common/data/select/location');
        }
        
        $data = [
            'lng'  => isset($value['lng']) ? $value['lng'] : '',
            'lat'  => isset($value['lat']) ? $value['lat'] : '',
            'addr' => isset($value['addr']) ? $value['addr'] : (isset($value['address']) ? $value['address'] : ''),
        ];
        $settings['modal_url'] = Ioc::url($settings['modal_url'], $data);
        
        return static::select($name, $value, $settings);
    }
445123
private function validateDefaultAuthorSetting($name, $value)
    {
        $definedValues = [
            self::DEFAULT_VALUE_EMPTY,
            self::DEFAULT_CURRENT_USER,
        ];

        if (!in_array($value, $definedValues, true)) {
            return new ValidationError(
                "Setting '%setting%' has unknown default value",
                null,
                [
                    '%setting%' => $name,
                ],
                "[$name]"
            );
        }

        return null;
    }
796820
static function position($name, $value=null, $settings=[])
    {
        if (!isset($settings['description'])) {
            $settings['description'] = '位置可设为：1到9的数字表示九宫格的位置, 或100|30, 或 center|center, 或100|left';
        }
        
        return static::input('text', $name, $value, $settings);
    }
1135465
static function input($input_type, $name, $value=null, $settings=[])
    {
        $settings = static::formatSettings($settings);
        is_array($value) && $value = current($value);
        $str = '';
        $pre_input_type = $input_type;
        switch ($input_type) {
            case 'checkbox':
            case 'radio':
                $settings['class'] = isset($settings['class']) ? $settings['class'] : 'ace ace-switch ace-switch-5';
                $str .= '<label>' . PHP_EOL ;
                break;
            case 'text':
            case 'password':
                $settings['id'] = isset($settings['id']) ? static::formatId($settings['id']) : static::formatId($name);
                $settings['class'] = isset($settings['class']) ? 'form-control ' . $settings['class'] : 'form-control';
                break;
            case 'datetime':
            case 'date':
                $input_type = 'text';
                $value = $pre_input_type == 'datetime' ? DataHelper::fromUnixtime($value) : DataHelper::toDate($value);
                $settings['id'] = isset($settings['id']) ? static::formatId($settings['id']) : static::formatId($name);
                $settings['class']  = isset($settings['class']) ? $settings['class'] . ' form-control date-picker' : ' form-control date-picker';
                break;
            default:
                $settings['class'] = isset($settings['class']) ? $settings['class'] : '';
                break;
        }
        
        $str .= '<input type="' . $input_type . '" name="' . $name . '"';
        
        if ($input_type == 'checkbox' || $input_type == 'radio') {
            // 处理 value, checked
            $o_form_value = !is_null($value) || $value !== '' ? $value : '1';
            $value   = $value ? : '1';
            if (isset($settings['checked'])) {
                if (is_array($settings['checked'])) {
                    $_checked = in_array($value, $settings['checked']) ? true : false;
                } elseif (in_array($settings['checked'], ['', 1,0,true,false])) {
                    $_checked = $settings['checked'];
                } else {
                    $_checked = $value == $settings['checked'] ? true : false;
                }
                $str .= $_checked ? ' checked="checked"' : '';
            } elseif (is_numeric($o_form_value) || is_bool($o_form_value)) {
                if (intval($o_form_value) == 1) {
                    $str .= ' checked="checked"';
                }
            }
        }
        
        $str .= ' value="' . $value . '"';
        
        foreach($settings as $k => $v) {
            if (in_array($k, array('class', 'onchange', 'id', 'readonly', 'style', 'placeholder'))) {
                $str .= " $k=\"$v\"";
            } elseif($k == 'checked' && ($input_type !== 'checkbox' && $input_type !== 'radio')) {
                $str .= " $k=\"$v\"";
            }
        }
        $str .= '> ';
        
        if ($input_type == 'checkbox' || $input_type == 'radio') {
            $title = isset($settings['title']) ? $settings['title'] : '';
            $str .= ' <span class="lbl"> '.$title.' </span> ' . PHP_EOL;
            $str .= '</label>' . PHP_EOL ;
        }
        
        /**
         * 处理日期输入控件，依赖于 jquery.js, jquery-ui.datetime.js, datetimepicker.js, datetimepicker.css
         * <script src='{$rootUrl}/static/jquery/jquery-1.10.2.min.js'></script>
         * <link type="text/css" rel="stylesheet" href="{$rootUrl}/static/datetimepicker-2.5.3/jquery.datetimepicker.css"/>
         * <script src="{$rootUrl}/static/datetimepicker-2.5.3/jquery.datetimepicker.full.min.js"></script>
         */
        if ($pre_input_type == 'datetime' || $pre_input_type == 'date') {
            $innerJs = "";
            $dformat = $pre_input_type == 'datetime' ? 'Y-m-d H:i:s' : 'Y-m-d';
            if (!static::$isLoaded['datetime']) {
                $web_url = Config::getRootUrl();
                $innerJs .= <<<EOF
                    <link type="text/css" rel="stylesheet" href="${web_url}/static/datetimepicker-2.5.3/jquery.datetimepicker.css"/>
EOF;
                static::$isLoaded['datetime'] = true;
            }
            $innerJs .= <<<EOF
                <script>
                    require(['jquery.datetime'], function() {
                        $("#${settings['id']}").datetimepicker({
                    		format:	"{$dformat}",
                    	});
                    });
                </script>
EOF;
            $dt_str = '<div class="input-group input-group-sm">' . PHP_EOL;
            $dt_str .= $str . PHP_EOL;
            $dt_str .= '<span class="input-group-addon">' . PHP_EOL;
            $dt_str .= '    <i class="fa fa-clock-o bigger-110"></i>' . PHP_EOL;
            $dt_str .= '</span>' . PHP_EOL;
            $dt_str .= '</div>' . PHP_EOL;
            $dt_str .= $innerJs;
            	
            $str = & $dt_str;
        }
         
        return $str;
    }
76066
public function label($name, $value = null, array $options = [])
    {
        $options = $this->getLabelOptions($options);

        $escapeHtml = false;

        if (is_array($value) and isset($value['html'])) {
            $value = $value['html'];
        } elseif ($value instanceof HtmlString) {
            $value = $value->toHtml();
        } else {
            $escapeHtml = true;
        }

        return $this->form->label($name, $value, $options, $escapeHtml);
    }
617835
static public function signature($name=null, $value=null, $settings=[])
    {
        $name || $name = 'row[signature]';
        $nts_name = explode(']', $name);
        $nts_name[0] .= '_nts';
        $nts_name = count($nts_name)>1 ? implode(']', $nts_name) : $nts_name[0];
        $value && $value = Ioc::url('upload:'.$value);
        
        $width = isset($settings['width']) ? intval($settings['width']) : 400;
        $height = isset($settings['height']) ? intval($settings['height']) : 100;
        if ($width < 300) {
            $width = 300;
        }
        if ($height < 100) {
            $height = 100;
        }
        $str = <<<EOF
        <style>.signature-result {border: 1px solid #333;background:#fff;} .signature-result img {}</style>
        <div class="row">
            <div class="col-sm-12 col-md-6">
                <div class="js-signature" style="width:${width}px;height:${height}px;" data-width="${width}" data-height="${height}" data-border="1px solid black" data-line-color="#bc0000" data-auto-fit="true"></div>
                <p style="margin-top:15px;text-align:center;">
                    <button type="button" class="btn btn-primary btn-sm signature-default" style="display:none;">默认签名</button>&nbsp;
                    <button type="button" class="btn btn-primary btn-sm signature-clear" >清空重签</button>&nbsp;
                    <button type="button" class="btn btn-success btn-sm signature-build" disabled>生成签名</button>
                </p>
            </div>
            <div class="col-sm-12 col-md-6">
                <input name="audit[default_signature]" value="${value}" type="hidden" id="default_signature">
                <input name="${name}" value="${value}" type="hidden" class="signature-text">
                <input name="${nts_name}" value="${value}" type="hidden" class="signature-nts-text">
                <div class="signature-result" style="width:${width}px;height:${height}px;" ><p><em>this is signature image</em></p></div>
                <p style="margin-top:15px;text-align:center;">
                    <label>
                    <input name="audit[save_signature]" value="1" class="ace ace-switch ace-switch-5" type="checkbox">  <span class="lbl"> 保存为我的默认签名 </span> 
                    </label>
                </p>
            </div>
        </div>
        <script>
        require(["jquery", "jquery.signature"], function (){
            var src = "${value}";

            if ($('.js-signature').length) {
                $('.js-signature').jqSignature({autoFit: true});

                $('.signature-clear').on("click", clearCanvas);
                $('.signature-build').on("click", buildSignature);
                
                if (src) {
                    $(".signature-default").show().on("click", function () {
                        $('.js-signature').eq(0).jqSignature('drawImage', src);
                        buildSignature();
                        $("#default_signature").val(src);
                    });
                    setTimeout(function(){
                        $('.js-signature').eq(0).jqSignature('drawImage', src);
                        buildSignature();
                        $("#default_signature").val(src);
                    }, 1000);
                }
            }
            
            function clearCanvas() {
                $('.signature-result').html('<p><em>签名图</em></p>');
                $('.js-signature').eq(0).jqSignature('clearCanvas');
                $('.signature-build').attr('disabled', true);
            }
            
            function buildSignature() {
                $("#default_signature").val("");
                
                $('.signature-result').empty();
                
                var ntsDataUrl = $('.js-signature').eq(0).jqSignature('getNotimeDataURL');
                $('.signature-result').prevAll("input.signature-nts-text").val(ntsDataUrl);
                
                var dataUrl = $('.js-signature').eq(0).jqSignature('getDataURL'); 
                var img = $('<img>').attr('src', dataUrl);
                $('.signature-result').append(img);
                $('.signature-result').prevAll("input.signature-text").val(dataUrl);
            }
            
            $('.js-signature').eq(0).on('jq.signature.changed', function() {
                $('.signature-build').attr('disabled', false);
            });
        });
        </script>
EOF;
        return $str;
    }
210647
public function validateCondition(string $name, $value)
    {
        foreach ($this->validations as $validation) {
            $success = true;
            list($condition, $conditionValue) = $validation;
            $conditionValue = is_array($conditionValue) ? implode(';', $conditionValue) : $conditionValue;

            switch ($condition) {
                case 'gte':
                    if ($value < $conditionValue) {
                        $success = false;
                    }
                    break;

                case 'gt':
                    if ($value <= $conditionValue) {
                        $success = false;
                    }
                    break;

                case 'lte':
                    if ($value > $conditionValue) {
                        $success = false;
                    }
                    break;

                case 'lt':
                    if ($value >= $conditionValue) {
                        $success = false;
                    }
                    break;

                case 'in':
                    $allValues = strpos($this->getType(), '[]') !== false ? $value : [$value];

                    $conditionValue = is_array($conditionValue) ? $conditionValue : [$conditionValue];

                    foreach ($allValues as $currentValue) {
                        if (!in_array($currentValue, $conditionValue)) {
                            $success = false;
                        }
                    }

                    break;

                case 'isip':
                    $isValid = Ip::isValid();
                    $success = ($isValid && $conditionValue == 'true') || (!$isValid && $conditionValue == 'false');
                    break;

                default:
                    throw new \Exception(sprintf(
                        "Invalid condition parameters '%s: %s' for parameter '%s' with value '%s'",
                        $condition,
                        $conditionValue,
                        $name,
                        $value
                    ));
                    break;
            }

            if (!$success) {
                $value = is_array($value) ? json_encode($value) : $value;
                throw new ResponseCode(sprintf(
                    "Invalid conditions for parameter '%s' with value '%s' for condition '%s : %s'",
                    $name,
                    $value,
                    $condition,
                    is_array($conditionValue) ? json_encode($conditionValue) : $conditionValue
                ), 422);
            }
        }

        return $value;
    }
246554
public function addFormParam($name, $value)
    {
        $this->options[GuzzleRequestOptions::FORM_PARAMS][$name] = $value;

        return $this;
    }
560188
public function set($name, $value)
	{
		if ( $value === null ) {
			unset($this->settings[$name]);
		}
		else {
			$this->settings[$name] = $value;
		}

		$this->store();
	}
37183
static public function simditor($name, $value=null, $settings=[])
    {
        $settings = static::formatSettings($settings);
        $form_id    = isset($settings['id']) ? static::formatId($settings['id']) : static::formatId($name);
        $web_url = Config::getRootUrl() . '/lib';
        if(empty($value)) {
            $value = '<p>Thanks for Simditor.</p>';
        }

        // 此处动态加载有问题，不能直接运行脚本
        if (!static::$isLoaded['simditor']) {
            $inner .= <<<EOF
                <link rel="stylesheet" href="${web_url}/simditor-2.3.6/assets/simditor.css" />
                <script type="text/javascript" src="${web_url}/simditor-2.3.6/assets/simditor-2.3.6.full.js"></script>
EOF;
            static::$isLoaded['simditor'] = true;
        }
    
        $inner .= <<<EOF
            <section id="${form_id}wrap">
                <textarea id="${form_id}" name="${name}" data-autosave="${form_id}-content" autofocus required>
                    ${value}
                </textarea>
            </section>
EOF;
        $innerJs = <<<EOF
        <script>
            (function() {
    
                $(function() {
                    var preview, editor, mobileToolbar, toolbar;
                    Simditor.locale = 'zh-CN';	// en-US
                    toolbar = ['title', 'bold', 'italic', 'underline', 'strikethrough', 'fontScale', 'color', '|', 'ol', 'ul', 'blockquote', 'code', 'table', '|', 'link', 'image', 'hr', '|', 'indent', 'outdent', 'alignment'];
                    mobileToolbar = ["bold", "underline", "strikethrough", "color", "ul", "ol"];
                    if (mobilecheck()) {
                      toolbar = mobileToolbar;
                    }
                    editor = new Simditor({
                      textarea: $('#${form_id}'),
                      placeholder: '这里输入文字...',
                      toolbar: toolbar,
                      pasteImage: true,
                      defaultImage: '${web_url}/simditor-2.3.6/assets/images/image.png',
                      upload: location.search === '?upload' ? {
                        url: '/upload'
                      } : false
                    });
                    preview = $('#preview');
                    if (preview.length > 0) {
                      return editor.on('valuechanged', function(e) {
                        return preview.html(editor.getValue());
                      });
                    }
                });
            }).call(this);
        </script>
EOF;
        return $inner . PHP_EOL . $innerJs;
    }
1186817
static public function wx_contents_input($form_name, $form_value=null, $settings=null)
    {
        $settings['id']     = isset($settings['id']) ? $settings['id'] : str_replace(array('[', ']'), array('_'), $form_name);
        $index = 0;
        $template = <<<INPUT
<li style="%s" class="%s">
    <img src="%s" class="content-img">
    <div class="content-body">
        <span class="content-title">%s</span>
        <span class="content-description">%s</span>
        <input type="hidden" name="%s" value="%s" class="content-title-input">
        <input type="hidden" name="%s" value="%s" class="content-description-input">
        <input type="hidden" name="%s" value="%s" class="content-pic-url-input">
        <input type="hidden" name="%s" value="%s" class="content-url-input">
        <input type="hidden" name="%s" value="%s" class="content-id-input">
    </div>
    <div class="content-op">
        <input type="button" class="btn btn-primary btn-sm edit-content" value="编辑">
        <input type="button" class="btn btn-primary btn-sm delete-content" value="删除">
    </div>
</li>
INPUT;
        $str = '<ul class="list-unstyled contents-wrap">' . PHP_EOL;
        if (isset($form_value) && is_array($form_value)) foreach ($form_value as $k => $v) {
            $img_src = isset($v['pic_url']) ? $v['pic_url'] : '';
            $title = isset($v['title']) ? $v['title'] : '';
            $description = isset($v['description']) ? $v['description'] : '';
            $url = isset($v['url']) ? $v['url'] : '';
            $id  = isset($v['id']) ? $v['id'] : 0;
            $str .= sprintf($template
                , '', $settings['id'] . '-content-wrap-' . $index
                , $img_src, $title, $description
                , $settings['id'] . '['. $index . '][title]', $title
                , $settings['id'] . '['. $index . '][description]', $description
                , $settings['id'] . '['. $index . '][pic_url]', $img_src
                , $settings['id'] . '['. $index . '][url]', $url
                , $settings['id'] . '['. $index . '][id]', $id
            );
            $index += 1;
        }
        $str .= sprintf($template
            , 'display:none;', $settings['id'] . '-content-wrap-' . 'x'
            , '', '', ''
            , $settings['id'] . '['. 'x' . '][title]', ''
            , $settings['id'] . '['. 'x' . '][description]', ''
            , $settings['id'] . '['. 'x' . '][pic_url]', ''
            , $settings['id'] . '['. 'x' . '][url]', ''
            , $settings['id'] . '['. 'x' . '][id]', 0
        );
        $str .= '</ul>' . PHP_EOL;
        
        $str .= '<div style="margin-top:15px;">'. PHP_EOL;
        $str .= '    <input type="button" class="btn btn-warning btn-sm select-content" data-id="' . $settings['id'] . '" value="选择图文列表">';
        $str .= '    <input type="button" class="btn btn-warning btn-sm add-content" data-id="' . $settings['id'] . '" value="自定义图文列表">';
        $str .= '</div>'. PHP_EOL;
        
        //if (!static::$isLoadedImageText) {
        $select_url = isset($settings['modal_url']) ? $settings['modal_url'] : Ioc::url('common/data/select_content');
            $innerJs = <<<EOF
                <script>
                require(["util"], function(){
                    var index = "{$index}";
                	$(".contents-wrap").on("click", ".delete-content", function() {
                	    //console.log($(this));
                        $(this).parent().parent("li").remove();
                        return false;
                    });
                    $(".select-content").on("click", function() {
                        var tid = $(this).attr('data-id');
                        
                        var dlg = util.dialog.show({
                            width: '800px',
                    		title: '选择图文内容',
                    		url: "{$select_url}",
                    		okValue: '确 定',
                    		ok: false,
                    		cancelValue: '取消',
                    		cancel: null,
                    		cancelDisplay: true
                    	});
                    	
                        dlg.addEventListener('close', function () {
                            if (dlg.returnValue.data) {
                                console.log(dlg.returnValue);
                                data = dlg.returnValue.data;
                                if (data.length > 0) {
                    		        for (dindex in data) {
                    		            var item_index = Number(dindex) + Number(index);
                                        var tpl_ele = $("." + tid + '-content-wrap-x');
                                        var html = tpl_ele.html().replace(/\[x\]/g, '[' + item_index + ']');
                                        $('<li style="text-align:center;" class="' + tid + '-content-wrap-' + item_index + '">').insertBefore(tpl_ele).html(html);
                                        var ele = $("." + tid + '-content-wrap-' + item_index);
                                        ele.find(".content-img").attr('src', data[dindex]["pic_url"]).show();
                    		            ele.find(".content-title").html(data[dindex]["title"]);
                    		            ele.find(".content-description").html(data[dindex]["description"]);
                    		    
                                        ele.find(".content-title-input").val(data[dindex]["title"]);
                    		            ele.find(".content-description-input").val(data[dindex]["description"]);
                    		            ele.find(".content-pic-url-input").val(data[dindex]["pic_url"]);
                    		            ele.find(".content-url-input").val(data[dindex]["url"]);
                                    }
                    		        index = Number(index) + data.length;
                                }
                            }
                    	});
                        
                    });
                });
                </script>
EOF;
            $str .= $innerJs;
            // 动态的添加该输入框时脚本不能作用，暂时先重复脚本生成
            //static::$isLoadedImageText = true;
        //}
        return $str;
    }
1176310
public static function form_hidden($name, $value = '')
    {
        if (is_string($name)) {
            return '<input type="hidden" id="'. $name .'" name="'. $name .'" value="'. $value .'" />'."\n";
        } elseif (is_array($name)) {
            $hidden = '';
            foreach ($name as $k => $v) {
                $hidden .= '<input type="hidden" id="'. $k .'" name="'. $k .'" value="'. $v .'" />'."\n";
            }
            return $hidden;
        } else {
            return '';
        }
    }
175406
public final function set_config($name, $value) {
        global $DB;

        $dbparams = array('assignment'=>$this->assignment->get_instance()->id,
                          'subtype'=>$this->get_subtype(),
                          'plugin'=>$this->get_type(),
                          'name'=>$name);
        $current = $DB->get_record('assign_plugin_config', $dbparams, '*', IGNORE_MISSING);

        if ($current) {
            $current->value = $value;
            return $DB->update_record('assign_plugin_config', $current);
        } else {
            $setting = new stdClass();
            $setting->assignment = $this->assignment->get_instance()->id;
            $setting->subtype = $this->get_subtype();
            $setting->plugin = $this->get_type();
            $setting->name = $name;
            $setting->value = $value;

            return $DB->insert_record('assign_plugin_config', $setting) > 0;
        }
    }