Code snippets for symfony 1.x

Navigation

Snippets by user Halil Köklü

Define indicator for all ajax requests

I've found it annoying to set the show and hide commands on each remote request. So I've used this to define it globally:

/*
 * Defines the indicator globally
 */ 
Ajax.Responders.register({
  onCreate: function() { Element.show('indicator'); },
  onComplete: function() { Element.hide('indicator'); }
});
 
by Halil Köklü on 2007-09-16, tagged ajax  javascript 
(2 comments)

Doctrine-build-all(-load) workaround

It's very annoying that the pake tasks @doctrine-build-all@ and @doctrine-build-all-load@ don't work. So I've thought, why don't write a shell script which executes the single steps for me.

Just create a new file in your batch directory. For example 'build' or 'doctrine'

#!/usr/bin/env bash
 
symfony doctrine-drop-db <your app>
symfony doctrine-build-db <your app>
symfony doctrine-build-model <your app>
symfony doctrine-build-sql <your app>
symfony doctrine-insert-sql <your app>
 
php batch/<your load-data-batch-file>.php
by Halil Köklü on 2007-07-25, tagged batch  doctrine  model 

Double List for ManyToMany relationships (deprecated)

I needed the object_admin_double_list helper of the admin generator for my regular projects (without using admin generator). So I ported the admin_double_list helper a bit and now I want to publish this for you.

The admin_double_list helper is for selecting multiple items from a pool of items using ManyToMany relationships. For example to associate a user to multiple groups.

The helper itself has two parts: - two helper functions - two javascript functions

After that I have an example how the three controller, view and model parts handle this helper.

The snippet itself

Helper file

/**
 * two multiline select tags with associated and unassociated items
 *
 * @return string
 * @param object object
 * @param string method of object
 * @param array options
 * @param array html options of select tags
 **/
function double_list($object, $method, $options = array(), $html_options = array())
{
  $options = _parse_attributes($options);
 
  // get the lists of objects
  list($all_objects, $objects_associated, $associated_ids) = _get_object_list($object, $method, _get_option($options, 'through_class'));
 
  // options
  $html_options['multiple'] = _get_option($html_options, 'multiple', true);
  $html_options['size'] = _get_option($html_options, 'size', 10);
  $html_options['class'] = 'double_list';
 
  $label_assoc = _get_option($options, 'associated_label', 'Zugehörige Gruppen');
  $label_all   = _get_option($options, 'unassociated_label', 'Gruppenliste');
  $name1 = _get_option($options, 'associated', 'associated');
  $name2 = _get_option($options, 'unassociated', 'unassociated');
  $form = _get_option($options, 'form_id', 'editForm');
 
  // unassociated objects
  $objects_unassociated = array();
  foreach ($all_objects as $object)
  {
    if (!in_array($object->getPrimaryKey(), $associated_ids))
      $objects_unassociated[] = $object;
  }
 
  // select tags
  $select1 = select_tag($name1, options_for_select(_get_options_from_objects($objects_associated), '', $options), $html_options);
  unset($html_options['class']);
  $select2 = select_tag($name2, options_for_select(_get_options_from_objects($objects_unassociated), '', $options), $html_options);
 
  // output skeloton
  $html =
'<div style="float:left; padding-right: 20px;">
  <label for="%s">%s</label>
  %s
</div>
<div class="float:left; padding-right: 20px; padding-top: 20px">%s<br />%s</div>
<div class="float:left;">
  <label for="%s">%s</label>
  %s
</div>
<div style="clear:both"></div>';
 
  // include js library
  $response = sfContext::getInstance()->getResponse();
  $response->addJavascript('/js/double_list.js', 'last');
 
  return sprintf($html,
      $name1, $label_assoc, $select1,
      link_to_function(image_tag('resultset_previous'), "double_list_move(\$('{$name2}'), \$('{$name1}'))"),
      link_to_function(image_tag('resultset_next'), "double_list_move(\$('{$name1}'), \$('{$name2}'))", 'style=display:block'),
      $name2, $label_all, $select2,
      $form
    );
}
 
/**
 * retrieve object list via propel
 *
 * @return array
 * @param object root object
 * @param string retrieving method
 * @param string name of satellite class
 **/
