Friday, December 9, 2011

Send Emails with PHP mail() in Symfony

Remove all mailer sections from factories.yml in apps/frontend-or-backend/config, then add this code to the "all" section:
mailer:
  class: sfMailer
  param:
    logging: %SF_LOGGING_ENABLED%
    charset: %SF_CHARSET%
    delivery_strategy: realtime
    transport:
      class: Swift_MailTransport

Saturday, November 12, 2011

Change =yourfield Link to Show View with sfAdminThemejRollerPlugin

  1. Change class to jRollerDoctrineGenerator in generator.yml.
  2. Add extra: [show] to the param section.
That's all. Clear cache.

Show view does not accept actions parameter in sfAdminThemejRollerPlugin

Change getShowActions() method in plugins / sfAdminThemejRollerPlugin / data / generator / sfDoctrineModule / joller / parts / showConfiguration.php to this:
public function getShowActions()
  {
    return <?php echo isset($this->config['show']['actions']) ? $this->asPhp($this->config['show']['actions']) : "array(  '_list' => NULL,  '_edit' => NULL, '_delete' => NULL)" ?>;
    <?php unset($this->config['show']['actions']) ?>
  }

Source and Thanks to Ton Sharp.

Monday, November 7, 2011

Session Cookie Name and Timeout in Symfony

In apps/frontend or backend or other/config/factories.yml... put this to the all section:
  user:
    class: myUser
    param:
      timeout: 43200
          
  storage:
    class: sfSessionStorage
    param:
      session_name: frontend
Don't forget to clear the cache and set the value of session.gc_maxlifetime to the same or a bit higher than 43200 in php.ini.

Monday, October 24, 2011

Enable Virtual Host Site

Enable: a2ensite mysiteavailable-site
Disable: a2dissite mysiteavailable-site

Friday, October 21, 2011

Format getCreatedAt and getUpdatedAt in Symfony

Example....
echo $article->getDateTimeObject('created_at')->format('m/d/Y');

Thursday, October 6, 2011

Clear Cache from Action in Symfony

/**
 * Delete cache for application and environment
 *
 * @param string $app aplicación
 * @param string $env entorno
 */
function clear_cache ($app, $env)
{
  $cacheDir = sfConfig::get('sf_cache_dir').'/'. $app.'/'.$env.'/';

  //Clear cache
  $cache = new sfFileCache(array('cache_dir' => $cacheDir));
  $cache->clean();
}

Tuesday, August 16, 2011

Get the Label Text of a Form Field in Symfony

$form->getWidgetSchema()->getLabel('fieldname')

Friday, August 12, 2011

Check Symfony Environment in Javascript

function prefix() {
  return window.location.href.indexOf('frontend_dev.php') != -1 ? '/frontend_dev.php' : '';
}

function example() {
  window.open(prefix()+'/module/action');
}

Thursday, August 11, 2011

Login Automagicly to phpMyAdmin 3.4

Change the config.inc.php file...

$cfg['Servers'][$i]['auth_type'] = 'config';
$cfg['Servers'][$i]['user'] = 'YOUR USER';
$cfg['Servers'][$i]['password'] = 'YOUR PASSWORD';

Wednesday, August 3, 2011

