Posts tagged with “Symfony”
My PHP code snippets at GitHub
These functions were mostly written by me for a current project but I also have compiled some stuff from other devs and open source repos.
You’ll find mostly PHP here but I’ll also keep Ant tasks, JS and notes here.
Symfony 1.1 Time/Code Saver using Model->fromArray()
I found a pretty nice time and code saver in the fromArray() method. Currently, we’re translating our arrays from the form’s POST data into what works for the models’ fromArray() method.
Here’s an example:
$pet_txt->fromArray(array(
“PetInfoId” => $params[‘pet_info_id’],
“VetInfo” => $params[‘vet_info’],
“SpecialCare” => $params[‘special_care’],
));
Apparently there’s an easier way:
$pet_txt->fromArray($params, BasePeer::TYPE_FIELDNAME);
What that does is use the underscored field_name style rather than the default CamelCase TYPE_PHPNAME when inserting the new variables. Please note that fromArray() will only insert the parts of the array that match the model (ie. ‘password’ won’t get set on the Pet model). It will also overwrite anything you’ve set previously.
If you need to set other keys that are not in the array, you can use the Model->setFieldName() methods, or you can use Model->setByName(‘pet_id’, $params[‘pet_id’], BasePeer::TYPE_FIELDNAME).
Here’s the other options available:
/**
* phpname type
* e.g. ‘AuthorId’
*/
const TYPE_PHPNAME = ‘phpName’;
/**
* column (peer) name type
* e.g. ‘book.AUTHOR_ID’
*/
const TYPE_COLNAME = ‘colName’;
/**
* column fieldname type
* e.g. ‘author_id’
*/
const TYPE_FIELDNAME = ‘fieldName’;
/**
* num type
* simply the numerical array index, e.g. 4
*/
const TYPE_NUM = ‘num’;
Using Symfony 1.1's Error Levels Properly
Here’s how to log a message in your action (using the INFO=6 level):
$this->logMessage(‘account_id: ‘.$account->getAccountId(),‘INFO’);
And elsewhere (using the CRIT=2 level):
sfContext::getInstance()->getLogger()->log(‘rsync returned error code (’.$return.’)’, ‘<span class="caps">CRIT</span>’);
sfContext::getInstance()->getLogger()->log(debug($output,0,1),‘<span class="caps">CRIT</span>’); // for Arrays
sfContext::getInstance()->getLogger()->warning(‘we should look at why this is happening’); // using the <span class="caps">WARNING</span>=4 levelHere’s the error levels that symfony gives us, ERR=3 being the default:
const EMERG = 0; // System is unusable
const ALERT = 1; // Immediate action required
const CRIT = 2; // Critical conditions
const ERR = 3; // Error conditions
const WARNING = 4; // Warning conditions
const NOTICE = 5; // Normal but significant
const INFO = 6; // Informational
const DEBUG = 7; // Debug-level messages
I wrote a new logException method for us to have a standard way to log and deal with Exceptions. This should hopefully end up being a standard way to deal with Exceptions across the project. The dUtils::logException() method sets the message at the ERR=3 level by default. You can change that with the second argument.
class dUtils{
public static function exceptionToString($e){
return $e->getFile().” on line no. “.$e->getLine().” “.$e->getMessage().“nn”.$e->getTraceAsString();
}
public static function logException($e,$error=sfLogger::ERR){
sfContext::getInstance()->getLogger()->log(dUtils::exceptionToString($e),$error);
}
}try {
$sf_secure_user->save();
} catch (PropelException $e) {
// problem with save
dUtils::logException($e);
$this->getUser()->setFlash(‘error’, ‘Account not created. Please try again.’);
return sfView::SUCCESS;
}
And here’s how to set the logging level in factories.yml. Please be aware that the default level for all logs is set at the lowest level, DEBUG=7. On production, the level is set at ERR=3. This means that in the log file, we’ll see those errors above level DEBUG=7 or ERR=3, respectively.
logger:
class: sfAggregateLogger
param:
level: debug
loggers:
sf_web_debug:
class: sfWebDebugLogger
param:
level: debug
condition: SF_WEB_DEBUG
xdebug_logging: true
sf_file_debug:
class: sfFileLogger
param:
level: debug
file: SF_LOG_DIR/%SF_APP%_%SF_ENVIRONMENT%.log
Adding and/or injecting error messages into Symfony 1.1 Forms
Symfony 1.1 does a great job handling forms and form validation but say you have a few external forces checking the validity of the user submitted data, such as Paypal. Paypal would love to return it’s own error messages (thank you very much!) and tie it to a particular form field (say, the credit_card field).
Place this method into “symfony_project/lib/form/BaseFormPropel.class.php”:
/** * Define error * * <code>author Dmitry Nesteruk, Andrey Kotlyarov *
param string $fieldName *
param string $message *
return void */ public function defineError($fieldName, $message) { $checkName = ‘check_define_’.md5($fieldName); $this->getErrorSchema()->getValidator()->addOption($checkName); $this->getErrorSchema()->getValidator()->addMessage($checkName, $message); $this->getErrorSchema()->addError( new sfValidatorError( $this->getErrorSchema()->getValidator(), $checkName, array( ‘value’ => sfContext::getInstance()->getRequest()->getParameter($fieldName), $checkName => $this->getErrorSchema()->getValidator($checkName) ) ) ); }
And use it like so:
<br />
$this->form = new BillingForm();<br />
$Paypal->sendPayment();<br />
if(in_array($Paypal->error_codes,10527)){
$this->form->defineError(‘credit_card’,“Paypal doesn’t like your credit card number. Please try another.”);<br />
}<br />Loading extra YAML config files in Symfony 1.1
At Dogster, we had a bunch of strings and settings that we wanted to keep out of our actions and place into their own YAML files instead of overloading the app.yml file. Here’s how I did it:
You can use this Filter to load the files we’ll setup in app.yml. Place this new PHP file at “symfony_project/apps/frontend/lib/addYmlFilter.class.php”.
class addYmlFilter extends sfFilter<br />
{
public function execute($filterChain)
{
// Execute this filter only once
if ($this->isFirstCall() && is_array(sfConfig::get(‘app_load_yml_files’)))
{
// Filters don’t have direct access to the request and user objects.
// You will need to use the context object to get them
foreach(sfConfig::get(‘app_load_yml_files’) as $file){
@include(sfContext::getInstance()->getConfigCache()->checkConfig(‘config/’.$file.’.yml’));
}
}
// Execute next filter
$filterChain->execute();
}<br />
}That filter takes care of all your caching and per-environment settings, the same as app.yml or the others in the config folder.
We will now setup four (4) new YAML files (config/paypal.yml, config/email.yml, config/flash.yml, config/forms.yml)
Place this in your app.yml file:
load:
yml_files:
0: paypal
1: email
2: flash
3: formsLastly, create a new YAML file “config/config_handlers.yml” with entries for each YAML file we would like to load:
config/paypal.yml:
class: sfDefineEnvironmentConfigHandler
param:
prefix: paypal_<br />
config/email.yml:
class: sfDefineEnvironmentConfigHandler
param:
prefix: email_<br />
config/forms.yml:
class: sfDefineEnvironmentConfigHandler
param:
prefix: forms_<br />
config/flash.yml:
class: sfDefineEnvironmentConfigHandler
param:
prefix: flash_Here is some example content you might find within email.yml:
all: admin: 'admin@example.com'
Once you load up Symfony, you should see all of your new config settings in the debug toolbar under “vars & config” > “SETTINGS”.
If you would like to place the new admin email setting within your code, you can now use sfConfig:
echo sfConfig::get(‘email_admin’);<br /> //outputs: admin@example.com
Simple!