Tag Archives: symfony

Not a big fan of the Web Developer toolbar? Me either! But I do use the logging system quite a bit. Thankfully, OS X ships with an useful application called Console that comes to the rescue.
- Open the Console application
- Go to File > Open and browse to your
frontend_dev.logor desired log file in the symfony logs directory - Click
Show Log Listand select your newly opened file to avoid the clutter of the rest of the OS logs - You’re done! You can now take advantage of features like clearing the view, search, and more
If you had used Symfony 1.2 with Swift 3 before, you probably sent emails like this:
try
{
$mailer = new Swift(new Swift_Connection_NativeMail());
$message = new Swift_Message('The subject', 'The body html', 'text/html');
$mailer->send($message, 'to@user.com', 'noreply@company.com');
$mailer->disconnect();
}
catch (Exception $e)
{
$mailer->disconnect();
}
However, due to API changes in Swift 4, that would have thrown an error:
Fatal error: Cannot instantiate abstract class Swift in /[...]/apps/frontend/modules/[...]/actions/actions.class.php on line 40
It turns out that now the class Swift is defined as abstract, which means it can’t be instantiated. Now, classes that you used to instantiate directly, like Swift_Message, have been added factory methods called newInstance
require_once('lib/vendor/swift/swift_init.php'); # needed due to symfony autoloader
$mailer = Swift_Mailer::newInstance(Swift_MailTransport::newInstance());
$message = Swift_Message::newInstance('The subject')
->setFrom(array('noreply@company.com' => 'Mailer Name'))
->setTo(array('email@email.com' => 'Name Lastname'))
->setBody('The body html', 'text/html');
$mailer->send($message);
Remember that it’s good practise to get the body HTML from a partial, instead of hardcoding it into the action.
$mailBody = $this->getPartial('emailPartial', array(/* parameters */));
// ...
->setBody($mailBody, 'text/html');
The code has become a lot more readable, easier to customize and write.
More information here and here.
A few weeks back a client relaunched a Facebook App that commended me to rewrite. The growth since then has been tremendous, with over 2000 registered users everyday, who upload pictures, make friends and comment on other users’ profiles. My application has been able to handle that growth perfectly in terms of responsiveness, but I was told that if the growing rate persisted, within only a few days the content would exceed the hard drive capacity.
The natural solution for these scenarios is a NFS mount, so that the content can be distributed across a network, which gives your application virtually limitless storage capacity. Joyent provides this service reliably.
The biggest challenge was to minimize the downtime, so these were the steps we took:
- Move all current files to the NFS mount to clear up disk space
-
Override the sf_upload_dir configuration directive. In settings.yml
all: upload_dir: /nfsmount/site/uploads -
Adjust the Apache VHost configuration with an alias that points outside the DocumentRoot (hence the need for a special
<Directory>)Alias /uploads /nfsmount/site/uploads
Order allow,deny Allow from all - Clear symfony cache and reload Apache. If your application is well-written, the change should be transparent to all the modules that deal with file uploads.
- Use
cp -uvRto make sure no images were left out from the initial copy.
Let’s say we want to create a field to set the password in plain text from the admin panel, then convert it to sha1 before saving it. Our hypothetical module will be located in backend/modules/admins/, which is a Symfony admin generator module for an AdminUser model.
First we define the getters and setters for the plaintext password in the AdminUser model:
public function setPasswordPlain($plain)
{
if(! empty($plain))
$this->setPassword(sha1($plain));
}
public function getPasswordPlain()
{
return "";
}
Then, in generator.yml we add this field to form sections, using the display parameter:
form:
display: [login, password_plain, email]
If we try the generator now, we’ll get an error message telling us that password_plain widget does not exist, which is true. The new admin generator uses the great Symfony 1.2 forms system, which treats a form as a set of widgets and validators.
If we inspect the lib directory of our generated module we’ll notice the file called adminsGeneratorConfiguration.class.php. This file extends BaseAdminsGeneratorConfiguration which, if we look closely, configures what form is related to this generated module:
public function getFormClass()
{
return 'AdminUserForm';
}
What we have to do is obvious. We extend AdminUserForm, and we override that method to return the name of our new class. In the same lib directory we create the form:
class myAdminUserForm extends BaseAdminUserForm
{
public function configure()
{
parent::configure();
$this->setWidget('password_plain', new sfWidgetFormInput());
$this->setValidator('password_plain', new sfValidatorString(array('max_length' => 255, 'required' => false)));
}
}
and finally we alter the adminsGeneratorConfiguration accordingly:
class adminsGeneratorConfiguration extends BaseAdminsGeneratorConfiguration
{
public function getFormClass()
{
return 'myAdminUserForm';
}
}