Generate an Excel file with sfPhpExcel in Symfony

  public function executeExcel(sfWebRequest $request)
  {
    // We're not going to be displaying any html, so no need to pass the data through the template
    $this->setLayout(false);

    // Initialize the Excel document
    $obj = new PHPExcel();
       
    // Set the active excel sheet
    $obj->setActiveSheetIndex(0);
    
    $obj->setActiveSheetIndex(0);
    $obj->getActiveSheet()->setCellValue('A1', 'Hello');
    $obj->getActiveSheet()->setCellValue('B2', 'world!');
    $obj->getActiveSheet()->setCellValue('C1', 'Hello');
    $obj->getActiveSheet()->setCellValue('D2', 'world!');
    
    // Output the excel data to a file
    $filePath = realpath('./excel') . DIRECTORY_SEPARATOR . 'excel.xlsx';
    $writer = PHPExcel_IOFactory::createWriter($obj, 'Excel2007');
    $writer->save($filePath);
    
    // Redirect request to the outputed file
    $this->getResponse()->setHttpHeader('Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    $this->redirect('/excel/excel.xlsx');
  }

Tuesday, August 2, 2011

Calling the i18n Function __() in an Action in Symfony

$this->getContext()->getI18N()->__($text, $args, 'messages');

Monday, May 30, 2011

Get the Route Name in Symfony

In View, Layout:
sfContext::getInstance()->getRouting()->getCurrentRouteName();

In Action:
$this->getContext()->getRouting()->getCurrentRouteName();

Thursday, April 21, 2011

Display Confirm Message before a Custom Object Action with Admin Generator in Symfony

        object_actions:
          _edit: ~
          send: { params: { onclick : "if(confirm('Are you sure?')){return true;}else{return false;}" } }

Form Validation Errors At Top of the Page in Symfony

    <?php foreach($form->getWidgetSchema()->getPositions() as $widgetName): ?> <?php if($form[$widgetName]->hasError()): ?>
  • <?php echo $form[$widgetName]->renderLabelName().': '.__($form[$widgetName]->getError()->getMessageFormat()); ?>
  • <?php endif; ?> <?php endforeach; ?>

Monday, April 18, 2011

Show HTML Tags Instead of Entities in Flash Messages in Symfony

Use this instead:
$sf_user->getFlash('msg', ESC_RAW);

Send Email with Gmail SMTP in Symfony

Put this to the fatories.yml:
  mailer:
    param:
      transport:
        class: Swift_SmtpTransport
        param:
          host:       smtp.gmail.com
          port:       465
          encryption: ssl
          username:   "...@gmail.com"
          password:   "..."

Thursday, April 7, 2011

Mime Type Problem when Uploading DOC, DOCX, ODT Files in Symfony

If you create a DOC file with OpenOffice, its mimetype will be application/octet-stream, that can be anything binary data. Of course, you can't allow this mimetype at uploading.

If you try to upload DOCX and ODT files, symfony will recognise them as a ZIP archive. To corrrect this and the OpenOffice DOC mimetype problem, add the 'mime_type_guessers' option to sfValidatorFile:
$this->setValidator('filename', new sfValidatorFile(array(
      'max_size' => ...,
      'path' => ...,
      'mime_type_guessers' => array('guessFromFileinfo'),
      'required' => ...,
      ...

Convert RTF to TEXT with PHP and Linux

I always use UnRTF to get text from RTF files. The simplest way to convert the rtf file to html, then use the strip_tags method.
exec("unrtf test.rtf", $output);
echo strip_tags(implode('', $output));
However UnRTF is not fully compatible with UTF-8, it has problems with accents, ex. with the Hungarian accents, thus, I had to correct the Hungarian accents this way:
$from = array("Û", "û", "õ", "Õ");
$to = array("Ű", "ű", "ő", "Ő");

exec("unrtf test.rtf", $output);
echo strip_tags(str_replace($from, $to, html_entity_decode(implode('', $output), ENT_QUOTES, 'UTF-8')));

Convert ODT to TEXT with PHP

Shorter way (requires odt2txt installed and shell_exec enabled):
echo shell_exec("odt2txt --encoding=utf8 test.odt");
Longer way (requires PHP 5.2+ and ZIP extension enabled):
function odt2text($filename) {
    return readZippedXML($filename, "content.xml");
}

function readZippedXML($archiveFile, $dataFile) {
    // Create new ZIP archive
    $zip = new ZipArchive;

    // Open received archive file
    if (true === $zip->open($archiveFile)) {
        // If done, search for the data file in the archive
        if (($index = $zip->locateName($dataFile)) !== false) {
            // If found, read it to the string
            $data = $zip->getFromIndex($index);
            // Close archive file
            $zip->close();
            // Load XML from a string
            // Skip errors and warnings
            $xml = DOMDocument::loadXML($data, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING);
            // Return data without XML formatting tags
            return strip_tags($xml->saveXML());
        }
        $zip->close();
    }

    // In case of failure return empty string
    return "";
}

echo odt2text("test.odt");

Convert DOCX to TEXT with PHP

First, you have to use PHP 5.2+ and enable the ZIP (ZipArchive) extension for PHP.
function docx2text($filename) {
    return readZippedXML($filename, "word/document.xml");
}

function readZippedXML($archiveFile, $dataFile) {
    // Create new ZIP archive
    $zip = new ZipArchive;

    // Open received archive file
    if (true === $zip->open($archiveFile)) {
        // If done, search for the data file in the archive
        if (($index = $zip->locateName($dataFile)) !== false) {
            // If found, read it to the string
            $data = $zip->getFromIndex($index);
            // Close archive file
            $zip->close();
            // Load XML from a string
            // Skip errors and warnings
            $xml = DOMDocument::loadXML($data, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING);
            // Return data without XML formatting tags
            return strip_tags($xml->saveXML());
        }
        $zip->close();
    }

    // In case of failure return empty string
    return "";
}

echo docx2text("test.docx"); 

Wednesday, April 6, 2011

Convert DOC to TEXT with PHP and Linux

$file     = $directory.'/'.$filename;
$fileinfo = pathinfo($filename);
$content  = "";

// doc to text
if($fileinfo['extension'] == 'doc')
{
   $content = shell_exec("antiword -m UTF-8.txt -t $file");
}

Convert PDF to TEXT with PHP and Linux

To install pdftotext, use: apt-get install xpdf
$file     = $directory.'/'.$filename;
$fileinfo = pathinfo($filename);
$content  = "";

// pdt to text
if($fileinfo['extension'] == 'pdf')
{
   $outpath = preg_replace("/\.pdf$/", "", $file).".txt";
   system("pdftotext -enc UTF-8 ".escapeshellcmd($file), $ret);
   if($ret == 0) {
      $content = file_get_contents($outpath);
      unlink($outpath);
   }
}

Monday, April 4, 2011

Correct the Icon Position of sfAdminThemejRollerPlugin Buttons in IE, Chrome, Safari

Use this code in the layout after the CSS definitions....

    

Tuesday, March 29, 2011

Create the Mobile Version of a Symfony WebSite

Change the config/ProjectConfiguration.class.php file. Add a new row to the setup method and add a completely new method to the class:
public function setup()
  {
    ...

    $this->dispatcher->connect('request.filter_parameters', array($this, 'filterRequestParameters'));
  }

  public function filterRequestParameters(sfEvent $event, $parameters)
  {
    $request = $event->getSubject();

    if(preg_match('#^(?!.*iPad).*(Mobile|Jasmine|Symbian|NetFront|BlackBerry|Opera Mini|Opera Mobi).*$#i', $request->getHttpHeader('User-Agent')))
    {
      $request->setRequestFormat('mobile');
    }

    return $parameters;
  }
That's all. Now you have to create the mobile version of your layout (layout.mobile.php), your templates (ex. showSuccess.mobile.php), your partials (ex. _menu.mobile.php). Then you can try to open your site with your mobile, or you can use an emulator like Opera Mobile Emulator.

ps: you can use the $request->getRequestFormat() in an action which returns with "mobile".
ps2: Useful urls:
How to create an optimized version of your website for the iPhone in symfony 1.1
WebMozarts - Creating mobile symfony sites
Symfony users - mobile site strategy  

Disable the Web Debug Toolbar in an Action in Symfony

Simply use...
sfConfig::set('sf_web_debug', false);

Tuesday, February 8, 2011

Remove User Attribute in Symfony

$this->getUser()->getAttributeHolder()->remove('attribute_name');

Saturday, January 29, 2011

Create Object with More Doctrine Translation

$country = new Country();

// set a language-independent value
$country->setCountryCode('H');

// set translations
$country->Translation['hu']->name = 'Magyarország';
$country->Translation['en']->name = 'Hungary';
$country->Translation['de']->name = 'Ungarn';

$country->save();

Thursday, January 27, 2011

Truncate Table with Doctrine

$doctrine = Doctrine_Manager::getInstance()->getCurrentConnection()->getDbh();
$doctrine->query('TRUNCATE TABLE tableName');
unset($doctrine);

Sunday, January 23, 2011

Work with Doctrine Migration in Symfony

To update your schema, classes, database without losing data, try to do this...
  1. Change your schema.yml file.
  2. Use the symfony doctrine:generate-migrations-diff command to generate the differences between the current classes and the changed schema. These changes are converted by Doctrine into a migrations files, you can find them in the lib/migration directory. In the filename you will see a version number.
  3. Type the symfony doctrine:migrate x command to update your database. x is the version number you found in the filename of the last migration file.
  4. Type the symfony doctrine:build --all-classes command to generate new classes for symfony.
Symfony will create a migration_version table in the database to store the current migration version number.

Saturday, January 22, 2011

Remove Dotted Outline On Links and Buttons

button::-moz-focus-inner,
input[type="reset"]::-moz-focus-inner,
input[type="button"]::-moz-focus-inner,
input[type="submit"]::-moz-focus-inner,
input[type="file"] > input[type="button"]::-moz-focus-inner {
    border: 1px dotted transparent;
}
* {
    outline: none;
}

Saturday, January 15, 2011

Remove 'is empty' checkbox from Filter Form in Symfony

Use the following line in the filter form's setup or configure function:
$this->getWidget('name')->setOption('with_empty', false);

Adding Config Parameters to sfWidgetFormCKEditor

$this->setWidget('content', new sfWidgetFormCKEditor(array('jsoptions' => array('toolbar' => 'Basic', 'width' => '100%', 'height' => '280px'))));

Friday, January 7, 2011

Allow Extra Fields in Symfony Forms

$this->validatorSchema->setOption('allow_extra_fields', true);

Tuesday, January 4, 2011

Sort By Foreign Key or Custom Column in Symfony Admin Generator

This solution is works with Doctrine ORM.
  1. Put this to the backend module's actions.class.php
    protected function addSortQuery($query)
      {
        $rootAlias = $query->getRootAlias();
        if (array(null, null) == ($sort = $this->getSort()))
        {
          return;
        }
        $s = $sort[0];
        $fields = $this->varHolder->get('configuration')->getFieldsDefault();
        if ($fields != null)
        {
          $field = $fields[$s];
          if ($field != null)
          {
            if (isset($field['sortBy']))
            {
              $criterion = $field['sortBy'];
              if ($criterion != null)
              {
                $s = $criterion;
              }
            }
          }
        }
        
        if (isset($field['noRootAlias']) && $field['noRootAlias'] == true)
        {
          $query->addOrderBy($s . ' ' . $sort[1]);
        }
        else
        {
          $query->addOrderBy($rootAlias.'.'.$s . ' ' . $sort[1]);
        }
      }
    
  2. Let's see first the foreign key sorting with an example. If you want to show the related object's name instead of its id, you must use the relation name (in this case 'Group'). To enable sorting, add the sortBy parameter to the field.
    config:
          ...
          fields:
            name:    { label: Name }
            Group:   { label: Group, sortBy: Group.name }  
          list:
            title:   Users
            display: [id, name, Group]
    
    That's all, the sorting now works, but the column's name is not clickable yet. You have to change the generator's template. As I use the sfAdminThemejRollerPlugin, I will do this with that.
  3. Open the \ plugins \ sfAdminThemejRollerPlugin \ data \ generator \ sfDoctrineModule \ jroller \ template \ templates \ _list_th_tabular.php file and change the 4th row from this:
    <?php if ($field->isReal()): ?>
    to this:
    <?php if ($field->isReal() || $field->getConfig('sortBy')): ?>
    Now the foreign key sorting must work.
  4. Let's see the custom column sorting with an example. The data you will want to see in the custom column is somewhere in the database. You have to add your custom column to the original sql statement. Use joins, relations or simply subqueries. You can overwrite the sql in backend module's actions.class.php:
    protected function buildQuery()
      {
         $query = parent::buildQuery();
         // do what ever you like with the query    
         // use the die($query->getSqlQuery()); row to see the original sql statement
         return $query->addSelect('*, (SELECT foo FROM bar) as foobarcolumn');
      }
    As you can see I didn't change the query output, I only add an extra column to the query.
  5. Now we have to add this column to the generator.yml...
    config:
          ...
          fields:
            name:    { label: Name }
            Group:   { label: Group, sortBy: Group.name }
            foobar:  { label: FooBar, sortBy: foobarcolumn, noRootAlias: true }
          list:
            title:   Users
            display: [id, name, Group, foobar]
    
I hope this helps. The noRootAlias param is created by me, perhaps you won't need it or you can avoid using it. If you have an easier/better solution, please tell me!

Monday, January 3, 2011

Enable Frontend Logging in Production Environment in Symfony

  1. Enable logging in frontend/config/settings.yml.
    logging_enabled: true
  2. Change the code below in the prod section of the factories.yml:
      logger:
        class:   sfNoLogger
        param:
          level:   err
          loggers: ~
    
    with this:
      logger:
        class: sfAggregateLogger
        param:
          level: debug
          loggers:
            sf_web_debug:
              class: sfWebDebugLogger
              param:
                level: debug
                condition:       %SF_WEB_DEBUG%
                xdebug_logging:  true
                web_debug_class: sfWebDebug
            sf_file_debug:
              class: sfFileLogger
              param:
                level: debug
                file: %SF_LOG_DIR%/%SF_APP%_%SF_ENVIRONMENT%.log