Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
* @package ##PROJECT_NAME##
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These template files form the basis for how the Base<Model>Form and Base<Model>FormFilter class files get generated. It's a fascinating and kinda weird process, but the whole file is treated like a plain text file with embedded PHP tags.

You'll see that each document contains both standard <?php and odd-looking [?php tags. During the process, PHP does a first parse through the content and interprets any PHP code found within the standard <?php and <?= tags - exactly the same as any HTML document might be parsed. But importantly for this implementation, any otherwise-valid PHP code which is inside [?php or [?= tags is left alone by this process.

The output of this parsing is otherwise-valid PHP source code which is wrapped with invalid PHP opening tags. To resolve this, the content is then run through a final str_replace() to "fix" the invalid PHP tags to their standard equivalents. The original template content has now been transformed into a standard PHP source code document - held in memory - ready to be written to a file on disk.

The base Models are generated using a different mechanism, so you won't see template files here for those base classes.

All that said, while I was digging through the weeds to find the source of the bug, I happened across these template files. Previously, the generated base classes were not tracked in our repo so the generated content in those classes kinda didn't really matter. Now that we have started tracking these files into our repo, it felt appropriate that these files be generating code which more closely matches our code style/PSR requirements. The changes in the next few files are exactly that overhauling, but if you feel that's overkill, then it can be undone.

* @subpackage form
* @author ##AUTHOR_NAME##
* @version SVN: $Id$
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also bugged me for years that we still have reference to Subversion (🤮) in our source code, so nuking these lines was particularly satisfying.

