1<?php
2
3use ComboStrap\Bootstrap;
4use ComboStrap\Identity;
5use ComboStrap\LogUtility;
6use ComboStrap\PluginUtility;
7
8if (!defined('DOKU_INC')) die();
9require_once(__DIR__ . '/../ComboStrap/PluginUtility.php');
10
11/**
12 *
13 */
14class action_plugin_combo_profile extends DokuWiki_Action_Plugin
15{
16
17    const CANONICAL = Identity::CANONICAL;
18    const TAG_UPDATE = "profile-update"; // form 1
19    const TAG_DELETE = "profile-delete"; // form 2
20    const FORM_PROFILE_UPDATE_CLASS = "form-" . self::TAG_UPDATE;
21    const FORM_PROFILE_DELETE_CLASS = "form-" . self::TAG_DELETE;
22    const CONF_ENABLE_PROFILE_UPDATE_FORM = "enableProfileUpdateForm";
23    const CONF_ENABLE_PROFILE_DELETE_FORM = "enableProfileDeleteForm";
24
25
26    function register(Doku_Event_Handler $controller)
27    {
28        /**
29         * To modify the profile update form and add class
30         *
31         * Deprecated object passed by the event but still in use
32         * https://www.dokuwiki.org/devel:event:html_updateprofileform_output
33         *
34         * Event using the new object but not found anywhere
35         * https://www.dokuwiki.org/devel:event:form_updateprofile_output
36         */
37        if (PluginUtility::getConfValue(self::CONF_ENABLE_PROFILE_UPDATE_FORM, 1)) {
38            $controller->register_hook('HTML_UPDATEPROFILEFORM_OUTPUT', 'BEFORE', $this, 'handle_profile_update', array());
39        }
40
41        /**
42         * To modify the register form and add class
43         *
44         * Deprecated object passed by the event but still in use
45         * https://www.dokuwiki.org/devel:event:html_profiledeleteform_output
46         *
47         * Event using the new object but not found anywhere
48         * https://www.dokuwiki.org/devel:event:form_profiledelete_output
49         */
50        if (PluginUtility::getConfValue(self::CONF_ENABLE_PROFILE_DELETE_FORM, 1)) {
51            $controller->register_hook('HTML_PROFILEDELETEFORM_OUTPUT', 'BEFORE', $this, 'handle_profile_delete', array());
52        }
53
54
55    }
56
57    function handle_profile_update(&$event, $param)
58    {
59
60        /**
61         * The profile page is created via buffer
62         * We print before the forms to avoid a FOUC
63         */
64        print Identity::getHtmlStyleTag(self::TAG_UPDATE);
65
66        /**
67         * @var Doku_Form $form
68         */
69        $form = &$event->data;
70        $class = &$form->params["class"];
71        Identity::addIdentityClass($class, self::FORM_PROFILE_UPDATE_CLASS);
72        $newFormContent = [];
73
74        /**
75         * Header (Logo / Title)
76         */
77        $newFormContent[] = Identity::getHeaderHTML($form, self::FORM_PROFILE_UPDATE_CLASS);
78
79
80        /**
81         * Form Attributes
82         * https://getbootstrap.com/docs/5.0/forms/layout/#horizontal-form
83         */
84        $rowClass = "row";
85        if (Bootstrap::getBootStrapMajorVersion() == Bootstrap::BootStrapFourMajorVersion) {
86            $rowClass .= " form-group";
87        }
88        $firstColWeight = 5;
89        $secondColWeight = 12 - $firstColWeight;
90
91
92        /**
93         * Replace the field
94         *
95         * The password text localized by lang is shared
96         * between the password and the password check field
97         */
98        $passwordText = "Password";
99        foreach ($form->_content as $field) {
100            if (!is_array($field)) {
101                continue;
102            }
103            $fieldName = $field["name"];
104            if ($fieldName == null) {
105                // this is not an input field
106                switch ($field["type"]) {
107                    case "submit":
108                        /**
109                         * This is important to keep the submit element intact
110                         * for forms integration such as captcha
111                         * The search the submit button to insert before it
112                         */
113                        $classes = "btn btn-primary";
114                        if (isset($field["class"])) {
115                            $field["class"] = $field["class"] . " " . $classes;
116                        } else {
117                            $field["class"] = $classes;
118                        }
119                        $field["tabindex"] = "6";
120                        $newFormContent[] = $field;
121                        break;
122                    case "reset":
123                        $classes = "btn btn-secondary";
124                        if (isset($field["class"])) {
125                            $field["class"] = $field["class"] . " " . $classes;
126                        } else {
127                            $field["class"] = $classes;
128                        }
129                        $field["tabindex"] = "7";
130                        $newFormContent[] = $field;
131                        break;
132                }
133                continue;
134            }
135            switch ($fieldName) {
136                case "login":
137                    $loginText = $field["_text"];
138                    $loginValue = $field["value"];
139                    $loginHTML = <<<EOF
140<div class="$rowClass">
141    <label for="inputUserName" class="col-sm-$firstColWeight col-form-label">$loginText</label>
142    <div class="col-sm-$secondColWeight">
143      <input type="text" class="form-control" id="inputUserName" placeholder="Username" name="$fieldName" value="$loginValue" disabled>
144    </div>
145</div>
146EOF;
147                    $newFormContent[] = $loginHTML;
148                    break;
149                case "fullname":
150                    $fullNameText = $field["_text"];
151                    $fullNameValue = $field["value"];
152                    $fullNameHtml = <<<EOF
153<div class="$rowClass">
154    <label for="inputRealName" class="col-sm-$firstColWeight col-form-label">$fullNameText</label>
155    <div class="col-sm-$secondColWeight">
156      <input type="text" class="form-control" id="inputRealName" placeholder="$fullNameText" tabindex="1" name="$fieldName" value="$fullNameValue" required="required">
157    </div>
158</div>
159EOF;
160                    $newFormContent[] = $fullNameHtml;
161                    break;
162                case "email":
163                    $emailText = $field["_text"];
164                    $emailValue = $field["value"];
165                    $emailHTML = <<<EOF
166<div class="$rowClass">
167    <label for="inputEmail" class="col-sm-$firstColWeight col-form-label">$emailText</label>
168    <div class="col-sm-$secondColWeight">
169      <input type="email" class="form-control" id="inputEmail" placeholder="name@example.com" tabindex="2" name="$fieldName" value="$emailValue" required="required">
170    </div>
171</div>
172EOF;
173                    $newFormContent[] = $emailHTML;
174                    break;
175                case "newpass":
176                    $passwordText = $field["_text"];
177                    $passwordHtml = <<<EOF
178<div class="$rowClass">
179    <label for="inputPassword" class="col-sm-$firstColWeight col-form-label">$passwordText</label>
180    <div class="col-sm-$secondColWeight">
181      <input type="password" class="form-control" id="inputPassword" placeholder="$passwordText" tabindex="3" name="$fieldName">
182    </div>
183</div>
184EOF;
185                    $newFormContent[] = $passwordHtml;
186                    break;
187                case "passchk":
188                    $passwordCheckText = $field["_text"];
189                    $passwordCheckHtml = <<<EOF
190<div class="$rowClass">
191    <label for="inputPasswordCheck" class="col-sm-$firstColWeight col-form-label">$passwordCheckText</label>
192    <div class="col-sm-$secondColWeight">
193      <input type="password" class="form-control" id="inputPasswordCheck" placeholder="$passwordText" tabindex="4" name="$fieldName">
194    </div>
195</div>
196EOF;
197                    $newFormContent[] = $passwordCheckHtml;
198                    break;
199                case "oldpass":
200                    $passwordCheckText = $field["_text"];
201                    $passwordCheckHtml = <<<EOF
202<div class="$rowClass">
203    <label for="inputPasswordCheck" class="col-sm-$firstColWeight col-form-label">$passwordCheckText</label>
204    <div class="col-sm-$secondColWeight">
205      <input type="password" class="form-control" id="inputPasswordCheck" placeholder="$passwordCheckText" tabindex="5" name="$fieldName" required="required">
206    </div>
207</div>
208EOF;
209                    $newFormContent[] = $passwordCheckHtml;
210                    break;
211
212
213                default:
214                    $tag = self::TAG_UPDATE;
215                    LogUtility::msg("The $tag field name ($fieldName) is unknown", LogUtility::LVL_MSG_ERROR, self::CANONICAL);
216
217            }
218        }
219
220
221        /**
222         * Update
223         */
224        $form->_content = $newFormContent;
225        return true;
226
227
228    }
229
230    public function handle_profile_delete($event, $param)
231    {
232
233        /**
234         * The profile page is created via buffer
235         * We print before the forms to avoid a FOUC
236         */
237        print Identity::getHtmlStyleTag(self::TAG_DELETE);
238
239        /**
240         * @var Doku_Form $form
241         */
242        $form = &$event->data;
243        $class = &$form->params["class"];
244        Identity::addIdentityClass($class, self::FORM_PROFILE_DELETE_CLASS);
245        $newFormContent = [];
246
247        /**
248         * Header (Logo / Title)
249         */
250        $newFormContent[] = Identity::getHeaderHTML($form, self::FORM_PROFILE_DELETE_CLASS, false);
251
252        /**
253         * Field
254         */
255        foreach ($form->_content as $field) {
256            if (!is_array($field)) {
257                continue;
258            }
259            $fieldName = $field["name"];
260            if ($fieldName == null) {
261                // this is not an input field
262                if ($field["type"] == "submit") {
263                    /**
264                     * This is important to keep the submit element intact
265                     * for forms integration such as captcha
266                     * They search the submit button to insert before it
267                     */
268                    $classes = "btn btn-primary btn-block";
269                    if (isset($field["class"])) {
270                        $field["class"] = $field["class"] . " " . $classes;
271                    } else {
272                        $field["class"] = $classes;
273                    }
274                    $newFormContent[] = $field;
275                }
276                continue;
277            }
278            switch ($fieldName) {
279                case "oldpass":
280                    $passwordText = $field["_text"];
281                    $passwordFieldHTML = <<<EOF
282<div>
283    <input type="password" class="form-control" placeholder="$passwordText" required="required" name="$fieldName">
284</div>
285EOF;
286                    $newFormContent[] = $passwordFieldHTML;
287                    break;
288                case "confirm_delete":
289                    $confirmText = $field["_text"];
290                    $ConfirmValue = $field["value"];
291                    $rememberMeHtml = <<<EOF
292<div class="checkbox rememberMe">
293    <label><input type="checkbox" name="$fieldName" value="$ConfirmValue" required="required"> $confirmText</label>
294</div>
295EOF;
296                    $newFormContent[] = $rememberMeHtml;
297                    break;
298                default:
299                    $tag = self::TAG_DELETE;
300                    LogUtility::msg("The $tag field name ($fieldName) is unknown", LogUtility::LVL_MSG_ERROR, self::CANONICAL);
301
302
303            }
304        }
305        $form->_content = $newFormContent;
306        return true;
307    }
308
309
310}
311
312