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