1<?php
2/**
3 * Action Component
4 * Add a button in the edit toolbar
5 *
6 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
7 * @author     Nicolas GERARD
8 */
9
10use ComboStrap\Bootstrap;
11use ComboStrap\Identity;
12use ComboStrap\IdentityFormsHelper;
13use ComboStrap\LogUtility;
14use ComboStrap\Snippet;
15use dokuwiki\Form\Form;
16use dokuwiki\Menu\Item\Register;
17
18if (!defined('DOKU_INC')) die();
19require_once(__DIR__ . '/../ComboStrap/PluginUtility.php');
20
21/**
22 *
23 * Register forms depend on the following configuration
24 * https://www.dokuwiki.org/config:autopasswd
25 * If true, there is no password field
26 */
27class action_plugin_combo_registration extends DokuWiki_Action_Plugin
28{
29
30    const CANONICAL = Identity::CANONICAL;
31    const TAG = "register";
32    const FORM_REGISTER_CLASS = "form-" . self::TAG;
33    const CONF_ENABLE_REGISTER_FORM = "enableRegistrationForm";
34
35
36
37
38    function register(Doku_Event_Handler $controller)
39    {
40        /**
41         * To modify the register form and add class
42         *
43         * Deprecated object passed by the event but still in use
44         * https://www.dokuwiki.org/devel:event:html_registerform_output
45         */
46        $controller->register_hook('HTML_REGISTERFORM_OUTPUT', 'BEFORE', $this, 'handle_register_page', array());
47        /**
48         * New Event using the new object
49         * https://www.dokuwiki.org/devel:event:form_register_output
50         */
51        $controller->register_hook('FORM_REGISTER_OUTPUT', 'BEFORE', $this, 'handle_register_page', array());
52
53
54    }
55
56    function handle_register_page(&$event, $param)
57    {
58
59        $form = &$event->data;
60        $class = get_class($form);
61        switch ($class) {
62            case Doku_Form::class:
63                /**
64                 * Old one
65                 * @var Doku_Form $form
66                 */
67                self::updateDokuFormRegistration($form);
68                return;
69            case dokuwiki\Form\Form::class;
70                /**
71                 * New One
72                 * @var Form $form
73                 */
74                self::updateNewFormRegistration($form);
75                return;
76        }
77
78
79    }
80
81    /**
82     * Return the register text and link paragraph
83     * @return string
84     */
85    public static function getRegisterLinkAndParagraph(): string
86    {
87
88
89        $registerHtml = "";
90        if (actionOK('register')) {
91
92            /**
93             * The register class does not allow
94             * registration if your are logged in (What ?)
95             * and send an exception
96             */
97            if (!Identity::isLoggedIn()) {
98                $registerLink = (new Register())->asHtmlLink('', false);
99                global $lang;
100                $tag = self::TAG;
101                $registerText = $lang['reghere'];
102                $registerHtml = <<<EOF
103<p class="$tag">$registerText : $registerLink</p>
104EOF;
105            }
106        }
107        return $registerHtml;
108    }
109
110
111    private static function updateNewFormRegistration(Form &$form)
112    {
113        /**
114         * The Login page is an admin page created via buffer
115         * We print before the forms
116         * to avoid a FOUC
117         */
118        print IdentityFormsHelper::getHtmlStyleTag(self::TAG);
119
120
121        $form->addClass(Identity::FORM_IDENTITY_CLASS . " " . self::FORM_REGISTER_CLASS);
122        /**
123         * Heading
124         */
125        $headerHTML = IdentityFormsHelper::getHeaderHTML($form, self::FORM_REGISTER_CLASS);
126        if ($headerHTML != "") {
127            $form->addHTML($headerHTML, 1);
128        }
129
130        IdentityFormsHelper::deleteFieldSetAndBrFromForm($form);
131        IdentityFormsHelper::toBoostrapInputElements($form, self::FORM_REGISTER_CLASS);
132        IdentityFormsHelper::toBootStrapSubmitButton($form);
133    }
134
135    private static function updateDokuFormRegistration(Doku_Form &$form)
136    {
137        /**
138         * The register page is created via buffer
139         * We print before the forms
140         * to avoid a FOUC
141         */
142        print IdentityFormsHelper::getHtmlStyleTag(self::TAG);
143
144
145        /**
146         * @var Doku_Form $form
147         */
148        $class = &$form->params["class"];
149        IdentityFormsHelper::addIdentityClass($class, self::FORM_REGISTER_CLASS);
150        $newFormContent = [];
151
152        /**
153         * Header (Logo / Title)
154         */
155        $newFormContent[] = IdentityFormsHelper::getHeaderHTML($form, self::FORM_REGISTER_CLASS);
156
157
158        /**
159         * Form Attributes
160         * https://getbootstrap.com/docs/5.0/forms/layout/#horizontal-form
161         */
162        $rowClass = "row";
163        if (Bootstrap::getBootStrapMajorVersion() == Bootstrap::BootStrapFourMajorVersion) {
164            $rowClass .= " form-group";
165        }
166        $firstColWeight = 5;
167        $secondColWeight = 12 - $firstColWeight;
168
169
170        /**
171         * Replace the field
172         *
173         * The password text localized by lang is shared
174         * between the password and the password check field
175         */
176        $passwordText = "Password";
177        foreach ($form->_content as $pos => $field) {
178            if (!is_array($field)) {
179                continue;
180            }
181            $fieldName = $field["name"];
182            if ($fieldName == null) {
183                // this is not an input field
184                if ($field["type"] == "submit") {
185                    /**
186                     * This is important to keep the submit element intact
187                     * for forms integration such as captcha
188                     * The search the submit button to insert before it
189                     */
190                    $classes = "btn btn-primary";
191                    if (isset($field["class"])) {
192                        $field["class"] = $field["class"] . " " . $classes;
193                    } else {
194                        $field["class"] = $classes;
195                    }
196                    $field["tabindex"] = "6";
197                    $newFormContent[] = $field;
198                }
199                continue;
200            }
201            switch ($fieldName) {
202                case "login":
203                    $loginText = $field["_text"];
204                    $loginValue = $field["value"];
205                    $loginHTML = <<<EOF
206<div class="$rowClass">
207    <label for="inputUserName" class="col-sm-$firstColWeight col-form-label">$loginText</label>
208    <div class="col-sm-$secondColWeight">
209      <input type="text" class="form-control" id="inputUserName" placeholder="Username" tabindex="1" name="login" value="$loginValue" required="required">
210    </div>
211</div>
212EOF;
213                    $newFormContent[] = $loginHTML;
214                    break;
215                case "pass":
216                    $passwordText = $field["_text"];
217                    $passwordHtml = <<<EOF
218<div class="$rowClass">
219    <label for="inputPassword" class="col-sm-$firstColWeight col-form-label">$passwordText</label>
220    <div class="col-sm-$secondColWeight">
221      <input type="password" class="form-control" id="inputPassword" placeholder="$passwordText" tabindex="2" name="pass" required="required">
222    </div>
223</div>
224EOF;
225                    $newFormContent[] = $passwordHtml;
226                    break;
227                case "passchk":
228                    $passwordCheckText = $field["_text"];
229                    $passwordCheckHtml = <<<EOF
230<div class="$rowClass">
231    <label for="inputPasswordCheck" class="col-sm-$firstColWeight col-form-label">$passwordCheckText</label>
232    <div class="col-sm-$secondColWeight">
233      <input type="password" class="form-control" id="inputPasswordCheck" placeholder="$passwordText" tabindex="3" name="passchk" required="required">
234    </div>
235</div>
236EOF;
237                    $newFormContent[] = $passwordCheckHtml;
238                    break;
239                case "fullname":
240                    $fullNameText = $field["_text"];
241                    $fullNameValue = $field["value"];
242                    $fullNameHtml = <<<EOF
243<div class="$rowClass">
244    <label for="inputRealName" class="col-sm-$firstColWeight col-form-label">$fullNameText</label>
245    <div class="col-sm-$secondColWeight">
246      <input type="text" class="form-control" id="inputRealName" placeholder="$fullNameText" tabindex="4" name="fullname" value="$fullNameValue" required="required">
247    </div>
248</div>
249EOF;
250                    $newFormContent[] = $fullNameHtml;
251                    break;
252                case "email":
253                    $emailText = $field["_text"];
254                    $emailValue = $field["value"];
255                    $emailHTML = <<<EOF
256<div class="$rowClass">
257    <label for="inputEmail" class="col-sm-$firstColWeight col-form-label">$emailText</label>
258    <div class="col-sm-$secondColWeight">
259      <input type="email" class="form-control" id="inputEmail" placeholder="name@example.com" tabindex="5" name="email" value="$emailValue" required="required">
260    </div>
261</div>
262EOF;
263                    $newFormContent[] = $emailHTML;
264                    break;
265                default:
266                    $tag = self::TAG;
267                    LogUtility::msg("The $tag field name ($fieldName) is unknown", LogUtility::LVL_MSG_ERROR, self::CANONICAL);
268
269            }
270        }
271
272
273        /**
274         * Link in the form footer to login and resend
275         */
276        $loginLinkToHtmlForm = action_plugin_combo_login::getLoginParagraphWithLinkToFormPage();
277        if (!empty($loginHTML)) {
278            $newFormContent[] = $loginLinkToHtmlForm;
279        }
280        $resendHtml = action_plugin_combo_resend::getResendPasswordParagraphWithLinkToFormPage();
281        if (!empty($resendHtml)) {
282            $newFormContent[] = $resendHtml;
283        }
284
285        /**
286         * Update
287         */
288        $form->_content = $newFormContent;
289
290    }
291
292
293}
294
295