Completed
Pull Request — master (#291)
by Richard
08:32
created

renderFormTextDateSelect()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 122
Code Lines 65

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 65
nc 12
nop 1
dl 0
loc 122
rs 8.1463
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * You may not change or alter any portion of this comment or credits
4
 * of supporting developers from this source code or any supporting source code
5
 * which is considered copyrighted (c) material of the original comment or credit authors.
6
 * This program is distributed in the hope that it will be useful,
7
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9
 */
10
11
/**
12
 * Legacy style form renderer
13
 *
14
 * @category  XoopsForm
15
 * @package   XoopsFormRendererBootstrap3
16
 * @author    Richard Griffith <[email protected]>
17
 * @copyright 2017 XOOPS Project (http://xoops.org)
18
 * @license   GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
19
 * @link      http://xoops.org
20
 */
21
class XoopsFormRendererBootstrap3 implements XoopsFormRendererInterface
22
{
23
24
    /**
25
     * Render support for XoopsFormButton
26
     *
27
     * @param XoopsFormButton $element form element
28
     *
29
     * @return string rendered form element
30
     */
31
    public function renderFormButton(XoopsFormButton $element)
32
    {
33
        return "<input type='" . $element->getType() . "' class='btn btn-default' name='"
34
            . $element->getName() . "'  id='" . $element->getName() . "' value='" . $element->getValue()
35
            . "' title='" . $element->getValue() . "'" . $element->getExtra() . ' />';
36
    }
37
38
    /**
39
     * Render support for XoopsFormButtonTray
40
     *
41
     * @param XoopsFormButtonTray $element form element
42
     *
43
     * @return string rendered form element
44
     */
45 View Code Duplication
    public function renderFormButtonTray(XoopsFormButtonTray $element)
46
    {
47
        $ret = '';
48
        if ($element->_showDelete) {
49
            $ret .= '<input type="submit" class="btn btn-danger" name="delete" id="delete" value="' . _DELETE
50
                . '" onclick="this.form.elements.op.value=\'delete\'">&nbsp;';
51
        }
52
        $ret .= '<input type="button" class="btn btn-danger" value="' . _CANCEL
53
             . '" onClick="history.go(-1);return true;" />&nbsp;'
54
             . '<input type="reset" class="btn btn-warning"  name="reset"  id="reset" value="' . _RESET . '" />&nbsp;'
55
             . '<input type="' . $element->getType() . '" class="btn btn-success"  name="' . $element->getName()
56
             . '"  id="' . $element->getName() . '" value="' . $element->getValue() . '"' . $element->getExtra()
57
             . '  />';
58
59
        return $ret;
60
    }
61
62
    /**
63
     * Render support for XoopsFormCheckBox
64
     *
65
     * @param XoopsFormCheckBox $element form element
66
     *
67
     * @return string rendered form element
68
     */
69
    public function renderFormCheckBox(XoopsFormCheckBox $element)
70
    {
71
        $elementName = $element->getName();
72
        $elememtId = $elementName;
73
        $elementOptions = $element->getOptions();
74
        if (count($elementOptions) > 1 && substr($elementName, -2, 2) !== '[]') {
75
            $elementName .= '[]';
76
            $element->setName($elementName);
77
        }
78
79 View Code Duplication
        switch ((int) ($element->columns)) {
80
            case 0:
81
                return $this->renderCheckedInline($element, 'checkbox', $elememtId, $elementName);
82
            case 1:
83
                return $this->renderCheckedOneColumn($element, 'checkbox', $elememtId, $elementName);
84
            default:
85
                return $this->renderCheckedColumnar($element, 'checkbox', $elememtId, $elementName);
86
        }
87
    }
88
89
    protected function renderCheckedInline(XoopsFormElement $element, $type, $elememtId, $elementName)
90
    {
91
        $class = $type . '-inline';
92
        $ret = '';
93
94
        $idSuffix = 0;
95
        $elementOptions   = $element->getOptions();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class XoopsFormElement as the method getOptions() does only exist in the following sub-classes of XoopsFormElement: XoopsFormCheckBox, XoopsFormRadio, XoopsFormRadioYN, XoopsFormSelect, XoopsFormSelectCheckGroup, XoopsFormSelectCountry, XoopsFormSelectGroup, XoopsFormSelectLang, XoopsFormSelectMatchOption, XoopsFormSelectTheme, XoopsFormSelectTimezone. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
96
        foreach ($elementOptions as $value => $name) {
97
            ++$idSuffix;
98
            $ret .= '<label class="' . $class . '">';
99
            $ret .= "<input type='" . $type . "' name='{$elementName}' id='{$elememtId}{$idSuffix}' title='"
100
                . htmlspecialchars(strip_tags($name), ENT_QUOTES) . "' value='" . htmlspecialchars($value, ENT_QUOTES) . "'";
101
102
            if (isset($elementValue) && $value == $elementValue) {
103
                $ret .= ' checked';
104
            }
105
            $ret .= $element->getExtra() . ' />' . $name . $element->getDelimeter();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class XoopsFormElement as the method getDelimeter() does only exist in the following sub-classes of XoopsFormElement: XoopsFormCheckBox, XoopsFormDateTime, XoopsFormElementTray, XoopsFormRadio, XoopsFormRadioYN, XoopsFormSelectCheckGroup, XoopsFormSelectEditor, XoopsFormSelectUser. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
106
            $ret .= '</label>';
107
        }
108
109
        return $ret;
110
    }
111
112 View Code Duplication
    protected function renderCheckedOneColumn(XoopsFormElement $element, $type, $elememtId, $elementName)
113
    {
114
        $class = $type;
115
        $ret = '';
116
117
        $idSuffix = 0;
118
        $elementOptions   = $element->getOptions();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class XoopsFormElement as the method getOptions() does only exist in the following sub-classes of XoopsFormElement: XoopsFormCheckBox, XoopsFormRadio, XoopsFormRadioYN, XoopsFormSelect, XoopsFormSelectCheckGroup, XoopsFormSelectCountry, XoopsFormSelectGroup, XoopsFormSelectLang, XoopsFormSelectMatchOption, XoopsFormSelectTheme, XoopsFormSelectTimezone. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
119
        foreach ($elementOptions as $value => $name) {
120
            ++$idSuffix;
121
            $ret .= '<div class="' . $class . '">';
122
            $ret .= '<label>';
123
            $ret .= "<input type='" . $type . "' name='{$elementName}' id='{$elememtId}{$idSuffix}' title='"
124
                . htmlspecialchars(strip_tags($name), ENT_QUOTES) . "' value='" . htmlspecialchars($value, ENT_QUOTES) . "'";
125
126
            if (isset($elementValue) && $value == $elementValue) {
127
                $ret .= ' checked';
128
            }
129
            $ret .= $element->getExtra() . ' />' . $name . $element->getDelimeter();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class XoopsFormElement as the method getDelimeter() does only exist in the following sub-classes of XoopsFormElement: XoopsFormCheckBox, XoopsFormDateTime, XoopsFormElementTray, XoopsFormRadio, XoopsFormRadioYN, XoopsFormSelectCheckGroup, XoopsFormSelectEditor, XoopsFormSelectUser. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
130
            $ret .= '</label>';
131
            $ret .= '</div>';
132
        }
133
134
        return $ret;
135
    }
136
137 View Code Duplication
    protected function renderCheckedColumnar(XoopsFormElement $element, $type, $elememtId, $elementName)
138
    {
139
        $class = $type;
140
        $ret = '';
141
142
        $idSuffix = 0;
143
        $elementOptions   = $element->getOptions();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class XoopsFormElement as the method getOptions() does only exist in the following sub-classes of XoopsFormElement: XoopsFormCheckBox, XoopsFormRadio, XoopsFormRadioYN, XoopsFormSelect, XoopsFormSelectCheckGroup, XoopsFormSelectCountry, XoopsFormSelectGroup, XoopsFormSelectLang, XoopsFormSelectMatchOption, XoopsFormSelectTheme, XoopsFormSelectTimezone. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
144
        foreach ($elementOptions as $value => $name) {
145
            ++$idSuffix;
146
            $ret .= '<div class="' . $class . ' col-md-2">';
147
            $ret .= '<label>';
148
            $ret .= "<input type='" . $type . "' name='{$elementName}' id='{$elememtId}{$idSuffix}' title='"
149
                . htmlspecialchars(strip_tags($name), ENT_QUOTES) . "' value='" . htmlspecialchars($value, ENT_QUOTES) . "'";
150
151
            if (isset($elementValue) && $value == $elementValue) {
152
                $ret .= ' checked';
153
            }
154
            $ret .= $element->getExtra() . ' />' . $name . $element->getDelimeter();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class XoopsFormElement as the method getDelimeter() does only exist in the following sub-classes of XoopsFormElement: XoopsFormCheckBox, XoopsFormDateTime, XoopsFormElementTray, XoopsFormRadio, XoopsFormRadioYN, XoopsFormSelectCheckGroup, XoopsFormSelectEditor, XoopsFormSelectUser. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
155
            $ret .= '</label>';
156
            $ret .= '</div>';
157
        }
158
159
        return $ret;
160
    }
161
    /**
162
     * Render support for XoopsFormColorPicker
163
     *
164
     * @param XoopsFormColorPicker $element form element
165
     *
166
     * @return string rendered form element
167
     */
168
    public function renderFormColorPicker(XoopsFormColorPicker $element)
169
    {
170 View Code Duplication
        if (isset($GLOBALS['xoTheme'])) {
171
            $GLOBALS['xoTheme']->addScript('include/spectrum.js');
172
            $GLOBALS['xoTheme']->addStylesheet('include/spectrum.css');
173
        } else {
174
            echo '<script type="text/javascript" src="' . XOOPS_URL . '/include/spectrum.js"></script>';
175
            echo '<link rel="stylesheet" type="text/css" href="' . XOOPS_URL . '/include/spectrum.css">';
176
        }
177
        return '<input class="form-control" style="width: 25%;" type="color" name="' . $element->getName()
178
            . "' title='" . $element->getTitle() . "' id='" . $element->getName()
179
            . '" size="7" maxlength="7" value="' . $element->getValue() . '"' . $element->getExtra() . ' />';
180
    }
181
182
    /**
183
     * Render support for XoopsFormDhtmlTextArea
184
     *
185
     * @param XoopsFormDhtmlTextArea $element form element
186
     *
187
     * @return string rendered form element
188
     */
189
    public function renderFormDhtmlTextArea(XoopsFormDhtmlTextArea $element)
190
    {
191
        static $js_loaded;
192
193
        xoops_loadLanguage('formdhtmltextarea');
194
        $ret = '';
195
        // actions
196
        $ret .= $this->renderFormDhtmlTAXoopsCode($element) . "<br>\n";
197
        // fonts
198
        $ret .= $this->renderFormDhtmlTATypography($element);
199
        // length checker
200
201
        $ret .= "<br>\n";
202
        // the textarea box
203
        $ret .= "<textarea class='form-control' id='" . $element->getName() . "' name='" . $element->getName()
204
            . "' title='" . $element->getTitle() . "' onselect=\"xoopsSavePosition('" . $element->getName()
205
            . "');\" onclick=\"xoopsSavePosition('" . $element->getName()
206
            . "');\" onkeyup=\"xoopsSavePosition('" . $element->getName() . "');\" cols='"
207
            . $element->getCols() . "' rows='" . $element->getRows() . "'" . $element->getExtra()
208
            . '>' . $element->getValue() . "</textarea>\n";
209
210 View Code Duplication
        if (empty($element->skipPreview)) {
211
            if (empty($GLOBALS['xoTheme'])) {
212
                $element->js .= implode('', file(XOOPS_ROOT_PATH . '/class/textsanitizer/image/image.js'));
213
            } else {
214
                $GLOBALS['xoTheme']->addScript('/class/textsanitizer/image/image.js', array('type' => 'text/javascript'));
215
            }
216
            $button = "<button type='button' class='btn btn-primary' onclick=\"form_instantPreview('" . XOOPS_URL . "', '" . $element->getName() . "','" . XOOPS_URL . "/images', " . (int)$element->doHtml . ", '" . $GLOBALS['xoopsSecurity']->createToken() . "')\" title='" . _PREVIEW . "'>" . _PREVIEW . "</button>";
217
218
            $ret .= '<br>' . "<div id='" . $element->getName() . "_hidden' style='display: block;'> " . '   <fieldset>' . '       <legend>' . $button . '</legend>' . "       <div id='" . $element->getName() . "_hidden_data'>" . _XOOPS_FORM_PREVIEW_CONTENT . '</div>' . '   </fieldset>' . '</div>';
219
        }
220
        // Load javascript
221 View Code Duplication
        if (empty($js_loaded)) {
222
            $javascript = ($element->js ? '<script type="text/javascript">' . $element->js . '</script>' : '') . '<script type="text/javascript" src="' . XOOPS_URL . '/include/formdhtmltextarea.js"></script>';
223
            $ret        = $javascript . $ret;
224
            $js_loaded  = true;
225
        }
226
227
        return $ret;
228
    }
229
230
    /**
231
     * Render xoopscode buttons for editor, include calling text sanitizer extensions
232
     *
233
     * @param XoopsFormDhtmlTextArea $element form element
234
     *
235
     * @return string rendered buttons for xoopscode assistance
236
     */
237 View Code Duplication
    protected function renderFormDhtmlTAXoopsCode(XoopsFormDhtmlTextArea $element)
238
    {
239
        $textarea_id = $element->getName();
240
        $code = '';
241
        $code .= "<div class='row'><div class='col-md-12'>";
242
        $code .= "<button type='button' class='btn btn-default' onclick='xoopsCodeUrl(\"{$textarea_id}\", \"" . htmlspecialchars(_ENTERURL, ENT_QUOTES) . "\", \"" . htmlspecialchars(_ENTERWEBTITLE, ENT_QUOTES) . "\");' onmouseover='style.cursor=\"hand\"' title='" . _XOOPS_FORM_ALT_URL . "'><span class='fa fa-fw fa-link' aria-hidden='true'></span></button>";
243
        $code .= "<button type='button' class='btn btn-default' onclick='xoopsCodeEmail(\"{$textarea_id}\", \"" . htmlspecialchars(_ENTEREMAIL, ENT_QUOTES) . "\", \"" . htmlspecialchars(_ENTERWEBTITLE, ENT_QUOTES) . "\");' onmouseover='style.cursor=\"hand\"' title='" . _XOOPS_FORM_ALT_EMAIL . "'><span class='fa fa-fw fa-envelope-o' aria-hidden='true'></span></button>";
244
        $code .= "<button type='button' class='btn btn-default' onclick='xoopsCodeImg(\"{$textarea_id}\", \"" . htmlspecialchars(_ENTERIMGURL, ENT_QUOTES) . "\", \"" . htmlspecialchars(_ENTERIMGPOS, ENT_QUOTES) . "\", \"" . htmlspecialchars(_IMGPOSRORL, ENT_QUOTES) . "\", \"" . htmlspecialchars(_ERRORIMGPOS, ENT_QUOTES) . "\", \"" . htmlspecialchars(_XOOPS_FORM_ALT_ENTERWIDTH, ENT_QUOTES) . "\");' onmouseover='style.cursor=\"hand\"' title='" . _XOOPS_FORM_ALT_IMG . "'><span class='fa fa-fw fa-file-image-o' aria-hidden='true'></span></button>";
245
        $code .= "<button type='button' class='btn btn-default' onclick='openWithSelfMain(\"" . XOOPS_URL . "/imagemanager.php?target={$textarea_id}\",\"imgmanager\",400,430);' onmouseover='style.cursor=\"hand\"' title='" . _XOOPS_FORM_ALT_IMAGE . "'><span class='fa fa-file-image-o' aria-hidden='true'></span><small> Manager</small></button>";
246
        $code .= "<button type='button' class='btn btn-default' onclick='openWithSelfMain(\"" . XOOPS_URL . "/misc.php?action=showpopups&amp;type=smilies&amp;target={$textarea_id}\",\"smilies\",300,475);' onmouseover='style.cursor=\"hand\"' title='" . _XOOPS_FORM_ALT_SMILEY . "'><span class='fa fa-fw fa-smile-o' aria-hidden='true'></span></button>";
247
248
        $myts        = MyTextSanitizer::getInstance();
249
250
        $extensions = array_filter($myts->config['extensions']);
251
        foreach (array_keys($extensions) as $key) {
252
            $extension = $myts->loadExtension($key);
253
            @list($encode, $js) = $extension->encode($textarea_id);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
254
            if (empty($encode)) {
255
                continue;
256
            }
257
            $code .= $encode;
258
            if (!empty($js)) {
259
                $element->js .= $js;
260
            }
261
        }
262
        $code .= "<button type='button' class='btn btn-default' onclick='xoopsCodeCode(\"{$textarea_id}\", \"" . htmlspecialchars(_ENTERCODE, ENT_QUOTES) . "\");' onmouseover='style.cursor=\"hand\"' title='" . _XOOPS_FORM_ALT_CODE . "'><span class='fa fa-fw fa-code' aria-hidden='true'></span></button>";
263
        $code .= "<button type='button' class='btn btn-default' onclick='xoopsCodeQuote(\"{$textarea_id}\", \"" . htmlspecialchars(_ENTERQUOTE, ENT_QUOTES) . "\");' onmouseover='style.cursor=\"hand\"' title='" . _XOOPS_FORM_ALT_QUOTE . "'><span class='fa fa-fw fa-quote-right' aria-hidden='true'></span></button>";
264
        $code .= "</div></div>";
265
266
        $xoopsPreload = XoopsPreload::getInstance();
267
        $xoopsPreload->triggerEvent('core.class.xoopsform.formdhtmltextarea.codeicon', array(&$code));
268
269
        return $code;
270
    }
271
272
    /**
273
     * Render typography controls for editor (font, size, color)
274
     *
275
     * @param XoopsFormDhtmlTextArea $element form element
276
     *
277
     * @return string rendered typography controls
278
     */
279
    protected function renderFormDhtmlTATypography(XoopsFormDhtmlTextArea $element)
280
    {
281
        $textarea_id = $element->getName();
282
        $hiddentext  = $element->_hiddenText;
283
284
        $fontarray = !empty($GLOBALS['formtextdhtml_fonts']) ? $GLOBALS['formtextdhtml_fonts'] : array(
285
            'Arial',
286
            'Courier',
287
            'Georgia',
288
            'Helvetica',
289
            'Impact',
290
            'Verdana',
291
            'Haettenschweiler');
292
293
        $colorArray = array(
294
            'Black'  => '000000',
295
            'Blue'   => '38AAFF',
296
            'Brown'  => '987857',
297
            'Green'  => '79D271',
298
            'Grey'   => '888888',
299
            'Orange' => 'FFA700',
300
            'Paper'  => 'E0E0E0',
301
            'Purple' => '363E98',
302
            'Red'    => 'FF211E',
303
            'White'  => 'FEFEFE',
304
            'Yellow' => 'FFD628',
305
        );
306
307
        $fontStr = '<div class="row"><div class="col-md-12"><div class="btn-group" role="toolbar">';
308
        $fontStr .= '<div class="btn-group">'
309
            . '<button type="button" class="btn btn-default dropdown-toggle" title="'. _SIZE .'"'
310
            . ' data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">'
311
            . '<span class = "glyphicon glyphicon-text-height"></span><span class="caret"></span></button>'
312
            . '<ul class="dropdown-menu">';
313
            //. _SIZE . '&nbsp;&nbsp;<span class="caret"></span></button><ul class="dropdown-menu">';
314 View Code Duplication
        foreach ($GLOBALS['formtextdhtml_sizes'] as $value => $name) {
315
            $fontStr .= '<li><a href="javascript:xoopsSetElementAttribute(\'size\', \'' . $value . '\', \''
316
                . $textarea_id . '\', \'' . $hiddentext . '\');">' . $name . '</a></li>';
317
        }
318
        $fontStr .= '</ul></div>';
319
320
        $fontStr .= '<div class="btn-group">'
321
            . '<button type="button" class="btn btn-default dropdown-toggle" title="'. _FONT .'"'
322
            . ' data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">'
323
            . '<span class = "glyphicon glyphicon-font"></span><span class="caret"></span></button>'
324
            . '<ul class="dropdown-menu">';
325
            //. _FONT . '&nbsp;&nbsp;<span class="caret"></span></button><ul class="dropdown-menu">';
326 View Code Duplication
        foreach ($fontarray as $font) {
327
            $fontStr .= '<li><a href="javascript:xoopsSetElementAttribute(\'font\', \'' . $font . '\', \''
328
                . $textarea_id . '\', \'' . $hiddentext . '\');">' . $font . '</a></li>';
329
        }
330
        $fontStr .= '</ul></div>';
331
332
        $fontStr .= '<div class="btn-group">'
333
            . '<button type="button" class="btn btn-default dropdown-toggle" title="'. _COLOR .'"'
334
            . ' data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">'
335
            . '<span class = "glyphicon glyphicon-text-color"></span><span class="caret"></span></button>'
336
            . '<ul class="dropdown-menu">';
337
            //. _COLOR . '&nbsp;&nbsp;<span class="caret"></span></button><ul class="dropdown-menu">';
338
        foreach ($colorArray as $color => $hex) {
339
            $fontStr .= '<li><a href="javascript:xoopsSetElementAttribute(\'color\', \'' . $hex . '\', \''
340
                . $textarea_id . '\', \'' . $hiddentext . '\');">'
341
                . '<span style="color:#' . $hex . ';">' . $color .'</span></a></li>';
342
        }
343
        $fontStr .= '</ul></div>';
344
        $fontStr .= '</div>';
345
346
        //$styleStr = "<div class='row'><div class='col-md-12'>";
347
        $styleStr  = "<div class='btn-group' role='group'>";
348
        $styleStr .= "<button type='button' class='btn btn-default' onclick='xoopsMakeBold(\"{$hiddentext}\", \"{$textarea_id}\");' title='" . _XOOPS_FORM_ALT_BOLD . "' aria-label='Left Align'><span class='fa fa-bold' aria-hidden='true'></span></button>";
349
        $styleStr .= "<button type='button' class='btn btn-default' onclick='xoopsMakeItalic(\"{$hiddentext}\", \"{$textarea_id}\");' title='" . _XOOPS_FORM_ALT_ITALIC . "' aria-label='Left Align'><span class='fa fa-italic' aria-hidden='true'></span></button>";
350
        $styleStr .= "<button type='button' class='btn btn-default' onclick='xoopsMakeUnderline(\"{$hiddentext}\", \"{$textarea_id}\");' title='" . _XOOPS_FORM_ALT_UNDERLINE . "' aria-label='Left Align'>" . '<span class="fa fa-underline"></span></button>';
351
        $styleStr .= "<button type='button' class='btn btn-default' onclick='xoopsMakeLineThrough(\"{$hiddentext}\", \"{$textarea_id}\");' title='" . _XOOPS_FORM_ALT_LINETHROUGH . "' aria-label='Left Align'>" . '<span class="fa fa-strikethrough"></span></button>';
352
        $styleStr .= "</div>";
353
354
        $alignStr = "<div class='btn-group' role='group'>";
355
        $alignStr .= "<button type='button' class='btn btn-default' onclick='xoopsMakeLeft(\"{$hiddentext}\", \"{$textarea_id}\");' title='" . _XOOPS_FORM_ALT_LEFT . "' aria-label='Left Align'><span class='fa fa-align-left' aria-hidden='true'></span></button>";
356
        $alignStr .= "<button type='button' class='btn btn-default' onclick='xoopsMakeCenter(\"{$hiddentext}\", \"{$textarea_id}\");' title='" . _XOOPS_FORM_ALT_CENTER . "' aria-label='Left Align'><span class='fa fa-align-center' aria-hidden='true'></span></button>";
357
        $alignStr .= "<button type='button' class='btn btn-default' onclick='xoopsMakeRight(\"{$hiddentext}\", \"{$textarea_id}\");' title='" . _XOOPS_FORM_ALT_RIGHT . "' aria-label='Left Align'><span class='fa fa-align-right' aria-hidden='true'></span></button>";
358
        $alignStr .= "</div>";
359
360
        $fontStr .= "&nbsp;{$styleStr}&nbsp;{$alignStr}&nbsp;\n";
361
362
        $fontStr .= "<button type='button' class='btn btn-default' onclick=\"XoopsCheckLength('"
363
            . $element->getName() . "', '" . @$element->configs['maxlength'] . "', '"
0 ignored issues
show
Bug introduced by
The property configs does not seem to exist in XoopsFormDhtmlTextArea.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
364
            . _XOOPS_FORM_ALT_LENGTH . "', '" . _XOOPS_FORM_ALT_LENGTH_MAX . "');\" title='"
365
            . _XOOPS_FORM_ALT_CHECKLENGTH . "'><span class='fa fa-check-square-o' aria-hidden='true'></span></button>";
366
        $fontStr .= "</div></div>";
367
368
        return $fontStr;
369
    }
370
371
    /**
372
     * Render support for XoopsFormElementTray
373
     *
374
     * @param XoopsFormElementTray $element form element
375
     *
376
     * @return string rendered form element
377
     */
378 View Code Duplication
    public function renderFormElementTray(XoopsFormElementTray $element)
379
    {
380
        $count = 0;
381
        $ret = '<div class="form-inline">';
382
        foreach ($element->getElements() as $ele) {
383
            if ($count > 0) {
384
                $ret .= $element->getDelimeter();
385
            }
386
            if ($ele->getCaption() != '') {
387
                $ret .= $ele->getCaption() . '&nbsp;';
388
            }
389
            $ret .= $ele->render() . NWLINE;
390
            if (!$ele->isHidden()) {
391
                ++$count;
392
            }
393
        }
394
        /*
395
        if (substr_count($ret, '<div class="form-group form-inline">') > 0) {
396
            $ret = str_replace('<div class="form-group form-inline">', '', $ret);
397
            $ret = str_replace('</div>', '', $ret);
398
        }
399
        if (substr_count($ret, '<div class="checkbox-inline">') > 0) {
400
            $ret = str_replace('<div class="checkbox-inline">', '', $ret);
401
        }
402
        */
403
        $ret .= '</div>';
404
        return $ret;
405
    }
406
407
    /**
408
     * Render support for XoopsFormFile
409
     *
410
     * @param XoopsFormFile $element form element
411
     *
412
     * @return string rendered form element
413
     */
414 View Code Duplication
    public function renderFormFile(XoopsFormFile $element)
415
    {
416
        return '<input class="form-control-static" type="file" name="' . $element->getName()
417
            . '" id="' . $element->getName()
418
            . '" title="' . $element->getTitle() . '" ' . $element->getExtra() . ' />'
419
            . '<input type="hidden" name="MAX_FILE_SIZE" value="' . $element->getMaxFileSize() . '" />'
420
            . '<input type="hidden" name="xoops_upload_file[]" id="xoops_upload_file[]" value="'
421
            . $element->getName() . '" />';
422
423
    }
424
425
    /**
426
     * Render support for XoopsFormLabel
427
     *
428
     * @param XoopsFormLabel $element form element
429
     *
430
     * @return string rendered form element
431
     */
432
    public function renderFormLabel(XoopsFormLabel $element)
433
    {
434
        return '<div class="form-control-static">' . $element->getValue() . '</div>';
435
    }
436
437
    /**
438
     * Render support for XoopsFormPassword
439
     *
440
     * @param XoopsFormPassword $element form element
441
     *
442
     * @return string rendered form element
443
     */
444
    public function renderFormPassword(XoopsFormPassword $element)
445
    {
446
        return '<input class="form-control" type="password" name="'
447
            . $element->getName() . '" id="' . $element->getName() . '" size="' . $element->getSize()
448
            . '" maxlength="' . $element->getMaxlength() . '" value="' . $element->getValue() . '"'
449
            . $element->getExtra() . ' ' . ($element->autoComplete ? '' : 'autocomplete="off" ') . '/>';
450
    }
451
452
    /**
453
     * Render support for XoopsFormRadio
454
     *
455
     * @param XoopsFormRadio $element form element
456
     *
457
     * @return string rendered form element
458
     */
459
    public function renderFormRadio(XoopsFormRadio $element)
460
    {
461
462
        $elementName = $element->getName();
463
        $elememtId = $elementName;
464
465 View Code Duplication
        switch ((int) ($element->columns)) {
466
            case 0:
467
                return $this->renderCheckedInline($element, 'radio', $elememtId, $elementName);
468
            case 1:
469
                return $this->renderCheckedOneColumn($element, 'radio', $elememtId, $elementName);
470
            default:
471
                return $this->renderCheckedColumnar($element, 'radio', $elememtId, $elementName);
472
        }
473
    }
474
475
    /**
476
     * Render support for XoopsFormSelect
477
     *
478
     * @param XoopsFormSelect $element form element
479
     *
480
     * @return string rendered form element
481
     */
482 View Code Duplication
    public function renderFormSelect(XoopsFormSelect $element)
483
    {
484
        $ele_name    = $element->getName();
485
        $ele_title   = $element->getTitle();
486
        $ele_value   = $element->getValue();
487
        $ele_options = $element->getOptions();
488
        $ret = '<select class="form-control" size="'
489
            . $element->getSize() . '"' . $element->getExtra();
490
        if ($element->isMultiple() != false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison !== instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
491
            $ret .= ' name="' . $ele_name . '[]" id="' . $ele_name . '" title="' . $ele_title
492
                . '" multiple="multiple">';
493
        } else {
494
            $ret .= ' name="' . $ele_name . '" id="' . $ele_name . '" title="' . $ele_title . '">';
495
        }
496
        foreach ($ele_options as $value => $name) {
497
            $ret .= '<option value="' . htmlspecialchars($value, ENT_QUOTES) . '"';
498
            if (count($ele_value) > 0 && in_array($value, $ele_value)) {
499
                $ret .= ' selected';
500
            }
501
            $ret .= '>' . $name . '</option>';
502
        }
503
        $ret .= '</select>';
504
505
        return $ret;
506
    }
507
    /**
508
     * Render support for XoopsFormText
509
     *
510
     * @param XoopsFormText $element form element
511
     *
512
     * @return string rendered form element
513
     */
514 View Code Duplication
    public function renderFormText(XoopsFormText $element)
515
    {
516
        return "<input class='form-control' type='text' name='"
517
            . $element->getName() . "' title='" . $element->getTitle() . "' id='" . $element->getName()
518
            . "' size='" . $element->getSize() . "' maxlength='" . $element->getMaxlength()
519
            . "' value='" . $element->getValue() . "'" . $element->getExtra() . ' />';
520
    }
521
522
    /**
523
     * Render support for XoopsFormTextArea
524
     *
525
     * @param XoopsFormTextArea $element form element
526
     *
527
     * @return string rendered form element
528
     */
529 View Code Duplication
    public function renderFormTextArea(XoopsFormTextArea $element)
530
    {
531
        return "<textarea class='form-control' name='"
532
            . $element->getName() . "' id='" . $element->getName() . "'  title='" . $element->getTitle()
533
            . "' rows='" . $element->getRows() . "' cols='" . $element->getCols() . "'"
534
            . $element->getExtra() . '>' . $element->getValue() . '</textarea>';
535
    }
536
537
    /**
538
     * Render support for XoopsFormTextDateSelect
539
     *
540
     * @param XoopsFormTextDateSelect $element form element
541
     *
542
     * @return string rendered form element
543
     */
544
    public function renderFormTextDateSelect(XoopsFormTextDateSelect $element)
545
    {
546
        static $included = false;
547
        if (file_exists(XOOPS_ROOT_PATH . '/language/' . $GLOBALS['xoopsConfig']['language'] . '/calendar.php')) {
548
            include_once XOOPS_ROOT_PATH . '/language/' . $GLOBALS['xoopsConfig']['language'] . '/calendar.php';
549
        } else {
550
            include_once XOOPS_ROOT_PATH . '/language/english/calendar.php';
551
        }
552
553
        $ele_name  = $element->getName();
554
        $ele_value = $element->getValue(false);
555
        if (is_string($ele_value)) {
556
            $display_value = $ele_value;
557
            $ele_value     = time();
558
        } else {
559
            $display_value = date(_SHORTDATESTRING, $ele_value);
560
        }
561
562
        $jstime = formatTimestamp($ele_value, _SHORTDATESTRING);
563
        if (isset($GLOBALS['xoTheme']) && is_object($GLOBALS['xoTheme'])) {
564
            $GLOBALS['xoTheme']->addScript('include/calendar.js');
565
            $GLOBALS['xoTheme']->addStylesheet('include/calendar-blue.css');
566
            if (!$included) {
567
                $included = true;
568
                $GLOBALS['xoTheme']->addScript('', '', '
569
                    var calendar = null;
570
571
                    function selected(cal, date)
572
                    {
573
                    cal.sel.value = date;
574
                    }
575
576
                    function closeHandler(cal)
577
                    {
578
                    cal.hide();
579
                    Calendar.removeEvent(document, "mousedown", checkCalendar);
580
                    }
581
582
                    function checkCalendar(ev)
583
                    {
584
                    var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev);
585
                    for (; el != null; el = el.parentNode)
586
                    if (el == calendar.element || el.tagName == "A") break;
587
                    if (el == null) {
588
                    calendar.callCloseHandler(); Calendar.stopEvent(ev);
589
                    }
590
                    }
591
                    function showCalendar(id)
592
                    {
593
                    var el = xoopsGetElementById(id);
594
                    if (calendar != null) {
595
                    calendar.hide();
596
                    } else {
597
                    var cal = new Calendar(true, "' . $jstime . '", selected, closeHandler);
598
                    calendar = cal;
599
                    cal.setRange(1900, 2100);
600
                    calendar.create();
601
                    }
602
                    calendar.sel = el;
603
                    calendar.parseDate(el.value);
604
                    calendar.showAtElement(el);
605
                    Calendar.addEvent(document, "mousedown", checkCalendar);
606
607
                    return false;
608
                    }
609
610
                    Calendar._DN = new Array
611
                    ("' . _CAL_SUNDAY . '",
612
                    "' . _CAL_MONDAY . '",
613
                    "' . _CAL_TUESDAY . '",
614
                    "' . _CAL_WEDNESDAY . '",
615
                    "' . _CAL_THURSDAY . '",
616
                    "' . _CAL_FRIDAY . '",
617
                    "' . _CAL_SATURDAY . '",
618
                    "' . _CAL_SUNDAY . '");
619
                    Calendar._MN = new Array
620
                    ("' . _CAL_JANUARY . '",
621
                    "' . _CAL_FEBRUARY . '",
622
                    "' . _CAL_MARCH . '",
623
                    "' . _CAL_APRIL . '",
624
                    "' . _CAL_MAY . '",
625
                    "' . _CAL_JUNE . '",
626
                    "' . _CAL_JULY . '",
627
                    "' . _CAL_AUGUST . '",
628
                    "' . _CAL_SEPTEMBER . '",
629
                    "' . _CAL_OCTOBER . '",
630
                    "' . _CAL_NOVEMBER . '",
631
                    "' . _CAL_DECEMBER . '");
632
633
                    Calendar._TT = {};
634
                    Calendar._TT["TOGGLE"] = "' . _CAL_TGL1STD . '";
635
                    Calendar._TT["PREV_YEAR"] = "' . _CAL_PREVYR . '";
636
                    Calendar._TT["PREV_MONTH"] = "' . _CAL_PREVMNTH . '";
637
                    Calendar._TT["GO_TODAY"] = "' . _CAL_GOTODAY . '";
638
                    Calendar._TT["NEXT_MONTH"] = "' . _CAL_NXTMNTH . '";
639
                    Calendar._TT["NEXT_YEAR"] = "' . _CAL_NEXTYR . '";
640
                    Calendar._TT["SEL_DATE"] = "' . _CAL_SELDATE . '";
641
                    Calendar._TT["DRAG_TO_MOVE"] = "' . _CAL_DRAGMOVE . '";
642
                    Calendar._TT["PART_TODAY"] = "(' . _CAL_TODAY . ')";
643
                    Calendar._TT["MON_FIRST"] = "' . _CAL_DISPM1ST . '";
644
                    Calendar._TT["SUN_FIRST"] = "' . _CAL_DISPS1ST . '";
645
                    Calendar._TT["CLOSE"] = "' . _CLOSE . '";
646
                    Calendar._TT["TODAY"] = "' . _CAL_TODAY . '";
647
648
                    // date formats
649
                    Calendar._TT["DEF_DATE_FORMAT"] = "' . _SHORTDATESTRING . '";
650
                    Calendar._TT["TT_DATE_FORMAT"] = "' . _SHORTDATESTRING . '";
651
652
                    Calendar._TT["WK"] = "";
653
                ');
654
            }
655
        }
656
        return '<div class="input-group">'
657
            . '<input class="form-control" type="text" name="' . $ele_name . '" id="' . $ele_name
658
            . '" size="' . $element->getSize() . '" maxlength="' . $element->getMaxlength()
659
            . '" value="' . $display_value . '"' . $element->getExtra() . ' />'
660
            . '<span class="input-group-btn"><button class="btn btn-default" type="button"'
661
            . ' onclick="return showCalendar(\'' . $ele_name . '\');">'
662
            . '<span class="fa fa-calendar" aria-hidden="true"></span></button>'
663
            . '</span>'
664
            . '</div>';
665
    }
666
667
    /**
668
     * Render support for XoopsThemeForm
669
     *
670
     * @param XoopsThemeForm $form form to render
671
     *
672
     * @return string rendered form
673
     */
674
    public function renderThemeForm(XoopsThemeForm $form)
675
    {
676
        $ele_name = $form->getName();
677
678
        $ret = '<div>';
679
        $ret .= '<form class="form-horizontal" name="' . $ele_name . '" id="' . $ele_name . '" action="'
680
            . $form->getAction() . '" method="' . $form->getMethod()
681
            . '" onsubmit="return xoopsFormValidate_' . $ele_name . '();"' . $form->getExtra() . '>'
682
            . '<h3>' . $form->getTitle() . '</h3>';
683
        $hidden   = '';
684
685
        foreach ($form->getElements() as $ele) {
686
            if (!is_object($ele)) { // see $form->addBreak()
687
                $ret .= $ele;
688
                continue;
689
            }
690
            if ($ele->isHidden()) {
691
                $hidden .= $ele->render();
692
                continue;
693
            }
694
695
            $ret .= '<div class="form-group">';
696
            if (($caption = $ele->getCaption()) != '') {
697
                $ret .= '<label for="' . $ele->getName() . '" class="col-md-2 control-label">'
698
                    . $ele->getCaption()
699
                    . ($ele->isRequired() ? '<span class="caption-required">*</span>' : '')
700
                    . '</label>';
701
            } else {
702
                $ret .= '<div class="col-md-2"> </div>';
703
            }
704
            $ret .= '<div class="col-md-10">';
705
            $ret .= $ele->render();
706
            if (($desc = $ele->getDescription()) != '') {
707
                $ret .= '<p class="text-muted">' . $desc . '</p>';
708
            }
709
            $ret .= '</div>';
710
            $ret .= '</div>';
711
        }
712
        $ret .= $hidden;
713
        $ret .= '</form></div>';
714
        $ret .= $form->renderValidationJS(true);
715
716
        return $ret;
717
    }
718
719
    /**
720
     * Support for themed addBreak
721
     *
722
     * @param XoopsThemeForm $form
723
     * @param string         $extra pre-rendered content for break row
724
     * @param string         $class class for row
725
     *
726
     * @return void
727
     */
728
    public function addThemeFormBreak(XoopsThemeForm $form, $extra, $class)
729
    {
730
        $class = ($class != '') ? preg_replace('/[^A-Za-z0-9\s\s_-]/i', '', $class) : '';
731
        $form->addElement('<div class="col-sm-12 ' . $class .'">'. $extra . '</div>');
732
    }
733
}
734