Tag: symfony

Symfony 1.4: Doctrine and SQL Azure

 

To get your SQL Azure DB running with Symony 1.4 and Doctrine 1.2.4 you need to make the following changes:

In databases.yml:

all:
  doctrine:
    class: sfDoctrineDatabase
    param:
      dsn:      odbc:DRIVER={SQL Server Native Client 10.0};Server=SERVER.database.windows.net;Database=DATABASE;Encrypt=yes;
      username: USERNAME@SERVER
      password: PASSWORD

Sadly there appeard some ugly errors, but I could fix them (please don’t ask me how I found the solutions).

The first error appeared trying to build the model:

When using the attribute ATTR_AUTO_ACCESSOR_OVERRIDE you cannot use the field name “defaultculture” because it is reserved by Doctrine. You must cho
ose another field name.

In my case it’s not possible to change the field name because the DB schema is not under my control. To solve this I did the follwing changes:

In symfony/lib/plugins/sfDoctrinePlugin/config/sfDoctrinePluginConfiguration.class.php deactivate the setting ATTR_AUTO_ACCESSOR_OVERRIDE:

$manager->setAttribute(Doctrine_Core::ATTR_AUTO_ACCESSOR_OVERRIDE, false);

And in symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Import/Mssql.php I had to change:

    public function listTableColumns($table)
    {
        #$sql = 'EXEC sp_primary_keys_rowset @table_name = ' . $this->conn->quoteIdentifier($table, true);
        $sql = 'EXEC sp_pkeys @table_name = ' . $this->conn->quoteIdentifier($table, true);

The changes inside the Doctrine Plugin are not clean, it should be an accrodingly extension, but it worked for my quick requirement to generate a schema out of the database.

EDIT:

For some reason I got again an error while trying to build the schema out of the SQL Azure database:

SQLSTATE[42000]: Syntax error or access violation: 156 [Microsoft][SQL Server Native Client 10.0][SQL Server]Incorrect syntax near the keyword ‘File’. (SQLExecute[156] at ext\pdo_odbc\odbc_stmt.c:254). Failing Query: “EXEC sp_pkeys @table_name = File”

and

SQLSTATE[42000]: Syntax error or access violation: 156 [Microsoft][SQL Server Native Client 10.0][SQL Server]Incorrect syntax near the keyword ‘File’. (SQLExecute[156] at ext\pdo_odbc\odbc_stmt.c:254). Failing Query: “EXEC sp_columns @table_name = File”

To solve the problem I need to modifie the change I did in

symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Import/Mssql.php:

    public function listTableColumns($table)
    {
        #$sql = 'EXEC sp_primary_keys_rowset @table_name = ' . $this->conn->quoteIdentifier($table, true);
        $sql = 'EXEC sp_pkeys @table_name = ' . $this->conn->quoteIdentifier($table, false);
        ...
        #$sql     = 'EXEC sp_columns @table_name = ' . $this->conn->quoteIdentifier($table, true);
        $sql     = 'EXEC sp_columns @table_name = ' . $this->conn->quoteIdentifier($table, false);

I changed the 2nd quoteIdentifier parameter to “false“.


Windows Azure and symfony 1.4 important php.ini settings

When you try to get symfony running (for instance with windowsazure4e) there will occur some problems with the deployed version.

I could solve the problems with these very important php.ini settings:

  • Locate the “cgi.force_redirect” setting and remove the comment and set the value to “0“‘ (Note: 0 for IIS and 1 for Apache or iPlanet).
  • Locate the “cgi.fix_pathinfo” setting and remove the comment. Leave the value as “1” (Note: cgi.fix_pathinfo provides full PATH_INFO/PATH_TRANSLATED support for CGI. Previously the behavior of PHP was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to ignore PATH_INFO. For more information on PATH_INFO, see the cgi specs. Setting this to 1 will cause PHP CGI to fix its paths to conform to the spec.).
  • Locate the “fastcgi.impersonate” setting and remove the comment, leave the value as “1” (Note: FastCGI under IIS supports the ability to impersonate security tokens of the calling client. This allows IIS to define the security context that the request runs under.).
  • Locate “extension_dir” and set it to “ext“.

PHP: Symfony Framework Pros&Contras

Im Folgenden werden u.a. die Pros und Contras des Symfony-Frameworks vorgestellt, welches für viele als eine mögliche Alternative zur aktuellen Lösung angesehen wird.

Definition

Das Symfony-Framework wurde von Sensio Labs entwickelt. Es kapselt jahrelange Erfahrung der PHP-Entwicklung und vereinfacht enorm die Entwicklung mittlerer bis großer Web-Projekte. Es ist aus der Idee heraus entstanden das perfekte Tool für Web-Entwickler zu kreieren die Kunden mit hoch performanten Ansprüchen bedienen.

Symfony basiert auf dem MVC Design-Pattern und versucht die Entwickler selbst dazu zu bringen sauberen, gut strukturierten Code zu produzieren. D.h. in Templates nur Präsentationslogik, Controller lediglich als eine Art schlankes Batch-Script zu gebrauchen und die Businesslogik in den Modell- und Form-Klassen zu hinterlegen.

Es bietet zahlreiche Hilfsmittel um die Entwicklungszeit von komplexen Web-Applikationen stark zu reduzieren. Außerdem sind gängige Aufgaben automatisiert, so dass sich die Entwickler mehr auf die Anwendungslogik konzentrieren können. Ziel ist es das Rad nicht immer wieder neu zu erfinden wenn eine neue Web-Applikation entwickelt wird.

Symfony ist komplett in PHP geschrieben und hat sich bereits in zahlreichen Real-World-Projekten bewiesen. Darunter auch High-Demand Webseiten (z.B. delicious.com und answers.yahoo.com, dailymotion.com).

Symfony Features

Symfony wurde entwickelt um die folgenden Anforderungen zu erfüllen:

  • Einfach auf den gängigsten Plattformen zu installieren und konfigurieren.
  • Datenbank-Engine-Unabhängig.
  • Ãœberwiegend einfach zu benutzen aber dennoch flexibel genug um komplexe Klassen zu adaptieren.
  • Verträglich mit den meisten Web-Best-Practises.
  • Stabil genug für Langzeit-Projekte.
  • Sehr lesbarer Code mit phpDocumenter-Kommentaren für einfache Wartung.
  • Einfach zu erweitern. Integration von anderen Code-Bibliotheken ist möglich.
  • Ein Mal geschriebener Code soll möglichst einfach wiederverwendbar sein (Components, Slots).

Webprojekt-Features

  • Symfony Autoloader für .class.php Dateien in lib-Verzeichnissen.
  • Parameter-Holder für saubere Ãœbergabe von http-Request Parametern mit Getter und Setter.
  • Internationalisierungs-Ebene.
  • Die Präsentations-Ebene ist Template-basiert und unterstützt AJAX-Funktionalitäten (jQuery).
  • Formulare lassen sich automatisiert validieren und einfach wiederverwenden.
  • Ausgabefilterung schätzt vor Cross-Site-Scripting durch korrupte Daten.
  • Die Cache-Management-Features reduzieren die Bandbreitennutzung und den Server-Load.
  • Authentifizierungs- und Rechtefeatures vereinfachen die Erstellung von geschätzten Bereichen und ermöglichen Benutzer-Sicherheits-Management.
  • Routing und Smart URLs machen Seitenadressen Suchmaschinen tauglich.
  • E-Mail-Management (SWIFT-Mailer).
  • Benutzerfreundliche Listen durch automatisch generierte Pager, Sortierer und Filter.
  • Factories, Plugins und Events ermöglichen einen hohen Grad der Erweiterbarkeit.

Entwicklungsumgebung und Werkzeuge

Symfony beinhaltet bereits standardmäßig verschiedene Entwicklungsumgebungen und bietet verschiedene Werkzeuge und automatisierte Tasks für gängige Aufgaben der Software-Entwicklung:

  • Code-Generierungs-Werkzeuge sind bestens geeignet für Prototypen und Administrationen.
  • Das eingebaute Unit- und Functional-Testing Framework bietet Tools für Test-Driven-Development-Unterstützung.
  • Das Debug-Panel beschleunigt das Debugging durch das Anzeigen vieler wichtiger Seiten-Informationen die ein Entwickler benätigt (SQL Queries, Ladezeiten, Chaching-Informationen, http-Parameter, Logs, Umgebungsvariablen etc.).
  • Kommandozeilen-Schnittstellen automatisieren das Deployment zwischen zwei Servern.
  • Live-Änderung an den Konfigurationen sind möglich und effektiv.
  • Die Logging- und Exception-Features geben Administratoren Transparenz über die Anwendungsaktivitäten.

Symfony vs. Zend

An dieser Stelle muss zuerst erwähnt werden, dass sich beide Frameworks wohl kaum vergleichen lassen, da sie unterschiedlicher nicht sein könnten.

Wie das .NET Framework ist das Zend Framework (ZF) eine Ansammlung von Funktionen welche zusammen gute Schnittstellen bereitstellen um die komplexesten Anforderungen, die regelmäig auftreten, von Webentwicklern zu befriedigen. Der größte Vorteil aber auch Nachteil von ZF ist, dass es keinen bestimmten Weg bzw. Konventionen vorgibt wie die Anforderungen zu bewerkstelligen sind.

Bei ZF gibt es kaum Code-Generierung und Konfigurationen werden alle im Front-Controller vorgenommen. Symfony (SF) generiert anhand des DB-Schemas eine Menge Code, welcher zunächst die Code-Basis aufbläht aber den Entwicklern viel Zeit erspart. Konfigurationen (wie Authentifizierung, Caching, Layout uvm.) können in hierarchischer Erbreihenfolge von Applikation über Module bis hinunter zur einzelnen Action über YAML-Files vorgenommen werden. ZF lässt einem bei der Ordnerstruktur alle Freiheiten, wohingegen symfony eine strikte Struktur vorgibt. Dies trägt am Anfang nicht zu einer höheren Lernkurve bei, aber die Einheitlichkeit lässt die Entwickler später sehr leicht im Code navigieren.

Symfony hat eine sehr gute und aktuelle online Dokumentation sowie daraus entstandene Begleitbücher. Darüber hinaus ist die Community sehr aktiv und auch bei komplexeren Problemen sehr hilfreich. ZF verfügt leider nicht über so viel Dokumentation und richtet sich sehr stark an die erfahreneren Entwickler die schon sehr geübt sind mit den komplexeren Aspekten der objektorientierten Programmierung.

Im Gegensatz zu ZF hat SF eine sehr aktive Plugin- und Erweiterungs-Community. Man kann sogar ZF-Funktionalitäten über das Zend-Framework-Plugin in Symfony integrieren.

Symfony 1.4 vs Symfony2

Sensio Labs veröffentlicht ein neues Major-Release Symfony2.0, worauf dieser Abschnitt kurz eingeht:

Unterschiede (soweit bekannt):

  • Neues Template-System (Twig), bisher PHP-Files die von den Actions die Template-Variablen erben.
  • Partials und Page-Templates werden nicht mehr unterschieden.
  • Templates unterstützen Vererbung.
  • Actions entsprechen Components (Components sind wiederverwendbar).
  • Kein sfWebRequest Objekt mehr. Ãœber das Routing werden Parameter direkt übergeben.
  • Mit Doctrine 2 wird der Active Record Pattern durch den Entity Pattern ersetzt.
  • Nur noch einen Entity-Manager statt einer Factory (Table Object) pro Model.
  • Logger und Caches von Zend Framework.
  • Für Unit-Tests werden statt Lime PHPUnit Tests verwendet.
  • Mit PHP 5.3 Verwendung von Namespaces etc.
  • Forms bestehen nicht mehr aus Widgets und Validatoren sondern aus Feldern mit Renderern und Validatoren).

Es stellt sich die Frage ob so kurz vor einer grundlegend neuen Version nicht schon diese verwendet werden sollte. Nun, auf der Projekt-Homepage selbst steht, dass Symfony2.0 noch nicht reif ist für den produktiven Einsatz. Das Final-Release ist für ~März 2011 geplant. Es wird empfohlen neue Projekte, mindestens bis zu diesem Termin, mit Symfony 1.4 umzusetzen. Symfony 1.4 (aktuell 1.4.8) wird bis Ende 2012 unterstützt.

Von Symfony 1.0 ist bekannt dass erste Major-Release-Versionen noch voller Kinderkrankheiten stecken, welche erst nach Jahren zufriedenstellend beseitig werden. Symfony 1.4 hat diese Zeit erfolgreich gemeistert und eine treue Anhängerschaft um sich gebildet. Symfony2.0 steht hier noch am Anfang. Symfony versucht immer einen gewissen Grad an Updatefähig zu gewährleisten, vorausgesetzt die Entwickler halten sich so gut es geht an die vorgegebenen Konventionen. Auch kann man schon von vorn herein versuchen so zu entwickeln das ein evtl. Update später leichter möglich ist, wenn man sich mit den Änderung in der Version 2.0 befasst (s.o.).

Kurzum ein neues Projekt sollte derzeit noch mit Symfony 1.4 umgesetzt werden, jedoch mit technischer Voraussicht auf Symfony2.0.

Symfony2 Benchmark Results:

For the “Product” application, Symfony2 is about:

  • 50% faster than Yii 1.1.1
  • 2.5 times faster than symfony 1.4.2
  • 3 times faster than Zend 1.10
  • 6 times faster than CakePHP 1.2.6

Quelle: http://symfony-reloaded.org/fast

Symfony Nachteile

Symfony hat natürlich auch ein paar Nachteile die Beachtung finden sollten:

  • Größe der Framework-Dateien ohne die Modelklassen: ~30MB.
  • Der Einstieg ist vergleichsweise aufwendig, da erst die Strukturen, Konfigurationsmöglichkeiten und nutzbaren Funktionen gelernt werden müssen.
  • Bei komplexeren Aufgaben kommt man nicht umhin sich mit dem Framework-Kern zu befassen.
  • Nicht dokumentierteÄ nderungen am Kern erschweren Framework-Updates.
  • Wenn kein Zugriff auf die Kommandozeile möglich ist muss ggf. ein Weg gefunden werden die Symfony-Tasks (Unit-Test, Model-Klassen generieren, Cache löschen etc.) auf anderem Wege auszuführen.
  • Symfony ist gerade auf dem Sprung in ein neues Major-Release, welches viele Äderungen mit sich bringt. Es kann sein dass die alte Community evtl. an Aktivität verliert.
  • Viele Vorteile des Frameworks (Admin-, Form- CRUD-Generator etc.) sind Abhängig von einem Datenbank-Modell.
  • Template-Files sind nicht alle in einem Verzeichnis. Grafiker müssen sich ggf. mit der Ordnerstruktur auskennen.
  • YAML-Konfigurations-Files sind sehr empfindlich gegenüber Tippfehlern (Leerzeichen).
  • Updates auf neue Versionen sind oft nicht ganz Problemlos.
  • Ungewolltes überschreiben von Konfigurationsdateien über die Hierarchieebenen.

Ist Symfony das richtige für einen Umstieg?

Für einen kleinen Funktionsumfang wäre Symfony wahrscheinlich zu viel des Guten. Es wäre wohl damit getan sich auf eine Businesslogikstruktur zu einigen und ein Template-System zu integrieren. Doch die meisten Plattformen werden sich ohne Zweifel weiter entwickeln, um den professionellen Ansprüchen der Kunden gerecht zu werden. Hier bietet Symfony bereits die nötige Schablone um solch ein Projekt Modul für Modul zu skalieren bis hin zu höchsten High-Demand-Anforderungen. Der Weg ist durch Symfony bereits geebnet und muss mit unseren Ideen nur noch befahren werden.

Es kam die Frage auf, ob man nicht evtl. nur Teile des Frameworks benutzen könnte. Eigentlich sind nahezu alle Symfony-Features für eine moderne Web-Anwendung essentiell. Trotzdem lassen sich über die tiefgreifenden Konfigurationsfiles die meisten Features einfach abschalten.

Natürlich darf dabei nicht vergessen werden, dass ein Framework auch Probleme mit sich bringen kann, wenn die Umgebung oder die Anforderung an das System zu speziell sind. Spontan stellen sich dann Symfony-Erfahrene die Frage nach der korrekten Funktionsweise des Symfony Caches, des Session-Management, Logging oder das Ausführen von Tasks, was bisher Konsolenzugriffe sowie ein beschreibbares Filessystem voraussetzt. Beantworten lässt sich die Frage mit den symfony-Factories, über die sich nahezu alle Standard-Handler, die für die genannten Funktionen zuständig sind, mit eigenen Lösungen überschreiben oder anpassen lassen.

Symfony ist vielleicht nicht die schnellste Lösung, aber unter den umgesetzten Notwendigkeiten, um die eine Webapplikation nicht herumkommt, unübertroffen. Es lässt sich leicht hardwaretechnisch eine Performancesteigerung erreichen, aber es ist sehr schwer einen neuen Entwickler einem existierenden Projekt hinzuzufügen um es performanter zu machen.

Quellen

Bücher

  • A Gentle Introduction to Symfony 1.4 (ISBN-13: 978-2918390305)
  • More with Symfony 1.3 & 1.4 (ISBN-13: 978-2918390176)

Symfony: Propel: Criteria SQL (hibernate sql)

Hi Volks,

today I had a lot of testing with the symfony criteria object. And everyone who knows about the problem to get the raw SQL query out of the criteria object.

There is a toString method, but the result just looks like this:

SELECT FROM media, media_category WHERE media.FEATURED=? AND media.MEDIATYPE IN (?,?) AND 1=1 AND media_category.CID NOT IN (?,?,?,?) AND media.MID=media_category.MID GROUP BY media.MID
Parameters to replace: array (
0 =>
array (
'table' => 'media',
'column' => 'FEATURED',
'value' => true,
),
1 =>
array (
'table' => 'media',
'column' => 'MEDIATYPE',
'value' => 'video',
),
2 =>
array (
'table' => 'media',
'column' => 'MEDIATYPE',
'value' => 'audio',
),
3 =>
array (
'table' => 'media_category',
'column' => 'CID',
'value' => 10,
),
4 =>
array (
'table' => 'media_category',
'column' => 'CID',
'value' => 9,
),
5 =>
array (
'table' => 'media_category',
'column' => 'CID',
'value' => 4,
),
6 =>
array (
'table' => 'media_category',
'column' => 'CID',
'value' => 7,
)
)

And it is very strange to fill the question marks by hand with the related values from the parameters array.

So I wrote a function which does this for me:

function getCriteriaSQL($c, $select = '*')
{
$params = array();
$r = BasePeer::createSelectSql($c, $params);
$o = str_replace('?', '%s', $r);

$ggg = array();
foreach($params AS $e)
{
if(is_integer($e['value']) OR is_bool($e['value']))
{
$ggg[] = $e['value'];
}
else
{
$ggg[] = "'".$e['value']."'";
}
}

$sql = vsprintf($o, $ggg);

$sql = str_replace('SELECT ', 'SELECT '.$select, $sql);

return $sql;
}

I just wanted to share this with you and I appreciate your comments.


symfony: How to build a dojo dijit autocompleter sfForm widget

I was searching long time for a good auto completer widget, but I couldn’t find one. So I created it by my self.
I did the same with the build in symfony auto completer widget. When I have time I’ll post it, too.
I hope I could help someboby with this small tutorial. Please give me feedback if there are any questions or suggestions.

Now lets start:

1. Copy the dojo package to the js folder
Resulting path to dojo.js: web/js/dojoToolkit/dojo/dojo.js

2. Enable dojo.js
If not yet happend elsewhere:
Modify the view.yml: apps/[YOUR_APP]/config/view.yml

default:
javascripts: [dojoToolkit/dojo/dojo.js]

3. Create the widget
lib/widget/itWidgetFormInputTextDijitAutocomplete.php

class itWidgetFormInputTextDijitAutocomplete extends sfWidgetForm
{
/**
* Constructor.
*
* Available options:
*
* * model: Name of the Model
* * searchfield: Table field in which will be searched
* * action: Optional: request action or url
* * value_method: Optional: getter for form field value
* * output_method: Optional: getter for form field name
* * criteria_method: Optional: getter for additional cirteria
* * add_empty: Optional: add emtpy value option to the list
* * choices: An array of possible choices (n/a)
* * formatter: A callable to call to format the checkbox choices
*
* @see sfWidgetForm
*/
protected function configure($options = array(), $attributes = array())
{
$this->addRequiredOption('model');
$this->addRequiredOption('search_field');
$this->addOption('action', 'default/ajaxAutocomplete');
$this->addOption('value_method', 'getPrimaryKey');
$this->addOption('output_method', 'getPrimaryKey');
$this->addOption('choices', array());
$this->addOption('criteria_method', '');
$this->addOption('formatter', array($this, 'formatter'));
$this->addOption('add_empty', false);
}

/**
* Renders the widget as HTML.
*
* @param string The name of the HTML widget
* @param mixed The value of the widget
* @param array An array of HTML attributes
* @param array An array of errors
*
* @return string A HTML representation of the widget
*
* @see sfWidgetForm
*/
public function render($name, $value = null, $attributes = array(), $errors = array())
{
$choices = $this->getOption('choices');
if ($choices instanceof sfCallable)
{
$choices = $choices->call();
}

$baseAttributes = array(
'action' => $this->getOption('action'),
'name' => $name,
'type' => 'text',
'value' => $value,
'id' => $id = $this->generateId($name, self::escapeOnce($name)),
);

return call_user_func($this->getOption('formatter'), $this, $baseAttributes);
}

/**
* Renders the input fields as HTML.
*
* @param widget
* @param attributes
*
* @return string A HTML representation of the input fields
*/
public function formatter($widget, $attributes)
{
sfLoader::loadHelpers(array('Form', 'Url'));
$request = sfContext::getInstance()->getRequest();
$field_id = $attributes['id'];
$field_name = $attributes['name'];
$ajax_field_id = 'ajax_'.$attributes['id'];
$out_field_id = 'out_'.$attributes['id'];
$object = @call_user_func(array($this->getOption('model').'Peer', 'retrieveByPk'), $attributes['value']);
$default_out = $request->getParameter('ajax_'.$attributes['name'], is_object($object) ? call_user_func(array(&$object, $this->getOption('output_method'))) : '');
$default_value = $request->getParameter($attributes['name'], is_object($object) ? $attributes['value'] : '');

$html = '';
$ajaxParams=array(
'model' => $this->getOption('model'),
'value_method' => $this->getOption('value_method'),
'output_method' => $this->getOption('output_method'),
'search_field' => $this->getOption('search_field'),
'criteria_method' => $this->getOption('criteria_method'),
'field_name' => 'ajax_'.$attributes['name']
);
if($this->getOption('add_empty')===false) $ajaxParams['add_empty'] = 'false';
elseif($this->getOption('add_empty')===true) $ajaxParams['add_empty'] = 'true';
else $ajaxParams['add_empty'] = $this->getOption('add_empty');

$requestUrl = url_for($attributes['action'].'?'.http_build_query($ajaxParams), true);
$requestUrl = str_replace('frontend_dev.php/', '', $requestUrl);
$requestUrl = str_replace('backend_dev.php/', 'backend.php/', $requestUrl);

$html .= <<
<script type="text/javascript">
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dijit.form.FilteringSelect");
</script>
<div dojoType="dojo.data.ItemFileReadStore"
jsId="{$field_id}Store" url="{$requestUrl}"></div>
EOF;

$input_text = <<
<input dojoType="dijit.form.FilteringSelect"
store="{$field_id}Store"
class="medium"
id="{$field_id}"
name="{$field_name}"
value="{$default_value}"
hasDownArrow="true",
invalidMessage="",
ignoreCase="true" />
}

4. Create action for the AJAX request
apps/[APP_NAME]/modules/default/actions/actions.class.php

<?php
class defaultActions extends sfActions
{
public function executeAjaxAutocomplete($request)
{
$model = $request->getParameter('model');
$criteria_method = $request->getParameter('criteria_method');
$add_empty = $request->getParameter('add_empty', 'false');
$this->value_method = $request->getParameter('value_method');
$this->output_method = $request->getParameter('output_method');

$peer_object = $model.'Peer';

if($criteria_method!='') $criteria = call_user_func(array($peer_object, $criteria_method));
else $criteria = new Criteria();

$search_field = $request->getParameter('search_field');
$field_name = $request->getParameter('field_name');
$var = $request->getParameter($field_name);

$j_object = array('identifier' => 'abbreviation', 'items'=>array());

$search_field = strtoupper($search_field);

$sql_field = constant($peer_object.'::'.$search_field);

$c = $criteria;
$c->add($sql_field, $var . '%', Criteria::LIKE);
$this->list = call_user_func(array($peer_object,'doSelect'), $c);

if($add_empty!='false')
{
$j_object['items'][] = array(
'name' => $add_empty=='true' ? '' : $add_empty,
'label' => '',
'abbreviation' => ''
);
}

foreach($this->list AS $v)
{
$j_object['items'][] = array(
'name' => call_user_func(array(&$v, $this->output_method)),
'label' => call_user_func(array(&$v, $this->output_method)),
'abbreviation' => call_user_func(array(&$v, $this->value_method))
);
}
$this->j_object = $j_object;
}
}

5. Create template for the AJAX request
apps/[APP_NAME]/modules/default/templates/ajaxAutocompleteSuccess.php

<?php decorate_with(false); ?>
<?php print_r(json_encode($j_object)); ?>

6. Insert the new widget into your sfForm
apps/[APP_NAME]/modules/default/templates/ajaxAutocompleteSuccess.php

...
# $widgets['user_id'] = new sfWidgetFormInput();
$widgets['user_id'] = new stWidgetFormInputTextDijitAutocomplete(array(
'model' => 'User',
'search_field' => 'username',
'value_method' => 'getId',
'output_method' => 'getUsername',
'criteria_method' => 'getCriteriaRegisteredUsers'
));

6. Clear symfony cache

Links:

  • http://api.dojotoolkit.org/jsdoc/1.3.2/dijit.form.FilteringSelect

Copyright © 2007-2012 iTopia. All rights reserved.
Jarrah theme by Templates Next | Powered by WordPress