sfApplyPlugin - 0.6.3

Allows users to apply for accounts

You are currently browsing
the website for symfony 1

Visit the Symfony2 website

« Back to the Plugins Home


Forgot your password?
Create an account



advanced search
Information Readme Dependencies Releases Changelog Contribute
Show source

sfApply plugin

Most public sites have similar needs where user registration is concerned. In order to slow down spam a little bit and get a grip on who's doing what, you want users to apply for accounts and confirm them by clicking on a link in an email message.

Symfony's sfGuardPlugin does a fine job managing the accounts you already have but doesn't provide a built-way for users to apply for and create accounts. sfApply adds that capability.

sfApplyPlugin also implements a password reset feature that works correctly and also requires users to confirm via email. This prevents a user who has discovered a momentarily unattended PC from taking over the account too easily.


You need:

  • sfGuardPlugin

  • Propel

A Symfony 1.2-plus-Doctrine version of this plugin will follow shortly.


Read the sfGuardPlugin documentation first! Set up that plugin before continuing.

Then add the following to your schema.yml:

      phpName: sfGuardUserProfile
      type: integer
      foreignTable: sf_guard_user
      foreignReference: id
      required: true
      onDelete: cascade
      type: varchar(80)
      index: yes
      type: varchar(80)
      type: varchar(17)
      index: yes

Note that sfApplyPlugin takes advantage of the "user profile" functionality offered by sfGuardPlugin as a place to store additional information. While sfGuardPlugin makes the name of the profile class configurable, sfApplyPlugin simply uses the default name (sfGuardUserProfile) for simplicity.

"But where do I put my own additional fields?" That's why I didn't build sfGuardUserProfile's schema directly into the plugin. Just add your additional fields after the full name field.

"Shouldn't there be yet another profile class for my stuff?" In theory, that might be nice. In practice, before you know it you'll be joining 28 tables every time someone accesses the page. Paste this one snippet of code just once instead.

You will also want to add the following routes to your config/routing.yml. The URLs are just suggestions, you can change them if you don't like them. Note that this plugin provides a working solution for users who have forgotten their passwords. Mapping the sf_guard_password route to sfApply/reset-request allows the "forgot your password?" link in the default sfGuardPlugin login form to work.

  url:  /apply
  param: { module: sfApply, action: apply }

  url: /reset
  param: { module: sfApply, action: reset }

  url: /reset-request
  param: { module: sfApply, action: resetRequest }

  url: /confirm/:validate
  param: { module: sfApply, action: confirm }

  url: /settings
  param: { module: sfApply, action: settings }

# We implement the missing sf_guard_password feature from sfGuardPlugin
  url: /reset-request
  param: { module: sfApply, action: resetRequest }

If you have enabled the built-in routes in sfGuardPlugin, then overriding sf_guard_password here might not work. You can fix that by copying sfGuardPlugin/modules/sfGuardAuth/templates/loginSuccess.php to your application and editing the "forgot your password?" link to point to sfApply/resetRequest instead.

Activate the sfApply module in your application's settings.yml file:

enabled_modules:        [default, sfGuardAuth, sfApply]

Note that you also need the sfGuardAuth module to enable logins.

Configure the "from" address and full name for email messages sent by sfApplyPlugin in your app.yml file:

      email: "your@emailaddress.com"
      fullname: "the staff at yoursite.com"

Important: sfApplyPlugin will not work unless you configure these options! The plugin will fail with a less than informative error message (although a more informative one appears in the log file). My apologies for leaving this rather important information out of the documentation of the earliest versions.

Now you can easily add a button to your pages sending users to sfApply/apply to request accounts:

echo button_to("Create Account", "sfApply/apply");

You will almost certainly also want to copy sfGuardPlugin's modules/sfGuardAuth/templates/signinSuccess.php to your own application's modules folder and add a "Create Account" link to it, so that users understand they can make accounts of their own at what would otherwise be the most frustrating point in your application.

Customizing Emails

sfApply sends out email messages inviting users to verify their accounts or reset their passwords. You can customize these by copying modules/sfApply/templates/sendValidateNew.php and modules/sfApply/templates/sendValidateReset.php from the plugin to your application and editing them. The default emails aren't that bad; they do contain the name of your site. But you really ought to customize these so that users get a warm, fuzzy, personal sense that the messages are not spam.

