Tutorial - Implement a self-registration button in a custom landing page. Part 2

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • telecastg
    Active Community Member
    • Jun 2018
    • 907

    Tutorial - Implement a self-registration button in a custom landing page. Part 2

    UPDATE: This tutorial is only applicable for Espo 5.9 and before

    This is the continuation of the previous thread: https://forum.espocrm.com/forum/deve...ng-page-part-1

    Due to the length of the additional scripts required, I opted for saving them in GitHub where they can be downloaded instead of posting them in this thread, and concentrate on explaining the functionality of each.

    Steps cont'd:

    5) Create js script client/custom/src/views/modals/registration-request.js copying the code from https://github.com/telecastg/espocrm...ion-request.js

    This is the view class that will render a form in a modal window where the visitor can enter its information to request to be registered as a portal user.

    The information required from the visitor is:
    First Name
    Last name
    Email Address
    Cell Phone Number

    The view will use template client/custom/res/templates/modals/registration-request to render the form and when the visitor clicks on the "Submit" button, it will invoke the entry point anonymousRegistrationRequest.php which will initiate processing the request at the back end.

    6) Create template script client/custom/res/templates/modals/registration-request.tpl copying the code from https://github.com/telecastg/espocrm-self-registration-tutorial-files/blob/master/client/custom/res/templates/modals/registration-request.tpl

    This is the template called by the view script above.


    7) Create php script custom/Espo/Custom/EntryPoints/AnonymousRegistrationRequest.php copying the code from https://github.com/telecastg/espocrm...ionRequest.php

    The entry point will call the service RegistrationRequest.php function processAnonymousRegistrationRequest which will actually process the registration request and will provide a response message, which the entry point will send back to the front-end view to be displayed to the user at the registration request form.

    8) Create php script custom/Espo/Custom/Services/RegistrationRequest.php copying the code from
    https://github.com/telecastg/espocrm...ionRequest.php
    The service will perform the following functions to process the request:

    First it will execute the function processAnonymousRegistrationRequest invoked by the entry point. The goal of this function is to determine if the registration request is a duplicate by attempting to match the information provided by the visitor with an existing portal user, the parameters used for comparison are the ones entered by the visitor: first name, last name, email address and cell phone number.

    If an existing portal user is matched, the system will send an email to the visitor informing it of the existing duplicate, providing the username in record and requesting that the visitor go back to the login page and request instead a change of password.

    If no matching portal user is identified, then the system creates a new RegistrationRequest record with the data provided and notifies the administrator via email of the pending request for approval or rejection.

    This tutorial does not cover possible automated actions after the Administrator has approved or rejected a request, such as sending a rejection email or automatically creating a new portal user. Such actions could be easily implemented using BPN or by coding them in a hook for the RegistrationRequest entity that is triggered when the entity status changes from "Received" to either "Approved" or "Rejected".

    Another strong candidate for improvement is the processAnonymousRegistrationRequest function contained by the RegistrationRequest Service, which detects possible duplicates.

    This function could be modified to perform more sophisticated comparisions, for example, in our business (Rentals Management), we include two additional fields in the request "Current Rent" and "Postal Code" and we use those fields to locate existing tenants that might have changed their cell phone number or email address.
    Last edited by telecastg; 07-17-2023, 01:55 AM.
  • attachaudhury
    Junior Member
    • Jun 2020
    • 6

    #2
    telecastg
    i followed the tutorial, but when i click register, it does not show registration modal. I also changed (data-action="createRegistrationRequest" to data-action="showRegistrationRequest") in templates/login.tpl ,because in src/views.js the function name is showRegistrationRequest. But is not working, Any suggestions what is the issue

    Comment

    • attachaudhury
      Junior Member
      • Jun 2020
      • 6

      #3
      Originally posted by attachaudhury
      telecastg
      i followed the tutorial, but when i click register, it does not show registration modal. I also changed (data-action="createRegistrationRequest" to data-action="showRegistrationRequest") in templates/login.tpl ,because in src/views.js the function name is showRegistrationRequest. But is not working, Any suggestions what is the issue
      Solved it by registering a event in client\custom\src\views\login.js like this
      Code:
        // specify your custom template
              template: 'custom:login',
              events: {
                  'click a[data-action="showRegistrationRequest"]': function (e) {
                      this.showRegistrationRequest();
                  }
              },
              // specify your own custom values for any custom placeholders that you are including in the template
              // in this example, a background image, company name, custom button for self-registration and captcha are included
              landingPageData: {
                  backgroundImage: '/client/img/broker92-logo.png',
                  companyName: 'Broker92',
                  selfRegistrationEnabled: true,
                  captchaEnabled: false            
              },
              // include the custom values in the standard "data" function which will provide the placeholder values to the template
              // the values for "logoSrc" and "showForgotPassword" are the standard values specified in the core login script
              data: function () {
                  return{        
                    logoSrc: this.getLogoSrc(),
                    showForgotPassword: this.getConfig().get('passwordRecoveryEnabled'),
                    companyName: this.landingPageData.companyName,
                    backgroundImage: this.landingPageData.backgroundImage,
                    selfRegistrationEnabled: this.landingPageData.selfRegistrationEnabled
                 };          
              },

      Comment


      • telecastg
        telecastg commented
        Editing a comment
        Thanks for providing the solution, you are absolutely correct, the click event was missing.I will correct the tutorial.
        Last edited by telecastg; 06-19-2020, 05:23 PM.
    • serqet
      Senior Member
      • Feb 2019
      • 109

      #4
      Hello, I made all the arrangements you described, but there is no change when you press the register button.
      Do I do something missing?

      telecastg

      Comment

      • telecastg
        Active Community Member
        • Jun 2018
        • 907

        #5
        Please see the posting above from attachaudhury

        The original tutorial was missing this line in the file: client/custom/src/views/login.js
        Code:
        events: {
            'click a[data-action="showRegistrationRequest"]': function (e) {
                this.showRegistrationRequest();
            }
        }
        This "event" instruction tells Espo to execute the function showRegistrationRequest() (which is defined inside the same script: client/custom/src/views/login.js) when the button is clicked, this function is executed which triggers the creation of the modal view with the registration form.

        One way to test that the button is actually triggering the function, is to include a "console.log" or "alert" in the first line of the showRegistrationRequest() function. That will tell you if the button is calling the right function, even if there's some error inside the function.

        If that happens, then the problem can be inside the function so you would have to troubleshoot that function and check for possible typographical errors.

        If it doesn't trigger the function, then check the spelling in the "events" section to make sure it matches the name of the function perfectly.
        Last edited by telecastg; 07-18-2020, 07:35 AM.

        Comment

        • serqet
          Senior Member
          • Feb 2019
          • 109

          #6
          Thanks for your answer.

          My login.js content is exactly like this;
          Code:
          define('custom:views/login', 'views/login', function (Dep) {
          
          return Dep.extend({
          
          // specify your custom template
          template: 'custom:login',
          events: {
          'click a[data-action="showRegistrationRequest"]': function (e) {
          this.showRegistrationRequest();
          }
          },
          // specify your own custom values for any custom placeholders that you are including in the template
          // in this example, a background image, company name, custom button for self-registration and captcha are included
          landingPageData: {
          backgroundImage: 'client/img/ventura.jpg',
          companyName: '',
          selfRegistrationEnabled: true,
          captchaEnabled: false
          },
          
          // include the custom values in the standard "data" function which will provide the placeholder values to the template
          // the values for "logoSrc" and "showForgotPassword" are the standard values specified in the core login script
          data: function () {
          return{
          logoSrc: this.getLogoSrc(),
          showForgotPassword: this.getConfig().get('passwordRecoveryEnabled'),
          companyName: this.landingPageData.companyName,
          backgroundImage: this.landingPageData.backgroundImage,
          selfRegistrationEnabled: this.landingPageData.selfRegistrationEnabled
          };
          },
          
          // this is the function that will be triggered when the visitor clicks on the custom "Register" button
          events: {
          'submit #login-form': function (e) {
          this.login();
          return false;
          },
          'click a[data-action="showRegistrationRequest"]': function (e) {
          this.showRegistrationRequest();
          },
          'click a[data-action="passwordChangeRequest"]': function (e) {
          this.showPasswordChangeRequest();
          }
          },
          
          showRegistrationRequest: function () {
          Espo.Ui.notify(this.translate('pleaseWait', 'messages'));
          this.createView('registrationRequest', 'custom:views/modals/registration-request', {
          url: window.location.href
          }, function (view) {
          view.render();
          Espo.Ui.notify(false);
          });
          }
          
          });
          });
          I also couldn't solve the cause of the error in the picture.
          Click image for larger version

