?
avatar clayfreeman
clayfreeman
11 Jul 2017

Steps to reproduce the issue

  • Load the existing JUser in JPlugin::onUserLogin(...).
  • Call JUser::setParam($key, $value) with key/value pair.
  • Call JUser::save(false) to supposedly commit changes to the database.
  • Observe no changes to the database params column.

Expected result

The params column of the user table in the database should reflect the updated parameter.

Actual result

The params column of the user table in the database remains the same.

System information (as much as possible)

  • Ubuntu 16.04.2 LTS
  • nginx (1.9.15-0ubuntu1)
  • PHP 7.1 FPM (7.1.7.retag-1+ubuntu16.04.1+deb.sury.org+1)
  • Joomla (3.7.3)
  • No warnings detected.

Additional comments

If the user doesn't exist yet, then JUser::setParam($key, $value) and JUser::save(false) work as expected. I feel like JUser::save(false) is committing an old, possibly cached instance of the user because JUser::getParam($key) === $value after calling JUser::setParam($key, $value).

<?php
/**
 * @copyright  Copyright (C) Clay Freeman. All rights reserved.
 * @license    GNU General Public License version 3 or later.
 */

// No direct access
defined('_JEXEC') or die;

class PlgUserExample extends JPlugin {
  /**
   * This method intercepts the login process during the
   * post-authentication phase.
   *
   * @param   array    $user     Holds the user data.
   * @param   array    $options  Extra options.
   *
   * @return  boolean  True on success
   */
  public function onUserLogin($user, $options) {
    // Fetch the JUser from the database with the resulting ID
    $instance = $this->_getUser($user);
    // Other functionality here...
    return true;
  }

  /**
   * Attempt to fetch a user by username or create a user if it doesn't exist.
   *
   * @param   JAuthenticationResponse  $user  User account details.
   *
   * @return  JUser                           The resulting user.
   */
  protected function _getUser($user) {
    // Attempt to fetch the user by username
    $instance = JUser::getInstance();
    $id = (int) JUserHelper::getUserId($user['username']);

    // If the user already exists, load and return it
    if ($id > 0) $instance->load($id);
    else {
      // Fetch the default user creation group
      $config = JComponentHelper::getParams('com_users');
      $defaultGroup = $config->get('new_usertype', 2);

      // Fill in the values for the new user
      $instance->set('id', 0);
      $instance->set('name', $user['fullname']);
      $instance->set('username', $user['username']);
      $instance->set('groups', array($defaultGroup));
      // etc...
    }

    // Forcibly set the user's preferred editor
    $instance->setParam('editor', 'codemirror');

    // Attempt to create or update the user
    if (!$instance->save(false)) JLog::add('Error in login for user '.
      $user['username'].'.', JLog::WARNING, 'error');

    // Return the resulting JUser instance
    return $instance;
  }
}
avatar clayfreeman clayfreeman - open - 11 Jul 2017
avatar joomla-cms-bot joomla-cms-bot - change - 11 Jul 2017
Labels Added: ?
avatar joomla-cms-bot joomla-cms-bot - labeled - 11 Jul 2017
avatar franz-wohlkoenig franz-wohlkoenig - change - 12 Jul 2017
Category com_users
avatar joomla-cms-bot joomla-cms-bot - edited - 12 Jul 2017
avatar franz-wohlkoenig franz-wohlkoenig - change - 12 Jul 2017
Title
[com_user] Call to setParam() and save() does nothing
[com_users] Call to setParam() and save() does nothing
avatar matrikular
matrikular - comment - 17 Jul 2017

It seems you have some issues with the ACL. Are you creating / editing a Super User maybe? I've tested this with the following result:
https://pastebin.com/QcckQAZc

As you can see, the key / value pair of this & that has been saved.


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/17080.

avatar clayfreeman
clayfreeman - comment - 17 Jul 2017

@matrikular Yes, this plugin is modifying a Super User. Should I be using a different facility for this?

avatar matrikular
matrikular - comment - 17 Jul 2017

I wouldn't recommend to bypass any ACL checks and / or changing Super User params on the fly but here you go:

use Joomla\Registry\Registry;

$userToBeEdited = JFactory::getUser(578);

$registry = new Registry($userToBeEdited->params);

$registry->set('this', 'foo');

$shenanigan = new stdClass;

$shenanigan->id = $userToBeEdited->id;
$shenanigan->params = $registry->toString();

JFactory::getDbo()->updateObject('#__users', $shenanigan, 'id')
avatar clayfreeman
clayfreeman - comment - 17 Jul 2017

@matrikular If I were to add an onUserAfterLogin(...) hook, do you think I would succeed in editing the parameters using the correct API? The user being edited is always themselves.

avatar matrikular
matrikular - comment - 17 Jul 2017

Yes, you would.

avatar clayfreeman
clayfreeman - comment - 18 Jul 2017

Awesome! Thanks!

avatar clayfreeman clayfreeman - change - 18 Jul 2017
Status New Closed
Closed_Date 0000-00-00 00:00:00 2017-07-18 00:42:10
Closed_By clayfreeman
avatar clayfreeman clayfreeman - close - 18 Jul 2017

Add a Comment

Login with GitHub to post a comment