Search

Hey guys, I'm loving symphony I'm just trying to wrap my head around extension building. What I'm trying to do is automatically generate a password for users. I've built my own Users section (instead of using symphony's author system) which looks like this

  • username (text)
  • agree (checkbox)
  • passphrase (text)

the passphrase field does not exist in the html at this time and I have an extension using the delegate "EventPreSaveFilter" (because I assume this is where you edit the form data before saving).

    public function generatePassword($context) {  

        $salt = hash(md5, $this->genRandomString());

        $context['fields']['passphrase'] = $salt;        

    }

I would love to be able to save the data using a new field like this. But it appears that there is a level of complexity to how symphony likes to save data.

So after debugging I realized there was an XMLElement at $context['post_values']; that pretty much dictates the saving process. So I added a new element to the XMLElement too.

    public function generatePassword($context) { 
        $salt = hash(md5, $this->genRandomString());
        $context['fields']['passphrase'] = $salt;
        $context['post_values']->appendChild(new XMLElement('passphrase', $salt));
    }

and the element still isn't saving. I've done some debug information in a pastebin for you here: http://pastebin.com/NM5Jrr4a

My question is, How do you edit data in fields before the data is saved to a section? Am I doing this the entirely wrong way?

Thanks for your help everyone, I'm at wits end.

Perhaps you would like to wait for Members extension? It tackles every aspect of Frontend user management.

You might find it easier to manipulate the raw $_POST array inside the save event itself.

Inside the __trigger() method, before the require you could add:

$_POST['fields']['passphrase'] = md5($_POST['fields']['passphrase']);

This will manipulate the POST directly, before it gets passed to the event.

From what I can tell, by the point that the EventPreSaveFilter delegate fires, the entry has already been created (in memory at least) but has not been persisted to the database. Changing the data here therefore has no effect. The only extensions I have seen that use this delegate do so only to check POST data and terminate the event if certain conditions are met (Can of Spam, Akismet, Members and XSS FIlter extensions).

Hope this helps!

(By the way, your decision to use delegates over customising the PHP was a good one, and the way we try to recommend where possible since it is less obtrusive. But it looks like in this case there isn't a delegate that can achieve what you need.)

Ah, thanks Nick. That was exactly what I needed. I still have some questions about doing it this way though, maybe you could shed some light on it.

  • I've noticed that making changes to the Event in the symphony back-end overwrites my changes in the events file. Is there anyway to stop this?
  • I understand that Delegates are quite new, but would it be possible to create a custom delegate that can capture the moment before the User is created and make changes to the post data?

Thanks for your time!

(And thanks for pointing out that extension vladG. I'll keep an eye on it but half the fun of frameworks is tinkering yourself!)

Cheers

In your event file you should find the allowEditorToParse() function. Change it to return false instead of true.

Alright, I've added a new custom Delegate in the core file /symphony/lib/toolkit/events on line 21, before the post_values XMLElement is built.

        Symphony::ExtensionManager()->notifyMembers(
            'EventPreBuild',
            '/frontend/', 
            array('fields' => &$fields)
        );

This allows me to edit $context['fields'] in my extension and the changes be made before save like so:

    public function generatePassword ($context) {
        $context['fields']['passphrase'] = md5($this->genRandomString());
    }

However! I do not like editing the core this way, is there any way I can make this suggestion to the symphony developers to have this included in the next release? I would be willing to document this process. I imagine the need for PHP calculated fields would be useful for a framework to have.

Cheers

In Symphony 2.2.1, the EventPreSaveFilter will allow you to do exactly what you require. There are also some other changes the Event delegates that may interest you.

From the release notes:

  • EventPreSaveFilter delegate now passes $fields by reference.
  • EventPreSaveFilter, EventPostSaveFilter delegates can now handle a fourth option for $filter_result arrays that allow attributes to be added to the filter XML
  • EventFinalSaveFilter now is passed the $filter_results as well as messages. errors is now passed by reference and will be appended to the event XML.
  • EventPreCreate and EventPreEdit delegates now have one additional parameter, $filters

Amazing! thanks brendo. I'm a bit of a git newbie but next time I'll check the upcoming change log before doing a pull request :)

Cheers!

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details