![]() |
|
Snippets |
|
or apply transformation on sfGuard tables into your main schema
When you generate a schema with sf_guard tables from your main database with the following command, the schema contains all the tables included the sf_guard tables (it's normal).
symfony propel-build-schema xml
Then after, when you build the model classes, the sfGuardPlugin classes have a wrong name and are in a wrong place (lib/). There is a post on this problem, how to correctly use propel-build-schema after sfGuardPlugin installation?
symfony propel-build-model
To correct the schema, apply the transformation on the XML schema after the schema generation :
symfony transform-schema-sfguard xml
The script add in the schema for all sf_guard_* tables, the package and the phpName with the camelcase used by the plugin.
Also you have to switch off the schema in the plugin to don't have twice declaration :
mv ./plugins/sfGuardPlugin/config/schema.yml ./plugins/sfGuardPlugin/config/schema.yml.off
The script: myPakeTransformSchemaSfguard.php
pake_desc( 'apply transformation on sfGuard tables into your main schema' ); pake_task( 'transform-schema-sfguard', 'project_exists' ); function run_transform_schema_sfguard($task, $args) { // Check params // -- missing params ? if ( !count($args) > 1 ) { throw new Exception("You must provide a transformation to apply.\nsymfony transform-schema-sfguard\nsymfony transform-schema-sfguard xml"); } // -- schema exists ? if ($args[0] == 'xml') { $schema_filename = sprintf( '%s/schema.xml', sfConfig::get('sf_config_dir') ); if ( !file_exists($schema_filename) ) { throw new Exception( "Missing schema.xml" ); } } else { $schema_filename = sprintf( '%s/schema.yml', sfConfig::get('sf_config_dir') ); if ( !file_exists($schema_filename) ) { throw new Exception( "Missing schema.yml (not yet implemented)" ); } else { throw new Exception( "schema.yml not yet implemented" ); } } // Backup schema //pake_copy( $schema_filename, $schema_filename . '.previous', array('override' => true) ); if ($args[0] == 'xml') { $handle = fopen($schema_filename, "r"); // get the entire file in $contents $contents = ''; while (!feof($handle)) { $contents.= fread($handle, 8192); } fclose($handle); $num = preg_match_all('/<table(.*)>/i', $contents, $matches); // each table definition found foreach ($matches[0] as $val) { if (!preg_match('/package|phpName/i', $val) && preg_match('/name="(sf_guard_.+?)"/i', $val, $val_matches)) { $table_name = $val_matches[1]; //$php_name = sfInflector::camelize($val_matches[1]); $php_name = sfToolkit::pregtr($val_matches[1], array('#/(.?)#e' => "'::'.strtoupper('\\1')", '/(_)(.)/e' => "strtoupper('\\2')", '/(^)(.)/e' => "strtolower('\\2')")); $pattern = '/(<table.*)(name="'.$table_name.'")(.*>)/i'; $replace = '$1$2 package="plugins.sfGuardPlugin.lib.model" phpName="'.$php_name.'" $3'; $contents = preg_replace($pattern, $replace, $contents, 1, $count); pake_echo($table_name); } } // write the result $handle = fopen($schema_filename, "w+"); fwrite($handle, $contents); fclose($handle); } }
Put the myPakeTransformSchemaSfguard.php script into data/tasks directory
mv ./plugins/sfGuardPlugin/config/schema.yml ./plugins/sfGuardPlugin/config/schema.yml.off symfony propel-build-schema xml symfony transform-schema-sfguard xml symfony propel-build-model
Here is how I did this... Create a sfGuardAuth module in your application and edit the actions.class.php file as follow.
The trick is to not try to overwrite the sfGuardAuth/signin action, as it use validation. As well it allow you to use the "normal" signin way (form and etc).
require_once(sfConfig::get('sf_plugins_dir').'/sfGuardPlugin/modules/sfGuardAuth/lib/BasesfGuardAuthActions.class.php'); class sfGuardAuthActions extends BasesfGuardAuthActions { public function executeHTTPSignin() { // get somme interesting stuff! $request = $this->getRequest(); $response = $this->getResponse(); $user = $this->getUser(); // An HTTP authenticated user cannot logout (browser always send authentification datas) // So we must be sure that the user has seen the HTTP authentification box before if ( $user->getAttribute('request_authentification') ) { // If authentification datas has been sent if ( isset( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ) ) { // If correct username given $guarduser = sfGuardUserPeer::retrieveByUserName( $_SERVER['PHP_AUTH_USER'] ); if ( $guarduser instanceof sfGuardUser ) { // If correct Password given if ( ($guarduser instanceof sfGuardUser) and ($guarduser->checkpassword( $_SERVER['PHP_AUTH_PW'] )) ) { // we can signin the user and redirect it $user->signin( $guarduser ); $user->setAttribute('request_authentification',false); $this->redirect( sfConfig::get('app_sf_guard_plugin_success_signin_url','@homepage') ); throw new sfStopException; } } } } // else, popup the authentification box $user->setAttribute('request_authentification',true); $response->setHttpHeader( 'WWW-Authenticate', 'Basic realm="Identification"' ); $response->setHttpHeader( 'HTTP/1.0', '401 Unauthorized' ); // This will be displayed if the user cancel the authentification process $this->forward( 'sfGuardAuth', 'password' ); throw new sfStopException; } public function executePasswowd() { # Implement this action as usual... } }
Enjoy... (I hope)
If you want add a column to sfGuardUserProfile's list view for show a link to sfGuardUser's edit view:
Create a partial : site.com/apps/backend/modules/sf_Guard_User_Profile/templates/_user.php
And put this:
<?php echo link_to($sf_guard_user_profile->getSfGuardUser()->getUsername(), 'sfGuardUser/edit?id='.$sf_guard_user_profile->getSfGuardUser()->getId()) ?>
PD(It's not very much, but it is my first snippet)
Sometimes if you use sfGuardUser and sfGuardUserProfile you need to create an empty profile just after adding the new user (automating is such a great thing). This snippet will help out.
UPDATE: Will Killian pointed me to the solution of using this without touching the plugin files, this way it will still work after upgrading the plugin. Thanks!
Edit apps/backend/modules/sfGuardUser/actions/actions.class.php
(create directories and files as needed, just for the record I use this with admin generator on "backend" app)
Mine looks like this.
<?php require_once(sfConfig::get('sf_plugins_dir').'/sfGuardPlugin/modules/sfGuardUser/lib/BasesfGuardUserActions.class.php'); class sfGuardUserActions extends BasesfGuardUserActions { protected function savesfGuardUser($sf_guard_user) { parent::savesfGuardUser($sf_guard_user); $user_id = $sf_guard_user->getId(); $c = new Criteria(); $c->add(sfGuardUserProfilePeer::USER_ID,$user_id); $profile = sfGuardUserProfilePeer::doSelectOne($c); if(!$profile) { $profile = new sfGuardUserProfile(); $profile->setUserId($user_id); $profile->save(); } } }