0

Below is all relevant code and the resulting output. An explanation of my confusion follows.

Registration Script

<?php
if(isset($_POST['username']))
{
    echo "1 - Start<br />";

    $username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
    echo "2 - Username from POST - $username<br />";

    $password = $_POST['password'];
    echo "3 - Password from POST - $password<br />";

    $passhash = "{exp:encryption:create_hash password='" . $password . "'}"; //Contains echo 4
    echo "5 - Hashed Password Returned - $passhash<br />";

    $username2 = "{exp:encryption:print_username username='" . $username . "'}"; //Contains echo 6
    echo "7 - printed Username - $username2<br />";
?>
    {exp:database:add_user username="<?php echo $username2; ?>" passhash="<?php echo $passhash; ?>"} <!--Contains echo 8--> 
<?php
}
?>

Plugin: pi.encryption.php (excerpt)

function Create_hash()
{
    $password = ee()->TMPL->fetch_param('password');

    //echo "Password to hash: $password<br />";
    // format: algorithm:iterations:salt:hash
    $salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTE_SIZE, MCRYPT_DEV_URANDOM));
    $hashed = PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" .  $salt . ":" .
        base64_encode($this->Pbkdf2(
            PBKDF2_HASH_ALGORITHM,
            $password,
            $salt,
            PBKDF2_ITERATIONS,
            PBKDF2_HASH_BYTE_SIZE,
            true
        ));
    echo "4 - Hashed Password Method - $hashed<br />";
    return $hashed;
}

function Print_username()
{
    $username = ee()->TMPL->fetch_param('username');
    echo "6 - Pushing username through function - $username<br />";
    return $username;
}

Plugin: pi.database.php (excerpt)

function Add_user()
{
    $username = ee()->TMPL->fetch_param('username');
    $passhash = ee()->TMPL->fetch_param('passhash');

    echo "8<br />";
    echo "--->Username to database: $username<br />";
    echo "--->Passhash to database: $passhash<br />";

    $data = array(
        'User_ID'       =>null,
        'User_Name'     =>$username,
        'User_Passhash' =>$passhash.""
    );
    $query = ee()->db->insert('exp_user', $data);
}

Printed output from running the registration script

4 - Hashed Password Method - sha256:1000:axEzJMSQWDR/tyeeuWxDJC80YHJGlIm/:yk1KnSWyeXlwPb4vQThKAyXSF/yqwiID
6 - Pushing username through function - testUsername
8
--->Username to database: M10o93H7pQ09L8X1t49cHY01Z5j4TT91fGfr
--->Passhash to database: M00o93H7pQ09L8X1t49cHY01Z5j4TT91fGfr
1 - Start
2 - Username from POST - testUsername
3 - Password from POST - testPassword
5 - Hashed Password Returned - sha256:1000:axEzJMSQWDR/tyeeuWxDJC80YHJGlIm/:yk1KnSWyeXlwPb4vQThKAyXSF/yqwiID
7 - printed Username - testUsername

In my registration script which contains expression engine tags, I inserted some test prints to make it easier to follow the program execution.

My code (if the world were perfect) retrieves a given username and password from POST. The password is encrypted with a plugin function. Then a second plugin function is used to add the username and the encrypted password to a database.

The PHP parsing order is set to "Input", so the php is parsed before the EE tags. With this in mind, I am a bit confused why the PHP lines containing EE tags are all executed first as a group. Though that is confusing, that is not my main problem.

Look at output line #8. The $passhash sent to the Add_user() method via the EE tags is not the value of $passhash that is generated and returned by the Create_hash() method. Even though I explicitly send $passhash to the Add_user() function, a completely different string is sent instead.

$username, if passed directly to the Add_user() method, acts as is intended and is properly added to the database.

The problem I'm having with $passhash only happens when I'm using a result returned from a plugin function. I confirmed this by recreating the issue using $username. To see if the issue is consistent, I changed my code to pipe $username through the Print_username(). It simply returns the string given, and is saved as $username2 in the registration script.

Demonstrated in the output line 8, $username2 is now having the same issue as $passhash.

Now, my question: How can I use returned values from plugin functions as parameters for other plugins without the latter receiving garbage?

1 Answer 1

4

What you're trying to accomplish would be better served using a module, instead of plugins in a template. With a module, you can create a true form action and use pure PHP, rather than fighting the template parser with the spaghetti you've got here.

There are good docs on building a module: http://ellislab.com/expressionengine/user-guide/development/modules.html http://ellislab.com/expressionengine/user-guide/development/module_tutorial.html

In particular you want to create an action in your module->install function:

function install()
{
  $data = array(
    'module_name' => 'Module_name',
    'module_version' => $this->version,
    'has_cp_backend' => 'n',
    'has_publish_fields' => 'n',
  );

  ee()->db->insert('modules', $data);

  //here's where you create your action in the database
  //later on, you'll look up this action to POST to it
  $data = array(
    'class'     => 'Module_name',
    'method'    => 'register'
  );

  ee()->db->insert('actions', $data);
}

And then in your module you'd create a register method:

function register()
{
   //get the username & password from $_POST
   //hash the password
   //add the user to DB
   //redirect or print a message
}

You'll also need to create a form tag (you can call it whatever you want):

function form()
{
  $return_data = ee()->functions->form_declaration(array(
    'hidden_fields' => array(
      'ACT' => ee()->functions->fetch_action_id('Module_name', 'register'),
    ),
  ));

  $return_data .= ee()->TMPL->tagdata;

  $return_data .= '</form>';

  return $return_data;
}

Then you can print the form in a template on the front-end, and it will correctly POST to your form action:

{exp:module_name:form}
  <input name="username">
  <input type="password" name="password">
  <input type="submit" value="Submit">
{/exp:module_name:form}
1
  • You're an angel and a saint. +1 for calling my code "spaghetti". Thank you so much for the fully-detailed response!
    – John G
    Aug 30, 2013 at 19:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.