If you want to send HTML emails, you should create separate plaintext versions named sendValidateNew.altbody.php and sendValidateReset.altbody.php for plain text. When Symfony sees these, it will automatically expect HTML in sendValdiateNew.php and sendValidateReset.php.

This approach to email is not supported in Symfony 1.2. I'll be looking at alternate solutions for 1.2.

Displaying Login and Logout Prompts on Every Page

You probably have pages on which logging in is optional. It's nice to display a login prompt directly on these pages. If you want to do that, try including my login/logout prompt template from your apps/frontend/templates/layout.php file:

<?php include_partial('sfApply/login') ?>

If you are using the provided stylesheet, the login prompt will be floated at the far right, so you'll want to emit this code before anything that should appear to the left of the prompt.

When the user is already logged in, the login prompt is automatically replaced by a logout prompt.

Using the Suggested Stylesheet

sfApply comes with a stylesheet. You don't have to use it. If you do, you'll get reasonable styles for the sfApply pages as well as a reasonably good-looking style for the sfGuardPlugin login page.

If you wish to use my stylesheet directly, first make sure you have a symbolic link from web/sfApplyPlugin to plugins/sfApplyPlugin/web. Then add the stylesheet to your view.yml file:

  stylesheets:    [main, /sfApplyPlugin/css/login-apply]

In the long run, you'll probably want to borrow from it rather than using it directly.

Extending sfApply

"But I need the user's birthdate!" Of course you do. Every application needs something extra. Here's how to go about it:

  1. Add your extra fields to sfGuardUserProfile in your schema.yml.
  2. Create a modules/sfApply/templates folder in your application.
  3. Copy my applySuccess.php and settingsSuccess.php files over.
  4. Add the form fields you need for your additional information to those templates.
  5. Copy sfApplyPlugin/modules/sfApply/actions/actions.class.php to your own modules/sfApply/actions folder. Notice that this class is initially empty. That's because it inherits its default behavior from sfApplyPlugin/modules/sfApply/lib/BasesfApplyActions.class.php.
  6. Extend the populateProfileSettings method to save additional information to the profile when an account is first created:

    function populateProfileSettings($profile)
      $birthday = $this->getRequestParameter('birthday');
      // Don't forget to call the parent class version!
      return parent::populateProfileSettings($profile);
  7. Extend updateProfileSettings in exactly the same way. The difference is that updateProfileSettings is called when the user edits their settings later, while populateProfileSettings is called only the first time. If your needs in both situations are similar, I suggest that you keep the shared code in a private method that you call from both.

  8. Optionally override validateApply and validateSettings as well. Again, be sure to call the parent class versions before returning and return false if the parent class version returns false.


sfApplyPlugin was written by Tom Boutell. He can be contacted at tom@punkave.com. See also www.punkave.com and www.boutell.com for further information about his work.


Version 0.63

Version 0.63 corrects a significant oversight: earlier versions relied on sfGuardProfilePeer::retrieveUserByValidate() which existed only in my application. I discovered this problem when I employed the plugin a second application. This has been fixed.

Version 0.62

Version 0.62 corrects a documentation bug: I neglected to mention the importance of configuring the "from" address for emails sent by sfApplyPlugin. If you do not do so the account confirmation and password reset email messages will never be sent. See above.

Version 0.61

Version 0.61 had a minor markdown problem with the README.

Version 0.60

Version 0.6 adds the optional sfApply/_login.php template, which provides an easy way to insert a login prompt on every page. I realized I was using this code in two sites and that others would likely want to do the same thing. Just include it in your layout template.

Version 0.6 also adds a suggested stylesheet. Use it or not as you see fit. In addition to styling the apply and reset pages, it also styles the standard sfGuardUser login page.

Version 0.6 renames all of the CSS classes and ids emitted by sfApplyPlugin in order to avoid potential conflicts with your own CSS elements.

Version 0.53

Version 0.53 corrected Markdown errors in the documentation. There were no code changes from version 0.5, which was the first public release.