*/
abstract class BaseFormDoctrine extends sfFormDoctrine
{
public function setup()
{
}
public function setup()
{
}
}
Original file line number Diff line number Diff line change
@@ -1,97 +1,129 @@
[?php

/**
* <?php echo $this->modelName ?> form base class.
* <?= $this->modelName; ?> form base class.
*
* @method <?php echo $this->modelName ?> getObject() Returns the current form's model object
* @method <?= $this->modelName; ?> getObject() Returns the current form's model object
*
* @package ##PROJECT_NAME##
* @subpackage form
* @author ##AUTHOR_NAME##
* @version SVN: $Id$
*/
abstract class Base<?php echo $this->modelName ?>Form extends <?php echo $this->getFormClassToExtend().PHP_EOL ?>
abstract class Base<?= $this->modelName; ?>Form extends <?= $this->getFormClassToExtend() . PHP_EOL; ?>
{
protected function setupInheritance()
{
parent::setupInheritance();

<?php foreach ($this->getColumns() as $column): ?>
$this->widgetSchema ['<?php echo $column->getFieldName() ?>'] = new <?php echo $this->getWidgetClassForColumn($column) ?>(<?php echo $this->getWidgetOptionsForColumn($column) ?>);
$this->validatorSchema['<?php echo $column->getFieldName() ?>'] = new <?php echo $this->getValidatorClassForColumn($column) ?>(<?php echo $this->getValidatorOptionsForColumn($column) ?>);

<?php endforeach; ?>
<?php foreach ($this->getManyToManyRelations() as $relation): ?>
$this->widgetSchema ['<?php echo $this->underscore($relation['alias']) ?>_list'] = new sfWidgetFormDoctrineChoice(array('multiple' => true, 'model' => '<?php echo $relation['table']->getOption('name') ?>'));
$this->validatorSchema['<?php echo $this->underscore($relation['alias']) ?>_list'] = new sfValidatorDoctrineChoice(array('multiple' => true, 'model' => '<?php echo $relation['table']->getOption('name') ?>', 'required' => false));

<?php endforeach; ?>
$this->widgetSchema->setNameFormat('<?php echo $this->underscore($this->modelName) ?>[%s]');
}

public function getModelName()
{
return '<?php echo $this->modelName ?>';
}

<?php if ($this->getManyToManyRelations()): ?>
public function updateDefaultsFromObject()
{
parent::updateDefaultsFromObject();

<?php foreach ($this->getManyToManyRelations() as $relation): ?>
if (isset($this->widgetSchema['<?php echo $this->underscore($relation['alias']) ?>_list']))
protected function setupInheritance()
{
$this->setDefault('<?php echo $this->underscore($relation['alias']) ?>_list', $this->object-><?php echo $relation['alias']; ?>->getPrimaryKeys());
parent::setupInheritance();

<?php
foreach ($this->getColumns() as $column) {
$field_name = $column->getFieldName();
$widget_class = $this->getWidgetClassForColumn($column);
$widget_arguments = $this->getWidgetOptionsForColumn($column);
$validator_class = $this->getValidatorClassForColumn($column);
$validator_arguments = $this->getValidatorOptionsForColumn($column);
?>
$this->widgetSchema['<?= $field_name; ?>'] = new <?= $widget_class; ?>(<?= $widget_arguments; ?>);
$this->validatorSchema['<?= $field_name; ?>'] = new <?= $validator_class; ?>(<?= $validator_arguments; ?>);

<?php
}
?>
<?php
$relations = $this->getManyToManyRelations();
foreach ($relations as $relation) {
$alias = $this->underscore($relation['alias']);
$table_name = $relation['table']->getOption('name');
?>
$this->widgetSchema['<?= $alias; ?>_list'] = new sfWidgetFormDoctrineChoice([
'multiple' => true,
'model' => '<?= $table_name; ?>',
]);
Comment on lines +38 to +41
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to the way the base classes are generated, some of the content in any template file doesn't actually survive unmodified all the way through the process (and I don't mean the blocks of PHP which get interpreted during the process).

Specifically, any place where a new array is being defined using square brace syntax [] (like we see here with the options being parsed to new sfWidgetFormDoctrineChoice()) get interpolated automatically into array() syntax instead.

This interpolation is done by the PHP engine directly, and we have zero control of it unfortunately.

$this->validatorSchema['<?= $alias; ?>_list'] = new sfValidatorDoctrineChoice([
'multiple' => true,
'model' => '<?= $table_name; ?>',
'required' => false,
]);

<?php
}
?>
$this->widgetSchema->setNameFormat('<?= $this->underscore($this->modelName); ?>[%s]');
}

<?php endforeach; ?>
}

protected function doUpdateObject($values)
{
<?php foreach ($this->getManyToManyRelations() as $relation): ?>
$this->update<?php echo $relation['alias'] ?>List($values);
<?php endforeach; ?>

parent::doUpdateObject($values);
}

<?php foreach ($this->getManyToManyRelations() as $relation): ?>
public function update<?php echo $relation['alias'] ?>List($values)
{
if (!isset($this->widgetSchema['<?php echo $this->underscore($relation['alias']) ?>_list']))
public function getModelName()
{
// somebody has unset this widget
return;
return '<?= $this->modelName; ?>';
}

if (!array_key_exists('<?php echo $this->underscore($relation['alias']) ?>_list', $values))
<?php
if ($relations) {
?>
public function updateDefaultsFromObject()
{
// no values for this widget
return;
parent::updateDefaultsFromObject();

<?php
foreach ($relations as $relation) {
$alias = $this->underscore($relation['alias']);
?>
if (isset($this->widgetSchema['<?= $alias; ?>_list'])) {
$this->setDefault('<?= $alias; ?>_list', $this->object-><?= $relation['alias']; ?>->getPrimaryKeys());
}

<?php
}
?>
}

$existing = $this->object-><?php echo $relation['alias']; ?>->getPrimaryKeys();
$values = $values['<?php echo $this->underscore($relation['alias']) ?>_list'];
if (!is_array($values))
protected function doUpdateObject($values)
{
$values = array();
<?php
foreach ($relations as $relation) {
?>
$this->update<?= $relation['alias']; ?>List($values);
<?php
}
?>

$unlink = array_diff($existing, $values);
if (count($unlink))
{
$this->object->unlink('<?php echo $relation['alias'] ?>', array_values($unlink));
parent::doUpdateObject($values);
}

$link = array_diff($values, $existing);
if (count($link))
<?php
foreach ($relations as $relation) {
$alias = $this->underscore($relation['alias']);
?>
public function update<?= $relation['alias']; ?>List($values)
{
$this->object->link('<?php echo $relation['alias'] ?>', array_values($link));
if (!isset($this->widgetSchema['<?= $alias; ?>_list'])) {
// widget has been unset
return;
}

if (!array_key_exists('<?= $alias; ?>_list', $values)) {
// no values for this widget
return;
}

$existing = $this->object-><?= $relation['alias']; ?>->getPrimaryKeys();
$values = $values['<?= $alias; ?>_list'];
if (!is_array($values)) {
$values = [];
}

$unlink = array_diff($existing, $values);
if (count($unlink)) {
$this->object->unlink('<?= $relation['alias']; ?>', array_values($unlink));
}

$link = array_diff($values, $existing);
if (count($link)) {
$this->object->link('<?= $relation['alias'] ?>', array_values($link));
}
}
}

<?php endforeach; ?>
<?php endif; ?>
<?php
}
}
?>
}
Loading