Browse files

Merge pull request #14 from jeserkin/master

Final edits
  • Loading branch information...
2 parents de2d052 + d683140 commit 67fd8031eed1fb8d6ff0c3b41123e893046afaa9 @dominics committed Apr 25, 2012
View
20 source/en/manual/behaviors.rst
@@ -548,6 +548,8 @@ models with YAML.
In the next several examples we will demonstrate some of the behaviors
that come bundled with Doctrine.
+.. _behaviors-core-behaviors-versionable:
+
-----------
Versionable
-----------
@@ -705,6 +707,8 @@ The above example would produce the following output:
and the ``title`` is back to the original value was set it to when
creating the ``BlogPost``.
+.. _behaviors-core-behaviors-timestampable:
+
-------------
Timestampable
-------------
@@ -818,6 +822,8 @@ Name Default Description
``onInsert`` ``true`` Whether or not to set the updated date when the record is first inserted.
============ ======== =========================================================================
+.. _behaviors-core-behaviors-sluggable:
+
---------
Sluggable
---------
@@ -929,6 +935,8 @@ Name Default Description
``indexName`` ``sluggable`` The name of the index to create.
=============== ========================================= ===============================================
+.. _behaviors-core-behaviors-i18n:
+
----
I18n
----
@@ -1090,6 +1098,8 @@ The above example would produce the following output:
$ php test.php
joku otsikko
+.. _behaviors-core-behaviors-nestedset:
+
---------
NestedSet
---------
@@ -1170,6 +1180,8 @@ The above code would output the following SQL query:
We won't discuss the ``NestedSet`` behavior in 100% detail here. It is a
very large behavior so it has its own :doc:`hierarchical-data`.
+.. _behaviors-core-behaviors-searchable:
+
----------
Searchable
----------
@@ -1251,9 +1263,11 @@ The above code would output the following SQL query:
was automatically created.
Because the ``Searchable`` behavior is such a large topic, we have more
-information on this that can be found in the `doc:`searching`
+information on this that can be found in the :doc:`searching`
chapter.
+.. _behaviors-core-behaviors-geographical:
+
------------
Geographical
------------
@@ -1457,6 +1471,8 @@ Download and import the csv file with the following function:
$zipcode->save();
}
+.. _behaviors-core-behaviors-softdelete:
+
----------
SoftDelete
----------
@@ -1769,5 +1785,5 @@ to write our own for our models as well as how to use all the great
behaviors that come bundled with Doctrine.
Now we are ready to move on to discuss the :doc:`searching`
-behavior in more detail in the `doc:`searching` chapter. As it is a
+behavior in more detail in the :doc:`searching` chapter. As it is a
large topic we have devoted an entire chapter to it.
View
296 source/en/manual/coding-standards.rst
@@ -19,7 +19,7 @@ trailing whitespace from being accidentally injected into the output.
.. note::
Inclusion of arbitrary binary data as permitted by
- ``\_\_HALT_COMPILER()`` is prohibited from any Doctrine framework
+ ``__HALT_COMPILER()`` is prohibited from any Doctrine framework
PHP file or files derived from them. Use of this feature is only
permitted for special installation scripts.
@@ -68,12 +68,12 @@ Class names may only contain alphanumeric characters. Numbers are
permitted in class names but are discouraged. Underscores are only
permitted in place of the path separator, eg. the filename
"Doctrine/Table/Exception.php" must map to the class name
-"``Doctrine\_Table_Exception``".
+":php:class:`Doctrine_Table_Exception`".
If a class name is comprised of more than one word, the first letter of
each new word must be capitalized. Successive capitalized letters are
not allowed, e.g. a class "XML\_Reader" is not allowed while
-"Xml\_Reader" is acceptable.
+"Xml_Reader" is acceptable.
----------
Interfaces
@@ -83,13 +83,13 @@ Interface classes must follow the same conventions as other classes (see
above).
They must also end with the word "Interface" (unless the interface is
-approved not to contain it such as ``Doctrine_Overloadable``). Some
+approved not to contain it such as :php:class:`Doctrine_Overloadable`). Some
examples:
**Examples**
-- ``Doctrine\_Adapter_Interface``
-- ``Doctrine\_EventListener_Interface``
+- :php:class:`Doctrine_Adapter_Interface`
+- :php:class:`Doctrine_EventListener_Interface`
---------
Filenames
@@ -122,9 +122,9 @@ understandability of code.
For object-oriented programming, accessors for objects should always be
prefixed with either "get" or "set". This applies to all classes except
-for ``Doctrine_Record`` which has some accessor methods prefixed with
+for :php:class:`Doctrine_Record` which has some accessor methods prefixed with
'obtain' and 'assign'. The reason for this is that since all user
-defined ActiveRecords inherit ``Doctrine_Record``, it should populate
+defined ActiveRecords inherit :php:class:`Doctrine_Record`, it should populate
the get / set namespace as little as possible.
.. note::
@@ -142,16 +142,20 @@ not permitted. Numbers are permitted in variable names but are
discouraged. They must always start with a lowercase letter and follow
the "camelCaps" capitalization convention. Verbosity is encouraged.
Variables should always be as verbose as practical. Terse variable names
-such as ":code:`i" and "`\ n" are discouraged for anything other than
+such as "$i" and "$n" are discouraged for anything other than
the smallest loop contexts. If a loop contains more than 20 lines of
code, the variables for the indices need to have more descriptive names.
Within the framework certain generic object variables should always use
the following names:
-\|\|~ Object type \|\|~ Variable name \|\| \|\| ``Doctrine_Connection``
-\|\| $conn \|\| \|\| ``Doctrine_Collection`` \|\| $coll \|\| \|\|
-``Doctrine\_Manager`` \|\| $manager \|\| \|\| ``Doctrine_Query`` \|\|
-$q \|\|
+======================= ==================
+Object type Variable name
+======================= ==================
+``Doctrine_Connection`` $conn
+``Doctrine_Collection`` $coll
+``Doctrine_Manager`` $manager
+``Doctrine_Query`` $q
+======================= ==================
There are cases when more descriptive names are more appropriate (for
example when multiple objects of the same class are used in same
@@ -165,31 +169,50 @@ Constants
Constants may contain both alphanumeric characters and the underscore.
They must always have all letters capitalized. For readablity reasons,
words in constant names must be separated by underscore characters. For
-example, ``ATTR\_EXC\_LOGGING`` is permitted but ``ATTR_EXCLOGGING`` is
+example, ``ATTR_EXC_LOGGING`` is permitted but ``ATTR_EXCLOGGING`` is
not.Constants must be defined as class members by using the "const"
construct. Defining constants in the global scope with "define" is NOT
permitted.
- class Doctrine\_SomeClass { const MY\_CONSTANT = 'something'; }
+::
-echo $Doctrine\_SomeClass::MY\_CONSTANT;
+ class Doctrine_SomeClass
+ {
+ const MY_CONSTANT = 'something';
+ }
+
+ echo $Doctrine_SomeClass::MY_CONSTANT;
--------------
Record Columns
--------------
-All record columns must be in lowercase and usage of underscores(\_) are
+All record columns must be in lowercase and usage of underscores(_) are
encouraged for columns that consist of more than one word.
- class User { public function setTableDefinition() {
-$this->hasColumn('home\_address', 'string'); } }
+::
-Foreign key fields must be in format ``[table\_name]_[column]``. The
+ class User
+ {
+ public function setTableDefinition()
+ {
+ $this->hasColumn( 'home_address', 'string' );
+ }
+ }
+
+Foreign key fields must be in format ``[table_name]_[column]``. The
next example is a field that is a foreign key that points to
``user(id)``:
- class Phonenumber extends Doctrine\_Record { public function
-setTableDefinition() { $this->hasColumn('user\_id', 'integer'); } }
+::
+
+ class Phonenumber extends Doctrine_Record
+ {
+ public function setTableDefinition()
+ {
+ $this->hasColumn( 'user_id', 'integer' );
+ }
+ }
============
Coding Style
@@ -210,41 +233,57 @@ Strings
When a string is literal (contains no variable substitutions), the
apostrophe or "single quote" must always used to demarcate the string:
-++++ Literal String
+Literal String
+++++++++++++++
+
+::
- $string = 'something';
+ $string = 'something';
When a literal string itself contains apostrophes, it is permitted to
demarcate the string with quotation marks or "double quotes". This is
especially encouraged for SQL statements:
-++++ String Containing Apostrophes
+String Containing Apostrophes
++++++++++++++++++++++++++++++
- $sql = "SELECT id, name FROM people WHERE name = 'Fred' OR name =
-'Susan'";
+::
+
+ $sql = "SELECT id, name FROM people WHERE name = 'Fred' OR name = 'Susan'";
-++++ Variable Substitution
+Variable Substitution
++++++++++++++++++++++
Variable substitution is permitted using the following form:
- // variable substitution $greeting = "Hello $name, welcome back!";
+::
+
+ // variable substitution
+ $greeting = "Hello $name, welcome back!";
-++++ String Concatenation
+String Concatenation
+++++++++++++++++++++
Strings may be concatenated using the "." operator. A space must always
be added before and after the "." operator to improve readability:
- $framework = 'Doctrine' . ' ORM ' . 'Framework';
+::
+
+ $framework = 'Doctrine' . ' ORM ' . 'Framework';
-++++ Concatenation Line Breaking
+Concatenation Line Breaking
++++++++++++++++++++++++++++
When concatenating strings with the "." operator, it is permitted to
break the statement into multiple lines to improve readability. In these
cases, each successive line should be padded with whitespace such that
the "."; operator is aligned under the "=" operator:
- $sql = "SELECT id, name FROM user " . "WHERE name = ? " . "ORDER BY
-name ASC";
+::
+
+ $sql = "SELECT id, name FROM user "
+ . "WHERE name = ? "
+ . "ORDER BY name ASC";
------
Arrays
@@ -262,13 +301,18 @@ the statement into multiple lines. In this case, each successive line
must be padded with whitespace such that both the keys and the values
are aligned:
- $sampleArray = array('Doctrine', 'ORM', 1, 2, 3);
+::
-$sampleArray = array(1, 2, 3, $a, $b, $c,
- 56.44, $d, 500);
+ $sampleArray = array( 'Doctrine', 'ORM', 1, 2, 3 );
-$sampleArray = array('first' => 'firstValue', 'second' =>
-'secondValue');
+ $sampleArray = array( 1, 2, 3,
+ $a, $b, $c,
+ 56.44, $d, 500 );
+
+ $sampleArray = array(
+ 'first' => 'firstValue',
+ 'second' => 'secondValue'
+ );
-------
Classes
@@ -283,8 +327,16 @@ additional code in a class file is NOT permitted.
This is an example of an acceptable class declaration:
- /\*\* \* Documentation here \*/ class Doctrine\_SampleClass { // entire
-content of class // must be indented four spaces }
+::
+
+ /**
+ * Documentation here
+ */
+ class Doctrine_SampleClass
+ {
+ // entire content of class
+ // must be indented four spaces
+ }
---------------------
Functions and Methods
@@ -298,66 +350,99 @@ and the opening parenthesis for the arguments. Functions in the global
scope are strongly discouraged. This is an example of an acceptable
function declaration in a class:
- /\*\* \* Documentation Block Here */ class Foo { /*\* \* Documentation
-Block Here \*/ public function bar() { // entire content of function //
-must be indented four spaces }
-
::
- public function bar2()
+ /**
+ * Documentation Block Here
+ */
+ class Foo
{
-
+ /**
+ * Documentation Block Here
+ */
+ public function bar()
+ {
+ // entire content of function
+ // must be indented four spaces
+ }
+
+ public function bar2()
+ {
+
+ }
}
-}
-
.. note::
Functions must be separated by only ONE single new line
like is done above between the ``bar()`` and ``bar2()`` methods.
Passing by-reference is permitted in the function declaration only:
- /\*\* \* Documentation Block Here */ class Foo { /*\* \* Documentation
-Block Here \*/ public function bar(&$baz) { } }
+::
+
+ /**
+ * Documentation Block Here
+ */
+ class Foo
+ {
+ /**
+ * Documentation Block Here
+ */
+ public function bar( &$baz )
+ {
+
+ }
+ }
Call-time pass by-reference is prohibited. The return value must not be
enclosed in parentheses. This can hinder readability and can also break
code if a method is later changed to return by reference.
- /\*\* \* Documentation Block Here */ class Foo { /*\*
- \* WRONG
- \*/
- public function bar() { return($this->bar); }
-
::
- /**
- * RIGHT
- */
- public function bar()
+ /**
+ * Documentation Block Here
+ */
+ class Foo
{
- return $this->bar;
+ /**
+ * WRONG
+ */
+ public function bar()
+ {
+ return( $this->bar );
+ }
+
+ /**
+ * RIGHT
+ */
+ public function bar()
+ {
+ return $this->bar;
+ }
}
-}
-
Function arguments are separated by a single trailing space after the
comma delimiter. This is an example of an acceptable function call for a
function that takes three arguments:
- threeArguments(1, 2, 3);
+::
+
+ threeArguments( 1, 2, 3 );
Call-time pass by-reference is prohibited. See above for the proper way
to pass function arguments by-reference. For functions whose arguments
permitted arrays, the function call may include the array construct and
can be split into multiple lines to improve readability. In these cases,
the standards for writing arrays still apply:
- threeArguments(array(1, 2, 3), 2, 3);
+::
+
+ threeArguments( array( 1, 2, 3 ), 2, 3 );
-threeArguments(array(1, 2, 3, 'Framework', 'Doctrine', 56.44, 500), 2,
-3);
+ threeArguments( array( 1, 2, 3, 'Framework',
+ 'Doctrine', 56.44, 500 ), 2, 3 );
------------------
Control Statements
@@ -373,23 +458,48 @@ the same line as the conditional statement. The closing brace is always
written on its own line. Any content within the braces must be indented
four spaces.
- if ($foo != 2) { $foo = 2; }
+::
+
+ if ( $foo != 2 )
+ {
+ $foo = 2;
+ }
For if statements that include elseif or else, the formatting must be as
in these examples:
- if ($foo != 1) { $foo = 1; } else {
- $foo = 3; }
+::
-if ($foo != 2) { :code:`foo = 2; } elseif (`\ foo == 1) { $foo = 3; }
-else {
- $foo = 11; }
+ if ( $foo != 1 )
+ {
+ $foo = 1;
+ }
+ else
+ {
+ $foo = 3;
+ }
+
+ if ( $foo != 2 )
+ {
+ $foo = 2;
+ }
+ elseif ( $foo == 1 )
+ {
+ $foo = 3;
+ }
+ else
+ {
+ $foo = 11;
+ }
When ! operand is being used it must use the following formatting:
- if ( ! $foo) {
+::
+
+ if ( ! $foo )
+ {
-}
+ }
Control statements written with the switch construct must have a single
space before the opening parenthesis of the conditional statement, and
@@ -398,8 +508,18 @@ the switch statement must be indented four spaces. Content under each
case statement must be indented an additional four spaces but the breaks
must be at the same indentation level as the case statements.
- switch ($case) { case 1: case 2: break; case 3: break; default: break;
-}
+::
+
+ switch ( $case )
+ {
+ case 1:
+ case 2:
+ break;
+ case 3:
+ break;
+ default:
+ break;
+ }
The construct default may never be omitted from a switch statement.
@@ -411,7 +531,7 @@ Documentation Format:
All documentation blocks ("docblocks") must be compatible with the
phpDocumentor format. Describing the phpDocumentor format is beyond the
-scope of this document. For more information, visit: http://phpdoc.org/
+scope of this document. For more information, visit: `http://phpdoc.org/ <http://phpdoc.org/>`
Every method, must have a docblock that contains at a minimum:
@@ -424,19 +544,27 @@ Every method, must have a docblock that contains at a minimum:
If a function/method may throw an exception, use @throws:
- /\* \* Test function \* \* @throws Doctrine\_Exception \*/ public
-function test() { throw new Doctrine\_Exception('This function did not
-work'); }
+::
+
+ /*
+ * Test function
+ *
+ * @throws Doctrine_Exception
+ */
+ public function test()
+ {
+ throw new Doctrine_Exception('This function did not work');
+ }
==========
Conclusion
==========
-This is the last chapter of //Doctrine ORM for PHP - Guide to Doctrine
-for PHP//. I really hope that this book was a useful piece of
+This is the last chapter of **Doctrine ORM for PHP - Guide to Doctrine
+for PHP**. I really hope that this book was a useful piece of
documentation and that you are now comfortable with using Doctrine and
will be able to come back to easily reference things as needed.
As always, follow the Doctrine :)
-Thanks, Jon
+Thanks, Jon
View
15 source/en/manual/component-overview.rst
@@ -10,6 +10,8 @@ discussed most of the components in the previous chapters but after this
chapter you will have a better idea of all the components and what their
jobs are.
+.. _component-overview-manager:
+
=======
Manager
=======
@@ -44,6 +46,7 @@ over the $manager variable to loop over the connections.
echo $connection->getName() . "";
}
+.. _component-overview-connection:
==========
Connection
@@ -126,6 +129,8 @@ instances for that connection. You could of course optionally call
$user1->save();
$user2->save();
+.. _component-overview-table:
+
=====
Table
=====
@@ -448,6 +453,8 @@ Now when we ask for the ``User`` table object we will get the following::
dql-doctrine-query-language:magic-finders :name] section of the DQL
chapter.
+.. _component-overview-record:
+
======
Record
======
@@ -808,6 +815,8 @@ collection calling delete one each one::
$users->delete();
+.. _component-overview-using-expression-values:
+
-----------------------
Using Expression Values
-----------------------
@@ -1007,6 +1016,8 @@ simply use::
$record->call('trim', 'username');
+.. _component-overview-collection:
+
==========
Collection
==========
@@ -1610,6 +1621,8 @@ created when you try to instantiate an instance of the manager and the
future to provide a centralized and consistent table creation procedure
for installation purposes.
+.. _component-overview-views:
+
=====
Views
=====
@@ -1679,4 +1692,4 @@ help make your life easier on a day to day basis.
Lets move on to the :doc:`next chapter <native-sql>` where we can learn
about how to use native SQL to hydrate our data in to arrays and objects
-instead of the Doctrine Query Language.
+instead of the Doctrine Query Language.
View
8 source/en/manual/database-abstraction-layer.rst
@@ -18,6 +18,8 @@ old pieces to use the ORM.
The DBAL is composed of a few different modules. In this chapter we will
discuss the different modules and what their jobs are.
+.. _database-abstraction-layer-export:
+
======
Export
======
@@ -502,6 +504,8 @@ We can drop the database with the following code:
// ...
$conn->export->dropDatabase('events_db');
+.. _database-abstraction-layer-import:
+
======
Import
======
@@ -624,6 +628,8 @@ Now we can list the views we just created:
$views = $conn->import->listViews();
print_r($views);
+.. _database-abstraction-layer-datadict:
+
========
DataDict
========
@@ -752,4 +758,4 @@ This chapter is indeed a nice one. The Doctrine DBAL is a great tool all
by itself. It is probably one of the most fully featured and easy to use
PHP database abstraction layers available today.
-Now we are ready to move on and learn about how to use :doc:`transactions`.
+Now we are ready to move on and learn about how to use :doc:`transactions`.
View
4 source/en/manual/defining-models.rst
@@ -888,6 +888,8 @@ Field Type
``someblob`` ``longblob``
================= ===============
+.. _defining-models-relationships:
+
=============
Relationships
=============
@@ -2766,4 +2768,4 @@ are ready to move on to learning about how to :doc:`work with models
<working-with-models>` in your application.
This is a very large topic as well so take a break, grab a mountain dew
-and hurry back for the :doc:`next chapter <working-with-models>`.
+and hurry back for the :doc:`next chapter <working-with-models>`.
View
32 source/en/manual/exceptions-and-warnings.rst
@@ -6,11 +6,19 @@ Exceptions and Warnings
Manager exceptions
==================
-``Doctrine\_Manager_Exception`` is thrown if something failed at the
+:php:class:`Doctrine_Manager_Exception` is thrown if something failed at the
connection management
- try { $manager->getConnection('unknown'); } catch
-(Doctrine\_Manager\_Exception) { // catch errors }
+::
+
+ try
+ {
+ $manager->getConnection( 'unknown' );
+ }
+ catch ( Doctrine_Manager_Exception )
+ {
+ // catch errors
+ }
===================
Relation exceptions
@@ -28,9 +36,17 @@ database level. Doctrine offers fully portable database error handling.
This means that whether you are using sqlite or some other database you
can always get portable error code and message for the occurred error.
- try { $conn->execute('SELECT \* FROM unknowntable'); } catch
-(Doctrine\_Connection\_Exception $e) { echo 'Code : ' .
-$e->getPortableCode(); echo 'Message : ' . $e->getPortableMessage(); }
+::
+
+ try
+ {
+ $conn->execute( 'SELECT * FROM unknowntable' );
+ }
+ catch ( Doctrine_Connection_Exception $e )
+ {
+ echo 'Code : ' . $e->getPortableCode();
+ echo 'Message : ' . $e->getPortableMessage();
+ }
================
Query exceptions
@@ -44,5 +60,5 @@ Conclusion
==========
Now that you know how to deal with Doctrine throwing exceptions lets
-move on and show you some [doc real-world-examples real world schemas]
-that would be used in common web applications found today on the web.
+move on and show you some :doc:`real world schemas <real-world-examples>`
+that would be used in common web applications found today on the web.
View
167 source/en/manual/improving-performance.rst
@@ -15,6 +15,8 @@ lot of benefits like portability and ease of development it's inevitable that
this leads to drawbacks in terms of performance. This chapter tries to help
you to get the best performance out of Doctrine.
+.. _improving-performance-compile:
+
=======
Compile
=======
@@ -34,40 +36,51 @@ Doctrine root by the name :file:`Doctrine.compiled.php`.
Compiling is a method for making a single file of most used doctrine runtime
components including the compiled file instead of multiple files (in worst
cases dozens of files) can improve performance by an order of magnitude. In
-cases where this might fail, a :php:exc:`Doctrine_Exception` is throw detailing the
+cases where this might fail, a :php:class:`Doctrine_Exception` is throw detailing the
error.
Lets create a compile script named :file:`compile.php` to handle the
-compiling of Doctrine::
+compiling of DoctrineL:
+
+::
// compile.php
- require_once('/path/to/doctrine/lib/Doctrine.php');
- spl_autoload_register(array('Doctrine', 'autoload'));
+ require_once( '/path/to/doctrine/lib/Doctrine.php' );
+ spl_autoload_register( array( 'Doctrine', 'autoload' ) );
- Doctrine_Core::compile('Doctrine.compiled.php');
+ Doctrine_Core::compile( 'Doctrine.compiled.php' );
Now we can execute :file:`compile.php` and a file named
:file:`Doctrine.compiled.php` will be generated in the root of your
``doctrine_test`` folder:
.. code-block:: sh
- php compile.php
+ $ php compile.php
If you wish to only compile in the database drivers you are using you
can pass an array of drivers as the second argument to :php:meth:`compile`.
For this example we are only using MySQL so lets tell Doctrine to only
-compile the ``mysql`` driver::
+compile the ``mysql`` driver:
+
+::
+
+ // compile.php
// ...
- Doctrine_Core::compile('Doctrine.compiled.php', array('mysql'));
+ Doctrine_Core::compile( 'Doctrine.compiled.php', array( 'mysql' ) );
Now you can change your :file:`bootstrap.php` script to include the compiled
-Doctrine::
+Doctrine:
+::
+
+ // bootstrap.php
+
+ // ...
+ require_once( 'Doctrine.compiled.php' );
// ...
- require_once('Doctrine.compiled.php');
=====================
Conservative Fetching
@@ -78,9 +91,11 @@ actually need. This may sound trivial but laziness or lack of knowledge about
the possibilities that are available often lead to a lot of unnecessary
overhead.
-Take a look at this example::
+Take a look at this example:
- $record = $table->find($id);
+::
+
+ $record = $table->find( $id );
How often do you find yourself writing code like that? It's convenient but it's
very often not what you need. The example above will pull all columns of the
@@ -92,7 +107,9 @@ I'm sure you all know why a query like the following is not ideal:
.. code-block:: sql
- SELECT * FROM my_table
+ SELECT
+ *
+ FROM my_table
The above is bad in any application and this is also true when using Doctrine.
In fact it's even worse when using Doctrine because populating objects with
@@ -108,76 +125,88 @@ structures you can use in PHP. Objects have the most value when they're used
to accomplish complex business logic. It's a waste of resources when data gets
wrapped in costly object structures when you have no benefit of that. Take a
look at the following code that fetches all comments with some related data for
-an article, passing them to the view for display afterwards::
+an article, passing them to the view for display afterwards:
+
+::
$q = Doctrine_Query::create()
- ->select('b.title, b.author, b.created_at')
- ->addSelect('COUNT(t.id) as num_comments')
- ->from('BlogPost b')
- ->leftJoin('b.Comments c')
- ->where('b.id = ?')
- ->orderBy('b.created_at DESC');
+ ->select( 'b.title, b.author, b.created_at' )
+ ->addSelect( 'COUNT(t.id) as num_comments' )
+ ->from( 'BlogPost b' )
+ ->leftJoin( 'b.Comments c' )
+ ->where( 'b.id = ?' )
+ ->orderBy( 'b.created_at DESC' );
- $blogPosts = $q->execute(array(1));
+ $blogPosts = $q->execute( array( 1 ) );
Now imagine you have a view or template that renders the most recent
blog posts:
.. code-block:: html+php
- <?php foreach ($blogPosts as $blogPost): ?>
- <li>
- <strong>
- <?php echo $blogPost['title'] ?>
- </strong>
+ <?php foreach ( $blogPosts as $blogPost ): ?>
+ <li>
+ <strong>
+ <?php echo $blogPost['title'] ?>
+ </strong>
- - Posted on <?php echo $blogPost['created_at'] ?>
- by <?php echo $blogPost['author'] ?>.
+ - Posted on <?php echo $blogPost['created_at'] ?>
+ by <?php echo $blogPost['author'] ?>.
- <small>
- (<?php echo $blogPost['num_comments'] ?>)
- </small>
- </li>
+ <small>
+ (<?php echo $blogPost['num_comments'] ?>)
+ </small>
+ </li>
<?php endforeach; ?>
Can you think of any benefit of having objects in the view instead of
arrays? You're not going to execute business logic in the view, are you?
-One parameter can save you a lot of unnecessary processing::
+One parameter can save you a lot of unnecessary processing:
- $blogPosts = $q->execute(array(1), Doctrine_Core::HYDRATE_ARRAY);
+::
-If you prefer you can also use the :php:meth:`setHydrationMethod` method::
+ $blogPosts = $q->execute( array( 1 ), Doctrine_Core::HYDRATE_ARRAY );
- $q->setHydrationMode(Doctrine_Core::HYDRATE_ARRAY);
- $blogPosts = $q->execute(array(1));
+If you prefer you can also use the :php:meth:`setHydrationMethod` method:
+
+::
+
+ $q->setHydrationMode( Doctrine_Core::HYDRATE_ARRAY );
+ $blogPosts = $q->execute( array( 1 ) );
The above code will hydrate the data into arrays instead of objects
which is much less expensive.
.. note::
One great thing about array hydration is that if you use the
- ``ArrayAccess`` on your objects you can easily switch your queries to use
+ :php:class:`ArrayAccess` on your objects you can easily switch your queries to use
array hydration and your code will work exactly the same. For example the
above code we wrote to render the list of the most recent blog posts would
work when we switch the query behind it to array hydration.
Sometimes, you may want the direct output from PDO instead of an object or an
array. To do this, set the hydration mode to
-:php:const:`Doctrine_Core::HYDRATE_NONE`. Here's an example::
+:php:const:`Doctrine_Core::HYDRATE_NONE`. Here's an example:
+
+::
$q = Doctrine_Query::create()
- ->select('SUM(d.amount)')
- ->from('Donation d');
+ ->select( 'SUM(d.amount)' )
+ ->from( 'Donation d' );
- $results = $q->execute(array(), Doctrine_Core::HYDRATE_NONE);
+ $results = $q->execute( array(), Doctrine_Core::HYDRATE_NONE );
You will need to print the results and find the value in the array
-depending on your DQL query::
+depending on your DQL query:
+
+::
+
+ print_r( $results );
- print_r($results);
+In this example the result would be accessible with the following code:
-In this example the result would be accessible with the following code::
+::
$total = $results[0][1];
@@ -238,31 +267,40 @@ reference chains. Doctrine provides a :php:meth:`free` function on
:php:class:`Doctrine_Query` which eliminates the circular references on those
objects, freeing them up for garbage collection. Usage might look like:
-Free objects when mass inserting records::
+Free objects when mass inserting records:
- for ($i = 0; $i < 1000; $i++) {
+::
+
+ for ( $i = 0; $i < 1000; $i++ )
+ {
$object = createBigObject();
$object->save();
- $object->free(true);
+ $object->free( true );
}
-You can also free query objects in the same way::
+You can also free query objects in the same way:
+
+::
- for ($i = 0; $i < 1000; $i++) {
+ for ( $i = 0; $i < 1000; $i++ )
+ {
$q = Doctrine_Query::create()
- ->from('User u');
+ ->from( 'User u' );
$results = $q->fetchArray();
$q->free();
}
Or even better if you can reuse the same query object for each query in
-the loop that would be ideal::
+the loop that would be ideal:
+
+::
$q = Doctrine_Query::create()
- ->from('User u');
+ ->from('User u');
- for ($i = 0; $i < 1000; $i++) {
+ for ( $i = 0; $i < 1000; $i++ )
+ {
$results = $q->fetchArray();
$q->free();
}
@@ -275,7 +313,7 @@ Other Tips
There are two possible ways when it comes to using DQL. The first one is
writing the plain DQL queries and passing them to
- ``Doctrine_Connection::query($dql)``. The second one is to use a
+ ``Doctrine_Connection::query( $dql )``. The second one is to use a
:php:class:`Doctrine_Query` object and its fluent interface. The latter should
be preferred for all but very simple queries. The reason is that using the
:php:class:`Doctrine_Query` object and it's methods makes the life of the DQL
@@ -288,8 +326,7 @@ Other Tips
.. note::
- The following example assumes a many-many between ``Role``
- and ``User``.
+ The following example assumes a many-many between ``Role`` and ``User``.
::
@@ -303,12 +340,14 @@ Other Tips
The above code will load all roles of the user from the
database if they're not yet loaded! Just to add one new link!
- The following is the recommended way instead::
+ The following is the recommended way instead:
+
+ ::
- $userRole = new UserRole();
- $userRole->role_id = $role_id;
- $userRole->user_id = $user_id;
- $userRole->save();
+ $userRole = new UserRole();
+ $userRole->role_id = $role_id;
+ $userRole->user_id = $user_id;
+ $userRole->save();
==========
Conclusion
@@ -317,5 +356,5 @@ Conclusion
Lots of methods exist for improving performance in Doctrine. It is highly
recommended that you consider some of the methods described above.
-Now lets move on to learn about some of the :doc:`technology <technology>`
-used in Doctrine.
+Now lets move on to learn about some of the :doc:`technology`
+used in Doctrine.
View
543 source/en/manual/real-world-examples.rst
@@ -11,106 +11,204 @@ authentication system where you have users, roles, permissions, etc.
Below is an example where we setup several models that give you a basic
user management and security system.
- class User extends Doctrine\_Record { public function
-setTableDefinition() { $this->hasColumn('username', 'string', 255,
-array( 'unique' => true ) ); $this->hasColumn('password', 'string',
-255); } }
-
-class Role extends Doctrine\_Record { public function
-setTableDefinition() { $this->hasColumn('name', 'string', 255); } }
-
-class Permission extends Doctrine\_Record { public function
-setTableDefinition() { $this->hasColumn('name', 'string', 255); } }
-
-class RolePermission extends Doctrine\_Record { public function
-setTableDefinition() { $this->hasColumn('role\_id', 'integer', null,
-array( 'primary' => true ) ); $this->hasColumn('permission\_id',
-'integer', null, array( 'primary' => true ) ); }
-
::
- public function setUp()
+ class User extends Doctrine_Record
{
- $this->hasOne('Role', array(
- 'local' => 'role_id',
- 'foreign' => 'id'
- )
- );
- $this->hasOne('Permission', array(
- 'local' => 'permission_id',
- 'foreign' => 'id'
- )
- );
+ public function setTableDefinition()
+ {
+ $this->hasColumn( 'username', 'string', 255,
+ array(
+ 'unique' => true,
+ )
+ );
+ $this->hasColumn( 'password', 'string', 255 );
+ }
}
-}
-
-class UserRole extends Doctrine\_Record { public function
-setTableDefinition() { $this->hasColumn('user\_id', 'integer', null,
-array( 'primary' => true ) ); $this->hasColumn('role\_id', 'integer',
-null, array( 'primary' => true ) ); }
-
-::
-
- public function setUp()
+ class Role extends Doctrine_Record
{
- $this->hasOne('User', array(
- 'local' => 'user_id',
- 'foreign' => 'id'
- )
- );
- $this->hasOne('Role', array(
- 'local' => 'role_id',
- 'foreign' => 'id'
- )
- );
+ public function setTableDefinition()
+ {
+ $this->hasColumn( 'name', 'string', 255 );
+ }
}
-}
-
-class UserPermission extends Doctrine\_Record { public function
-setTableDefinition() { $this->hasColumn('user\_id', 'integer', null,
-array( 'primary' => true ) ); $this->hasColumn('permission\_id',
-'integer', null, array( 'primary' => true ) ); }
+ class Permission extends Doctrine_Record
+ {
+ public function setTableDefinition()
+ {
+ $this->hasColumn( 'name', 'string', 255 );
+ }
+ }
-::
+ class RolePermission extends Doctrine_Record
+ {
+ public function setTableDefinition()
+ {
+ $this->hasColumn( 'role_id', 'integer', null,
+ array(
+ 'primary' => true,
+ )
+ );
+ $this->hasColumn( 'permission_id', 'integer', null,
+ array(
+ 'primary' => true,
+ )
+ );
+ }
+
+ public function setUp()
+ {
+ $this->hasOne( 'Role',
+ array(
+ 'local' => 'role_id',
+ 'foreign' => 'id',
+ )
+ );
+ $this->hasOne( 'Permission',
+ array(
+ 'local' => 'permission_id',
+ 'foreign' => 'id',
+ )
+ );
+ }
+ }
- public function setUp()
+ class UserRole extends Doctrine_Record
{
- $this->hasOne('User', array(
- 'local' => 'user_id',
- 'foreign' => 'id'
- )
- );
- $this->hasOne('Permission', array(
- 'local' => 'permission_id',
- 'foreign' => 'id'
- )
- );
+ public function setTableDefinition()
+ {
+ $this->hasColumn( 'user_id', 'integer', null,
+ array(
+ 'primary' => true,
+ )
+ );
+ $this->hasColumn( 'role_id', 'integer', null,
+ array(
+ 'primary' => true,
+ )
+ );
+ }
+
+ public function setUp()
+ {
+ $this->hasOne( 'User',
+ array(
+ 'local' => 'user_id',
+ 'foreign' => 'id',
+ )
+ );
+ $this->hasOne( 'Role',
+ array(
+ 'local' => 'role_id',
+ 'foreign' => 'id',
+ )
+ );
+ }
}
-}
+ class UserPermission extends Doctrine_Record
+ {
+ public function setTableDefinition()
+ {
+ $this->hasColumn( 'user_id', 'integer', null,
+ array(
+ 'primary' => true,
+ )
+ );
+ $this->hasColumn( 'permission_id', 'integer', null,
+ array(
+ 'primary' => true,
+ )
+ );
+ }
+
+ public function setUp()
+ {
+ $this->hasOne( 'User',
+ array(
+ 'local' => 'user_id',
+ 'foreign' => 'id',
+ )
+ );
+ $this->hasOne( 'Permission',
+ array(
+ 'local' => 'permission_id',
+ 'foreign' => 'id',
+ )
+ );
+ }
+ }
Here is the same example in YAML format. You can read more about YAML in
-the [doc yaml-schema-files :name] chapter:
-
- User: columns: username: string(255) password: string(255) relations:
-Roles: class: Role refClass: UserRole foreignAlias: Users Permissions:
-class: Permission refClass: UserPermission foreignAlias: Users
-
-Role: columns: name: string(255) relations: Permissions: class:
-Permission refClass: RolePermission foreignAlias: Roles
-
-Permission: columns: name: string(255)
-
-RolePermission: columns: role\_id: type: integer primary: true
-permission\_id: type: integer primary: true relations: Role: Permission:
-
-UserRole: columns: user\_id: type: integer primary: true role\_id: type:
-integer primary: true relations: User: Role:
-
-UserPermission: columns: user\_id: type: integer primary: true
-permission\_id: type: integer primary: true relations: User: Permission:
+the :doc:`yaml-schema-files` chapter:
+
+.. code-block:: yaml
+
+ ---
+ User:
+ columns:
+ username: string(255)
+ password: string(255)
+ relations:
+ Roles:
+ class: Role
+ refClass: UserRole
+ foreignAlias: Users
+ Permissions:
+ class: Permission
+ refClass: UserPermission
+ foreignAlias: Users
+
+ Role:
+ columns:
+ name: string(255)
+ relations:
+ Permissions:
+ class: Permission
+ refClass: RolePermission
+ foreignAlias: Roles
+
+ Permission:
+ columns:
+ name: string(255)
+
+ RolePermission:
+ columns:
+ role_id:
+ type: integer
+ primary: true
+ permission_id:
+ type: integer
+ primary: true
+ relations:
+ Role:
+ Permission:
+
+ UserRole:
+ columns:
+ user_id:
+ type: integer
+ primary: true
+ role_id:
+ type: integer
+ primary: true
+ relations:
+ User:
+ Role:
+
+ UserPermission:
+ columns:
+ user_id:
+ type: integer
+ primary: true
+ permission_id:
+ type: integer
+ primary: true
+ relations:
+ User:
+ Permission:
=================
Forum Application
@@ -119,133 +217,192 @@ Forum Application
Below is an example of a forum application where you have categories,
boards, threads and posts:
- class Forum\_Category extends Doctrine\_Record { public function
-setTableDefinition() { $this->hasColumn('root\_category\_id', 'integer',
-10); $this->hasColumn('parent\_category\_id', 'integer', 10);
-$this->hasColumn('name', 'string', 50); $this->hasColumn('description',
-'string', 99999); }
-
::
- public function setUp()
+ class Forum_Category extends Doctrine_Record
{
- $this->hasMany('Forum_Category as Subcategory', array(
- 'local' => 'parent_category_id',
- 'foreign' => 'id'
- )
- );
- $this->hasOne('Forum_Category as Rootcategory', array(
- 'local' => 'root_category_id',
- 'foreign' => 'id'
- )
- );
+ public function setTableDefinition()
+ {
+ $this->hasColumn( 'root_category_id', 'integer', 10 );
+ $this->hasColumn( 'parent_category_id', 'integer', 10 );
+ $this->hasColumn( 'name', 'string', 50 );
+ $this->hasColumn( 'description', 'string', 99999 );
+ }
+
+ public function setUp()
+ {
+ $this->hasMany( 'Forum_Category as Subcategory',
+ array(
+ 'local' => 'parent_category_id',
+ 'foreign' => 'id',
+ )
+ );
+ $this->hasOne( 'Forum_Category as Rootcategory',
+ array(
+ 'local' => 'root_category_id',
+ 'foreign' => 'id',
+ )
+ );
+ }
}
-}
-
-class Forum\_Board extends Doctrine\_Record { public function
-setTableDefinition() { $this->hasColumn('category\_id', 'integer', 10);
-$this->hasColumn('name', 'string', 100); $this->hasColumn('description',
-'string', 5000); }
-
-::
-
- public function setUp()
+ class Forum_Board extends Doctrine_Record
{
- $this->hasOne('Forum_Category as Category', array(
- 'local' => 'category_id',
- 'foreign' => 'id'
- )
- );
- $this->hasMany('Forum_Thread as Threads', array(
- 'local' => 'id',
- 'foreign' => 'board_id'
- )
- );
- }
-
-}
-
-class Forum\_Entry extends Doctrine\_Record { public function
-setTableDefinition() { $this->hasColumn('author', 'string', 50);
-$this->hasColumn('topic', 'string', 100); $this->hasColumn('message',
-'string', 99999); $this->hasColumn('parent\_entry\_id', 'integer', 10);
-$this->hasColumn('thread\_id', 'integer', 10); $this->hasColumn('date',
-'integer', 10); }
-
-::
+ public function setTableDefinition()
+ {
+ $this->hasColumn( 'category_id', 'integer', 10 );
+ $this->hasColumn( 'name', 'string', 100 );
+ $this->hasColumn( 'description', 'string', 5000 );
+ }
+
+ public function setUp()
+ {
+ $this->hasOne( 'Forum_Category as Category',
+ array(
+ 'local' => 'category_id',
+ 'foreign' => 'id',
+ )
+ );
+ $this->hasMany( 'Forum_Thread as Threads',
+ array(
+ 'local' => 'id',
+ 'foreign' => 'board_id'
+ )
+ );
+ }
+ }
- public function setUp()
+ class Forum_Entry extends Doctrine_Record
{
- $this->hasOne('Forum_Entry as Parent', array(
- 'local' => 'parent_entry_id',
- 'foreign' => 'id'
- )
- );
- $this->hasOne('Forum_Thread as Thread', array(
- 'local' => 'thread_id',
- 'foreign' => 'id'
- )
- );
+ public function setTableDefinition()
+ {
+ $this->hasColumn( 'author', 'string', 50 );
+ $this->hasColumn( 'topic', 'string', 100 );
+ $this->hasColumn( 'message', 'string', 99999 );
+ $this->hasColumn( 'parent_entry_id', 'integer', 10 );
+ $this->hasColumn( 'thread_id', 'integer', 10 );
+ $this->hasColumn( 'date', 'integer', 10 );
+ }
+
+ public function setUp()
+ {
+ $this->hasOne( 'Forum_Entry as Parent',
+ array(
+ 'local' => 'parent_entry_id',
+ 'foreign' => 'id',
+ )
+ );
+ $this->hasOne( 'Forum_Thread as Thread',
+ array(
+ 'local' => 'thread_id',
+ 'foreign' => 'id',
+ )
+ );
+ }
}
-}
-
-class Forum\_Thread extends Doctrine\_Record { public function
-setTableDefinition() { $this->hasColumn('board\_id', 'integer', 10);
-$this->hasColumn('updated', 'integer', 10); $this->hasColumn('closed',
-'integer', 1); }
-
-::
-
- public function setUp()
+ class Forum_Thread extends Doctrine_Record
{
- $this->hasOne('Forum_Board as Board', array(
- 'local' => 'board_id',
- 'foreign' => 'id'
- )
- );
-
- $this->hasMany('Forum_Entry as Entries', array(
- 'local' => 'id',
- 'foreign' => thread_id'
- )
- );
+ public function setTableDefinition()
+ {
+ $this->hasColumn( 'board_id', 'integer', 10 );
+ $this->hasColumn( 'updated', 'integer', 10 );
+ $this->hasColumn( 'closed', 'integer', 1 );
+ }
+
+ public function setUp()
+ {
+ $this->hasOne( 'Forum_Board as Board',
+ array(
+ 'local' => 'board_id',
+ 'foreign' => 'id',
+ )
+ );
+ $this->hasMany( 'Forum_Entry as Entries',
+ array(
+ 'local' => 'id',
+ 'foreign' => 'thread_id',
+ )
+ );
+ }
}
-}
-
Here is the same example in YAML format. You can read more about YAML in
-the [doc yaml-schema-files :name] chapter:
-
- Forum\_Category: columns: root\_category\_id: integer(10)
-parent\_category\_id: integer(10) name: string(50) description:
-string(99999) relations: Subcategory: class: Forum\_Category local:
-parent\_category\_id foreign: id Rootcategory: class: Forum\_Category
-local: root\_category\_id foreign: id
-
-Forum\_Board: columns: category\_id: integer(10) name: string(100)
-description: string(5000) relations: Category: class: Forum\_Category
-local: category\_id foreign: id Threads: class: Forum\_Thread local: id
-foreign: board\_id
-
-Forum\_Entry: columns: author: string(50) topic: string(100) message:
-string(99999) parent\_entry\_id: integer(10) thread\_id: integer(10)
-date: integer(10) relations: Parent: class: Forum\_Entry local:
-parent\_entry\_id foreign: id Thread: class: Forum\_Thread local:
-thread\_id foreign: id
-
-Forum\_Thread: columns: board\_id: integer(10) updated: integer(10)
-closed: integer(1) relations: Board: class: Forum\_Board local:
-board\_id foreign: id Entries: class: Forum\_Entry local: id foreign:
-thread\_id
+the :doc:`yaml-schema-files` chapter:
+
+.. code-block:: yaml
+
+ ---
+ Forum_Category:
+ columns:
+ root_category_id: integer(10)
+ parent_category_id: integer(10)
+ name: string(50)
+ description: string(99999)
+ relations:
+ Subcategory:
+ class: Forum_Category
+ local: parent_category_id
+ foreign: id
+ Rootcategory:
+ class: Forum_Category
+ local: root_category_id
+ foreign: id
+
+ Forum_Board:
+ columns:
+ category_id: integer(10)
+ name: string(100)
+ description: string(5000)
+ relations:
+ Category:
+ class: Forum_Category
+ local: category_id
+ foreign: id
+ Threads:
+ class: Forum_Thread
+ local: id
+ foreign: board_id
+
+ Forum_Entry:
+ columns:
+ author: string(50)
+ topic: string(100)
+ message: string(99999)
+ parent_entry_id: integer(10)
+ thread_id: integer(10)
+ date: integer(10)
+ relations:
+ Parent:
+ class: Forum_Entry
+ local: parent_entry_id
+ foreign: id
+ Thread:
+ class: Forum_Thread
+ local: thread_id
+ foreign: id
+
+ Forum_Thread:
+ columns:
+ board_id: integer(10)
+ updated: integer(10)
+ closed: integer(1)
+ relations:
+ Board:
+ class: Forum_Board
+ local: board_id
+ foreign: id
+ Entries:
+ class: Forum_Entry
+ local: id
+ foreign: thread_id
==========
Conclusion
==========
I hope that these real world schema examples will help you with using
Doctrine in the real world in your application. The last chapter of this
-book will discuss the [doc coding-standards coding standards] used in
+book will discuss the :doc:`coding standards <coding-standards>` used in
Doctrine and are recommended for you to use in your application as well.
-Remember, consistency in your code is key!
+Remember, consistency in your code is key!
View
137 source/en/manual/technology.rst
@@ -16,10 +16,10 @@ done.
Doctrine has also borrowed pieces of code from other open
source projects instead of re-inventing the wheel. Two of the
- projects borrowed from are [http://www.symfony-project.com symfony]
- and the [http://framework.zend.com Zend Framework]. The relevant
+ projects borrowed from are `symfony <http://www.symfony-project.com>`_
+ and the `Zend Framework <http://framework.zend.com>`_. The relevant
license information can be found in the root of Doctrine when you
- [http://www.doctrine-project.org download] it in a file named
+ `download <http://www.doctrine-project.org>`_ it in a file named
``LICENSE``.
============
@@ -34,110 +34,87 @@ Doctrine CORE
-------------
- Doctrine
-- [doc component-overview:manager Doctrine\_Manager]
-- [doc component-overview:connection Doctrine\_Connection]
-- [doc improving-performance:compile Doctrine\_Compiler]
-- [doc exceptions-and-warnings Doctrine\_Exception]
-- Doctrine\_Formatter
-- Doctrine\_Object
-- Doctrine\_Null
-- [doc event-listeners Doctrine\_Event]
-- Doctrine\_Overloadable
-- Doctrine\_Configurable
-- [doc event-listeners Doctrine\_EventListener]
+- :ref:`Doctrine_Manager <component-overview-manager>`
+- :ref:`Doctrine_Connection <component-overview-connection>`
+- :ref:`Doctrine_Compiler <improving-performance-compile>`
+- :doc:`Doctrine_Exception <exceptions-and-warnings>`
+- Doctrine_Formatter
+- Doctrine_Object
+- Doctrine_Null
+- :doc:`Doctrine_Event <event-listeners>`
+- Doctrine_Overloadable
+- Doctrine_Configurable
+- :doc:`Doctrine_EventListener <event-listeners>`
-------------
Doctrine DBAL
-------------
-- [doc component-overview:record:using-expression-values
- Doctrine\_Expression\_Driver]
-- [doc database-abstraction-layer:export Doctrine\_Export]
-- [doc database-abstraction-layer:import Doctrine\_Import]
-- Doctrine\_Sequence
-- [doc transactions Doctrine\_Transaction]
-- [doc database-abstraction-layer:datadict Doctrine\_DataDict]
+- :ref:`Doctrine_Expression_Driver <component-overview-using-expression-values>`
+- :ref:`Doctrine_Export <database-abstraction-layer-export>`
+- :ref:`Doctrine_Import <database-abstraction-layer-import>`
+- Doctrine_Sequence
+- :doc:`Doctrine_Transaction <transactions>`
+- :ref:`Doctrine_DataDict <database-abstraction-layer-datadict>`
Doctrine DBAL is also divided into driver packages.
------------
Doctrine ORM
------------
-- [doc component-overview:record Doctrine\_Record]
-- [doc component-overview:table Doctrine\_Table]
-- [doc defining-models:relationships Doctrine\_Relation]
-- [doc component-overview:record:using-expression-values
- Doctrine\_Expression]
-- [doc dql-doctrine-query-language Doctrine\_Query]
-- [doc native-sql Doctrine\_RawSql]
-- [doc component-overview:collection Doctrine\_Collection]
-- Doctrine\_Tokenizer
+- :ref:`Doctrine_Record <component-overview-record>`
+- :ref:`Doctrine_Table <component-overview-table>`
+- :ref:`Doctrine_Relation <defining-models-relationships>`
+- :ref:`Doctrine_Expression <component-overview-using-expression-values>`
+- :doc:`Doctrine_Query <dql-doctrine-query-language>`
+- :doc:`Doctrine_RawSql <native-sql>`
+- :ref:`Doctrine_Collection <component-overview-collection>`
+- Doctrine_Tokenizer
Other miscellaneous packages.
-- [doc data-validation Doctrine\_Validator]
-- Doctrine\_Hook
-- [doc component-overview:views Doctrine\_View]
+- :doc:`Doctrine_Validator <data-validation>`
+- Doctrine_Hook
+- :ref:`Doctrine_View <component-overview-views>`
There are also behaviors for Doctrine:
-- [doc behaviors:core-behaviors:geographical :name]
-- [doc behaviors:core-behaviors:i18n :name]
-- [doc behaviors:core-behaviors:nestedset :name]
-- [doc behaviors:core-behaviors:searchable :name]
-- [doc behaviors:core-behaviors:sluggable :name]
-- [doc behaviors:core-behaviors:softdelete :name]
-- [doc behaviors:core-behaviors:timestampable :name]
-- [doc behaviors:core-behaviors:versionable :name]
+- :ref:`Geographical <behaviors-core-behaviors-geographical>`
+- :ref:`I18n <behaviors-core-behaviors-i18n>`
+- :ref:`NestedSet <behaviors-core-behaviors-nestedset>`
+- :ref:`Searchable <behaviors-core-behaviors-searchable>`
+- :ref:`Sluggable <behaviors-core-behaviors-sluggable>`
+- :ref:`SoftDelete <behaviors-core-behaviors-softdelete>`
+- :ref:`Timestampable <behaviors-core-behaviors-timestampable>`
+- :ref:`Versionable <behaviors-core-behaviors-versionable>`
====================
Design Patterns Used
====================
``GoF (Gang of Four)`` design patterns used:
-- [http://www.dofactory.com/Patterns/PatternSingleton.aspx Singleton],
- for forcing only one instance of ``Doctrine_Manager``
-- [http://www.dofactory.com/Patterns/PatternComposite.aspx Composite],
- for leveled configuration
-- [http://www.dofactory.com/Patterns/PatternFactory.aspx Factory], for
- connection driver loading and many other things
-- [http://www.dofactory.com/Patterns/PatternObserver.aspx Observer],
- for event listening
-- [http://www.dofactory.com/Patterns/PatternFlyweight.aspx Flyweight],
- for efficient usage of validators
-- [http://www.dofactory.com/Patterns/PatternFlyweight.aspx Iterator],
- for iterating through components (Tables, Connections, Records etc.)
-- [http://www.dofactory.com/Patterns/PatternState.aspx State], for
- state-wise connections
-- [http://www.dofactory.com/Patterns/PatternStrategy.aspx Strategy],
- for algorithm strategies
+- `Singleton <http://www.dofactory.com/Patterns/PatternSingleton.aspx>`_, for forcing only one instance of :php:class:`Doctrine_Manager`
+- `Composite <http://www.dofactory.com/Patterns/PatternComposite.aspx>`_, for leveled configuration
+- `Factory <http://www.dofactory.com/Patterns/PatternFactory.aspx>`_, for connection driver loading and many other things
+- `Observer <http://www.dofactory.com/Patterns/PatternObserver.aspx>`_, for event listening
+- `Flyweight <http://www.dofactory.com/Patterns/PatternFlyweight.aspx>`_, for efficient usage of validators
+- `Iterator <http://www.dofactory.com/Patterns/PatternFlyweight.aspx>`_, for iterating through components (Tables, Connections, Records etc.)
+- `State <http://www.dofactory.com/Patterns/PatternState.aspx>`_, for state-wise connections
+- `Strategy <http://www.dofactory.com/Patterns/PatternStrategy.aspx>`_, for algorithm strategies
Enterprise application design patterns used:
-- [http://www.martinfowler.com/eaaCatalog/activeRecord.html Active
- Record], Doctrine is an implementation of this pattern
-- [http://www.martinfowler.com/eaaCatalog/unitOfWork.html UnitOfWork],
- for maintaining a list of objects affected in a transaction
-- [http://www.martinfowler.com/eaaCatalog/identityField.html Identity
- Field], for maintaining the identity between record and database row
-- [http://www.martinfowler.com/eaaCatalog/metadataMapping.html Metadata
- Mapping], for Doctrine DataDict
-- [http://www.martinfowler.com/eaaCatalog/dependentMapping.html
- Dependent Mapping], for mapping in general, since all records extend
- ``Doctrine_Record`` which performs all mappings
-- [http://www.martinfowler.com/eaaCatalog/foreignKeyMapping.html
- Foreign Key Mapping], for one-to-one, one-to-many and many-to-one
- relationships
-- [http://www.martinfowler.com/eaaCatalog/associationTableMapping.html
- Association Table Mapping], for association table mapping (most
- commonly many-to-many relationships)
-- [http://www.martinfowler.com/eaaCatalog/lazyLoad.html Lazy Load], for
- lazy loading of objects and object properties
-- [http://www.martinfowler.com/eaaCatalog/queryObject.html Query
- Object], DQL API is actually an extension to the basic idea of Query
- Object pattern
+- `Active Record <http://www.martinfowler.com/eaaCatalog/activeRecord.html>`_, Doctrine is an implementation of this pattern
+- `UnitOfWork <http://www.martinfowler.com/eaaCatalog/unitOfWork.html>`_, for maintaining a list of objects affected in a transaction
+- `Identity Field <http://www.martinfowler.com/eaaCatalog/identityField.html>`_, for maintaining the identity between record and database row
+- `Metadata Mapping <http://www.martinfowler.com/eaaCatalog/metadataMapping.html>`_, for Doctrine DataDict
+- `Dependent Mapping <http://www.martinfowler.com/eaaCatalog/dependentMapping.html>`_, for mapping in general, since all records extend :php:class:`Doctrine_Record` which performs all mappings
+- `Foreign Key Mapping <http://www.martinfowler.com/eaaCatalog/foreignKeyMapping.html>`_, for one-to-one, one-to-many and many-to-one relationships
+- `Association Table Mapping <http://www.martinfowler.com/eaaCatalog/associationTableMapping.html>`_, for association table mapping (most commonly many-to-many relationships)
+- `Lazy Load <http://www.martinfowler.com/eaaCatalog/lazyLoad.html>`_, for lazy loading of objects and object properties
+- `Query Object <http://www.martinfowler.com/eaaCatalog/queryObject.html>`_, DQL API is actually an extension to the basic idea of Query Object pattern
=====
Speed
@@ -183,4 +160,4 @@ three main packages should have made things very clear for you if it was
not already.
Now we are ready to move on and learn about how to deal with Doctrine
-throwing exceptions in the [doc exceptions-and-warnings :name] chapter.
+throwing exceptions in the :doc:`exceptions-and-warnings` chapter.

0 comments on commit 67fd803

Please sign in to comment.