function _get_object_list($object, $method, $middleClass)
{
  // get object
  $object = $object instanceof sfOutputEscaper ? $object->getRawValue() : $object;
 
  // get all objects
  $objects = sfPropelManyToMany::getAllObjects($object, $middleClass);
  // get related objects
  $objects_associated = sfPropelManyToMany::getRelatedObjects($object, $middleClass);
  // get ids
  $ids = array_map(create_function('$o', 'return $o->getPrimaryKey();'), $objects_associated);
 
  return array($objects, $objects_associated, $ids);
}
 

You probably want to modify the look of the list using css (like I do). So you can change the $js variable like you want f.e. adding class names. And you perhaps also want to change the image paths (I used two icons of the famfamfam icon library).

The javascript

Put the code below in a file called double_list.js in your js directory. (For individual path and file name, modify the double_list helper, search for $response)

function double_list_move(src, dest)
{
  for (var i = 0; i < src.options.length; i++)
  {
    if (src.options[i].selected)
    {
      dest.options[dest.length] = new Option(src.options[i].text, src.options[i].value);
      src.options[i] = null;
      --i;
    }
  }
}
 
function double_list_submit()
{
  // get all selects with double list class
    selects = $$('select.double_list');
 
    selects.each(function(element){
        for (var i = 0; i < element.options.length; i++)
            element.options[i].selected = true;
    });
 
    return true;
}
 

Example

I would like to show an example how to handle this helper in the three patterns.

The example is easy. Assigning an user to many groups.

Model layer

We have to build a table which handles the ManyToMany relationship.

user_group:
  _attributes:
    phpName:    UserGroup
  group_id:
    type:       integer
    primaryKey: true
    foreignTable:groups
    foreignReference:id
    onDelete:   cascade
  user_id:
    type:       integer
    primaryKey: true
    foreignTable:users
    foreignReference:id
    onDelete:   cascade
 

Don't forget to rebuild all db stuff and to clear the cache.

Presentation layer

Now we display the double_list:

<?php echo double_list($user, 'getUserGroups', 'through_class=UserGroup associated=groups unassociated=not_groups associated_label=Associated Groups unassociated_label=Group list') ?>
 

The first parameter is the user object, than the method of the object retrieving the UserGroup records. I think the options are clear.

Controller layer

At last we have to save the selection of the user. Before doing this we have to delete all UserGroup objects of the user, because we would assign it twice, if the item was selected before.

// clear group data to save it again
$c = new Criteria();
$c->add(UserGroupPeer::USER_ID, $user->getId());
UserGroupPeer::doDelete($c);
 
// save groups
$groups = $this->getRequestParameter('groups');
if ($groups)
{
  foreach ($groups as $id)
  {
    $group = new UserGroup();
    $group->setGroupId($id);
    $group->setUserId($user->getId());
    $group->save();
  }
}
 

It was a bit too long. As I said, this is a port of the original object_admin_double_list helper, which can be practically only used with the Admin Generator.

Please check the snippet, because I use this in a little bit more customized version.

by Halil Köklü on 2007-07-04, tagged admin  form  propel 
(2 comments)

Correct defect anti-aliasing of Gecko engines, displaying WebDebugBar

If you are displeased having different anti-aliasing of fonts in your Gecko Browsers (Camino, Firefox, Flock), when WebDebug is on. Gecko Browsers will show the fonts more thiner. But when you close WebDebug, the fonts will be normal again.

I think that this is not a acceptable casualty, so i deactivate the semi-transparence of the Bar. This will correct the behavior of the Gecko engine.

Just put the code in your css file (don't modify the css of web debug):

#sfWebDebugBar, .sfWebDebugCache {
  filter:alpha(opacity=100);
  -moz-opacity:1;
  opacity: 1;
}
by Halil Köklü on 2007-06-25, tagged css  debug 
(1 comment)

Hide Web Debug Details on Launch.

If you want to hide the Web Debug Details/Menus but also want to have quick access when you need it.

Then this could help you. Just copy this in a js file or print it in your layout:

/*
 * HIDE WEB DEBUG DETAILS ON LAUNCH
 */
Event.observe(window, 'load', function(){
    // check if web debug is on
    if ($('sfWebDebugBar'))
        sfWebDebugToggleMenu();
});
by Halil Köklü on 2007-06-25, tagged debug  javascript