Skip to content

Commit

Permalink
[1.4] Added a primaryString column attribute to allow smart `__toSt…
Browse files Browse the repository at this point in the history
…ring()` generation (closes #763)
  • Loading branch information
fzaninotto committed Sep 28, 2009
1 parent 5edec27 commit 39594f6
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 1 deletion.
34 changes: 34 additions & 0 deletions WHATS_NEW
Expand Up @@ -43,6 +43,40 @@ LEFT JOIN user ON (book.USER_ID = user.ID AND user.RANK > 12)

Note that the former way to define a composite join using arrays as arguments of `addJoin()` is deprecated.

== Generated `__toString()` in Base Object ==

Propel can generate a `__toString()` method for your Model objects if you define a column as `primaryString` in the schema:

{{{
// in the schema
<table name="book" phpName="Book">
..
<column name="title" type="varchar" size="125" primaryString="true" />
..
</table>
}}}

After a model build, the generated `BaseBook` class offers the following magic method:

{{{
#!php
<?php
public function __toString()
{
return (string) $this->getTitle();
}
}}}

That means that the default string representation of `Book` objects is the value of the `title` column:

{{{
#!php
<?php
$book = new book();
$book->setTitle('War And Peace');
echo $book; // 'War And Peace'
}}}

== Better Introspection at Runtime ==

A few methods were added to the Map classes to ease runtime introspection:
Expand Down
2 changes: 2 additions & 0 deletions docs/guide/09-Schema-Reference.txt
Expand Up @@ -155,6 +155,7 @@ According to the schema, {{{name}}} is the only required attribute. Also, the {
[autoIncrement = "true|{false}"]
[lazyLoad = "true|{false}"]
[description = "/Column Description/"]
[primaryString = "true|{false}"]
[phpNamingMethod = "nochange|underscore|phpname"]
[inheritance = "single|{false}"]
[inputValidator = "NameOfInputValidatorClass"]
Expand All @@ -167,6 +168,7 @@ According to the schema, {{{name}}} is the only required attribute. Also, the {

* {{{defaultValue}}} The default value that the object will have for this column in the PHP instance after creating a "new Object". This value is always interpreted as a string.
* {{{defaultExpr}}} The default value for this column as expressed in SQL. This value is used solely for the "sql" target which builds your database from the schema.xml file. The defaultExpr is the SQL expression used as the "default" for the column.
* {{{primaryString}}} A column defined as primary string serves as default value for a `__toString()` method in the generated Propel object.

=== <foreign-key> element ===

Expand Down
Expand Up @@ -252,6 +252,8 @@ protected function addClassBody(&$script)
$this->addFKMethods($script);
$this->addRefFKMethods($script);
$this->addClearAllReferences($script);

$this->addPrimaryString($script);
}

/**
Expand Down Expand Up @@ -3925,4 +3927,30 @@ public function clearAllReferences(\$deep = false)
";
}

/**
* Adds a magic __toString() method if a string column was defined as primary string
* @param string &$script The script will be modified in this method.
*/
protected function addPrimaryString(&$script)
{
foreach ($this->getTable()->getColumns() as $column)
{
if ($column->isPrimaryString())
{
$script .= "
/**
* Return the string representation of this object
*
* @return string The value of the '{$column->getName()}' column
*/
public function __toString()
{
return (string) \$this->get{$column->getPhpName()}();
}
";
break;
}
}
}

} // PHP5ObjectBuilder
22 changes: 22 additions & 0 deletions generator/classes/propel/engine/database/model/Column.php
Expand Up @@ -85,6 +85,7 @@ class Column extends XMLElement {
private $isLazyLoad = false;
private $defaultValue;
private $referrers;
private $isPrimaryString = false;

// only one type is supported currently, which assumes the
// column either contains the classnames or a key to
Expand Down Expand Up @@ -191,6 +192,8 @@ protected function setupObject()
// retrieves the method for converting from specified name to a PHP name, defaulting to parent tables default method
$this->phpNamingMethod = $this->getAttribute("phpNamingMethod", $this->parentTable->getDatabase()->getDefaultPhpNamingMethod());

$this->isPrimaryString = $this->booleanValue($this->getAttribute("primaryString"));

$this->isPrimaryKey = $this->booleanValue($this->getAttribute("primaryKey"));

$this->isNodeKey = $this->booleanValue($this->getAttribute("nodeKey"));
Expand Down Expand Up @@ -530,6 +533,25 @@ public function getNotNullString()
return $this->getTable()->getDatabase()->getPlatform()->getNullString($this->isNotNull());
}

/**
* Set whether the column is the primary string,
* i.e. whether its value is the default string representation of the table
* @param boolean $v
*/
public function setPrimaryString($v)
{
$this->isPrimaryString = (boolean) $v;
}

/**
* Return true if the column is the primary string,
* i.e. if its value is the default string representation of the table
*/
public function isPrimaryString()
{
return $this->isPrimaryString;
}

/**
* Set whether the column is a primary key or not.
* @param boolean $v
Expand Down
1 change: 1 addition & 0 deletions generator/resources/dtd/database.dtd
Expand Up @@ -96,6 +96,7 @@ PHP class or method name.
phpNamingMethod (nochange|underscore|phpname) #IMPLIED
description CDATA #IMPLIED
lazyLoad (true|false) "false"
primaryString (true|false) "false"
>

<!ELEMENT inheritance EMPTY>
Expand Down
1 change: 1 addition & 0 deletions generator/resources/xsd/database.xsd
Expand Up @@ -316,6 +316,7 @@
<xs:attribute name="nestedSetRightKey" type="xs:boolean" default="false"/>
<xs:attribute name="treeScopeKey" type="xs:boolean" default="false"/>
<xs:attribute name="require" type="xs:string" use="optional"/>
<xs:attribute name="primaryString" type="xs:boolean" default="false"/>
</xs:complexType>

<xs:complexType name="foreign-key">
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/bookstore/schema.xml
Expand Up @@ -5,7 +5,7 @@
<column name="id" required="true" primaryKey="true"
autoIncrement="true" type="INTEGER" description="Book Id" />
<column name="title" type="VARCHAR" required="true"
description="Book Title" />
description="Book Title" primaryString="true" />
<column name="isbn" required="true" type="VARCHAR" size="24"
phpName="ISBN" description="ISBN Number" />
<column name="price" required="false" type="FLOAT"
Expand Down
Expand Up @@ -1055,4 +1055,13 @@ public function testUniqueFkRel()
$this->assertTrue(count($logs) == 1, "Expected 1 audit log result.");
$this->assertEquals($logs[0]->getId(), $al->getId(), "Expected returned audit log to match created audit log.");
}

public function testAddPrimaryString()
{
$this->assertFalse(method_exists('Author', '__toString'), 'addPrimaryString() does not add a __toString() method if no column has the primaryString attribute');
$this->assertTrue(method_exists('Book', '__toString'), 'addPrimaryString() adds a __toString() method if a column has the primaryString attribute');
$book = new Book();
$book->setTitle('foo');
$this->assertEquals((string) $book, 'foo', 'addPrimaryString() adds a __toString() method returning the value of the the first column where primaryString is true');
}
}

0 comments on commit 39594f6

Please sign in to comment.