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