[ Index ]
 

Code source de Symfony 1.0.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/helper/ -> JavascriptHelper.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the symfony package.
   5   * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
   6   * (c) 2004 David Heinemeier Hansson
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  /**
  13   * JavascriptHelper.
  14   *
  15   * @package    symfony
  16   * @subpackage helper
  17   * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
  18   * @author     John Christopher <john.christopher@symfony-project.com>
  19   * @author     David Heinemeier Hansson
  20   * @version    SVN: $Id: JavascriptHelper.php 3500 2007-02-18 10:25:13Z fabien $
  21   */
  22  
  23  /*
  24   * Provides a set of helpers for calling JavaScript functions and, most importantly,
  25   * to call remote methods using what has been labelled AJAX[http://www.adaptivepath.com/publications/essays/archives/000385.php].
  26   * This means that you can call actions in your controllers without reloading the page,
  27   * but still update certain parts of it using injections into the DOM.
  28   * The common use case is having a form that adds a new element to a list without reloading the page.
  29   *
  30   * To be able to use the JavaScript helpers, you must include the Prototype JavaScript Framework
  31   * and for some functions script.aculo.us (which both come with symfony) on your pages.
  32   * Choose one of these options:
  33   *
  34   * * Use <tt><?php echo javascript_include_tag :defaults ?></tt> in the HEAD section of your page (recommended):
  35   *   The function will return references to the JavaScript files created by the +rails+ command in your
  36   *   <tt>public/javascripts</tt> directory. Using it is recommended as the browser can then cache the libraries
  37   *   instead of fetching all the functions anew on every request.
  38   * * Use <tt><?php echo javascript_include_tag 'prototype' ?></tt>: As above, but will only include the Prototype core library,
  39   *   which means you are able to use all basic AJAX functionality. For the script.aculo.us-based JavaScript helpers,
  40   *   like visual effects, autocompletion, drag and drop and so on, you should use the method described above.
  41   * * Use <tt><?php echo define_javascript_functions ?></tt>: this will copy all the JavaScript support functions within a single
  42   *   script block.
  43   *
  44   * For documentation on +javascript_include_tag+ see ActionView::Helpers::AssetTagHelper.
  45   *
  46   * If you're the visual type, there's an AJAX movie[http://www.rubyonrails.com/media/video/rails-ajax.mov] demonstrating
  47   * the use of form_remote_tag.
  48   */
  49  
  50    function get_callbacks()
  51    {
  52      static $callbacks;
  53      if (!$callbacks)
  54      {
  55        $callbacks = array_merge(array(
  56          'uninitialized', 'loading', 'loaded', 'interactive', 'complete', 'failure', 'success'
  57          ), range(100, 599));
  58      }
  59  
  60      return $callbacks;
  61    }
  62  
  63    function get_ajax_options()
  64    {
  65      static $ajax_options;
  66      if (!$ajax_options)
  67      {
  68        $ajax_options = array_merge(array(
  69          'before', 'after', 'condition', 'url', 'asynchronous', 'method',
  70          'insertion', 'position', 'form', 'with', 'update', 'script'
  71          ), get_callbacks());
  72      }
  73  
  74      return $ajax_options;
  75    }
  76  
  77    /**
  78     * Returns a link that'll trigger a javascript function using the
  79     * onclick handler and return false after the fact.
  80     *
  81     * Examples:
  82     *   <?php echo link_to_function('Greeting', "alert('Hello world!')") ?>
  83     *   <?php echo link_to_function(image_tag('delete'), "if confirm('Really?'){ do_delete(); }") ?>
  84     */
  85    function link_to_function($name, $function, $html_options = array())
  86    {
  87      $html_options = _parse_attributes($html_options);
  88  
  89      $html_options['href'] = isset($html_options['href']) ? $html_options['href'] : '#';
  90      $html_options['onclick'] = $function.'; return false;';
  91  
  92      return content_tag('a', $name, $html_options);
  93    }
  94  
  95    /**
  96     * Returns a button that'll trigger a javascript function using the
  97     * onclick handler and return false after the fact.
  98     *
  99     * Examples:
 100     *   <?php echo button_to_function('Greeting', "alert('Hello world!')") ?>
 101     */
 102    function button_to_function($name, $function, $html_options = array())
 103    {
 104      $html_options = _parse_attributes($html_options);
 105  
 106      $html_options['onclick'] = $function.'; return false;';
 107      $html_options['type']    = 'button';
 108      $html_options['value']   = $name;
 109  
 110      return tag('input', $html_options);
 111    }
 112    
 113    /**
 114     * Returns an html button to a remote action defined by 'url' (using the
 115     * 'url_for()' format) that's called in the background using XMLHttpRequest.
 116     *
 117     * See link_to_remote() for details.
 118     *
 119     */
 120    function button_to_remote($name, $options = array(), $html_options = array())
 121    {
 122      return button_to_function($name, remote_function($options), $html_options);
 123    }
 124  
 125    /**
 126     * Returns a link to a remote action defined by 'url'
 127     * (using the 'url_for()' format) that's called in the background using
 128     * XMLHttpRequest. The result of that request can then be inserted into a
 129     * DOM object whose id can be specified with 'update'.
 130     * Usually, the result would be a partial prepared by the controller with
 131     * either 'render_partial()'.
 132     *
 133     * Examples:
 134     *  <?php echo link_to_remote('Delete this post'), array(
 135     *    'update' => 'posts',
 136     *    'url'    => 'destroy?id='.$post.id,
 137     *  )) ?>
 138     *  <?php echo link_to_remote(image_tag('refresh'), array(
 139     *    'update' => 'emails',
 140     *    'url'    => '@list_emails',
 141     *  )) ?>
 142     *
 143     * You can also specify a hash for 'update' to allow for
 144     * easy redirection of output to an other DOM element if a server-side error occurs:
 145     *
 146     * Example:
 147     *  <?php echo link_to_remote('Delete this post', array(
 148     *      'update' => array('success' => 'posts', 'failure' => 'error'),
 149     *      'url'    => 'destroy?id='.$post.id,
 150     *  )) ?>
 151     *
 152     * Optionally, you can use the 'position' parameter to influence
 153     * how the target DOM element is updated. It must be one of
 154     * 'before', 'top', 'bottom', or 'after'.
 155     *
 156     * By default, these remote requests are processed asynchronous during
 157     * which various JavaScript callbacks can be triggered (for progress indicators and
 158     * the likes). All callbacks get access to the 'request' object,
 159     * which holds the underlying XMLHttpRequest.
 160     *
 161     * To access the server response, use 'request.responseText', to
 162     * find out the HTTP status, use 'request.status'.
 163     *
 164     * Example:
 165     *  <?php echo link_to_remote($word, array(
 166     *    'url'      => '@undo?n='.$word_counter,
 167     *    'complete' => 'undoRequestCompleted(request)'
 168     *  )) ?>
 169     *
 170     * The callbacks that may be specified are (in order):
 171     *
 172     * 'loading'                 Called when the remote document is being
 173     *                           loaded with data by the browser.
 174     * 'loaded'                  Called when the browser has finished loading
 175     *                           the remote document.
 176     * 'interactive'             Called when the user can interact with the
 177     *                           remote document, even though it has not
 178     *                           finished loading.
 179     * 'success'                 Called when the XMLHttpRequest is completed,
 180     *                           and the HTTP status code is in the 2XX range.
 181     * 'failure'                 Called when the XMLHttpRequest is completed,
 182     *                           and the HTTP status code is not in the 2XX
 183     *                           range.
 184     * 'complete'                Called when the XMLHttpRequest is complete
 185     *                           (fires after success/failure if they are present).,
 186     *
 187     * You can further refine 'success' and 'failure' by adding additional
 188     * callbacks for specific status codes:
 189     *
 190     * Example:
 191     *  <?php echo link_to_remote($word, array(
 192     *       'url'     => '@rule',
 193     *       '404'     => "alert('Not found...? Wrong URL...?')",
 194     *       'failure' => "alert('HTTP Error ' + request.status + '!')",
 195     *  )) ?>
 196     *
 197     * A status code callback overrides the success/failure handlers if present.
 198     *
 199     * If you for some reason or another need synchronous processing (that'll
 200     * block the browser while the request is happening), you can specify
 201     * 'type' => 'synchronous'.
 202     *
 203     * You can customize further browser side call logic by passing
 204     * in JavaScript code snippets via some optional parameters. In
 205     * their order of use these are:
 206     *
 207     * 'confirm'             Adds confirmation dialog.
 208     * 'condition'           Perform remote request conditionally
 209     *                       by this expression. Use this to
 210     *                       describe browser-side conditions when
 211     *                       request should not be initiated.
 212     * 'before'              Called before request is initiated.
 213     * 'after'               Called immediately after request was
 214     *                       initiated and before 'loading'.
 215     * 'submit'              Specifies the DOM element ID that's used
 216     *                       as the parent of the form elements. By
 217     *                       default this is the current form, but
 218     *                       it could just as well be the ID of a
 219     *                       table row or any other DOM element.
 220     */
 221    function link_to_remote($name, $options = array(), $html_options = array())
 222    {
 223      return link_to_function($name, remote_function($options), $html_options);
 224    }
 225  
 226    /**
 227     * Periodically calls the specified url ('url') every 'frequency' seconds (default is 10).
 228     * Usually used to update a specified div ('update') with the results of the remote call.
 229     * The options for specifying the target with 'url' and defining callbacks is the same as 'link_to_remote()'.
 230     */
 231    function periodically_call_remote($options = array())
 232    {
 233      $frequency = isset($options['frequency']) ? $options['frequency'] : 10; // every ten seconds by default
 234      $code = 'new PeriodicalExecuter(function() {'.remote_function($options).'}, '.$frequency.')';
 235  
 236      return javascript_tag($code);
 237    }
 238  
 239    /**
 240     * Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular
 241     * reloading POST arrangement. Even though it's using JavaScript to serialize the form elements, the form submission
 242     * will work just like a regular submission as viewed by the receiving side (all elements available in 'params').
 243     * The options for specifying the target with 'url' and defining callbacks are the same as 'link_to_remote()'.
 244     *
 245     * A "fall-through" target for browsers that don't do JavaScript can be specified
 246     * with the 'action'/'method' options on '$options_html'
 247     *
 248     * Example:
 249     *  <?php echo form_remote_tag(array(
 250     *    'url'      => '@tag_add',
 251     *    'update'   => 'question_tags',
 252     *    'loading'  => "Element.show('indicator'); \$('tag').value = ''",
 253     *    'complete' => "Element.hide('indicator');".visual_effect('highlight', 'question_tags'),
 254     *  )) ?>
 255     *
 256     * The hash passed as a second argument is equivalent to the options (2nd) argument in the form_tag() helper.
 257     *
 258     * By default the fall-through action is the same as the one specified in the 'url'
 259     * (and the default method is 'post').
 260     */
 261    function form_remote_tag($options = array(), $options_html = array())
 262    {
 263      $options = _parse_attributes($options);
 264      $options_html = _parse_attributes($options_html);
 265  
 266      $options['form'] = true;
 267  
 268      $options_html['onsubmit'] = remote_function($options).'; return false;';
 269      $options_html['action'] = isset($options_html['action']) ? $options_html['action'] : url_for($options['url']);
 270      $options_html['method'] = isset($options_html['method']) ? $options_html['method'] : 'post';
 271  
 272      return tag('form', $options_html, true);
 273    }
 274  
 275    /**
 276     *  Returns a button input tag that will submit form using XMLHttpRequest in the background instead of regular
 277     *  reloading POST arrangement. The '$options' argument is the same as in 'form_remote_tag()'.
 278     */
 279    function submit_to_remote($name, $value, $options = array(), $options_html = array())
 280    {
 281      $options = _parse_attributes($options);
 282      $options_html = _parse_attributes($options_html);
 283  
 284      if (!isset($options['with']))
 285      {
 286        $options['with'] = 'Form.serialize(this.form)';
 287      }
 288  
 289      $options_html['type'] = 'button';
 290      $options_html['onclick'] = remote_function($options).'; return false;';
 291      $options_html['name'] = $name;
 292      $options_html['value'] = $value;
 293  
 294      return tag('input', $options_html, false);
 295    }
 296  
 297    /**
 298     * Returns a Javascript function (or expression) that will update a DOM element '$element_id'
 299     * according to the '$options' passed.
 300     *
 301     * Possible '$options' are:
 302     * 'content'            The content to use for updating. Can be left out if using block, see example.
 303     * 'action'             Valid options are 'update' (assumed by default), 'empty', 'remove'
 304     * 'position'           If the 'action' is 'update', you can optionally specify one of the following positions:
 305     *                      'before', 'top', 'bottom', 'after'.
 306     *
 307     * Example:
 308     *   <?php echo javascript_tag(
 309     *      update_element_function('products', array(
 310     *            'position' => 'bottom',
 311     *            'content'  => "<p>New product!</p>",
 312     *      ))
 313     *   ) ?>
 314     *
 315     *
 316     * This method can also be used in combination with remote method call
 317     * where the result is evaluated afterwards to cause multiple updates on a page.
 318     *
 319     * Example:
 320     *
 321     *  # Calling view
 322     *  <?php echo form_remote_tag(array(
 323     *      'url'      => '@buy',
 324     *      'complete' => evaluate_remote_response()
 325     *  )) ?>
 326     *  all the inputs here...
 327     *
 328     *  # Target action
 329     *  public function executeBuy()
 330     *  {
 331     *     $this->product = ProductPeer::retrieveByPk(1);
 332     *  }
 333     *
 334     *  # Returning view
 335     *  <php echo update_element_function('cart', array(
 336     *      'action'   => 'update',
 337     *      'position' => 'bottom',
 338     *      'content'  => '<p>New Product: '.$product->getName().'</p>',
 339     *  )) ?>
 340     */
 341    function update_element_function($element_id, $options = array())
 342    {
 343      sfContext::getInstance()->getResponse()->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/prototype');
 344  
 345      $content = escape_javascript(isset($options['content']) ? $options['content'] : '');
 346  
 347      $value = isset($options['action']) ? $options['action'] : 'update';
 348      switch ($value)
 349      {
 350        case 'update':
 351          if (isset($options['position']) && $options['position'])
 352          {
 353            $javascript_function = "new Insertion.".sfInflector::camelize($options['position'])."('$element_id','$content')";
 354          }
 355          else
 356          {
 357            $javascript_function = "\$('$element_id').innerHTML = '$content'";
 358          }
 359          break;
 360  
 361        case 'empty':
 362          $javascript_function = "\$('$element_id').innerHTML = ''";
 363          break;
 364  
 365        case 'remove':
 366          $javascript_function = "Element.remove('$element_id')";
 367          break;
 368  
 369        default:
 370          throw new sfException('Invalid action, choose one of update, remove, empty');
 371      }
 372  
 373      $javascript_function .= ";\n";
 374  
 375      return (isset($options['binding']) ? $javascript_function.$options['binding'] : $javascript_function);
 376    }
 377  
 378    /**
 379     * Returns 'eval(request.responseText)', which is the Javascript function that
 380     * 'form_remote_tag()' can call in 'complete' to evaluate a multiple update return document
 381     * using 'update_element_function()' calls.
 382     */
 383    function evaluate_remote_response()
 384    {
 385      return 'eval(request.responseText)';
 386    }
 387  
 388    /**
 389     * Returns the javascript needed for a remote function.
 390     * Takes the same arguments as 'link_to_remote()'.
 391     *
 392     * Example:
 393     *   <select id="options" onchange="<?php echo remote_function(array('update' => 'options', 'url' => '@update_options')) ?>">
 394     *     <option value="0">Hello</option>
 395     *     <option value="1">World</option>
 396     *   </select>
 397     */
 398    function remote_function($options)
 399    {
 400      sfContext::getInstance()->getResponse()->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/prototype');
 401  
 402      $javascript_options = _options_for_ajax($options);
 403  
 404      $update = '';
 405      if (isset($options['update']) && is_array($options['update']))
 406      {
 407        $update = array();
 408        if (isset($options['update']['success']))
 409        {
 410          $update[] = "success:'".$options['update']['success']."'";
 411        }
 412        if (isset($options['update']['failure']))
 413        {
 414          $update[] = "failure:'".$options['update']['failure']."'";
 415        }
 416        $update = '{'.join(',', $update).'}';
 417      }
 418      else if (isset($options['update']))
 419      {
 420        $update .= "'".$options['update']."'";
 421      }
 422  
 423      $function = !$update ?  "new Ajax.Request(" : "new Ajax.Updater($update, ";
 424  
 425      $function .= '\''.url_for($options['url']).'\'';
 426      $function .= ', '.$javascript_options.')';
 427  
 428      if (isset($options['before']))
 429      {
 430        $function = $options['before'].'; '.$function;
 431      }
 432      if (isset($options['after']))
 433      {
 434        $function = $function.'; '.$options['after'];
 435      }
 436      if (isset($options['condition']))
 437      {
 438        $function = 'if ('.$options['condition'].') { '.$function.'; }';
 439      }
 440      if (isset($options['confirm']))
 441      {
 442        $function = "if (confirm('".escape_javascript($options['confirm'])."')) { $function; }";
 443        if (isset($options['cancel']))
 444        {
 445          $function = $function.' else { '.$options['cancel'].' }';
 446        }
 447      }
 448  
 449      return $function;
 450    }
 451  
 452    /**
 453     * Observes the field with the DOM ID specified by '$field_id' and makes
 454     * an AJAX call when its contents have changed.
 455     *
 456     * Required '$options' are:
 457     * 'url'                 'url_for()'-style options for the action to call
 458     *                       when the field has changed.
 459     *
 460     * Additional options are:
 461     * 'frequency'           The frequency (in seconds) at which changes to
 462     *                       this field will be detected. Not setting this
 463     *                       option at all or to a value equal to or less than
 464     *                       zero will use event based observation instead of
 465     *                       time based observation.
 466     * 'update'              Specifies the DOM ID of the element whose
 467     *                       innerHTML should be updated with the
 468     *                       XMLHttpRequest response text.
 469     * 'with'                A JavaScript expression specifying the
 470     *                       parameters for the XMLHttpRequest. This defaults
 471     *                       to 'value', which in the evaluated context
 472     *                       refers to the new field value.
 473     *
 474     * Additionally, you may specify any of the options documented in
 475     * link_to_remote().
 476     */
 477    function observe_field($field_id, $options = array())
 478    {
 479      sfContext::getInstance()->getResponse()->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/prototype');
 480  
 481      if (isset($options['frequency']) && $options['frequency'] > 0)
 482      {
 483        return _build_observer('Form.Element.Observer', $field_id, $options);
 484      }
 485      else
 486      {
 487        return _build_observer('Form.Element.EventObserver', $field_id, $options);
 488      }
 489    }
 490  
 491    /**
 492     * Like 'observe_field()', but operates on an entire form identified by the
 493     * DOM ID '$form_id'. '$options' are the same as 'observe_field()', except
 494     * the default value of the 'with' option evaluates to the
 495     * serialized (request string) value of the form.
 496     */
 497    function observe_form($form_id, $options = array())
 498    {
 499      sfContext::getInstance()->getResponse()->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/prototype');
 500  
 501      if (isset($options['frequency']) && $options['frequency'] > 0)
 502      {
 503        return _build_observer('Form.Observer', $form_id, $options);
 504      }
 505      else
 506      {
 507        return _build_observer('Form.EventObserver', $form_id, $options);
 508      }
 509    }
 510  
 511    /**
 512     * Returns a JavaScript snippet to be used on the AJAX callbacks for starting
 513     * visual effects.
 514     *
 515     * Example:
 516     *  <?php echo link_to_remote('Reload', array(
 517     *        'update'  => 'posts',
 518     *        'url'     => '@reload',
 519     *        'complete => visual_effect('highlight', 'posts', array('duration' => 0.5 )),
 520     *  )) ?>
 521     *
 522     * If no '$element_id' is given, it assumes "element" which should be a local
 523     * variable in the generated JavaScript execution context. This can be used
 524     * for example with drop_receiving_element():
 525     *
 526     *  <?php echo drop_receving_element( ..., array(
 527     *        ...
 528     *        'loading' => visual_effect('fade'),
 529     *  )) ?>
 530     *
 531     * This would fade the element that was dropped on the drop receiving element.
 532     *
 533     * You can change the behaviour with various options, see
 534     * http://script.aculo.us for more documentation.
 535     */
 536    function visual_effect($name, $element_id = false, $js_options = array())
 537    {
 538      $response = sfContext::getInstance()->getResponse();
 539      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/prototype');
 540      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/builder');
 541      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/effects');
 542  
 543      $element = $element_id ? "'$element_id'" : 'element';
 544  
 545      if (in_array($name, array('toggle_appear', 'toggle_blind', 'toggle_slide')))
 546      {
 547        return "new Effect.toggle($element, '".substr($name, 7)."', "._options_for_javascript($js_options).");";
 548      }
 549      else
 550      {
 551        return "new Effect.".sfInflector::camelize($name)."($element, "._options_for_javascript($js_options).");";
 552      }
 553    }
 554  
 555    /**
 556     * Makes the elements with the DOM ID specified by '$element_id' sortable
 557     * by drag-and-drop and make an AJAX call whenever the sort order has
 558     * changed. By default, the action called gets the serialized sortable
 559     * element as parameters.
 560     *
 561     * Example:
 562     *   <php echo sortable_element($my_list, array(
 563     *      'url' => '@order',
 564     *   )) ?>
 565     *
 566     * In the example, the action gets a '$my_list' array parameter
 567     * containing the values of the ids of elements the sortable consists
 568     * of, in the current order.
 569     *
 570     * You can change the behaviour with various options, see
 571     * http://script.aculo.us for more documentation.
 572     */
 573    function sortable_element($element_id, $options = array())
 574    {
 575      $response = sfContext::getInstance()->getResponse();
 576      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/prototype');
 577      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/builder');
 578      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/effects');
 579      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/dragdrop');
 580  
 581      if (!isset($options['with']))
 582      {
 583        $options['with'] = "Sortable.serialize('$element_id')";
 584      }
 585  
 586      if (!isset($options['onUpdate']))
 587      {
 588        $options['onUpdate'] = "function(){".remote_function($options)."}";
 589      }
 590  
 591      foreach (get_ajax_options() as $key)
 592      {
 593        unset($options[$key]);
 594      }
 595  
 596      foreach (array('tag', 'overlap', 'constraint', 'handle') as $option)
 597      {
 598        if (isset($options[$option]))
 599        {
 600          $options[$option] = "'{$options[$option]}'";
 601        }
 602      }
 603  
 604      if (isset($options['containment']))
 605      {
 606        $options['containment'] = _array_or_string_for_javascript($options['containment']);
 607      }
 608  
 609      if (isset($options['hoverclass']))
 610      {
 611        $options['hoverclass'] = "'{$options['hoverclass']}'";
 612      }
 613  
 614      if (isset($options['only']))
 615      {
 616        $options['only'] = _array_or_string_for_javascript($options['only']);
 617      }
 618  
 619      return javascript_tag("Sortable.create('$element_id', "._options_for_javascript($options).")");
 620    }
 621  
 622    /**
 623     * Makes the element with the DOM ID specified by '$element_id' draggable.
 624     *
 625     * Example:
 626     *   <?php echo draggable_element('my_image', array(
 627     *      'revert' => true,
 628     *   )) ?>
 629     *
 630     * You can change the behaviour with various options, see
 631     * http://script.aculo.us for more documentation.
 632     */
 633    function draggable_element($element_id, $options = array())
 634    {
 635      $response = sfContext::getInstance()->getResponse();
 636      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/prototype');
 637      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/builder');
 638      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/effects');
 639      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/dragdrop');
 640  
 641      return javascript_tag("new Draggable('$element_id', "._options_for_javascript($options).")");
 642    }
 643  
 644    /**
 645     * Makes the element with the DOM ID specified by '$element_id' receive
 646     * dropped draggable elements (created by 'draggable_element()') and make an AJAX call.
 647     * By default, the action called gets the DOM ID of the element as parameter.
 648     *
 649     * Example:
 650     *   <?php drop_receiving_element('my_cart', array(
 651     *      'url' => 'cart/add',
 652     *   )) ?>
 653     *
 654     * You can change the behaviour with various options, see
 655     * http://script.aculo.us for more documentation.
 656     */
 657    function drop_receiving_element($element_id, $options = array())
 658    {
 659      $response = sfContext::getInstance()->getResponse();
 660      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/prototype');
 661      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/builder');
 662      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/effects');
 663      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/dragdrop');
 664  
 665      if (!isset($options['with']))
 666      {
 667        $options['with'] = "'id=' + encodeURIComponent(element.id)";
 668      }
 669      if (!isset($options['onDrop']))
 670      {
 671        $options['onDrop'] = "function(element){".remote_function($options)."}";
 672      }
 673  
 674      foreach (get_ajax_options() as $key)
 675      {
 676        unset($options[$key]);
 677      }
 678  
 679      if (isset($options['accept']))
 680      {
 681        $options['accept'] = _array_or_string_for_javascript($options['accept']);
 682      }
 683  
 684      if (isset($options['hoverclass']))
 685      {
 686        $options['hoverclass'] = "'{$options['hoverclass']}'";
 687      }
 688  
 689      return javascript_tag("Droppables.add('$element_id', "._options_for_javascript($options).")");
 690    }
 691  
 692    /**
 693     * Returns a JavaScript tag with the '$content' inside.
 694     * Example:
 695     *   <?php echo javascript_tag("alert('All is good')") ?>
 696     *   => <script type="text/javascript">alert('All is good')</script>
 697     */
 698    function javascript_tag($content)
 699    {
 700      return content_tag('script', javascript_cdata_section($content), array('type' => 'text/javascript'));
 701    }
 702  
 703    function javascript_cdata_section($content)
 704    {
 705      return "\n//".cdata_section("\n$content\n//")."\n";
 706    }
 707  
 708    /**
 709     * wrapper for script.aculo.us/prototype Ajax.Autocompleter.
 710     * @param string name value of input field
 711     * @param string default value for input field
 712     * @param array input tag options. (size, autocomplete, etc...)
 713     * @param array completion options. (use_style, etc...)
 714     *
 715     * @return string input field tag, div for completion results, and
 716     *                 auto complete javascript tags
 717     */
 718    function input_auto_complete_tag($name, $value, $url, $tag_options = array(), $completion_options = array())
 719    {
 720      $context = sfContext::getInstance();
 721  
 722      $tag_options = _convert_options($tag_options);
 723  
 724      $response = $context->getResponse();
 725      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/prototype');
 726      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/effects');
 727      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/controls');
 728  
 729      $comp_options = _convert_options($completion_options);
 730      if (isset($comp_options['use_style']) && $comp_options['use_style'] == true)
 731      {
 732        $response->addStylesheet(sfConfig::get('sf_prototype_web_dir').'/css/input_auto_complete_tag');
 733      }
 734  
 735      $tag_options['id'] = get_id_from_name(isset($tag_options['id']) ? $tag_options['id'] : $name);
 736  
 737      $javascript  = input_tag($name, $value, $tag_options);
 738      $javascript .= content_tag('div', '' , array('id' => $tag_options['id'].'_auto_complete', 'class' => 'auto_complete'));
 739      $javascript .= _auto_complete_field($tag_options['id'], $url, $comp_options);
 740  
 741      return $javascript;
 742    }
 743  
 744    /**
 745     * wrapper for script.aculo.us/prototype Ajax.InPlaceEditor.
 746     * @param string name id of field that can be edited
 747     * @param string url of module/action to be called when ok is clicked
 748     * @param array editor tag options. (rows, cols, highlightcolor, highlightendcolor, etc...)
 749     *
 750     * @return string javascript to manipulate the id field to allow click and edit functionality
 751     */
 752    function input_in_place_editor_tag($name, $url, $editor_options = array())
 753    {
 754      $response = sfContext::getInstance()->getResponse();
 755      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/prototype');
 756      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/effects');
 757      $response->addJavascript(sfConfig::get('sf_prototype_web_dir').'/js/controls');
 758  
 759      $editor_options = _convert_options($editor_options);
 760      $default_options = array('tag' => 'span', 'id' => '\''.$name.'_in_place_editor', 'class' => 'in_place_editor_field');
 761  
 762      return _in_place_editor($name, $url, array_merge($default_options, $editor_options));
 763    }
 764  
 765    /**
 766     * Mark the start of a block that should only be shown in the browser if JavaScript
 767     * is switched on.
 768     */
 769    function if_javascript()
 770    {
 771      ob_start();
 772    }
 773  
 774    /**
 775     * Mark the end of a block that should only be shown in the browser if JavaScript
 776     * is switched on.
 777     */
 778    function end_if_javascript()
 779    {
 780      $content = ob_get_clean();
 781  
 782      echo javascript_tag("document.write('" . esc_js_no_entities($content) . "');");
 783    }
 784  
 785    /*
 786     * Makes an HTML element specified by the DOM ID '$field_id' become an in-place
 787     * editor of a property.
 788     *
 789     * A form is automatically created and displayed when the user clicks the element,
 790     * something like this:
 791     * <form id="myElement-in-place-edit-form" target="specified url">
 792     *   <input name="value" text="The content of myElement"/>
 793     *   <input type="submit" value="ok"/>
 794     *   <a onclick="javascript to cancel the editing">cancel</a>
 795     * </form>
 796     *
 797     * The form is serialized and sent to the server using an AJAX call, the action on
 798     * the server should process the value and return the updated value in the body of
 799     * the reponse. The element will automatically be updated with the changed value
 800     * (as returned from the server).
 801     *
 802     * Required '$options' are:
 803     * 'url'                 Specifies the url where the updated value should
 804     *                       be sent after the user presses "ok".
 805     *
 806     * Addtional '$options' are:
 807     * 'rows'                Number of rows (more than 1 will use a TEXTAREA)
 808     * 'cancel_text'         The text on the cancel link. (default: "cancel")
 809     * 'save_text'           The text on the save link. (default: "ok")
 810     * 'external_control'    The id of an external control used to enter edit mode.
 811     * 'options'             Pass through options to the AJAX call (see prototype's Ajax.Updater)
 812     * 'with'                JavaScript snippet that should return what is to be sent
 813     *                       in the AJAX call, 'form' is an implicit parameter
 814     */
 815      function _in_place_editor($field_id, $url, $options = array())
 816      {
 817        $javascript = "new Ajax.InPlaceEditor(";
 818  
 819        $javascript .= "'$field_id', ";
 820        $javascript .= "'" . url_for($url) . "'";
 821  
 822        $js_options = array();
 823  
 824        if (isset($options['tokens'])) $js_options['tokens'] = _array_or_string_for_javascript($options['tokens']);
 825  
 826        if (isset($options['cancel_text']))
 827        {
 828          $js_options['cancelText'] = "'".$options['cancel_text']."'";
 829        }
 830        if (isset($options['save_text']))
 831        {
 832          $js_options['okText'] = "'".$options['save_text']."'";
 833        }
 834        if (isset($options['cols']))
 835        {
 836          $js_options['cols'] = $options['cols'];
 837        }
 838        if (isset($options['rows']))
 839        {
 840          $js_options['rows'] = $options['rows'];
 841        }
 842        if (isset($options['external_control']))
 843        {
 844          $js_options['externalControl'] = "'".$options['external_control']."'";
 845        }
 846        if (isset($options['options']))
 847        {
 848          $js_options['ajaxOptions'] = $options['options'];
 849        }
 850        if (isset($options['with']))
 851        {
 852          $js_options['callback'] = "function(form, value) { return ".$options['with']." }";
 853        }
 854        if (isset($options['highlightcolor']))
 855        {
 856          $js_options['highlightcolor'] = "'".$options['highlightcolor']."'";
 857        }
 858        if (isset($options['highlightendcolor']))
 859        {
 860          $js_options['highlightendcolor'] = "'".$options['highlightendcolor']."'";
 861        }
 862        if (isset($options['loadTextURL']))
 863        {
 864          $js_options['loadTextURL'] =  "'".$options['loadTextURL']."'";
 865        }
 866  
 867        $javascript .= ', '._options_for_javascript($js_options);
 868        $javascript .= ');';
 869  
 870        return javascript_tag($javascript);
 871      }
 872  
 873    /**
 874     * wrapper for script.aculo.us/prototype Ajax.Autocompleter.
 875     * @param string id value of input field
 876     * @param string url of module/action to execute for autocompletion
 877     * @param array completion options
 878     * @return string javascript tag for Ajax.Autocompleter
 879     */
 880    function _auto_complete_field($field_id, $url, $options = array())
 881    {
 882      $javascript = "new Ajax.Autocompleter(";
 883  
 884      $javascript .= "'".get_id_from_name($field_id)."', ";
 885      if (isset($options['update']))
 886      {
 887        $javascript .= "'".$options['update']."', ";
 888      }
 889      else
 890      {
 891        $javascript .= "'".get_id_from_name($field_id)."_auto_complete', ";
 892      }
 893  
 894      $javascript .= "'".url_for($url)."'";
 895  
 896      $js_options = array();
 897      if (isset($options['tokens']))
 898      {
 899        $js_options['tokens'] = _array_or_string_for_javascript($options['tokens']);
 900      }
 901      if (isset ($options['with']))
 902      {
 903        $js_options['callback'] = "function(element, value) { return".$options['with']."}";
 904      }
 905      if (isset($options['indicator']))
 906      {
 907        $js_options['indicator']  = "'".$options['indicator']."'";
 908      }
 909      if (isset($options['on_show']))
 910      {
 911        $js_options['onShow'] = $options['on_show'];
 912      }
 913      if (isset($options['on_hide']))
 914      {
 915        $js_options['onHide'] = $options['on_hide'];
 916      }
 917      if (isset($options['min_chars']))
 918      {
 919        $js_options['minChars'] = $options['min_chars'];
 920      }
 921      if (isset($options['frequency']))
 922      {
 923        $js_options['frequency'] = $options['frequency'];
 924      }
 925      if (isset($options['update_element']))
 926      {
 927        $js_options['updateElement'] = $options['update_element'];
 928      }
 929      if (isset($options['after_update_element']))
 930      {
 931        $js_options['afterUpdateElement'] = $options['after_update_element'];
 932      }
 933  
 934      $javascript .= ', '._options_for_javascript($js_options).');';
 935  
 936      return javascript_tag($javascript);
 937    }
 938  
 939    function _options_for_javascript($options)
 940    {
 941      $opts = array();
 942      foreach ($options as $key => $value)
 943      {
 944        $opts[] = "$key:$value";
 945      }
 946      sort($opts);
 947  
 948      return '{'.join(', ', $opts).'}';
 949    }
 950  
 951    function _array_or_string_for_javascript($option)
 952    {
 953      if (is_array($option))
 954      {
 955        return "['".join('\',\'', $option)."']";
 956      }
 957      else if ($option)
 958      {
 959        return "'$option'";
 960      }
 961    }
 962  
 963    function _options_for_ajax($options)
 964    {
 965      $js_options = _build_callbacks($options);
 966  
 967      $js_options['asynchronous'] = (isset($options['type']) && ($options['type'] == 'synchronous')) ? 'false' : 'true';
 968      if (isset($options['method'])) $js_options['method'] = _method_option_to_s($options['method']);
 969      if (isset($options['position'])) $js_options['insertion'] = "Insertion.".sfInflector::camelize($options['position']);
 970      $js_options['evalScripts'] = (!isset($options['script']) || $options['script'] == '0' || $options['script'] == false) ? 'false' : 'true';
 971  
 972      if (isset($options['form']))
 973      {
 974        $js_options['parameters'] = 'Form.serialize(this)';
 975      }
 976      else if (isset($options['submit']))
 977      {
 978        $js_options['parameters'] = "Form.serialize(document.getElementById('{$options['submit']}'))";
 979      }
 980      else if (isset($options['with']))
 981      {
 982        $js_options['parameters'] = $options['with'];
 983      }
 984  
 985      return _options_for_javascript($js_options);
 986    }
 987  
 988    function _method_option_to_s($method)
 989    {
 990      return (is_string($method) && $method[0] != "'") ? "'$method'" : $method;
 991    }
 992  
 993    function _build_observer($klass, $name, $options = array())
 994    {
 995      if (!isset($options['with']) && $options['update'])
 996      {
 997        $options['with'] = 'value';
 998      }
 999  
1000      $callback = remote_function($options);
1001  
1002      $javascript  = 'new '.$klass.'("'.$name.'", ';
1003      if (isset($options['frequency']) && $options['frequency'] > 0)
1004      {
1005        $javascript .= $options['frequency'].", ";
1006      }
1007      $javascript .= "function(element, value) {";
1008      $javascript .= $callback.'});';
1009  
1010      return javascript_tag($javascript);
1011    }
1012  
1013    function _build_callbacks($options)
1014    {
1015      $callbacks = array();
1016      foreach (get_callbacks() as $callback)
1017      {
1018        if (isset($options[$callback]))
1019        {
1020          $name = 'on'.ucfirst($callback);
1021          $code = $options[$callback];
1022          $callbacks[$name] = 'function(request, json){'.$code.'}';
1023        }
1024      }
1025  
1026      return $callbacks;
1027    }
', [['lib/helper','JavascriptHelper.php',692]], 14], 'get_ajax_options': ['get_ajax_options', '', [['lib/helper','JavascriptHelper.php',63]], 2], 'add': ['add', 'Method called to associate a ".$tblFK->getPhpName()." object to this object through the $className foreign key attribute ', [['lib/vendor/propel-generator/classes/propel/engine/builder/om/php5','PHP5ComplexObjectBuilder.php',679],['lib/vendor/propel-generator/templates/om/php4','Object.tpl',833],['lib/util','sfParameterHolder.class.php',327],['lib/config','sfConfig.class.php',62],['lib/vendor/propel/util','Criteria.php',536],['lib/vendor/phing/lib','Zip.php',210],['data/bin','symfony.php',86],['lib/vendor/propel-generator/templates/om/php5','Object.tpl',740],['lib/addon/propel','sfPropelBehavior.class.php',50]], 119], '_options_for_ajax': ['_options_for_ajax', '', [['lib/helper','JavascriptHelper.php',963]], 1], 'get': ['get', 'Get the associated $className object ', [['lib/vendor/propel-generator/classes/propel/engine/builder/om/php5','PHP5ComplexObjectBuilder.php',370],['lib/vendor/propel-generator/classes/propel/engine/builder/om/php5','PHP5ComplexObjectBuilder.php',515],['lib/vendor/propel-generator/classes/propel/engine/builder/om/php5','PHP5ComplexObjectBuilder.php',757],['lib/vendor/pake','pakeTask.class.php',262],['lib/util','sfBrowser.class.php',71],['lib/cache','sfFileCache.class.php',210],['lib/vendor/phing/system/util','Properties.php',194],['lib/vendor/propel-generator/templates/om/php4','Object.tpl',162],['lib/vendor/propel-generator/templates/om/php4','Object.tpl',207],['lib/i18n','sfMessageCache.class.php',85],['lib/config','sfConfig.class.php',24],['lib/vendor/propel/util','Criteria.php',472],['lib/vendor/propel-generator/classes/propel/engine/builder/om/php5','PHP5BasicObjectBuilder.php',344],['lib/vendor/propel-generator/classes/propel/engine/builder/om/php5','PHP5BasicObjectBuilder.php',399],['lib/view/escaper','sfOutputEscaperGetterDecorator.class.php',34],['lib/cache','sfProcessCache.class.php',100],['lib/addon/propel/builder','SfObjectBuilder.php',158],['lib/vendor/creole/common','ResultSetCommon.php',289],['lib/vendor/creole','ResultSet.php',257],['data/generator/sfPropelAdmin/default/template/actions','actions.class.php',285],['lib/vendor/phing/lib','Capsule.php',196],['lib/vendor/propel-generator/templates/om/php5','Object.tpl',159],['lib/vendor/propel-generator/templates/om/php5','Object.tpl',194],['lib/vendor/propel-generator/templates/om/php5','Object.tpl',598],['lib/vendor/propel-generator/templates/om/php5','Object.tpl',791],['lib/vendor/propel-generator/templates/om/php5','Object.tpl',924],['lib/view','sfViewCacheManager.class.php',301],['lib/cache','sfSQLiteCache.class.php',175]], 885], 'visual_effect': ['visual_effect', 'Returns a JavaScript snippet to be used on the AJAX callbacks for starting visual effects. ', [['lib/helper','JavascriptHelper.php',511]], 6], 'form_remote_tag': ['form_remote_tag', 'Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular reloading POST arrangement. Even though it\'s using JavaScript to serialize the form elements, the form submission will work just like a regular submission as viewed by the receiving side (all elements available in \'params\'). The options for specifying the target with \'url\' and defining callbacks are the same as \'link_to_remote()\'. ', [['lib/helper','JavascriptHelper.php',239]], 4], 'periodically_call_remote': ['periodically_call_remote', 'Periodically calls the specified url (\'url\') every \'frequency\' seconds (default is 10). Usually used to update a specified div (\'update\') with the results of the remote call. The options for specifying the target with \'url\' and defining callbacks is the same as \'link_to_remote()\'. ', [['lib/helper','JavascriptHelper.php',226]], 3], 'javascript_cdata_section': ['javascript_cdata_section', '', [['lib/helper','JavascriptHelper.php',703]], 2], '_build_callbacks': ['_build_callbacks', '', [['lib/helper','JavascriptHelper.php',1013]], 1], '_array_or_string_for_javascript': ['_array_or_string_for_javascript', '', [['lib/helper','JavascriptHelper.php',951]], 5], 'sortable_element': ['sortable_element', 'Makes the elements with the DOM ID specified by \'$element_id\' sortable by drag-and-drop and make an AJAX call whenever the sort order has changed. By default, the action called gets the serialized sortable element as parameters. ', [['lib/helper','JavascriptHelper.php',555]], 4], 'if_javascript': ['if_javascript', 'Mark the start of a block that should only be shown in the browser if JavaScript is switched on. ', [['lib/helper','JavascriptHelper.php',765]], 5], 'camelize': ['camelize', 'Returns a camelized string from a lower case and underscored string by replaceing slash with double-colol and upper-casing each letter preceded by an underscore. ', [['lib/util','sfInflector.class.php',20]], 12], 'get_callbacks': ['get_callbacks', '', [['lib/helper','JavascriptHelper.php',50]], 2], 'esc_js_no_entities': ['esc_js_no_entities', 'A function the c-escapes a string, making it suitable to be placed in a JavaScript string. ', [['lib/helper','EscapingHelper.php',82]], 2], 'button_to_remote': ['button_to_remote', 'Returns an html button to a remote action defined by \'url\' (using the \'url_for()\' format) that\'s called in the background using XMLHttpRequest. ', [['lib/helper','JavascriptHelper.php',113]], 0], 'create': ['create', 'Creates the sequence emulation table. ', [['lib/vendor/creole/drivers/odbc','ODBCIdGenerator.php',97],['lib/vendor/phing/lib','Zip.php',142]], 25], 'end_if_javascript': ['end_if_javascript', 'Mark the end of a block that should only be shown in the browser if JavaScript is switched on. ', [['lib/helper','JavascriptHelper.php',774]], 4], '_parse_attributes': ['_parse_attributes', '', [['lib/helper','TagHelper.php',101]], 45], 'update_element_function': ['update_element_function', 'Returns a Javascript function (or expression) that will update a DOM element \'$element_id\' according to the \'$options\' passed. ', [['lib/helper','JavascriptHelper.php',297]], 8], 'get_id_from_name': ['get_id_from_name', 'Returns a formatted ID based on the $name parameter and optionally the $value parameter. ', [['lib/helper','FormHelper.php',855]], 14], '_auto_complete_field': ['_auto_complete_field', 'wrapper for script.aculo.us/prototype Ajax.Autocompleter. ', [['lib/helper','JavascriptHelper.php',873]], 1], 'getinstance': ['getinstance', 'Retrieve the singleton instance of this class. ', [['lib/util','sfContext.class.php',76],['lib/controller','sfRouting.class.php',34],['lib/config','sfConfigCache.class.php',31],['lib/i18n','sfDateTimeFormatInfo.class.php',172],['lib/log','sfLogger.class.php',60],['lib/debug','sfWebDebug.class.php',35],['lib/vendor/phing/types/selectors','SelectorUtils.php',43],['lib/i18n','sfNumberFormatInfo.class.php',175],['lib/i18n','sfI18N.class.php',29]], 141], '_build_observer': ['_build_observer', '', [['lib/helper','JavascriptHelper.php',993]], 4], 'input_auto_complete_tag': ['input_auto_complete_tag', 'wrapper for script.aculo.us/prototype Ajax.Autocompleter. ', [['lib/helper','JavascriptHelper.php',708]], 4], 'input_tag': ['input_tag', 'Returns an XHTML compliant tag with type="text". ', [['lib/helper','FormHelper.php',282],['doc','07-Inside-the-View-Layer.txt',42]], 29], '_in_place_editor': ['_in_place_editor', '', [['lib/helper','JavascriptHelper.php',815]], 1], 'addjavascript': ['addjavascript', 'Adds javascript code to the current web response. ', [['lib/response','sfWebResponse.class.php',541]], 35], '_method_option_to_s': ['_method_option_to_s', '', [['lib/helper','JavascriptHelper.php',988]], 1], 'content_tag': ['content_tag', '', [['lib/helper','TagHelper.php',40]], 21], '_options_for_javascript': ['_options_for_javascript', '', [['lib/helper','JavascriptHelper.php',939]], 8], 'observe_form': ['observe_form', 'Like \'observe_field()\', but operates on an entire form identified by the DOM ID \'$form_id\'. \'$options\' are the same as \'observe_field()\', except the default value of the \'with\' option evaluates to the serialized (request string) value of the form. ', [['lib/helper','JavascriptHelper.php',491]], 1], 'getresponse': ['getresponse', 'Retrieve the response. ', [['lib/util','sfContext.class.php',235],['lib/util','sfBrowser.class.php',261],['lib/action','sfComponent.class.php',178]], 106], 'observe_field': ['observe_field', 'Observes the field with the DOM ID specified by \'$field_id\' and makes an AJAX call when its contents have changed. ', [['lib/helper','JavascriptHelper.php',452]], 5], 'link_to_function': ['link_to_function', 'Returns a link that\'ll trigger a javascript function using the onclick handler and return false after the fact. ', [['lib/helper','JavascriptHelper.php',77]], 7], 'escape_javascript': ['escape_javascript', 'Escape carrier returns and single and double quotes for Javascript segments. ', [['lib/helper','TagHelper.php',55]], 3], 'ob_get_clean': ['ob_get_clean', '', [], 10], 'substr': ['substr', '', [], 384], 'is_array': ['is_array', '', [], 192], 'ob_start': ['ob_start', '', [], 19], 'array_merge': ['array_merge', '', [], 112], 'is_string': ['is_string', '', [], 37], 'in_array': ['in_array', '', [], 121], 'range': ['range', '', [], 1], 'serialize': ['serialize', '', [], 28], 'sort': ['sort', '', [], 11], 'ucfirst': ['ucfirst', '', [], 41]}; CLASS_DATA={ 'sfcontext': ['sfcontext', 'sfContext provides information about the current application context, such as the module and action names and the module directory. References to the current controller, request, and user implementation instances are also provided. ', [['lib/util','sfContext.class.php',12]], 82], 'sfconfig': ['sfconfig', 'sfConfig stores all configuration information for a symfony application. ', [['lib/config','sfConfig.class.php',11]], 714], 'sfinflector': ['sfinflector', '', [['lib/util','sfInflector.class.php',18]], 32], 'sfexception': ['sfexception', 'sfException is the base class for all symfony related exceptions and provides an additional method for printing up a detailed view of an exception. ', [['lib/exception','sfException.class.php',12]], 126]}; CONST_DATA={ };


Généré le : Fri Mar 16 22:42:14 2007 par Balluche grâce à PHPXref 0.7