Name:	error.png
Views:	824
Size:	363.2 KB
ID:	60613

          Thank you admirable.

          Comment

          • serqet
            Senior Member
            • Feb 2019
            • 109

            #7
            I guess it is also necessary to change the data-action = "createRegistrationRequest" section to data-action = "showRegistrationRequest" in line 27 in the login.tpl file. In this way, clicking the register button opened the registration form. Because there is no createRegistrationRequest action in login.js ...

            There is a new registration information mail right now, but there is no warning mail like you are already registered. Nothing happens when I approve or reject the incoming request.

            I think I'm making a mistake somewhere.

            Comment

            • telecastg
              Active Community Member
              • Jun 2018
              • 907

              #8
              Hi,

              Regarding the console message, the error is triggered because file client/custom/lib/js/landingPage.js does not exist.

              Please re-read the original landing page tutorial referred in part 1. https://forum.espocrm.com/forum/deve...n-landing-page

              You should had created the script client/custom/lib/js/landingPage.js as part of the landing page tutorial. It's an empty javascript script where you can incorporate some special ui actions or simply leave it blank.

              Regarding
              Nothing happens when I approve or reject the incoming request.
              You need to write the code into custom/Espo/Custom/Services/RegistrationRequest.php for whatever actions you want the system to take after a registration request has been received.

              The tutorial was just to get you started, right now the script only sends the administrator an email to alert him/her that a registration request was received. (a registration request record has been created)

              This tutorial does not cover possible automated actions after the Administrator has approved or rejected a request, such as sending a rejection email or automatically creating a new portal user. Such actions could be easily implemented using BPN or by coding them in a hook for the RegistrationRequest entity that is triggered when the entity status changes from "Received" to either "Approved" or "Rejected".
              Last edited by telecastg; 07-19-2020, 05:24 AM.

              Comment

              • tosin
                Junior Member
                • Aug 2020
                • 1

                #9
                Hi,

                Thank you for this great tutorial. I appreciate your detailed explanations and well commented codes.

                However, on submitting the registration form, having followed through carefully, I keep getting :

                500 Internal Server Error
                SQLSTATE[42S22]: Column not found: 1054 Unknown column 'phone_number.numeric' in 'where clause'

                I have checked the table, and the column exists. Why am I doing wrong please?


                Comment

                • telecastg
                  Active Community Member
                  • Jun 2018
                  • 907

                  #10
                  Hi, I am sorry, can't figure out why the error is being thrown out.

                  None of the tutorial scripts have any reference to "phone_number.numeric". It sounds like a database query issue because it is a valid column reference.

                  May try rebuilding Espo ?

                  Comment

                  • serqet
                    Senior Member
                    • Feb 2019
                    • 109

                    #11
                    Originally posted by telecastg
                    Hi, I am sorry, can't figure out why the error is being thrown out.

                    None of the tutorial scripts have any reference to "phone_number.numeric". It sounds like a database query issue because it is a valid column reference.

                    May try rebuilding Espo ?
                    this is problem RegistrationRequest.php

                    Code:
                    $sql = 'Select user.user_name As userName, ' . 'user.id As `userId` ' .
                    'From user '
                    . 'Inner Join entity_email_address On entity_email_address.entity_id = user.id '
                    . 'Inner Join email_address On email_address.id = entity_email_address.email_address_id '
                    . 'Inner Join contact On user.contact_id = contact.id '
                    . 'Where user.type = "portal" '
                    . 'And [B][COLOR=#e74c3c]phone_number.`numeric`[/COLOR][/B] [B][COLOR=#e74c3c]="'.$numericPhone.'[/COLOR][/B]" '
                    . 'And email_address.lower = "'.$pdo->quote($lowCapsEmail).'" '
                    . 'And entity_phone_number.entity_type = "Contact" '
                    . 'And entity_email_address.entity_type = "Contact" ';
                    because this table is not joined.

                    Also although I fixed this, the user you mentioned is not doing the check and every time a new user sends a registration request.

                    First it will execute the function processAnonymousRegistrationRequest invoked by the entry point. The goal of this function is to determine if the registration request is a duplicate by attempting to match the information provided by the visitor with an existing portal user, the parameters used for comparison are the ones entered by the visitor: first name, last name, email address and cell phone number.

                    Comment

                    • telecastg
                      Active Community Member
                      • Jun 2018
                      • 907

                      #12
                      Thanks for tracking the error.

                      I changed the sql statement to link properly the tables and filter using "Contact" as target entity, please change the existing sql statement in custom/Espo/Custom/Services/RegistrationRequest.php to read like this:
                      Code:
                      // set criteria to identify an existing portal user by matching email and numeric phone number
                      $sql = 'Select user.user_name As userName, '
                      . 'user.id As `userId` '
                      . 'From user '
                      . 'Inner Join contact On user.contact_id = contact.id '
                      . 'Inner Join entity_email_address On entity_email_address.entity_id = contact.id '
                      . 'Inner Join email_address On email_address.id = entity_email_address.email_address_id '
                      . 'Inner Join entity_phone_number On entity_phone_number.entity_id = contact.id '
                      . 'Inner Join phone_number On phone_number_id = entity_phone_number.phone_number_id '
                      . 'Where user.type = "portal" '
                      . 'And phone_number.`numeric` ="'.$numericPhone.'" '
                      . 'And email_address.lower = "'.$pdo->quote($lowCapsEmail).'" '
                      . 'And entity_phone_number.entity_type = "Contact" '
                      . 'And entity_email_address.entity_type = "Contact" ';
                      I changed the source code in the repository to reflect these changes.

                      This code will attempt to match an existing portal user with the phone number and email provided by a portal user.

                      Please do not forget that this tutorial is NOT a fully functional auto-registration implementation. This section it is only intended to show the functionality to build a basic authentication to detect existing portal users based on their phone number and email address only, but the developer must adapt it to its own system.
                      Last edited by telecastg; 09-13-2020, 07:30 PM.

                      Comment

                      Working...