Add new field in registration form from custom plugin

Hello everybody! Please help me.

I’m trying to add a new field into the registration form from custom plugin. My main code

My main code plugins/generic/customUserFields/CustomUserFieldsPlugin.inc.php
<?php
import('lib.pkp.classes.plugins.GenericPlugin');

class CustomUserFieldsPlugin extends GenericPlugin {
  public function register($category, $path, $mainContextId = NULL) {
    $success = parent::register($category, $path);

    if ($success && $this->getEnabled()) {
          HookRegistry::register('Schema::get::user', array($this, 'addToSchema'));
          HookRegistry::register('registrationform::execute', array($this, 'collectUserCustomFields'));
          HookRegistry::register('userdao::getAdditionalFieldNames', array($this, 'handleAdditionalFieldNames'));
        }
        return $success;
      }

  public function getDisplayName() {
        return __('plugins.generic.customuserfield.name');
  }

  public function getDescription() {
    return __('plugins.generic.customuserfield.description');
  }

  public function addToSchema($hookName, $args) {
    error_log("+ function addToSchema\n\r", 3, '/var/www/html/error.log');

    $schema = $args[0];
    $schema->properties->patronymic = (object) [
      'type' => 'string',
      'multilingual' => "true",
      'apiSummary' => true,
    ];

    error_log("- function addToSchema\n\r", 3, '/var/www/html/error.log');
  }

  public function collectUserCustomFields($hookName, $params) {
    error_log("+ function collectUserCustomFields\n\r", 3, '/var/www/html/error.log');

    $form = $params[0];
    $user = $form->user;
    $request = Application::get()->getRequest();
    $site = $request->getSite();
    $sitePrimaryLocale = $site->getPrimaryLocale();
    $currentLocale = AppLocale::getLocale();

    $form->readUserVars(array(
      'patronymic',
    ));

    error_log("currentLocale is «" . $currentLocale . "»\n\r", 3, '/var/www/html/error.log');

    $user->setData('patronymic', $form->getData('patronymic'), $currentLocale);

    if ($sitePrimaryLocale != $currentLocale) {

      $user->setData('patronymic', $form->getData('patronymic'), $sitePrimaryLocale);
    }

    error_log("- function collectUserCustomFields\n\r", 3, '/var/www/html/error.log');

    return false;
  }

  

  function handleAdditionalFieldNames($hookName, $params) {
    error_log("+ function handleAdditionalFieldNames\n\r", 3, '/var/www/html/error.log');

    $fields =& $params[1];
    $fields[] = 'patronymic';

    error_log("- function handleAdditionalFieldNames\n\r", 3, '/var/www/html/error.log');

    return false;
  }
}
Field in template (theme plugin)
<!-- default html code registrationForm.tpl -->

        <div class="patronymic">
          <label>
            <span class="label">
              {translate key="user.patronymic"}
            </span>
            <input type="text" name="patronymic" id="patronymic" value="{$patronymic|escape}" maxlength="255">
          </label>
        </div>

<!-- default html code registrationForm.tpl -->

I have a problem

  1. When I’m saving field without locale everything is fine. If I try to set a locale, field is saved as object (need string).
    truble-with-locale

  2. I’m trying to change user schema with hook in plugin (function addToSchema is not called).Also, I’ve tried to make changes in file /lib/pkp/schemas/user.json. All this methods didn’t help me.

error_log in file lib/pkp/classes/core/DataObject.inc.php in function setData and in my plugin when user register:

Modified function setData
function setData($key, $value, $locale = null) {
    if ($key === 'patronymic') error_log("+ function setData\n\r", 3, '/var/www/html/error.log');

    if ($key === 'patronymic') {
      error_log("key is «" . $key . "»\n\r", 3, '/var/www/html/error.log');
      error_log("value is «" . $value . "»\n\r", 3, '/var/www/html/error.log');
      error_log("locale is «" . $locale . "»\n\r", 3, '/var/www/html/error.log');
    }

    ... not modified code ...

    if ($key === 'patronymic') error_log("- function setData\n\r", 3, '/var/www/html/error.log');
  }
Error log file
+ function setData
key is «patronymic»
value is «Array»
locale is «»
- function setData

+ function collectUserCustomFields
currentLocale is «ru_RU»
+ function setData
key is «patronymic»
value is «О 41»
locale is «ru_RU»
- function setData
- function collectUserCustomFields

+ function handleAdditionalFieldNames
- function handleAdditionalFieldNames

+ function setData
key is «patronymic»
value is «Array»
locale is «»
- function setData

+ function setData
key is «patronymic»
value is «Array»
locale is «»
- function setData

+ function handleAdditionalFieldNames
- function handleAdditionalFieldNames

+ function setData
key is «patronymic»
value is «Array»
locale is «»
- function setData

+ function setData
+ function setData
key is «patronymic»
key is «patronymic»
value is «Array»
value is «Array»
locale is «»
locale is «»
- function setData
- function setData

+ function setData
+ function setData
key is «patronymic»
key is «patronymic»
value is «Array»
value is «Array»
locale is «»
locale is «»
- function setData
+ function setData
- function setData
key is «patronymic»
value is «Array»
locale is «»
- function setData

+ function setData
key is «patronymic»
value is «Array»
locale is «»
- function setData

+ function setData
key is «patronymic»
value is «Array»
locale is «»
- function setData

+ function setData
key is «patronymic»
value is «Array»
locale is «»
- function setData

Could you tell me what I’m doing wrong? I would be grateful for any help and ideas!

Environment: OJS 3.2.0-2, nginx, php 7.4, PostgreSQL

You’ll want to avoid editing the core files (like lib/pkp/schemas/user.json or lib/pkp/classes/core/DataObject.inc.php) in favor of calling hooks within your plugin.

Have you seen this thread?

It contains references to several examples.

Yes. I don’t want to modify the core. Thank you for the link to learn!

Hi. Added a new field, but not using my plugin. Changed the core…

lib/pkp/classes/identity/Identity.inc.php

php

lib/pkp/classes/user/UserDAO.inc.php

php

lib/pkp/classes/user/form/IdentityForm.inc.php

php

lib/pkp/classes/user/form/RegistrationForm.inc.php

php

lib/pkp/controllers/grid/settings/user/form/UserDetailsForm.inc.php

php

lib/pkp/templates/common/userDetails.tpl

tpl

lib/pkp/templates/user/identityForm.tpl

tpl

plugins/themes/spbpu/templates/frontend/components/registrationForm.tpl (my custom plugin)

tpl

It seems that we will not make an analog with plugins and hooks. Am I wrong?
Constructive criticism is welcome!

P.S. Sorry for the images, but they better show changes in the code.

Was the core problem you encountered in having the plugin do this work the fact that this field was multilingual? Or did you have trouble adding the field to the forms or to the data object, when the plugin was calling the hooks?

Main problem:

  1. Localization and database (no or hook is not called to change the user’s schema);
  2. I didn’t understand how to implement all the necessary changes using hooks (system doesn’t call many hooks).

A common cause of hooks not being called from a brand new generic plugin is that the plugin has not yet be registered. To register a new generic plugin, one of the following must occur: installation via the Plugin Gallery, running the plugin installation script lib/pkp/tools/installPluginVersion.php, or running the application Upgrade (via web interface or command line).

Thank you very much for your answers! The plugin was registered. I will update carefully just now.