1
0
mirror of synced 2025-01-18 06:21:40 +03:00

Finialized ReST doc changes, merged changes from latest Markdown docs.

This commit is contained in:
Benjamin Eberlei 2010-12-03 20:13:10 +01:00
parent ee042bc642
commit 46983465fd
52 changed files with 897 additions and 1170 deletions

View File

@ -1,34 +0,0 @@
Getting Started XML-Edition
===========================
Implementing ArrayAccess for domain objects
===========================================
Implementing the NOTIFY change-tracking policy
==============================================
Validation of Entities
======================
Implementing wakeup or clone
============================
Integrating with CodeIgniter
============================
DQL Custom Walkers
==================
DQL User Defined Functions
==========================
SQL Table Prefixes
==================
Strategy Cookbook Introduction
==============================
Aggregate Fields
================

View File

@ -1,11 +0,0 @@
# Getting Started XML-Edition
# Implementing ArrayAccess for domain objects
# Implementing the NOTIFY change-tracking policy
# Validation of Entities
# Implementing wakeup or clone
# Integrating with CodeIgniter
# DQL Custom Walkers
# DQL User Defined Functions
# SQL Table Prefixes
# Strategy Cookbook Introduction
# Aggregate Fields

View File

@ -1,89 +0,0 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Doctrine2ORMCookbook.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Doctrine2ORMCookbook.qhc"
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

View File

@ -1,196 +0,0 @@
# -*- coding: utf-8 -*-
#
# Doctrine 2 ORM Cookbook documentation build configuration file, created by
# sphinx-quickstart on Mon Nov 1 21:13:13 2010.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.append(os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Doctrine 2 ORM Cookbook'
copyright = u'2010, Doctrine Project Team'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '2.0'
# The full version, including alpha/beta/rc tags.
release = '2.0.0-BETA4'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
language = 'en'
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
#unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
highlight_language = 'php'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_use_modindex = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'Doctrine2ORMCookbookdoc'
# -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'Doctrine2ORMCookbook.tex', u'Doctrine 2 ORM Cookbook Documentation',
u'Doctrine Project Team', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True

View File

@ -1,32 +0,0 @@
.. Doctrine 2 ORM Cookbook documentation master file, created by
sphinx-quickstart on Mon Nov 1 21:13:13 2010.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Doctrine 2 ORM Cookbook's documentation!
===================================================
Contents:
.. toctree::
:maxdepth: 2
getting-started-xml-edition
implementing-arrayaccess-for-domain-objects
implementing-the-notify-changetracking-policy
validations-of-entities
implementing-wakeup-or-clone
integrating-with-codeigniter
dql-custom-walkers
dql-user-defined-functions
sql-table-prefixes
strategy-cookbook-introdution
aggregates-fields
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -1,113 +0,0 @@
@ECHO OFF
REM Command file for Sphinx documentation
set SPHINXBUILD=sphinx-build
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Doctrine2ORMCookbook.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Doctrine2ORMCookbook.ghc
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
:end

198
en/_templates/layout.html Normal file
View File

@ -0,0 +1,198 @@
{%- block doctype -%}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
{%- endblock %}
{%- set reldelim1 = reldelim1 is not defined and ' &raquo;' or reldelim1 %}
{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
{%- set url_root = pathto('', 1) %}
{%- if url_root == '#' %}{% set url_root = '' %}{% endif %}
{%- macro relbar() %}
<div class="related">
<h3>{{ _('Navigation') }}</h3>
<ul>
{%- for rellink in rellinks %}
<li class="right" {% if loop.first %}style="margin-right: 10px"{% endif %}>
<a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags }}"
{{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
{%- if not loop.first %}{{ reldelim2 }}{% endif %}</li>
{%- endfor %}
{%- block rootrellink %}
<li><a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a>{{ reldelim1 }}</li>
{%- endblock %}
{%- for parent in parents %}
<li><a href="{{ parent.link|e }}" {% if loop.last %}{{ accesskey("U") }}{% endif %}>{{ parent.title }}</a>{{ reldelim1 }}</li>
{%- endfor %}
{%- block relbaritems %} {% endblock %}
</ul>
</div>
{%- endmacro %}
{%- macro sidebar() %}
{%- if not embedded %}{% if not theme_nosidebar|tobool %}
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
{%- block sidebarlogo %}
{%- if logo %}
<p class="logo"><a href="{{ pathto(master_doc) }}">
<img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
</a></p>
{%- endif %}
{%- endblock %}
{%- block sidebartoc %}
{%- if display_toc %}
<h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3>
{{ toc }}
{%- endif %}
{%- endblock %}
{%- block sidebarrel %}
{%- if prev %}
<h4>{{ _('Previous topic') }}</h4>
<p class="topless"><a href="{{ prev.link|e }}"
title="{{ _('previous chapter') }}">{{ prev.title }}</a></p>
{%- endif %}
{%- if next %}
<h4>{{ _('Next topic') }}</h4>
<p class="topless"><a href="{{ next.link|e }}"
title="{{ _('next chapter') }}">{{ next.title }}</a></p>
{%- endif %}
{%- endblock %}
{%- block sidebarsourcelink %}
{%- if show_source and has_source and sourcename %}
<h3>{{ _('This Page') }}</h3>
<ul class="this-page-menu">
<li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
rel="nofollow">{{ _('Show Source') }}</a></li>
</ul>
{%- endif %}
{%- endblock %}
{%- if customsidebar %}
{% include customsidebar %}
{%- endif %}
{%- block sidebarsearch %}
{%- if pagename != "search" %}
<div id="searchbox" style="display: none">
<h3>{{ _('Quick search') }}</h3>
<form class="search" action="{{ pathto('search') }}" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="{{ _('Go') }}" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
{{ _('Enter search terms or a module, class or function name.') }}
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
{%- endif %}
{%- endblock %}
</div>
</div>
{%- endif %}{% endif %}
{%- endmacro %}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
{{ metatags }}
{%- if not embedded and docstitle %}
{%- set titlesuffix = " &mdash; "|safe + docstitle|e %}
{%- else %}
{%- set titlesuffix = "" %}
{%- endif %}
<title>{{ title|striptags }}{{ titlesuffix }}</title>
<link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
<link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
{%- if not embedded %}
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '{{ url_root }}',
VERSION: '{{ release|e }}',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '{{ file_suffix }}',
HAS_SOURCE: {{ has_source|lower }}
};
</script>
{%- for scriptfile in script_files %}
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
{%- endfor %}
{%- if use_opensearch %}
<link rel="search" type="application/opensearchdescription+xml"
title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
href="{{ pathto('_static/opensearch.xml', 1) }}"/>
{%- endif %}
{%- if favicon %}
<link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
{%- endif %}
{%- endif %}
{%- block linktags %}
{%- if hasdoc('about') %}
<link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
{%- endif %}
{%- if hasdoc('genindex') %}
<link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
{%- endif %}
{%- if hasdoc('search') %}
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
{%- endif %}
{%- if hasdoc('copyright') %}
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
{%- endif %}
<link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}" />
{%- if parents %}
<link rel="up" title="{{ parents[-1].title|striptags }}" href="{{ parents[-1].link|e }}" />
{%- endif %}
{%- if next %}
<link rel="next" title="{{ next.title|striptags }}" href="{{ next.link|e }}" />
{%- endif %}
{%- if prev %}
<link rel="prev" title="{{ prev.title|striptags }}" href="{{ prev.link|e }}" />
{%- endif %}
{%- endblock %}
{%- block extrahead %} {% endblock %}
</head>
<body>
{%- block header %}{% endblock %}
{%- block relbar1 %}{{ relbar() }}{% endblock %}
{%- block sidebar1 %} {# possible location for sidebar #} {% endblock %}
<div class="document">
{%- block document %}
<div class="documentwrapper">
{%- if not embedded %}{% if not theme_nosidebar|tobool %}
<div class="bodywrapper">
{%- endif %}{% endif %}
<div class="body">
{% block body %} {% endblock %}
</div>
{%- if not embedded %}{% if not theme_nosidebar|tobool %}
</div>
{%- endif %}{% endif %}
</div>
{%- endblock %}
{%- block sidebar2 %}{{ sidebar() }}{% endblock %}
<div class="clearer"></div>
</div>
{%- block relbar2 %}{{ relbar() }}{% endblock %}
{%- block footer %}
<div class="footer">
{%- if hasdoc('copyright') %}
{% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
{%- else %}
{% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
{%- endif %}
{%- if last_updated %}
{% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
{%- endif %}
{%- if show_sphinx %}
{% trans sphinx_version=sphinx_version|e %}Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}
{%- endif %}
</div>
{%- endblock %}
</body>
</html>

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# Doctrine 2 ORM documentation build configuration file, created by # Doctrine 2 ORM documentation build configuration file, created by
# sphinx-quickstart on Mon Nov 1 21:19:39 2010. # sphinx-quickstart on Fri Dec 3 18:10:24 2010.
# #
# This file is execfile()d with the current directory set to its containing dir. # This file is execfile()d with the current directory set to its containing dir.
# #
@ -38,7 +38,7 @@ master_doc = 'index'
# General information about the project. # General information about the project.
project = u'Doctrine 2 ORM' project = u'Doctrine 2 ORM'
copyright = u'2010, Roman Borschel, Guilherme Blanco, Benjamin Eberlei, Jonathan Wage' copyright = u'2010, Doctrine Project Team'
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the # |version| and |release|, also used in various other places throughout the
@ -47,11 +47,11 @@ copyright = u'2010, Roman Borschel, Guilherme Blanco, Benjamin Eberlei, Jonathan
# The short X.Y version. # The short X.Y version.
version = '2.0' version = '2.0'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '2.0.0-BETA4' release = '2.0.0'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.
language = 'en' language = 'php'
# There are two options for replacing |today|: either, you set today to some # There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used: # non-false value, then it is used:
@ -78,13 +78,11 @@ exclude_trees = ['_build']
# If true, sectionauthor and moduleauthor directives will be shown in the # If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default. # output. They are ignored by default.
#show_authors = False show_authors = True
# The name of the Pygments (syntax highlighting) style to use. # The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx' pygments_style = 'sphinx'
highlight_language = 'php'
# A list of ignored prefixes for module index sorting. # A list of ignored prefixes for module index sorting.
#modindex_common_prefix = [] #modindex_common_prefix = []
@ -175,7 +173,7 @@ htmlhelp_basename = 'Doctrine2ORMdoc'
# (source start file, target name, title, author, documentclass [howto/manual]). # (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [ latex_documents = [
('index', 'Doctrine2ORM.tex', u'Doctrine 2 ORM Documentation', ('index', 'Doctrine2ORM.tex', u'Doctrine 2 ORM Documentation',
u'Roman Borschel, Guilherme Blanco, Benjamin Eberlei, Jonathan Wage', 'manual'), u'Doctrine Project Team', 'manual'),
] ]
# The name of an image file (relative to this directory) to place at the top of # The name of an image file (relative to this directory) to place at the top of

View File

@ -1,6 +1,8 @@
Aggregate Fields Aggregate Fields
================ ================
.. sectionauthor:: Benjamin Eberlei <kontakt@beberlei.de>
You will often come across the requirement to display aggregate You will often come across the requirement to display aggregate
values of data that can be computed by using the MIN, MAX, COUNT or values of data that can be computed by using the MIN, MAX, COUNT or
SUM SQL functions. For any ORM this is a tricky issue SUM SQL functions. For any ORM this is a tricky issue
@ -27,7 +29,7 @@ added on the ``Entry`` object.
Our entities look like: Our entities look like:
:: .. code-block:: php
<?php <?php
namespace Bank\Entities; namespace Bank\Entities;
@ -99,7 +101,7 @@ The Doctrine Query Language allows you to select for aggregate
values computed from fields of your Domain Model. You can select values computed from fields of your Domain Model. You can select
the current balance of your account by calling: the current balance of your account by calling:
:: .. code-block:: php
<?php <?php
$dql = "SELECT SUM(e.amount) AS balance FROM Bank\Entities\Entry e " . $dql = "SELECT SUM(e.amount) AS balance FROM Bank\Entities\Entry e " .
@ -138,7 +140,7 @@ Using your Domain Model
``Account`` and all the ``Entry`` instances are connected through a ``Account`` and all the ``Entry`` instances are connected through a
collection, which means we can compute this value at runtime: collection, which means we can compute this value at runtime:
:: .. code-block:: php
<?php <?php
class Account class Account
@ -168,7 +170,7 @@ the aggregate root of this relation. We can also enforce the
correctness of the bi-directional ``Account`` <-> ``Entry`` correctness of the bi-directional ``Account`` <-> ``Entry``
relation with this method: relation with this method:
:: .. code-block:: php
<?php <?php
class Account class Account
@ -185,7 +187,7 @@ relation with this method:
Now look at the following test-code for our entities: Now look at the following test-code for our entities:
:: .. code-block:: php
<?php <?php
class AccountTest extends \PHPUnit_Framework_TestCase class AccountTest extends \PHPUnit_Framework_TestCase
@ -214,7 +216,7 @@ Now look at the following test-code for our entities:
To enforce our rule we can now implement the assertion in To enforce our rule we can now implement the assertion in
``Account::addEntry``: ``Account::addEntry``:
:: .. code-block:: php
<?php <?php
class Account class Account
@ -236,7 +238,7 @@ account example before. You can call
database. All the nested ``Entry`` objects are automatically database. All the nested ``Entry`` objects are automatically
flushed to the database also. flushed to the database also.
:: .. code-block:: php
<?php <?php
$account = new Account("123456", 200); $account = new Account("123456", 200);
@ -258,7 +260,7 @@ entries collection) we want to add an aggregate field called
"balance" on the Account and adjust the code in "balance" on the Account and adjust the code in
``Account::getBalance()`` and ``Account:addEntry()``: ``Account::getBalance()`` and ``Account:addEntry()``:
:: .. code-block:: php
<?php <?php
class Account class Account
@ -301,7 +303,7 @@ Tackling Race Conditions with Aggregate Fields
Whenever you denormalize your database schema race-conditions can Whenever you denormalize your database schema race-conditions can
potentially lead to inconsistent state. See this example: potentially lead to inconsistent state. See this example:
:: .. code-block:: php
<?php <?php
// The Account $accId has a balance of 0 and a max credit limit of 200: // The Account $accId has a balance of 0 and a max credit limit of 200:
@ -327,7 +329,7 @@ Eric Evans DDD carefully he mentions that the "Aggregate Root"
Optimistic locking is as easy as adding a version column: Optimistic locking is as easy as adding a version column:
:: .. code-block:: php
<?php <?php
class Amount class Amount
@ -344,7 +346,7 @@ Pessimistic locking requires an additional flag set on the
``EntityManager::find()`` call, enabling write locking directly in ``EntityManager::find()`` call, enabling write locking directly in
the database using a FOR UPDATE. the database using a FOR UPDATE.
:: .. code-block:: php
<?php <?php
use Doctrine\DBAL\LockMode; use Doctrine\DBAL\LockMode;

View File

@ -1,6 +1,8 @@
Extending DQL in Doctrine 2: Custom AST Walkers Extending DQL in Doctrine 2: Custom AST Walkers
=============================================== ===============================================
.. sectionauthor:: Benjamin Eberlei <kontakt@beberlei.de>
The Doctrine Query Language (DQL) is a proprietary sql-dialect that The Doctrine Query Language (DQL) is a proprietary sql-dialect that
substitutes tables and columns for Entity names and their fields. substitutes tables and columns for Entity names and their fields.
Using DQL you write a query against the database using your Using DQL you write a query against the database using your
@ -58,7 +60,7 @@ Say you have a blog and posts all with one category and one author.
A query for the front-page or any archive page might look something A query for the front-page or any archive page might look something
like: like:
.. code-clock:: sql .. code-block:: sql
SELECT p, c, a FROM BlogPost p JOIN p.category c JOIN p.author a WHERE ... SELECT p, c, a FROM BlogPost p JOIN p.category c JOIN p.author a WHERE ...
@ -72,7 +74,7 @@ posts that match the WHERE clause of this query to be able to
predict the number of pages to show to the user. A draft of the DQL predict the number of pages to show to the user. A draft of the DQL
query for pagination would look like: query for pagination would look like:
.. code-clock:: sql .. code-block:: sql
SELECT count(DISTINCT p.id) FROM BlogPost p JOIN p.category c JOIN p.author a WHERE ... SELECT count(DISTINCT p.id) FROM BlogPost p JOIN p.category c JOIN p.author a WHERE ...
@ -80,7 +82,7 @@ Now you could go and write each of these queries by hand, or you
can use a tree walker to modify the AST for you. Lets see how the can use a tree walker to modify the AST for you. Lets see how the
API would look for this use-case: API would look for this use-case:
:: .. code-block:: php
<?php <?php
$pageNum = 1; $pageNum = 1;
@ -92,7 +94,7 @@ API would look for this use-case:
The ``Paginate::count(Query $query)`` looks like: The ``Paginate::count(Query $query)`` looks like:
:: .. code-block:: php
<?php <?php
class Paginate class Paginate
@ -114,7 +116,7 @@ and registers the ``CountSqlWalker`` customer tree walker which
will modify the AST to execute a count query. The walkers will modify the AST to execute a count query. The walkers
implementation is: implementation is:
:: .. code-block:: php
<?php <?php
class CountSqlWalker extends TreeWalkerAdapter class CountSqlWalker extends TreeWalkerAdapter
@ -167,7 +169,7 @@ previous example with the ``HINT_CUSTOM_TREE_WALKERS`` query hint.
We will implement a custom Output Walker that allows to specify the We will implement a custom Output Walker that allows to specify the
SQL\_NO\_CACHE query hint. SQL\_NO\_CACHE query hint.
:: .. code-block:: php
<?php <?php
$dql = "SELECT p, c, a FROM BlogPost p JOIN p.category c JOIN p.author a WHERE ..."; $dql = "SELECT p, c, a FROM BlogPost p JOIN p.category c JOIN p.author a WHERE ...";
@ -180,7 +182,7 @@ Our ``MysqlWalker`` will extend the default ``SqlWalker``. We will
modify the generation of the SELECT clause, adding the modify the generation of the SELECT clause, adding the
SQL\_NO\_CACHE on those queries that need it: SQL\_NO\_CACHE on those queries that need it:
:: .. code-block:: php
<?php <?php
class MysqlWalker extends SqlWalker class MysqlWalker extends SqlWalker

View File

@ -1,6 +1,8 @@
DQL User Defined Functions DQL User Defined Functions
========================== ==========================
.. sectionauthor:: Benjamin Eberlei <kontakt@beberlei.de>
By default DQL supports a limited subset of all the vendor-specific By default DQL supports a limited subset of all the vendor-specific
SQL functions common between all the vendors. However in many cases SQL functions common between all the vendors. However in many cases
once you have decided on a specific database vendor, you will never once you have decided on a specific database vendor, you will never
@ -8,13 +10,12 @@ change it during the life of your project. This decision for a
specific vendor potentially allows you to make use of powerful SQL specific vendor potentially allows you to make use of powerful SQL
features that are unique to the vendor. features that are unique to the vendor.
**Note**
It is worth to mention that Doctrine 2 also allows you to handwrite It is worth to mention that Doctrine 2 also allows you to handwrite
your SQL instead of extending the DQL parser, which is sort of an your SQL instead of extending the DQL parser. Extending DQL is sort of an
advanced extension point. You can map arbitrary SQL to your objects advanced extension point. You can map arbitrary SQL to your objects
and gain access to vendor specific functionalities using the and gain access to vendor specific functionalities using the
``EntityManager#createNativeQuery()`` API. ``EntityManager#createNativeQuery()`` API as described in
the :doc:`Native Query <../reference/native-sql>` chapter.
The DQL Parser has hooks to register functions that can then be The DQL Parser has hooks to register functions that can then be
@ -37,7 +38,7 @@ Registering your own DQL functions
You can register your functions adding them to the ORM You can register your functions adding them to the ORM
configuration: configuration:
:: .. code-block:: php
<?php <?php
$config = new \Doctrine\ORM\Configuration(); $config = new \Doctrine\ORM\Configuration();
@ -73,7 +74,7 @@ called ``parse`` and one for the TreeWalker process called
``getSql()``. I show you the code for the DateDiff method and ``getSql()``. I show you the code for the DateDiff method and
discuss it step by step: discuss it step by step:
:: .. code-block:: php
<?php <?php
/** /**
@ -135,7 +136,7 @@ function call around this output.
Now registering this DateDiff FunctionNode with the ORM using: Now registering this DateDiff FunctionNode with the ORM using:
:: .. code-block:: php
<?php <?php
$config = new \Doctrine\ORM\Configuration(); $config = new \Doctrine\ORM\Configuration();
@ -143,7 +144,7 @@ Now registering this DateDiff FunctionNode with the ORM using:
We can do fancy stuff like: We can do fancy stuff like:
.. code-clock:: sql .. code-block:: sql
SELECT p FROM DoctrineExtensions\Query\BlogPost p WHERE DATEDIFF(CURRENT_TIME(), p.created) < 7 SELECT p FROM DoctrineExtensions\Query\BlogPost p WHERE DATEDIFF(CURRENT_TIME(), p.created) < 7
@ -156,7 +157,7 @@ your DQL query using
I'll skip the blah and show the code for this function: I'll skip the blah and show the code for this function:
:: .. code-block:: php
<?php <?php
/** /**
@ -204,7 +205,7 @@ additionally need the ``Lexer`` to access the value of the
``T_IDENTIFIER`` token for the Date Interval unit, for example the ``T_IDENTIFIER`` token for the Date Interval unit, for example the
MONTH in: MONTH in:
.. code-clock:: sql .. code-block:: sql
SELECT p FROM DoctrineExtensions\Query\BlogPost p WHERE DATE_ADD(CURRENT_TIME(), INTERVAL 4 MONTH) > p.created SELECT p FROM DoctrineExtensions\Query\BlogPost p WHERE DATE_ADD(CURRENT_TIME(), INTERVAL 4 MONTH) > p.created

View File

@ -1,6 +1,8 @@
Implementing ArrayAccess for Domain Objects Implementing ArrayAccess for Domain Objects
=========================================== ===========================================
.. sectionauthor:: Roman Borschel (roman@code-factory.org)
This recipe will show you how to implement ArrayAccess for your This recipe will show you how to implement ArrayAccess for your
domain objects in order to allow more uniform access, for example domain objects in order to allow more uniform access, for example
in templates. In these examples we will implement ArrayAccess on a in templates. In these examples we will implement ArrayAccess on a
@ -18,7 +20,7 @@ at runtime. Note that this implementation has 2 main caveats:
- It will not work with private fields - It will not work with private fields
- It will not go through any getters/setters - It will not go through any getters/setters
:: .. code-block:: php
<?php <?php
abstract class DomainObject implements ArrayAccess abstract class DomainObject implements ArrayAccess
@ -53,7 +55,7 @@ caveats:
- The semantics of offsetExists can differ - The semantics of offsetExists can differ
- offsetUnset will not work with typehinted setters - offsetUnset will not work with typehinted setters
:: .. code-block:: php
<?php <?php
abstract class DomainObject implements ArrayAccess abstract class DomainObject implements ArrayAccess
@ -85,7 +87,7 @@ access read-only. This will also circumvent some of the caveats of
each option. Simply make offsetSet and offsetUnset throw an each option. Simply make offsetSet and offsetUnset throw an
exception (i.e. BadMethodCallException). exception (i.e. BadMethodCallException).
:: .. code-block:: php
<?php <?php
abstract class DomainObject implements ArrayAccess abstract class DomainObject implements ArrayAccess

View File

@ -1,6 +1,8 @@
Implementing the Notify ChangeTracking Policy Implementing the Notify ChangeTracking Policy
============================================= =============================================
.. sectionauthor:: Roman Borschel (roman@code-factory.org)
The NOTIFY change-tracking policy is the most effective The NOTIFY change-tracking policy is the most effective
change-tracking policy provided by Doctrine but it requires some change-tracking policy provided by Doctrine but it requires some
boilerplate code. This recipe will show you how this boilerplate boilerplate code. This recipe will show you how this boilerplate
@ -17,7 +19,7 @@ that purpose, a class that wants to use this policy needs to
implement the ``NotifyPropertyChanged`` interface from the implement the ``NotifyPropertyChanged`` interface from the
``Doctrine\Common`` namespace. ``Doctrine\Common`` namespace.
:: .. code-block:: php
<?php <?php
use Doctrine\Common\NotifyPropertyChanged, use Doctrine\Common\NotifyPropertyChanged,
@ -45,7 +47,7 @@ Then, in each property setter of concrete, derived domain classes,
you need to invoke \_onPropertyChanged as follows to notify you need to invoke \_onPropertyChanged as follows to notify
listeners: listeners:
:: .. code-block:: php
<?php <?php
// Mapping not shown, either in annotations, xml or yaml as usual // Mapping not shown, either in annotations, xml or yaml as usual

View File

@ -1,6 +1,8 @@
Implementing Wakeup or Clone Implementing Wakeup or Clone
============================ ============================
.. sectionauthor:: Roman Borschel (roman@code-factory.org)
As explained in the As explained in the
`restrictions for entity classes in the manual <http://www.doctrine-project.org/documentation/manual/2_0/en/architecture#entities>`_, `restrictions for entity classes in the manual <http://www.doctrine-project.org/documentation/manual/2_0/en/architecture#entities>`_,
it is usually not allowed for an entity to implement ``__wakeup`` it is usually not allowed for an entity to implement ``__wakeup``
@ -15,7 +17,7 @@ Safely implementing \_\_wakeup
To safely implement ``__wakeup``, simply enclose your To safely implement ``__wakeup``, simply enclose your
implementation code in an identity check as follows: implementation code in an identity check as follows:
:: .. code-block:: php
<?php <?php
class MyEntity class MyEntity
@ -40,7 +42,7 @@ Safely implementing \_\_clone
Safely implementing ``__clone`` is pretty much the same: Safely implementing ``__clone`` is pretty much the same:
:: .. code-block:: php
<?php <?php
class MyEntity class MyEntity

View File

@ -42,7 +42,7 @@ Creating your Doctrine CodeIgniter library
Now, here is what your Doctrine.php file should look like. Now, here is what your Doctrine.php file should look like.
Customize it to your needs. Customize it to your needs.
:: .. code-block:: php
<?php <?php
use Doctrine\Common\ClassLoader, use Doctrine\Common\ClassLoader,
@ -75,6 +75,9 @@ Customize it to your needs.
$config = new Configuration; $config = new Configuration;
$cache = new ArrayCache; $cache = new ArrayCache;
$config->setMetadataCacheImpl($cache); $config->setMetadataCacheImpl($cache);
$driverImpl = $config->newDefaultAnnotationDriver(array(APPPATH.'models/Entities'));
$config->setMetadataDriverImpl($driverImpl);
$config->setQueryCacheImpl($cache); $config->setQueryCacheImpl($cache);
// Proxy configuration // Proxy configuration
@ -115,7 +118,7 @@ Now to use it
Whenever you need a reference to the entity manager inside one of Whenever you need a reference to the entity manager inside one of
your controllers, views, or models you can do this: your controllers, views, or models you can do this:
:: .. code-block:: php
<?php <?php
$em = $this->doctrine->em; $em = $this->doctrine->em;
@ -126,7 +129,7 @@ EntityManager do your Doctrine 2.0 voodoo as normal.
Note: If you do not choose to autoload the Doctrine library, you Note: If you do not choose to autoload the Doctrine library, you
will need to put this line before you get a reference to it: will need to put this line before you get a reference to it:
:: .. code-block:: php
<?php <?php
$this->load->library('doctrine'); $this->load->library('doctrine');

View File

@ -20,7 +20,7 @@ DoctrineExtensions namespace. You create this file in your
library/DoctrineExtensions directory, but will need to set up library/DoctrineExtensions directory, but will need to set up
appropriate autoloaders. appropriate autoloaders.
:: .. code-block:: php
<?php <?php
@ -56,7 +56,7 @@ before the prefix has been set.
to clear your caches and drop then recreate your database schema. to clear your caches and drop then recreate your database schema.
:: .. code-block:: php
<?php <?php

View File

@ -59,7 +59,7 @@ the middle of your page, for example).
Such an interface could look like this: Such an interface could look like this:
:: .. code-block:: php
<?php <?php
/** /**
@ -133,6 +133,8 @@ Such an interface could look like this:
As you can see, we have a method "setBlockEntity" which ties a potential strategy to an object of type AbstractBlock. This type will simply define the basic behaviour of our blocks and could potentially look something like this: As you can see, we have a method "setBlockEntity" which ties a potential strategy to an object of type AbstractBlock. This type will simply define the basic behaviour of our blocks and could potentially look something like this:
.. code-block:: php
<?php <?php
/** /**
* This is the base class for both Panels and Blocks. * This is the base class for both Panels and Blocks.
@ -208,7 +210,7 @@ instance of it and set it via setStrategyBlock().
This might look like this: This might look like this:
:: .. code-block:: php
<?php <?php
use \Doctrine\ORM, use \Doctrine\ORM,

View File

@ -1,6 +1,8 @@
Validation of Entities Validation of Entities
====================== ======================
.. sectionauthor:: Benjamin Eberlei <kontakt@beberlei.de>
Doctrine 2 does not ship with any internal validators, the reason Doctrine 2 does not ship with any internal validators, the reason
being that we think all the frameworks out there already ship with being that we think all the frameworks out there already ship with
quite decent ones that can be integrated into your Domain easily. quite decent ones that can be integrated into your Domain easily.
@ -26,7 +28,7 @@ Say we have an ``Order`` with several ``OrderLine`` instances. We
never want to allow any customer to order for a larger sum than he never want to allow any customer to order for a larger sum than he
is allowed to: is allowed to:
:: .. code-block:: php
<?php <?php
class Order class Order
@ -53,7 +55,7 @@ a unknown reputation don't owe your business too much money.
We can enforce this constraint in any of the metadata drivers. We can enforce this constraint in any of the metadata drivers.
First Annotations: First Annotations:
:: .. code-block:: php
<?php <?php
/** /**
@ -70,9 +72,8 @@ First Annotations:
In XML Mappings: In XML Mappings:
:: .. code-block:: xml
[xml]
<doctrine-mapping> <doctrine-mapping>
<entity name="Order"> <entity name="Order">
<lifecycle-callbacks> <lifecycle-callbacks>
@ -95,7 +96,7 @@ Of course you can do any type of primitive checks, not null,
email-validation, string size, integer and date ranges in your email-validation, string size, integer and date ranges in your
validation callbacks. validation callbacks.
:: .. code-block:: php
<?php <?php
class Order class Order
@ -133,9 +134,4 @@ instances. This was already discussed in the previous blog post on
the Versionable extension, which requires another type of event the Versionable extension, which requires another type of event
called "onFlush". called "onFlush".
Further readings: Further readings: :doc:`Lifecycle Events <../reference/events>`
- `Doctrine 2 Manual: Events <http://www.doctrine-project.org/documentation/manual/2_0/en/events#lifecycle-events>`_

70
en/index.rst Normal file
View File

@ -0,0 +1,70 @@
Welcome to Doctrine 2 ORM's documentation!
==========================================
Reference Guide
---------------
.. toctree::
:maxdepth: 1
:numbered:
reference/introduction
reference/architecture
reference/configuration
reference/basic-mapping
reference/association-mapping
reference/inheritance-mapping
reference/working-with-objects
reference/working-with-associations
reference/transactions-and-concurrency
reference/events
reference/batch-processing
reference/dql-doctrine-query-language
reference/query-builder
reference/native-sql
reference/change-tracking-policies
reference/partial-objects
reference/xml-mapping
reference/yaml-mapping
reference/annotations-reference
reference/php-mapping
reference/caching
reference/improving-performance
reference/best-practices
reference/tools
reference/metadata-drivers
reference/best-practices
reference/limitations-and-known-issues
Tutorials
---------
.. toctree::
:maxdepth: 1
tutorials/getting-started-xml-edition
Cookbook
--------
.. toctree::
:maxdepth: 1
cookbook/aggregate-fields
cookbook/dql-custom-walkers
cookbook/dql-user-defined-functions
cookbook/implementing-arrayaccess-for-domain-objects
cookbook/implementing-the-notify-changetracking-policy
cookbook/implementing-wakeup-or-clone
cookbook/integrating-with-codeigniter
cookbook/sql-table-prefixes
cookbook/strategy-cookbook-introduction
cookbook/validation-of-entities
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -8,39 +8,41 @@ Index
----- -----
- `@Column <#ann_column>`_ - :ref:`@Column <annref_column>`
- `@ChangeTrackingPolicy <#ann_changetrackingpolicy>`_ - :ref:`@ChangeTrackingPolicy <annref_changetrackingpolicy>`
- `@DiscriminatorColumn <#ann_discriminatorcolumn>`_ - :ref:`@DiscriminatorColumn <annref_discriminatorcolumn>`
- `@DiscriminatorMap <#ann_discriminatormap>`_ - :ref:`@DiscriminatorMap <annref_discriminatormap>`
- `@Entity <#ann_entity>`_ - :ref:`@Entity <annref_entity>`
- `@GeneratedValue <#ann_generatedvalue>`_ - :ref:`@GeneratedValue <annref_generatedvalue>`
- `@HasLifecycleCallbacks <#ann_haslifecyclecallbacks>`_ - :ref:`@HasLifecycleCallbacks <annref_haslifecyclecallbacks>`
- `@Index <#ann_indexes>`_ - :ref:`@Index <annref_index>`
- `@Id <#ann_id>`_ - :ref:`@Id <annref_id>`
- `@InheritanceType <#ann_inheritancetype>`_ - :ref:`@InheritanceType <annref_inheritancetype>`
- `@JoinColumn <#ann_joincolumn>`_ - :ref:`@JoinColumn <annref_joincolumn>`
- `@JoinTable <#ann_jointable>`_ - :ref:`@JoinTable <annref_jointable>`
- `@ManyToOne <#ann_manytoone>`_ - :ref:`@ManyToOne <annref_manytoone>`
- `@ManyToMany <#ann_manytomany>`_ - :ref:`@ManyToMany <annref_manytomany>`
- `@MappedSuperclass <#ann_mappedsuperclass>`_ - :ref:`@MappedSuperclass <annref_mappedsuperclass>`
- `@OneToOne <#ann_onetoone>`_ - :ref:`@OneToOne <annref_onetoone>`
- `@OneToMany <#ann_onetomany>`_ - :ref:`@OneToMany <annref_onetomany>`
- `@OrderBy <#ann_orderby>`_ - :ref:`@OrderBy <annref_orderby>`
- `@PostLoad <#ann_postload>`_ - :ref:`@PostLoad <annref_postload>`
- `@PostPersist <#ann_postpersist>`_ - :ref:`@PostPersist <annref_postpersist>`
- `@PostRemove <#ann_postremove>`_ - :ref:`@PostRemove <annref_postremove>`
- `@PostUpdate <#ann_postupdate>`_ - :ref:`@PostUpdate <annref_postupdate>`
- `@PrePersist <#ann_prepersist>`_ - :ref:`@PrePersist <annref_prepersist>`
- `@PreRemove <#ann_preremove>`_ - :ref:`@PreRemove <annref_preremove>`
- `@PreUpdate <#ann_preupdate>`_ - :ref:`@PreUpdate <annref_preupdate>`
- `@SequenceGenerator <#ann_sequencegenerator>`_ - :ref:`@SequenceGenerator <annref_sequencegenerator>`
- `@Table <#ann_table>`_ - :ref:`@Table <annref_table>`
- `@UniqueConstraint <#ann_uniqueconstraint>`_ - :ref:`@UniqueConstraint <annref_uniqueconstraint>`
- `@Version <#ann_version>`_ - :ref:`@Version <annref_version>`
Reference Reference
--------- ---------
.. _annref_column:
@Column @Column
~~~~~~~ ~~~~~~~
@ -79,11 +81,11 @@ Optional attributes:
attribute still handles the conversion between PHP and Database attribute still handles the conversion between PHP and Database
values. If you use this attribute on a column that is used for values. If you use this attribute on a column that is used for
joins between tables you should also take a look at joins between tables you should also take a look at
`@JoinColumn <#ann_joincolumn>`_. :ref:`@JoinColumn <annref_joincolumn>`.
Examples: Examples:
:: .. code-block:: php
<?php <?php
/** /**
@ -101,6 +103,8 @@ Examples:
*/ */
protected $height; protected $height;
.. _annref_changetrackingpolicy:
@ChangeTrackingPolicy @ChangeTrackingPolicy
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
@ -113,13 +117,12 @@ snapshot. This works out of the box, however you might want to
tweak the flush performance where using another change tracking tweak the flush performance where using another change tracking
policy is an interesting option. policy is an interesting option.
The The :doc:`details on all the available change tracking policies <change-tracking-policies>`
`details on all the available change tracking policies </../configuration#change-tracking-policies>`_
can be found in the configuration section. can be found in the configuration section.
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -130,6 +133,8 @@ Example:
*/ */
class User {} class User {}
.. _annref_discriminatorcolumn:
@DiscrimnatorColumn @DiscrimnatorColumn
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
@ -150,6 +155,8 @@ Optional attributes:
- type - By default this is string. - type - By default this is string.
- length - By default this is 255. - length - By default this is 255.
.. _annref_discriminatormap:
@DiscriminatorMap @DiscriminatorMap
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
@ -160,7 +167,7 @@ which name in the database. Keys are the database value and values
are the classes, either as fully- or as unqualified class names are the classes, either as fully- or as unqualified class names
depending if the classes are in the namespace or not. depending if the classes are in the namespace or not.
:: .. code-block:: php
<?php <?php
/** /**
@ -174,6 +181,8 @@ depending if the classes are in the namespace or not.
// ... // ...
} }
.. _annref_entity:
@Entity @Entity
~~~~~~~ ~~~~~~~
@ -190,7 +199,7 @@ Optional attributes:
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -201,11 +210,13 @@ Example:
//... //...
} }
.. _annref_generatedvalue:
@GeneratedValue @GeneratedValue
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
Specifies which strategy is used for identifier generation for an Specifies which strategy is used for identifier generation for an
instance variable which is annotated by `@Id <#ann_id>`_. This instance variable which is annotated by :ref:`@Id <annref_id>`. This
annotation is optional and only has meaning when used in annotation is optional and only has meaning when used in
conjunction with @Id. conjunction with @Id.
@ -220,7 +231,7 @@ Required attributes:
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -230,6 +241,8 @@ Example:
*/ */
protected $id = null; protected $id = null;
.. _annref_haslifecyclecallbacks:
@HasLifecycleCallbacks @HasLifecycleCallbacks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -242,7 +255,7 @@ ignore the callbacks.
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -257,10 +270,12 @@ Example:
public function sendOptinMail() {} public function sendOptinMail() {}
} }
.. _annref_index:
@Index @Index
~~~~~~~ ~~~~~~~
Annotation is used inside the `@Table <#ann_table>`_ annotation on Annotation is used inside the :ref:`@Table <annref_table>` annotation on
the entity-class level. It allows to hint the SchemaTool to the entity-class level. It allows to hint the SchemaTool to
generate a database index on the specified table columns. It only generate a database index on the specified table columns. It only
has meaning in the SchemaTool schema generation context. has meaning in the SchemaTool schema generation context.
@ -273,7 +288,7 @@ Required attributes:
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -284,6 +299,8 @@ Example:
{ {
} }
.. _annref_id:
@Id @Id
~~~~~~~ ~~~~~~~
@ -295,7 +312,7 @@ be marked with @Id.
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -304,6 +321,8 @@ Example:
*/ */
protected $id = null; protected $id = null;
.. _annref_inheritancetype:
@InheritanceType @InheritanceType
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
@ -313,12 +332,12 @@ inheritance. Currently Single Table and Class Table Inheritance are
supported. supported.
This annotation has always been used in conjunction with the This annotation has always been used in conjunction with the
`@DiscriminatorMap <#ann_discriminatormap>`_ and :ref:`@DiscriminatorMap <annref_discriminatormap>` and
`@DiscriminatorColumn <#ann_discriminatorcolumn>`_ annotations. :ref:`@DiscriminatorColumn <annref_discriminatorcolumn>` annotations.
Examples: Examples:
:: .. code-block:: php
<?php <?php
/** /**
@ -343,12 +362,14 @@ Examples:
// ... // ...
} }
.. _annref_joincolumn:
@JoinColumn @JoinColumn
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
This annotation is used in the context of relations in This annotation is used in the context of relations in
`@ManyToOne <#ann_manytoone>`_, `@OneToOne <#ann_onetoone>`_ fields :ref:`@ManyToOne <annref_manytoone>`, :ref:`@OneToOne <annref_onetoone>` fields
and in the Context of `@JoinTable <#ann_jointable>`_ nested inside and in the Context of :ref:`@JoinTable <annref_jointable>` nested inside
a @ManyToMany. This annotation is not required. If its not a @ManyToMany. This annotation is not required. If its not
specified the attributes *name* and *referencedColumnName* are specified the attributes *name* and *referencedColumnName* are
inferred from the table and primary key names. inferred from the table and primary key names.
@ -378,13 +399,13 @@ Optional attributes:
this attribute on @JoinColumn is necessary if you need slightly this attribute on @JoinColumn is necessary if you need slightly
different column definitions for joining columns, for example different column definitions for joining columns, for example
regarding NULL/NOT NULL defaults. However by default a regarding NULL/NOT NULL defaults. However by default a
"columnDefinition" attribute on `@Column <#ann_column>`_ also sets "columnDefinition" attribute on :ref:`@Column <annref_column>` also sets
the related @JoinColumn's columnDefinition. This is necessary to the related @JoinColumn's columnDefinition. This is necessary to
make foreign keys work. make foreign keys work.
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -393,18 +414,22 @@ Example:
*/ */
private $customer; private $customer;
.. _annref_joincolumns:
@JoinColumns @JoinColumns
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
An array of @JoinColumn annotations for a An array of @JoinColumn annotations for a
`@ManyToOne <#ann_manytoone>`_ or `@OneToOne <#ann_onetoone>`_ :ref:`@ManyToOne <annref_manytoone>` or :ref:`@OneToOne <annref_onetoone>`
relation with an entity that has multiple identifiers. relation with an entity that has multiple identifiers.
.. _annref_jointable:
@JoinTable @JoinTable
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
Using `@OneToMany <#ann_onetomany>`_ or Using :ref:`@OneToMany <annref_onetomany>` or
`@ManyToMany <#ann_manytomany>`_ on the owning side of the relation :ref:`@ManyToMany <annref_manytomany>` on the owning side of the relation
requires to specify the @JoinTable annotation which describes the requires to specify the @JoinTable annotation which describes the
details of the database join table. If you do not specify details of the database join table. If you do not specify
@JoinTable on these relations reasonable mapping defaults apply @JoinTable on these relations reasonable mapping defaults apply
@ -427,7 +452,7 @@ Optional attributes:
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -439,6 +464,8 @@ Example:
*/ */
public $phonenumbers; public $phonenumbers;
.. _annref_manytoone:
@ManyToOne @ManyToOne
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -462,19 +489,21 @@ Optional attributes:
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
* @ManyToOne(targetEntity="Cart", cascade="ALL", fetch="EAGER") * @ManyToOne(targetEntity="Cart", cascade={"ALL"}, fetch="EAGER")
*/ */
private $cart; private $cart;
.. _annref_manytomany:
@ManyToMany @ManyToMany
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
Defines an instance variable holds a many-to-many relationship Defines an instance variable holds a many-to-many relationship
between two entities. `@JoinTable <#ann_jointable>`_ is an between two entities. :ref:`@JoinTable <annref_jointable>` is an
additional, optional annotation that has reasonable default additional, optional annotation that has reasonable default
configuration values using the table and names of the two related configuration values using the table and names of the two related
entities. entities.
@ -505,7 +534,7 @@ Optional attributes:
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -526,6 +555,8 @@ Example:
*/ */
private $features; private $features;
.. _annref_mappedsuperclass:
@MappedSuperclass @MappedSuperclass
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
@ -536,15 +567,17 @@ the Class docblock and has no additional attributes.
The @MappedSuperclass annotation cannot be used in conjunction with The @MappedSuperclass annotation cannot be used in conjunction with
@Entity. See the Inheritance Mapping section for @Entity. See the Inheritance Mapping section for
`more details on the restrictions of mapped superclasses </../inheritance-mapping#mapped-superclasses>`_. :doc:`more details on the restrictions of mapped superclasses <inheritance-mapping>`.
.. _annref_onetoone:
@OneToOne @OneToOne
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
The @OneToOne annotation works almost exactly as the The @OneToOne annotation works almost exactly as the
`@ManyToOne <#ann_manytoone>`_ with one additional option that can :ref:`@ManyToOne <annref_manytoone>` with one additional option that can
be specified. The configuration defaults for be specified. The configuration defaults for
`@JoinColumn <#ann_joincolumn>`_ using the target entity table and :ref:`@JoinColumn <annref_joincolumn>` using the target entity table and
primary key column names apply here too. primary key column names apply here too.
Required attributes: Required attributes:
@ -567,7 +600,7 @@ Optional attributes:
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -576,6 +609,8 @@ Example:
*/ */
private $customer; private $customer;
.. _annref_onetomany:
@OneToMany @OneToMany
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -599,7 +634,7 @@ Optional attributes:
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -607,11 +642,13 @@ Example:
*/ */
public $phonenumbers; public $phonenumbers;
.. _annref_orderby:
@OrderBy @OrderBy
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
Optional annotation that can be specified with a Optional annotation that can be specified with a
`@ManyToMany <#ann_manytomany>`_ or `@OneToMany <#ann_onetomany>`_ :ref:`@ManyToMany <annref_manytomany>` or :ref:`@OneToMany <annref_onetomany>`
annotation to specify by which criteria the collection should be annotation to specify by which criteria the collection should be
retrieved from the database by using an ORDER BY clause. retrieved from the database by using an ORDER BY clause.
@ -620,7 +657,7 @@ snippet:
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -635,6 +672,8 @@ positional statement. Multiple Fields are separated by a comma (,).
The referenced field names have to exist on the ``targetEntity`` The referenced field names have to exist on the ``targetEntity``
class of the ``@ManyToMany`` or ``@OneToMany`` annotation. class of the ``@ManyToMany`` or ``@OneToMany`` annotation.
.. _annref_postload:
@PostLoad @PostLoad
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -642,6 +681,8 @@ Marks a method on the entity to be called as a @PostLoad event.
Only works with @HasLifecycleCallbacks in the entity class PHP Only works with @HasLifecycleCallbacks in the entity class PHP
DocBlock. DocBlock.
.. _annref_postpersist:
@PostPersist @PostPersist
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -649,6 +690,8 @@ Marks a method on the entity to be called as a @PostPersist event.
Only works with @HasLifecycleCallbacks in the entity class PHP Only works with @HasLifecycleCallbacks in the entity class PHP
DocBlock. DocBlock.
.. _annref_postremove:
@PostRemove @PostRemove
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -656,6 +699,8 @@ Marks a method on the entity to be called as a @PostRemove event.
Only works with @HasLifecycleCallbacks in the entity class PHP Only works with @HasLifecycleCallbacks in the entity class PHP
DocBlock. DocBlock.
.. _annref_postupdate:
@PostUpdate @PostUpdate
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -663,6 +708,8 @@ Marks a method on the entity to be called as a @PostUpdate event.
Only works with @HasLifecycleCallbacks in the entity class PHP Only works with @HasLifecycleCallbacks in the entity class PHP
DocBlock. DocBlock.
.. _annref_prepersist:
@PrePersist @PrePersist
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -670,6 +717,8 @@ Marks a method on the entity to be called as a @PrePersist event.
Only works with @HasLifecycleCallbacks in the entity class PHP Only works with @HasLifecycleCallbacks in the entity class PHP
DocBlock. DocBlock.
.. _annref_preremove:
@PreRemove @PreRemove
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -677,6 +726,8 @@ Marks a method on the entity to be called as a @PreRemove event.
Only works with @HasLifecycleCallbacks in the entity class PHP Only works with @HasLifecycleCallbacks in the entity class PHP
DocBlock. DocBlock.
.. _annref_preupdate:
@PreUpdate @PreUpdate
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -684,6 +735,8 @@ Marks a method on the entity to be called as a @PreUpdate event.
Only works with @HasLifecycleCallbacks in the entity class PHP Only works with @HasLifecycleCallbacks in the entity class PHP
DocBlock. DocBlock.
.. _annref_sequencegenerator:
@SequenceGenerator @SequenceGenerator
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
@ -707,7 +760,7 @@ Optional attributes:
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -718,6 +771,8 @@ Example:
*/ */
protected $id = null; protected $id = null;
.. _annref_table:
@Table @Table
~~~~~~~ ~~~~~~~
@ -740,7 +795,7 @@ Optional attributes:
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -752,10 +807,12 @@ Example:
*/ */
class User { } class User { }
.. _annref_uniqueconstraint:
@UniqueConstraint @UniqueConstraint
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
Annotation is used inside the `@Table <#ann_table>`_ annotation on Annotation is used inside the :ref:`@Table <annref_table>` annotation on
the entity-class level. It allows to hint the SchemaTool to the entity-class level. It allows to hint the SchemaTool to
generate a database unique constraint on the specified table generate a database unique constraint on the specified table
columns. It only has meaning in the SchemaTool schema generation columns. It only has meaning in the SchemaTool schema generation
@ -769,7 +826,7 @@ Required attributes:
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**
@ -780,17 +837,19 @@ Example:
{ {
} }
.. _annref_version:
@Version @Version
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
Marker annotation that defines a specified column as version Marker annotation that defines a specified column as version
attribute used in an optimistic locking scenario. It only works on attribute used in an optimistic locking scenario. It only works on
`@Column <#ann_column>`_ annotations that have the type integer or :ref:`@Column <annref_column>` annotations that have the type integer or
datetime. datetime. Combining @Version with :ref:`@Id <annref_id>` is not supported.
Example: Example:
:: .. code-block:: php
<?php <?php
/** /**

View File

@ -60,6 +60,8 @@ DETACHED or REMOVED.
identity, associated with an EntityManager, that will be removed identity, associated with an EntityManager, that will be removed
from the database upon transaction commit. from the database upon transaction commit.
.. _architecture_persistent_fields:
Persistent fields Persistent fields
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

View File

@ -7,6 +7,8 @@ owning and inverse sides which is important to understand when
working with bidirectional associations. Please read these working with bidirectional associations. Please read these
explanations carefully. explanations carefully.
.. _association-mapping-owning-inverse:
Owning Side and Inverse Side Owning Side and Inverse Side
---------------------------- ----------------------------
@ -131,7 +133,7 @@ follows:
As an example, consider this mapping: As an example, consider this mapping:
:: .. code-block:: php
<?php <?php
/** @OneToOne(targetEntity="Shipping") */ /** @OneToOne(targetEntity="Shipping") */
@ -140,7 +142,7 @@ As an example, consider this mapping:
This is essentially the same as the following, more verbose, This is essentially the same as the following, more verbose,
mapping: mapping:
:: .. code-block:: php
<?php <?php
/** /**
@ -152,7 +154,7 @@ mapping:
The @JoinTable definition used for many-to-many mappings has The @JoinTable definition used for many-to-many mappings has
similar defaults. As an example, consider this mapping: similar defaults. As an example, consider this mapping:
:: .. code-block:: php
<?php <?php
class User class User
@ -166,7 +168,7 @@ similar defaults. As an example, consider this mapping:
This is essentially the same as the following, more verbose, This is essentially the same as the following, more verbose,
mapping: mapping:
:: .. code-block:: php
<?php <?php
class User class User
@ -200,7 +202,7 @@ You have to be careful when using entity fields that contain a
collection of related entities. Say we have a User entity that collection of related entities. Say we have a User entity that
contains a collection of groups: contains a collection of groups:
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -224,7 +226,7 @@ fresh instance of the User. When your user entity is still new
This is why we recommend to initialize all collection fields to an This is why we recommend to initialize all collection fields to an
empty ``ArrayCollection`` in your entities constructor: empty ``ArrayCollection`` in your entities constructor:
:: .. code-block:: php
<?php <?php
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
@ -249,7 +251,7 @@ empty ``ArrayCollection`` in your entities constructor:
Now the following code will be working even if the Entity hasn't Now the following code will be working even if the Entity hasn't
been associated with an EntityManager yet: been associated with an EntityManager yet:
:: .. code-block:: php
<?php <?php
$group = $entityManager->find('Group', $groupId); $group = $entityManager->find('Group', $groupId);
@ -266,13 +268,13 @@ associations are correctly defined.
You can either use the Doctrine Command Line Tool: You can either use the Doctrine Command Line Tool:
:: .. code-block:: php
doctrine orm:validate-schema doctrine orm:validate-schema
Or you can trigger the validation manually: Or you can trigger the validation manually:
:: .. code-block:: php
use Doctrine\ORM\Tools\SchemaValidator; use Doctrine\ORM\Tools\SchemaValidator;
@ -304,7 +306,7 @@ example of a ``Product`` that has one ``Shipping`` object
associated to it. The ``Shipping`` side does not reference back to associated to it. The ``Shipping`` side does not reference back to
the ``Product`` so it is unidirectional. the ``Product`` so it is unidirectional.
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -352,7 +354,7 @@ Here is a one-to-one relationship between a ``Customer`` and a
``Cart``. The ``Cart`` has a reference back to the ``Customer`` so ``Cart``. The ``Cart`` has a reference back to the ``Customer`` so
it is bidirectional. it is bidirectional.
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -409,7 +411,7 @@ One-To-One, Self-referencing
You can easily have self referencing one-to-one relationships like You can easily have self referencing one-to-one relationships like
below. below.
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -450,7 +452,7 @@ the join columns enforces the one-to-many cardinality. The
following example sets up such a unidirectional one-to-many following example sets up such a unidirectional one-to-many
association: association:
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -516,7 +518,7 @@ Many-To-One, Unidirectional
You can easily implement a many-to-one unidirectional association You can easily implement a many-to-one unidirectional association
with the following: with the following:
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -568,7 +570,7 @@ Bidirectional one-to-many associations are very common. The
following code shows an example with a Product and a Feature following code shows an example with a Product and a Feature
class: class:
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -625,7 +627,7 @@ self-referencing. In this example we setup a hierarchy of
This effectively models a hierarchy of categories and from the This effectively models a hierarchy of categories and from the
database perspective is known as an adjacency list approach. database perspective is known as an adjacency list approach.
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -670,7 +672,7 @@ Real many-to-many associations are less common. The following
example shows a unidirectional association between User and Group example shows a unidirectional association between User and Group
entities: entities:
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -734,7 +736,7 @@ Many-To-Many, Bidirectional
Here is a similar many-to-many relationship as above except this Here is a similar many-to-many relationship as above except this
one is bidirectional. one is bidirectional.
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -796,7 +798,7 @@ and allow to specify the tags directly. This is why you should pick
the Article as owning side, as it makes the code more the Article as owning side, as it makes the code more
understandable: understandable:
:: .. code-block:: php
<?php <?php
class Article class Article
@ -823,7 +825,7 @@ understandable:
This allows to group the tag adding on the ``Article`` side of the This allows to group the tag adding on the ``Article`` side of the
association: association:
:: .. code-block:: php
<?php <?php
$article = new Article(); $article = new Article();
@ -839,7 +841,7 @@ entity of that relationship is a ``User`` so it is self
referencing. In this example it is bidirectional so ``User`` has a referencing. In this example it is bidirectional so ``User`` has a
field named ``$friendsWithMe`` and ``$myFriends``. field named ``$friendsWithMe`` and ``$myFriends``.
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -899,7 +901,7 @@ collection.
Additional to any ``@OneToMany`` or ``@ManyToMany`` annotation you Additional to any ``@OneToMany`` or ``@ManyToMany`` annotation you
can specify the ``@OrderBy`` in the following way: can specify the ``@OrderBy`` in the following way:
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -935,9 +937,8 @@ The semantics of this feature can be described as follows.
Given our previously defined example, the following would not add Given our previously defined example, the following would not add
ORDER BY, since g is not fetch joined: ORDER BY, since g is not fetch joined:
:: .. code-block:: sql
[sql]
SELECT u FROM User u JOIN u.groups g WHERE SIZE(g) > 10 SELECT u FROM User u JOIN u.groups g WHERE SIZE(g) > 10
However the following: However the following:

View File

@ -23,7 +23,8 @@ chapters for XML and YAML mapping, respectively.
.. note:: .. note::
If you're wondering which mapping driver gives the best If you're wondering which mapping driver gives the best
performance, the answer is: None. Once the metadata of a class has performance, the answer is: They all give exactly the same performance.
Once the metadata of a class has
been read from the source (annotations, xml or yaml) it is stored been read from the source (annotations, xml or yaml) it is stored
in an instance of the ``Doctrine\ORM\Mapping\ClassMetadata`` class in an instance of the ``Doctrine\ORM\Mapping\ClassMetadata`` class
and these instances are stored in the metadata cache. Therefore at and these instances are stored in the metadata cache. Therefore at
@ -68,7 +69,7 @@ In order to mark a class for object-relational persistence it needs
to be designated as an entity. This can be done through the to be designated as an entity. This can be done through the
``@Entity`` marker annotation. ``@Entity`` marker annotation.
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -81,7 +82,7 @@ By default, the entity will be persisted to a table with the same
name as the class name. In order to change that, you can use the name as the class name. In order to change that, you can use the
``@Table`` annotation as follows: ``@Table`` annotation as follows:
:: .. code-block:: php
<?php <?php
/** /**
@ -161,7 +162,7 @@ since it is the most flexible.
Example: Example:
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -182,7 +183,7 @@ as the field names. To specify a different name for the column, you
can use the ``name`` attribute of the Column annotation as can use the ``name`` attribute of the Column annotation as
follows: follows:
:: .. code-block:: php
<?php <?php
/** @Column(name="db_name") */ /** @Column(name="db_name") */
@ -218,7 +219,7 @@ In order to create a new mapping type you need to subclass
``Doctrine\DBAL\Types\Type`` and implement/override the methods as ``Doctrine\DBAL\Types\Type`` and implement/override the methods as
you wish. Here is an example skeleton of such a custom type class: you wish. Here is an example skeleton of such a custom type class:
:: .. code-block:: php
<?php <?php
namespace My\Project\Types; namespace My\Project\Types;
@ -265,18 +266,14 @@ Restrictions to keep in mind:
When you have implemented the type you still need to let Doctrine When you have implemented the type you still need to let Doctrine
know about it. This can be achieved through the know about it. This can be achieved through the
``Doctrine\DBAL\Configuration#setCustomTypes(array $types)`` ``Doctrine\DBAL\Configuration#setCustomTypes(array $types)``
method. method. ``Doctrine\ORM\Configuration`` is a subclass of
.. note::
``Doctrine\ORM\Configuration`` is a subclass of
``Doctrine\DBAL\Configuration``, so the methods are available on ``Doctrine\DBAL\Configuration``, so the methods are available on
your ORM Configuration instance as well. your ORM Configuration instance as well.
Here is an example: Here is an example:
:: .. code-block:: php
<?php <?php
// in bootstrapping code // in bootstrapping code
@ -295,7 +292,7 @@ configuration you specify a unique name for the mapping type and
map that to the corresponding fully qualified class name. Now you map that to the corresponding fully qualified class name. Now you
can use your new type in your mapping like this: can use your new type in your mapping like this:
:: .. code-block:: php
<?php <?php
class MyPersistentClass class MyPersistentClass
@ -308,7 +305,7 @@ To have Schema-Tool convert the underlying database type of your
new "mytype" directly into an instance of ``MyType`` you have to new "mytype" directly into an instance of ``MyType`` you have to
additionally register this mapping with your database platform: additionally register this mapping with your database platform:
:: .. code-block:: php
<?php <?php
$conn = $em->getConnection(); $conn = $em->getConnection();
@ -327,7 +324,7 @@ Every entity class needs an identifier/primary key. You designate
the field that serves as the identifier with the ``@Id`` marker the field that serves as the identifier with the ``@Id`` marker
annotation. Here is an example: annotation. Here is an example:
:: .. code-block:: php
<?php <?php
class MyPersistentClass class MyPersistentClass
@ -346,7 +343,7 @@ A common alternative strategy is to use a generated value as the
identifier. To do this, you use the ``@GeneratedValue`` annotation identifier. To do this, you use the ``@GeneratedValue`` annotation
like this: like this:
:: .. code-block:: php
<?php <?php
class MyPersistentClass class MyPersistentClass
@ -404,7 +401,7 @@ The Sequence Generator can currently be used in conjunction with
Oracle or Postgres and allows some additional configuration options Oracle or Postgres and allows some additional configuration options
besides specifying the sequence's name: besides specifying the sequence's name:
:: .. code-block:: php
<?php <?php
class User { class User {
@ -430,7 +427,9 @@ need to access the sequence once to generate the identifiers for
*The default allocationSize for a @SequenceGenerator is currently 10.* *The default allocationSize for a @SequenceGenerator is currently 10.*
**CAUTION** The allocationSize is detected by SchemaTool and .. caution::
The allocationSize is detected by SchemaTool and
transformed into an "INCREMENT BY " clause in the CREATE SEQUENCE transformed into an "INCREMENT BY " clause in the CREATE SEQUENCE
statement. For a database schema created manually (and not statement. For a database schema created manually (and not
SchemaTool) you have to make sure that the allocationSize SchemaTool) you have to make sure that the allocationSize
@ -470,7 +469,7 @@ Doctrine know that you would like a table or column name to be
quoted in all SQL statements, enclose the table or column name in quoted in all SQL statements, enclose the table or column name in
backticks. Here is an example: backticks. Here is an example:
:: .. code-block:: php
<?php <?php
/** @Column(name="`number`", type="integer") */ /** @Column(name="`number`", type="integer") */

View File

@ -27,7 +27,7 @@ experiment with the batch size to find the size that works best for
you. Larger batch sizes mean more prepared statement reuse you. Larger batch sizes mean more prepared statement reuse
internally but also mean more work during ``flush``. internally but also mean more work during ``flush``.
:: .. code-block:: php
<?php <?php
$batchSize = 20; $batchSize = 20;
@ -54,7 +54,7 @@ DQL UPDATE
The by far most efficient way for bulk updates is to use a DQL The by far most efficient way for bulk updates is to use a DQL
UPDATE query. Example: UPDATE query. Example:
:: .. code-block:: php
<?php <?php
$q = $em->createQuery('update MyProject\Model\Manager m set m.salary = m.salary * 0.9'); $q = $em->createQuery('update MyProject\Model\Manager m set m.salary = m.salary * 0.9');
@ -69,7 +69,7 @@ by step instead of loading the whole result into memory at once.
The following example shows how to do this, combining the iteration The following example shows how to do this, combining the iteration
with the batching strategy that was already used for bulk inserts: with the batching strategy that was already used for bulk inserts:
:: .. code-block:: php
<?php <?php
$batchSize = 20; $batchSize = 20;
@ -87,7 +87,9 @@ with the batching strategy that was already used for bulk inserts:
++$i; ++$i;
} }
**NOTE** Iterating results is not possible with queries that .. note::
Iterating results is not possible with queries that
fetch-join a collection-valued association. The nature of such SQL fetch-join a collection-valued association. The nature of such SQL
result sets is not suitable for incremental hydration. result sets is not suitable for incremental hydration.
@ -107,7 +109,7 @@ DELETE query.
Example: Example:
:: .. code-block:: php
<?php <?php
$q = $em->createQuery('delete from MyProject\Model\Manager m where m.salary > 100000'); $q = $em->createQuery('delete from MyProject\Model\Manager m where m.salary > 100000');
@ -121,7 +123,7 @@ An alternative solution for bulk deletes is to use the
by step instead of loading the whole result into memory at once. by step instead of loading the whole result into memory at once.
The following example shows how to do this: The following example shows how to do this:
:: .. code-block:: php
<?php <?php
$batchSize = 20; $batchSize = 20;
@ -137,7 +139,9 @@ The following example shows how to do this:
++$i; ++$i;
} }
**NOTE** Iterating results is not possible with queries that .. note::
Iterating results is not possible with queries that
fetch-join a collection-valued association. The nature of such SQL fetch-join a collection-valued association. The nature of such SQL
result sets is not suitable for incremental hydration. result sets is not suitable for incremental hydration.
@ -151,7 +155,7 @@ instance returned from ``$query->iterate()`` implements the
Iterator interface so you can process a large result without memory Iterator interface so you can process a large result without memory
problems using the following approach: problems using the following approach:
:: .. code-block:: php
<?php <?php
$q = $this->_em->createQuery('select u from MyProject\Model\User u'); $q = $this->_em->createQuery('select u from MyProject\Model\User u');
@ -163,7 +167,9 @@ problems using the following approach:
$this->_em->detach($row[0]); $this->_em->detach($row[0]);
} }
**NOTE** Iterating results is not possible with queries that .. note::
Iterating results is not possible with queries that
fetch-join a collection-valued association. The nature of such SQL fetch-join a collection-valued association. The nature of such SQL
result sets is not suitable for incremental hydration. result sets is not suitable for incremental hydration.

View File

@ -85,7 +85,7 @@ Initialize collections in the constructor
It is recommended best practice to initialize any business It is recommended best practice to initialize any business
collections in entities in the constructor. Example: collections in entities in the constructor. Example:
:: .. code-block:: php
<?php <?php
namespace MyProject\Model; namespace MyProject\Model;

View File

@ -47,14 +47,14 @@ APC
In order to use the APC cache driver you must have it compiled and In order to use the APC cache driver you must have it compiled and
enabled in your php.ini. You can read about APC enabled in your php.ini. You can read about APC
`here <http://us2.php.net/apc>`_ on the PHP website. It will give `in the PHP Documentation <http://us2.php.net/apc>`_. It will give
you a little background information about what it is and how you you a little background information about what it is and how you
can use it as well as how to install it. can use it as well as how to install it.
Below is a simple example of how you could use the APC cache driver Below is a simple example of how you could use the APC cache driver
by itself. by itself.
:: .. code-block:: php
<?php <?php
$cacheDriver = new \Doctrine\Common\Cache\ApcCache(); $cacheDriver = new \Doctrine\Common\Cache\ApcCache();
@ -65,14 +65,14 @@ Memcache
In order to use the Memcache cache driver you must have it compiled In order to use the Memcache cache driver you must have it compiled
and enabled in your php.ini. You can read about Memcache and enabled in your php.ini. You can read about Memcache
`here <http://us2.php.net/memcache>`_ on the PHP website. It will ` on the PHP website <http://us2.php.net/memcache>`_. It will
give you a little background information about what it is and how give you a little background information about what it is and how
you can use it as well as how to install it. you can use it as well as how to install it.
Below is a simple example of how you could use the Memcache cache Below is a simple example of how you could use the Memcache cache
driver by itself. driver by itself.
:: .. code-block:: php
<?php <?php
$memcache = new Memcache(); $memcache = new Memcache();
@ -94,7 +94,7 @@ well as how to install it.
Below is a simple example of how you could use the Xcache cache Below is a simple example of how you could use the Xcache cache
driver by itself. driver by itself.
:: .. code-block:: php
<?php <?php
$cacheDriver = new \Doctrine\Common\Cache\XcacheCache(); $cacheDriver = new \Doctrine\Common\Cache\XcacheCache();
@ -108,7 +108,7 @@ the cache drivers to save cache, check if some cache exists, fetch
the cached data and delete the cached data. We'll use the the cached data and delete the cached data. We'll use the
``ArrayCache`` implementation as our example here. ``ArrayCache`` implementation as our example here.
:: .. code-block:: php
<?php <?php
$cacheDriver = new \Doctrine\Common\Cache\ArrayCache(); $cacheDriver = new \Doctrine\Common\Cache\ArrayCache();
@ -119,7 +119,7 @@ Saving
To save some data to the cache driver it is as simple as using the To save some data to the cache driver it is as simple as using the
``save()`` method. ``save()`` method.
:: .. code-block:: php
<?php <?php
$cacheDriver->save('cache_id', 'my_data'); $cacheDriver->save('cache_id', 'my_data');
@ -136,7 +136,7 @@ below.
You can save any type of data whether it be a string, array, You can save any type of data whether it be a string, array,
object, etc. object, etc.
:: .. code-block:: php
<?php <?php
$array = array( $array = array(
@ -152,7 +152,7 @@ Checking whether some cache exists is very simple, just use the
``contains()`` method. It accepts a single argument which is the ID ``contains()`` method. It accepts a single argument which is the ID
of the cache entry. of the cache entry.
:: .. code-block:: php
<?php <?php
if ($cacheDriver->contains('cache_id')) { if ($cacheDriver->contains('cache_id')) {
@ -168,7 +168,7 @@ Now if you want to retrieve some cache entry you can use the
``fetch()`` method. It also accepts a single argument just like ``fetch()`` method. It also accepts a single argument just like
``contains()`` which is the ID of the cache entry. ``contains()`` which is the ID of the cache entry.
:: .. code-block:: php
<?php <?php
$array = $cacheDriver->fetch('my_array'); $array = $cacheDriver->fetch('my_array');
@ -184,7 +184,7 @@ you can delete all entries.
By Cache ID By Cache ID
^^^^^^^^^^^ ^^^^^^^^^^^
:: .. code-block:: php
<?php <?php
$cacheDriver->delete('my_array'); $cacheDriver->delete('my_array');
@ -192,7 +192,7 @@ By Cache ID
You can also pass wild cards to the ``delete()`` method and it will You can also pass wild cards to the ``delete()`` method and it will
return an array of IDs that were matched and deleted. return an array of IDs that were matched and deleted.
:: .. code-block:: php
<?php <?php
$deleted = $cacheDriver->delete('users_*'); $deleted = $cacheDriver->delete('users_*');
@ -203,7 +203,7 @@ By Regular Expression
If you need a little more control than wild cards you can use a PHP If you need a little more control than wild cards you can use a PHP
regular expression to delete cache entries. regular expression to delete cache entries.
:: .. code-block:: php
<?php <?php
$deleted = $cacheDriver->deleteByRegex('/users_.*/'); $deleted = $cacheDriver->deleteByRegex('/users_.*/');
@ -216,7 +216,7 @@ a prefix or suffix is sufficient, it is recommended that you do
that instead of using a regular expression because it will be much that instead of using a regular expression because it will be much
faster if you have many cache entries. faster if you have many cache entries.
:: .. code-block:: php
<?php <?php
$deleted = $cacheDriver->deleteByPrefix('users_'); $deleted = $cacheDriver->deleteByPrefix('users_');
@ -227,7 +227,7 @@ By Suffix
Just like we did above with the prefix you can do the same with a Just like we did above with the prefix you can do the same with a
suffix. suffix.
:: .. code-block:: php
<?php <?php
$deleted = $cacheDriver->deleteBySuffix('_my_account'); $deleted = $cacheDriver->deleteBySuffix('_my_account');
@ -238,7 +238,7 @@ All
If you simply want to delete all cache entries you can do so with If you simply want to delete all cache entries you can do so with
the ``deleteAll()`` method. the ``deleteAll()`` method.
:: .. code-block:: php
<?php <?php
$deleted = $cacheDriver->deleteAll(); $deleted = $cacheDriver->deleteAll();
@ -249,12 +249,14 @@ Counting
If you want to count how many entries are stored in the cache If you want to count how many entries are stored in the cache
driver instance you can use the ``count()`` method. driver instance you can use the ``count()`` method.
:: .. code-block:: php
<?php <?php
echo $cacheDriver->count(); echo $cacheDriver->count();
**NOTE** In order to use ``deleteByRegex()``, ``deleteByPrefix()``, .. note::
In order to use ``deleteByRegex()``, ``deleteByPrefix()``,
``deleteBySuffix()``, ``deleteAll()``, ``count()`` or ``getIds()`` ``deleteBySuffix()``, ``deleteAll()``, ``count()`` or ``getIds()``
you must enable an option for the cache driver to manage your cache you must enable an option for the cache driver to manage your cache
IDs internally. This is necessary because APC, Memcache, etc. don't IDs internally. This is necessary because APC, Memcache, etc. don't
@ -279,7 +281,7 @@ naming collisions. This can be worked around by using namespaces.
You can set the namespace a cache driver should use by using the You can set the namespace a cache driver should use by using the
``setNamespace()`` method. ``setNamespace()`` method.
:: .. code-block:: php
<?php <?php
$cacheDriver->setNamespace('my_namespace_'); $cacheDriver->setNamespace('my_namespace_');
@ -303,7 +305,7 @@ change unless you alter the DQL query.
This can be done by configuring the query cache implementation to This can be done by configuring the query cache implementation to
use on your ORM configuration. use on your ORM configuration.
:: .. code-block:: php
<?php <?php
$config = new \Doctrine\ORM\Configuration(); $config = new \Doctrine\ORM\Configuration();
@ -317,7 +319,7 @@ so that we don't have to query the database or hydrate the data
again after the first time. You just need to configure the result again after the first time. You just need to configure the result
cache implementation. cache implementation.
:: .. code-block:: php
<?php <?php
$config->setResultCacheImpl(new \Doctrine\Common\Cache\ApcCache()); $config->setResultCacheImpl(new \Doctrine\Common\Cache\ApcCache());
@ -325,7 +327,7 @@ cache implementation.
Now when you're executing DQL queries you can configure them to use Now when you're executing DQL queries you can configure them to use
the result cache. the result cache.
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('select u from \Entities\User u'); $query = $em->createQuery('select u from \Entities\User u');
@ -334,12 +336,14 @@ the result cache.
You can also configure an individual query to use a different You can also configure an individual query to use a different
result cache driver. result cache driver.
:: .. code-block:: php
<?php <?php
$query->setResultCacheDriver(new \Doctrine\Common\Cache\ApcCache()); $query->setResultCacheDriver(new \Doctrine\Common\Cache\ApcCache());
**NOTE** Setting the result cache driver on the query will .. note::
Setting the result cache driver on the query will
automatically enable the result cache for the query. If you want to automatically enable the result cache for the query. If you want to
disable it pass false to ``useResultCache()``. disable it pass false to ``useResultCache()``.
@ -352,7 +356,7 @@ result cache driver.
If you want to set the time the cache has to live you can use the If you want to set the time the cache has to live you can use the
``setResultCacheLifetime()`` method. ``setResultCacheLifetime()`` method.
:: .. code-block:: php
<?php <?php
$query->setResultCacheLifetime(3600); $query->setResultCacheLifetime(3600);
@ -361,7 +365,7 @@ The ID used to store the result set cache is a hash which is
automatically generated for you if you don't set a custom ID automatically generated for you if you don't set a custom ID
yourself with the ``setResultCacheId()`` method. yourself with the ``setResultCacheId()`` method.
:: .. code-block:: php
<?php <?php
$query->setResultCacheId('my_custom_id'); $query->setResultCacheId('my_custom_id');
@ -369,7 +373,7 @@ yourself with the ``setResultCacheId()`` method.
You can also set the lifetime and cache ID by passing the values as You can also set the lifetime and cache ID by passing the values as
the second and third argument to ``useResultCache()``. the second and third argument to ``useResultCache()``.
:: .. code-block:: php
<?php <?php
$query->useResultCache(true, 3600, 'my_custom_id'); $query->useResultCache(true, 3600, 'my_custom_id');
@ -384,7 +388,7 @@ each request we should cache it using one of the cache drivers.
Just like the query and result cache we need to configure it Just like the query and result cache we need to configure it
first. first.
:: .. code-block:: php
<?php <?php
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ApcCache()); $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ApcCache());
@ -402,7 +406,7 @@ clearing the query, result and metadata cache.
From the Doctrine command line you can run the following command. From the Doctrine command line you can run the following command.
:: .. code-block:: php
$ ./doctrine clear-cache $ ./doctrine clear-cache
@ -412,19 +416,19 @@ what you clear you can use the following options.
To clear the query cache use the ``--query`` option. To clear the query cache use the ``--query`` option.
:: .. code-block:: php
$ ./doctrine clear-cache --query $ ./doctrine clear-cache --query
To clear the metadata cache use the ``--metadata`` option. To clear the metadata cache use the ``--metadata`` option.
:: .. code-block:: php
$ ./doctrine clear-cache --metadata $ ./doctrine clear-cache --metadata
To clear the result cache use the ``--result`` option. To clear the result cache use the ``--result`` option.
:: .. code-block:: php
$ ./doctrine clear-cache --result $ ./doctrine clear-cache --result
@ -435,29 +439,31 @@ clear.
Just like the API of the cache drivers you can clear based on an Just like the API of the cache drivers you can clear based on an
ID, regular expression, prefix or suffix. ID, regular expression, prefix or suffix.
:: .. code-block:: php
$ ./doctrine clear-cache --result --id=cache_id $ ./doctrine clear-cache --result --id=cache_id
Or if you want to clear based on a regular expressions. Or if you want to clear based on a regular expressions.
:: .. code-block:: php
$ ./doctrine clear-cache --result --regex=users_.* $ ./doctrine clear-cache --result --regex=users_.*
Or with a prefix. Or with a prefix.
:: .. code-block:: php
$ ./doctrine clear-cache --result --prefix=users_ $ ./doctrine clear-cache --result --prefix=users_
And finally with a suffix. And finally with a suffix.
:: .. code-block:: php
$ ./doctrine clear-cache --result --suffix=_my_account $ ./doctrine clear-cache --result --suffix=_my_account
**NOTE** Using the ``--id``, ``--regex``, etc. options with the .. note::
Using the ``--id``, ``--regex``, etc. options with the
``--query`` and ``--metadata`` are not allowed as it is not ``--query`` and ``--metadata`` are not allowed as it is not
necessary to be specific about what you clear. You only ever need necessary to be specific about what you clear. You only ever need
to completely clear the cache to remove stale entries. to completely clear the cache to remove stale entries.
@ -477,6 +483,6 @@ Ways exist to work around this, like pre-populating your cache and
not letting your users requests populate the cache. not letting your users requests populate the cache.
You can read more about cache slams You can read more about cache slams
`here <http://t3.dotgnu.info/blog/php/user-cache-timebomb>`_. `in this blog post <http://t3.dotgnu.info/blog/php/user-cache-timebomb>`_.

View File

@ -46,7 +46,7 @@ them to EntityManager#persist().
This policy can be configured as follows: This policy can be configured as follows:
:: .. code-block:: php
<?php <?php
/** /**
@ -68,7 +68,7 @@ the ``NotifyPropertyChanged`` interface from the Doctrine
namespace. As a guideline, such an implementation can look as namespace. As a guideline, such an implementation can look as
follows: follows:
:: .. code-block:: php
<?php <?php
use Doctrine\Common\NotifyPropertyChanged, use Doctrine\Common\NotifyPropertyChanged,
@ -95,7 +95,7 @@ need to notify all the ``PropertyChangedListener`` instances. As an
example we add a convenience method on ``MyEntity`` that shows this example we add a convenience method on ``MyEntity`` that shows this
behaviour: behaviour:
:: .. code-block:: php
<?php <?php
// ... // ...

View File

@ -22,7 +22,9 @@ and any other libraries where the coding standards ensure that a
class's location in the directory tree is reflected by its name and class's location in the directory tree is reflected by its name and
namespace and where there is a common root namespace. namespace and where there is a common root namespace.
**NOTE** You are not forced to use the Doctrine class loader to .. note::
You are not forced to use the Doctrine class loader to
load Doctrine classes. Doctrine does not care how the classes are load Doctrine classes. Doctrine does not care how the classes are
loaded, if you want to use a different class loader or your own to loaded, if you want to use a different class loader or your own to
load Doctrine classes, just do that. Along the same lines, the load Doctrine classes, just do that. Along the same lines, the
@ -44,7 +46,7 @@ different types of Doctrine Installations:
PEAR or Tarball Download PEAR or Tarball Download
^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
:: .. code-block:: php
<?php <?php
// test.php // test.php
@ -59,7 +61,7 @@ Git
The Git bootstrap assumes that you have fetched the related The Git bootstrap assumes that you have fetched the related
packages through ``git submodule update --init`` packages through ``git submodule update --init``
:: .. code-block:: php
<?php <?php
// test.php // test.php
@ -83,7 +85,7 @@ If you don't use Doctrine2 in combination with Symfony2 you have to
register an additional namespace to be able to use the Doctrine-CLI register an additional namespace to be able to use the Doctrine-CLI
Tool or the YAML Mapping driver: Tool or the YAML Mapping driver:
:: .. code-block:: php
<?php <?php
// PEAR or Tarball setup // PEAR or Tarball setup
@ -110,7 +112,7 @@ A simple configuration of the EntityManager requires a
``Doctrine\ORM\Configuration`` instance as well as some database ``Doctrine\ORM\Configuration`` instance as well as some database
connection parameters: connection parameters:
:: .. code-block:: php
<?php <?php
use Doctrine\ORM\EntityManager, use Doctrine\ORM\EntityManager,
@ -145,7 +147,9 @@ connection parameters:
$em = EntityManager::create($connectionOptions, $config); $em = EntityManager::create($connectionOptions, $config);
**CAUTION** Do not use Doctrine without a metadata and query cache! .. note::
Do not use Doctrine without a metadata and query cache!
Doctrine is highly optimized for working with caches. The main Doctrine is highly optimized for working with caches. The main
parts in Doctrine that are optimized for caching are the metadata parts in Doctrine that are optimized for caching are the metadata
mapping information with the metadata cache and the DQL to SQL mapping information with the metadata cache and the DQL to SQL
@ -167,7 +171,7 @@ available on a ``Doctrine\ORM\Configuration`` instance.
Proxy Directory (***REQUIRED***) Proxy Directory (***REQUIRED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
<?php <?php
$config->setProxyDir($dir); $config->setProxyDir($dir);
@ -181,7 +185,7 @@ down.
Proxy Namespace (***REQUIRED***) Proxy Namespace (***REQUIRED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
<?php <?php
$config->setProxyNamespace($namespace); $config->setProxyNamespace($namespace);
@ -194,7 +198,7 @@ Doctrine, refer to the "Proxy Objects" section further down.
Metadata Driver (***REQUIRED***) Metadata Driver (***REQUIRED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
<?php <?php
$config->setMetadataDriverImpl($driver); $config->setMetadataDriverImpl($driver);
@ -220,7 +224,7 @@ or YamlDriver please refer to the dedicated chapters
The annotation driver can be configured with a factory method on The annotation driver can be configured with a factory method on
the ``Doctrine\ORM\Configuration``: the ``Doctrine\ORM\Configuration``:
:: .. code-block:: php
<?php <?php
$driverImpl = $config->newDefaultAnnotationDriver('/path/to/lib/MyProject/Entities'); $driverImpl = $config->newDefaultAnnotationDriver('/path/to/lib/MyProject/Entities');
@ -236,7 +240,7 @@ directories of Entities.
Metadata Cache (***RECOMMENDED***) Metadata Cache (***RECOMMENDED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
<?php <?php
$config->setMetadataCacheImpl($cache); $config->setMetadataCacheImpl($cache);
@ -265,7 +269,7 @@ per-request basis.
Query Cache (***RECOMMENDED***) Query Cache (***RECOMMENDED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
<?php <?php
$config->setQueryCacheImpl($cache); $config->setQueryCacheImpl($cache);
@ -295,7 +299,7 @@ per-request basis.
SQL Logger (***Optional***) SQL Logger (***Optional***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
<?php <?php
$config->setSQLLogger($logger); $config->setSQLLogger($logger);
@ -311,7 +315,7 @@ implementation that logs to the standard output using ``echo`` and
Auto-generating Proxy Classes (***OPTIONAL***) Auto-generating Proxy Classes (***OPTIONAL***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
<?php <?php
$config->setAutoGenerateProxyClasses($bool); $config->setAutoGenerateProxyClasses($bool);
@ -385,7 +389,7 @@ useful, for example, as a performance enhancement, when you want to
establish an association to an entity for which you have the establish an association to an entity for which you have the
identifier. You could simply do this: identifier. You could simply do this:
:: .. code-block:: php
<?php <?php
// $em instanceof EntityManager, $cart instanceof MyProject\Model\Cart // $em instanceof EntityManager, $cart instanceof MyProject\Model\Cart
@ -427,7 +431,7 @@ Proxy classes can either be generated manually through the Doctrine
Console or automatically by Doctrine. The configuration option that Console or automatically by Doctrine. The configuration option that
controls this behavior is: controls this behavior is:
:: .. code-block:: php
<?php <?php
$config->setAutoGenerateProxyClasses($bool); $config->setAutoGenerateProxyClasses($bool);
@ -444,7 +448,7 @@ added to the entity class that are not yet in the proxy class. In
such a case, simply use the Doctrine Console to (re)generate the such a case, simply use the Doctrine Console to (re)generate the
proxy classes like so: proxy classes like so:
:: .. code-block:: php
$ ./doctrine orm:generate-proxies $ ./doctrine orm:generate-proxies
@ -456,7 +460,7 @@ with them using two different metadata drivers, for example XML and
YAML. You can use the DriverChain Metadata implementations to YAML. You can use the DriverChain Metadata implementations to
aggregate these drivers based on namespaces: aggregate these drivers based on namespaces:
:: .. code-block:: php
<?php <?php
$chain = new DriverChain(); $chain = new DriverChain();

View File

@ -1,17 +1,18 @@
Doctrine Query Language Doctrine Query Language
=========================== ===========================
DQL stands for **D**octrine **Q**uery **L**anguage and is an Object DQL stands for Doctrine Query Language and is an Object
Query Language derivate that is very similar to the **H**ibernate Query Language derivate that is very similar to the **H**ibernate
**Q**uery **L**anguage (HQL) or the **J**ava **P**ersistence Query Language (HQL) or the Java Persistence Query Language (JPQL).
**Q**uery **L**anguage (JPQL).
In essence, DQL provides powerful querying capabilities over your In essence, DQL provides powerful querying capabilities over your
object model. Imagine all your objects lying around in some storage object model. Imagine all your objects lying around in some storage
(like an object database). When writing DQL queries, think about (like an object database). When writing DQL queries, think about
querying that storage to pick a certain subset of your objects. querying that storage to pick a certain subset of your objects.
**CAUTION** A common mistake for beginners is to mistake DQL for .. note::
A common mistake for beginners is to mistake DQL for
being just some form of SQL and therefore trying to use table names being just some form of SQL and therefore trying to use table names
and column names or join arbitrary tables together in a query. You and column names or join arbitrary tables together in a query. You
need to think about DQL as a query language for your object model, need to think about DQL as a query language for your object model,
@ -54,7 +55,7 @@ clause also influences the nature of the query result.
Here is an example that selects all users with an age > 20: Here is an example that selects all users with an age > 20:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM MyProject\Model\User u WHERE u.age > 20'); $query = $em->createQuery('SELECT u FROM MyProject\Model\User u WHERE u.age > 20');
@ -115,7 +116,7 @@ Example:
Regular join of the address: Regular join of the address:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery("SELECT u FROM User u JOIN u.address a WHERE a.city = 'Berlin'"); $query = $em->createQuery("SELECT u FROM User u JOIN u.address a WHERE a.city = 'Berlin'");
@ -123,7 +124,7 @@ Regular join of the address:
Fetch join of the address: Fetch join of the address:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery("SELECT u, a FROM User u JOIN u.address a WHERE a.city = 'Berlin'"); $query = $em->createQuery("SELECT u, a FROM User u JOIN u.address a WHERE a.city = 'Berlin'");
@ -165,7 +166,7 @@ on the hydration mode.
Hydrate all User entities: Hydrate all User entities:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM MyProject\Model\User u'); $query = $em->createQuery('SELECT u FROM MyProject\Model\User u');
@ -173,7 +174,7 @@ Hydrate all User entities:
Retrieve the IDs of all CmsUsers: Retrieve the IDs of all CmsUsers:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u.id FROM CmsUser u'); $query = $em->createQuery('SELECT u.id FROM CmsUser u');
@ -181,7 +182,7 @@ Retrieve the IDs of all CmsUsers:
Retrieve the IDs of all users that have written an article: Retrieve the IDs of all users that have written an article:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT DISTINCT u.id FROM CmsArticle a JOIN a.user u'); $query = $em->createQuery('SELECT DISTINCT u.id FROM CmsArticle a JOIN a.user u');
@ -190,7 +191,7 @@ Retrieve the IDs of all users that have written an article:
Retrieve all articles and sort them by the name of the articles Retrieve all articles and sort them by the name of the articles
users instance: users instance:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT a FROM CmsArticle a JOIN a.user u ORDER BY u.name ASC'); $query = $em->createQuery('SELECT a FROM CmsArticle a JOIN a.user u ORDER BY u.name ASC');
@ -198,7 +199,7 @@ users instance:
Retrieve the Username and Name of a CmsUser: Retrieve the Username and Name of a CmsUser:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u.username, u.name FROM CmsUser u'); $query = $em->createQuery('SELECT u.username, u.name FROM CmsUser u');
@ -207,7 +208,7 @@ Retrieve the Username and Name of a CmsUser:
Retrieve a ForumUser and his single associated entity: Retrieve a ForumUser and his single associated entity:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u, a FROM ForumUser u JOIN u.avatar a'); $query = $em->createQuery('SELECT u, a FROM ForumUser u JOIN u.avatar a');
@ -216,7 +217,7 @@ Retrieve a ForumUser and his single associated entity:
Retrieve a CmsUser and fetch join all the phonenumbers he has: Retrieve a CmsUser and fetch join all the phonenumbers he has:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u, p FROM CmsUser u JOIN u.phonenumbers p'); $query = $em->createQuery('SELECT u, p FROM CmsUser u JOIN u.phonenumbers p');
@ -225,7 +226,7 @@ Retrieve a CmsUser and fetch join all the phonenumbers he has:
Hydrate a result in Ascending: Hydrate a result in Ascending:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM ForumUser u ORDER BY u.id ASC'); $query = $em->createQuery('SELECT u FROM ForumUser u ORDER BY u.id ASC');
@ -233,7 +234,7 @@ Hydrate a result in Ascending:
Or in Descending Order: Or in Descending Order:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM ForumUser u ORDER BY u.id DESC'); $query = $em->createQuery('SELECT u FROM ForumUser u ORDER BY u.id DESC');
@ -241,7 +242,7 @@ Or in Descending Order:
Using Aggregate Functions: Using Aggregate Functions:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT COUNT(u.id) FROM Entities\User u'); $query = $em->createQuery('SELECT COUNT(u.id) FROM Entities\User u');
@ -249,7 +250,7 @@ Using Aggregate Functions:
With WHERE Clause and Positional Parameter: With WHERE Clause and Positional Parameter:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM ForumUser u WHERE u.id = ?1'); $query = $em->createQuery('SELECT u FROM ForumUser u WHERE u.id = ?1');
@ -257,7 +258,7 @@ With WHERE Clause and Positional Parameter:
With WHERE Clause and Named Parameter: With WHERE Clause and Named Parameter:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM ForumUser u WHERE u.username = :name'); $query = $em->createQuery('SELECT u FROM ForumUser u WHERE u.username = :name');
@ -265,7 +266,7 @@ With WHERE Clause and Named Parameter:
With Nested Conditions in WHERE Clause: With Nested Conditions in WHERE Clause:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u from ForumUser u WHERE (u.username = :name OR u.username = :name2) AND u.id = :id'); $query = $em->createQuery('SELECT u from ForumUser u WHERE (u.username = :name OR u.username = :name2) AND u.id = :id');
@ -273,7 +274,7 @@ With Nested Conditions in WHERE Clause:
With COUNT DISTINCT: With COUNT DISTINCT:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT COUNT(DISTINCT u.name) FROM CmsUser'); $query = $em->createQuery('SELECT COUNT(DISTINCT u.name) FROM CmsUser');
@ -281,7 +282,7 @@ With COUNT DISTINCT:
With Arithmetic Expression in WHERE clause: With Arithmetic Expression in WHERE clause:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000'); $query = $em->createQuery('SELECT u FROM CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000');
@ -290,7 +291,7 @@ With Arithmetic Expression in WHERE clause:
Using a LEFT JOIN to hydrate all user-ids and optionally associated Using a LEFT JOIN to hydrate all user-ids and optionally associated
article-ids: article-ids:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u.id, a.id as article_id FROM CmsUser u LEFT JOIN u.articles a'); $query = $em->createQuery('SELECT u.id, a.id as article_id FROM CmsUser u LEFT JOIN u.articles a');
@ -298,7 +299,7 @@ article-ids:
Restricting a JOIN clause by additional conditions: Restricting a JOIN clause by additional conditions:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery("SELECT u FROM CmsUser u LEFT JOIN u.articles a WITH a.topic LIKE '%foo%'"); $query = $em->createQuery("SELECT u FROM CmsUser u LEFT JOIN u.articles a WITH a.topic LIKE '%foo%'");
@ -306,7 +307,7 @@ Restricting a JOIN clause by additional conditions:
Using several Fetch JOINs: Using several Fetch JOINs:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u, a, p, c FROM CmsUser u JOIN u.articles a JOIN u.phonenumbers p JOIN a.comments c'); $query = $em->createQuery('SELECT u, a, p, c FROM CmsUser u JOIN u.articles a JOIN u.phonenumbers p JOIN a.comments c');
@ -314,7 +315,7 @@ Using several Fetch JOINs:
BETWEEN in WHERE clause: BETWEEN in WHERE clause:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u.name FROM CmsUser u WHERE u.id BETWEEN ?1 AND ?2'); $query = $em->createQuery('SELECT u.name FROM CmsUser u WHERE u.id BETWEEN ?1 AND ?2');
@ -322,7 +323,7 @@ BETWEEN in WHERE clause:
DQL Functions in WHERE clause: DQL Functions in WHERE clause:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery("SELECT u.name FROM CmsUser u WHERE TRIM(u.name) = 'someone'"); $query = $em->createQuery("SELECT u.name FROM CmsUser u WHERE TRIM(u.name) = 'someone'");
@ -330,7 +331,7 @@ DQL Functions in WHERE clause:
IN() Expression: IN() Expression:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u.name FROM CmsUser u WHERE u.id IN(46)'); $query = $em->createQuery('SELECT u.name FROM CmsUser u WHERE u.id IN(46)');
@ -344,7 +345,7 @@ IN() Expression:
CONCAT() DQL Function: CONCAT() DQL Function:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery("SELECT u.id FROM CmsUser u WHERE CONCAT(u.name, 's') = ?1"); $query = $em->createQuery("SELECT u.id FROM CmsUser u WHERE CONCAT(u.name, 's') = ?1");
@ -355,7 +356,7 @@ CONCAT() DQL Function:
EXISTS in WHERE clause with correlated Subquery EXISTS in WHERE clause with correlated Subquery
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u.id FROM CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM CmsPhonenumber p WHERE p.user = u.id)'); $query = $em->createQuery('SELECT u.id FROM CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM CmsPhonenumber p WHERE p.user = u.id)');
@ -363,7 +364,7 @@ EXISTS in WHERE clause with correlated Subquery
Get all users who are members of $group. Get all users who are members of $group.
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u.id FROM CmsUser u WHERE :groupId MEMBER OF u.groups'); $query = $em->createQuery('SELECT u.id FROM CmsUser u WHERE :groupId MEMBER OF u.groups');
@ -372,7 +373,7 @@ Get all users who are members of $group.
Get all users that have more than 1 phonenumber Get all users that have more than 1 phonenumber
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM CmsUser u WHERE SIZE(u.phonenumbers) > 1'); $query = $em->createQuery('SELECT u FROM CmsUser u WHERE SIZE(u.phonenumbers) > 1');
@ -380,7 +381,7 @@ Get all users that have more than 1 phonenumber
Get all users that have no phonenumber Get all users that have no phonenumber
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM CmsUser u WHERE u.phonenumbers IS EMPTY'); $query = $em->createQuery('SELECT u FROM CmsUser u WHERE u.phonenumbers IS EMPTY');
@ -389,7 +390,7 @@ Get all users that have no phonenumber
Get all instances of a specific type, for use with inheritance Get all instances of a specific type, for use with inheritance
hierarchies: hierarchies:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee'); $query = $em->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee');
@ -408,7 +409,7 @@ and joining some data.
If you want to select partial objects you can use the ``partial`` If you want to select partial objects you can use the ``partial``
DQL keyword: DQL keyword:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT partial u.{id, username} FROM CmsUser u'); $query = $em->createQuery('SELECT partial u.{id, username} FROM CmsUser u');
@ -416,7 +417,7 @@ DQL keyword:
You use the partial syntax when joining as well: You use the partial syntax when joining as well:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT partial u.{id, username}, partial a.{id, name} FROM CmsUser u JOIN u.articles a'); $query = $em->createQuery('SELECT partial u.{id, username}, partial a.{id, name} FROM CmsUser u JOIN u.articles a');
@ -441,7 +442,7 @@ with primary or unique fields though:
Returns an array of the following kind, indexed by both user-id Returns an array of the following kind, indexed by both user-id
then phonenumber-id: then phonenumber-id:
:: .. code-block:: php
array array
0 => 0 =>
@ -543,7 +544,7 @@ Arithmetic operators
You can do math in DQL using numeric values, for example: You can do math in DQL using numeric values, for example:
.. warning:: .. code-block:: sql
SELECT person.salary * 1.5 FROM CompanyPerson person WHERE person.salary < 100000 SELECT person.salary * 1.5 FROM CompanyPerson person WHERE person.salary < 100000
@ -582,7 +583,7 @@ parser with own specialized platform functions.
You can register custom DQL functions in your ORM Configuration: You can register custom DQL functions in your ORM Configuration:
:: .. code-block:: php
<?php <?php
$config = new \Doctrine\ORM\Configuration(); $config = new \Doctrine\ORM\Configuration();
@ -597,7 +598,7 @@ value depending on the registered function type. As an example we
will add a MySQL specific FLOOR() functionality. All the given will add a MySQL specific FLOOR() functionality. All the given
classes have to implement the base class : classes have to implement the base class :
:: .. code-block:: php
<?php <?php
namespace MyProject\Query\AST; namespace MyProject\Query\AST;
@ -630,7 +631,7 @@ classes have to implement the base class :
We will register the function by calling and can then use it: We will register the function by calling and can then use it:
:: .. code-block:: php
<?php <?php
\Doctrine\ORM\Query\Parser::registerNumericFunction('FLOOR', 'MyProject\Query\MysqlFloor'); \Doctrine\ORM\Query\Parser::registerNumericFunction('FLOOR', 'MyProject\Query\MysqlFloor');
@ -654,7 +655,7 @@ discriminator column is used.
First we need to setup an example set of entities to use. In this First we need to setup an example set of entities to use. In this
scenario it is a generic Person and Employee example: scenario it is a generic Person and Employee example:
:: .. code-block:: php
<?php <?php
namespace Entities; namespace Entities;
@ -704,7 +705,7 @@ entities looks like the following:
Now when persist a new ``Employee`` instance it will set the Now when persist a new ``Employee`` instance it will set the
discriminator value for us automatically: discriminator value for us automatically:
:: .. code-block:: php
<?php <?php
$employee = new \Entities\Employee(); $employee = new \Entities\Employee();
@ -744,7 +745,7 @@ The example for class table inheritance is the same as single
table, you just need to change the inheritance type from table, you just need to change the inheritance type from
``SINGLE_TABLE`` to ``JOINED``: ``SINGLE_TABLE`` to ``JOINED``:
:: .. code-block:: php
<?php <?php
/** /**
@ -789,7 +790,7 @@ query. You create a Query instance be calling
Alternatively you can create an empty ``Query`` instance and invoke Alternatively you can create an empty ``Query`` instance and invoke
``Query#setDql($dql)`` afterwards. Here are some examples: ``Query#setDql($dql)`` afterwards. Here are some examples:
:: .. code-block:: php
<?php <?php
// $em instanceof EntityManager // $em instanceof EntityManager
@ -821,7 +822,9 @@ the Query class. Here they are:
array) that is largely interchangeable with the object graph array) that is largely interchangeable with the object graph
generated by ``Query#getResultList()`` for read-only purposes. generated by ``Query#getResultList()`` for read-only purposes.
**NOTE** An array graph can differ from the corresponding object .. note::
An array graph can differ from the corresponding object
graph in certain scenarios due to the difference of the identity graph in certain scenarios due to the difference of the identity
semantics between arrays and objects. semantics between arrays and objects.
@ -862,7 +865,7 @@ order to accommodate for the scalar values.
A pure result usually looks like this: A pure result usually looks like this:
:: .. code-block:: php
array array
[0] => Object [0] => Object
@ -873,7 +876,7 @@ A pure result usually looks like this:
A mixed result on the other hand has the following general A mixed result on the other hand has the following general
structure: structure:
:: .. code-block:: php
array array
array array
@ -900,7 +903,7 @@ clause, we get a mixed result.
Here is how the result could look like: Here is how the result could look like:
:: .. code-block:: php
array array
array array
@ -913,7 +916,7 @@ Here is how the result could look like:
And here is how you would access it in PHP code: And here is how you would access it in PHP code:
:: .. code-block:: php
<?php <?php
foreach ($results as $row) { foreach ($results as $row) {
@ -944,7 +947,7 @@ Object Hydration
Object hydration hydrates the result set into the object graph: Object hydration hydrates the result set into the object graph:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM CmsUser u'); $query = $em->createQuery('SELECT u FROM CmsUser u');
@ -956,7 +959,7 @@ Array Hydration
You can run the same query with array hydration and the result set You can run the same query with array hydration and the result set
is hydrated into an array that represents the object graph: is hydrated into an array that represents the object graph:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM CmsUser u'); $query = $em->createQuery('SELECT u FROM CmsUser u');
@ -964,7 +967,7 @@ is hydrated into an array that represents the object graph:
You can use the ``getArrayResult()`` shortcut as well: You can use the ``getArrayResult()`` shortcut as well:
:: .. code-block:: php
<?php <?php
$users = $query->getArrayResult(); $users = $query->getArrayResult();
@ -975,7 +978,7 @@ Scalar Hydration
If you want to return a flat rectangular result set instead of an If you want to return a flat rectangular result set instead of an
object graph you can use scalar hydration: object graph you can use scalar hydration:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM CmsUser u'); $query = $em->createQuery('SELECT u FROM CmsUser u');
@ -996,7 +999,7 @@ Single Scalar Hydration
If you a query which returns just a single scalar value you can use If you a query which returns just a single scalar value you can use
single scalar hydration: single scalar hydration:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT COUNT(a.id) FROM CmsUser u LEFT JOIN u.articles a WHERE u.username = ?1 GROUP BY u.id'); $query = $em->createQuery('SELECT COUNT(a.id) FROM CmsUser u LEFT JOIN u.articles a WHERE u.username = ?1 GROUP BY u.id');
@ -1005,7 +1008,7 @@ single scalar hydration:
You can use the ``getSingleScalarResult()`` shortcut as well: You can use the ``getSingleScalarResult()`` shortcut as well:
:: .. code-block:: php
<?php <?php
$numArticles = $query->getSingleScalarResult(); $numArticles = $query->getSingleScalarResult();
@ -1016,7 +1019,7 @@ Custom Hydration Modes
You can easily add your own custom hydration modes by first You can easily add your own custom hydration modes by first
creating a class which extends ``AbstractHydrator``: creating a class which extends ``AbstractHydrator``:
:: .. code-block:: php
<?php <?php
namespace MyProject\Hydrators; namespace MyProject\Hydrators;
@ -1033,14 +1036,14 @@ creating a class which extends ``AbstractHydrator``:
Next you just need to add the class to the ORM configuration: Next you just need to add the class to the ORM configuration:
:: .. code-block:: php
<?php <?php
$em->getConfiguration()->addCustomHydrationMode('CustomHydrator', 'MyProject\Hydrators\CustomHydrator'); $em->getConfiguration()->addCustomHydrationMode('CustomHydrator', 'MyProject\Hydrators\CustomHydrator');
Now the hydrator is ready to be used in your queries: Now the hydrator is ready to be used in your queries:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM CmsUser u'); $query = $em->createQuery('SELECT u FROM CmsUser u');
@ -1087,7 +1090,7 @@ cached at all. You have to enable the result cache on a per query
basis. The following example shows a complete workflow using the basis. The following example shows a complete workflow using the
Result Cache API: Result Cache API:
:: .. code-block:: php
<?php <?php
$query = $em->createQuery('SELECT u FROM MyProject\Model\User u WHERE u.id = ?1'); $query = $em->createQuery('SELECT u FROM MyProject\Model\User u WHERE u.id = ?1');
@ -1229,14 +1232,14 @@ Terminals
Query Language Query Language
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
:: .. code-block:: php
QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement
Statements Statements
~~~~~~~~~~ ~~~~~~~~~~
:: .. code-block:: php
SelectStatement ::= SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] SelectStatement ::= SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
UpdateStatement ::= UpdateClause [WhereClause] UpdateStatement ::= UpdateClause [WhereClause]
@ -1245,7 +1248,7 @@ Statements
Identifiers Identifiers
~~~~~~~~~~~ ~~~~~~~~~~~
:: .. code-block:: php
/* Alias Identification usage (the "u" of "u.name") */ /* Alias Identification usage (the "u" of "u.name") */
IdentificationVariable ::= identifier IdentificationVariable ::= identifier
@ -1282,7 +1285,7 @@ Identifiers
Path Expressions Path Expressions
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
:: .. code-block:: php
/* "u.Group" or "u.Phonenumbers" declarations */ /* "u.Group" or "u.Phonenumbers" declarations */
JoinAssociationPathExpression ::= IdentificationVariable "." (CollectionValuedAssociationField | SingleValuedAssociationField) JoinAssociationPathExpression ::= IdentificationVariable "." (CollectionValuedAssociationField | SingleValuedAssociationField)
@ -1311,7 +1314,7 @@ Path Expressions
Clauses Clauses
~~~~~~~ ~~~~~~~
:: .. code-block:: php
SelectClause ::= "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}* SelectClause ::= "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}*
SimpleSelectClause ::= "SELECT" ["DISTINCT"] SimpleSelectExpression SimpleSelectClause ::= "SELECT" ["DISTINCT"] SimpleSelectExpression
@ -1328,7 +1331,7 @@ Clauses
Items Items
~~~~~ ~~~~~
:: .. code-block:: php
UpdateItem ::= IdentificationVariable "." (StateField | SingleValuedAssociationField) "=" NewValue UpdateItem ::= IdentificationVariable "." (StateField | SingleValuedAssociationField) "=" NewValue
OrderByItem ::= (ResultVariable | StateFieldPathExpression) ["ASC" | "DESC"] OrderByItem ::= (ResultVariable | StateFieldPathExpression) ["ASC" | "DESC"]
@ -1338,7 +1341,7 @@ Items
From, Join and Index by From, Join and Index by
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}* IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}*
SubselectIdentificationVariableDeclaration ::= IdentificationVariableDeclaration | (AssociationPathExpression ["AS"] AliasIdentificationVariable) SubselectIdentificationVariableDeclaration ::= IdentificationVariableDeclaration | (AssociationPathExpression ["AS"] AliasIdentificationVariable)
@ -1351,7 +1354,7 @@ From, Join and Index by
Select Expressions Select Expressions
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
SelectExpression ::= IdentificationVariable | PartialObjectExpression | (AggregateExpression | "(" Subselect ")" | FunctionDeclaration | ScalarExpression) [["AS"] AliasResultVariable] SelectExpression ::= IdentificationVariable | PartialObjectExpression | (AggregateExpression | "(" Subselect ")" | FunctionDeclaration | ScalarExpression) [["AS"] AliasResultVariable]
SimpleSelectExpression ::= ScalarExpression | IdentificationVariable | SimpleSelectExpression ::= ScalarExpression | IdentificationVariable |
@ -1362,7 +1365,7 @@ Select Expressions
Conditional Expressions Conditional Expressions
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
ConditionalExpression ::= ConditionalTerm {"OR" ConditionalTerm}* ConditionalExpression ::= ConditionalTerm {"OR" ConditionalTerm}*
ConditionalTerm ::= ConditionalFactor {"AND" ConditionalFactor}* ConditionalTerm ::= ConditionalFactor {"AND" ConditionalFactor}*
@ -1375,7 +1378,7 @@ Conditional Expressions
Collection Expressions Collection Expressions
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
EmptyCollectionComparisonExpression ::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY" EmptyCollectionComparisonExpression ::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY"
CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression
@ -1383,7 +1386,7 @@ Collection Expressions
Literal Values Literal Values
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
:: .. code-block:: php
Literal ::= string | char | integer | float | boolean Literal ::= string | char | integer | float | boolean
InParameter ::= Literal | InputParameter InParameter ::= Literal | InputParameter
@ -1391,7 +1394,7 @@ Literal Values
Input Parameter Input Parameter
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
:: .. code-block:: php
InputParameter ::= PositionalParameter | NamedParameter InputParameter ::= PositionalParameter | NamedParameter
PositionalParameter ::= "?" integer PositionalParameter ::= "?" integer
@ -1400,7 +1403,7 @@ Input Parameter
Arithmetic Expressions Arithmetic Expressions
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
ArithmeticExpression ::= SimpleArithmeticExpression | "(" Subselect ")" ArithmeticExpression ::= SimpleArithmeticExpression | "(" Subselect ")"
SimpleArithmeticExpression ::= ArithmeticTerm {("+" | "-") ArithmeticTerm}* SimpleArithmeticExpression ::= ArithmeticTerm {("+" | "-") ArithmeticTerm}*
@ -1413,7 +1416,7 @@ Arithmetic Expressions
Scalar and Type Expressions Scalar and Type Expressions
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary | StateFieldPathExpression ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary | StateFieldPathExpression
BooleanPrimary | CaseExpression | EntityTypeExpression BooleanPrimary | CaseExpression | EntityTypeExpression
@ -1440,7 +1443,7 @@ Scalar and Type Expressions
Aggregate Expressions Aggregate Expressions
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
:: .. code-block:: php
AggregateExpression ::= ("AVG" | "MAX" | "MIN" | "SUM") "(" ["DISTINCT"] StateFieldPathExpression ")" | AggregateExpression ::= ("AVG" | "MAX" | "MIN" | "SUM") "(" ["DISTINCT"] StateFieldPathExpression ")" |
"COUNT" "(" ["DISTINCT"] (IdentificationVariable | SingleValuedPathExpression) ")" "COUNT" "(" ["DISTINCT"] (IdentificationVariable | SingleValuedPathExpression) ")"
@ -1450,7 +1453,7 @@ Other Expressions
QUANTIFIED/BETWEEN/COMPARISON/LIKE/NULL/EXISTS QUANTIFIED/BETWEEN/COMPARISON/LIKE/NULL/EXISTS
:: .. code-block:: php
QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")" QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")"
BetweenExpression ::= ArithmeticExpression ["NOT"] "BETWEEN" ArithmeticExpression "AND" ArithmeticExpression BetweenExpression ::= ArithmeticExpression ["NOT"] "BETWEEN" ArithmeticExpression "AND" ArithmeticExpression
@ -1464,7 +1467,7 @@ QUANTIFIED/BETWEEN/COMPARISON/LIKE/NULL/EXISTS
Functions Functions
~~~~~~~~~ ~~~~~~~~~
:: .. code-block:: php
FunctionDeclaration ::= FunctionsReturningStrings | FunctionsReturningNumerics | FunctionsReturningDateTime FunctionDeclaration ::= FunctionsReturningStrings | FunctionsReturningNumerics | FunctionsReturningDateTime

View File

@ -12,7 +12,7 @@ central point of Doctrine's event listener system. Listeners are
registered on the manager and events are dispatched through the registered on the manager and events are dispatched through the
manager. manager.
:: .. code-block:: php
<?php <?php
$evm = new EventManager(); $evm = new EventManager();
@ -20,7 +20,7 @@ manager.
Now we can add some event listeners to the ``$evm``. Let's create a Now we can add some event listeners to the ``$evm``. Let's create a
``EventTest`` class to play around with. ``EventTest`` class to play around with.
:: .. code-block:: php
<?php <?php
class EventTest class EventTest
@ -54,7 +54,7 @@ Now we can add some event listeners to the ``$evm``. Let's create a
Events can be dispatched by using the ``dispatchEvent()`` method. Events can be dispatched by using the ``dispatchEvent()`` method.
:: .. code-block:: php
<?php <?php
$evm->dispatchEvent(EventTest::preFoo); $evm->dispatchEvent(EventTest::preFoo);
@ -63,7 +63,7 @@ Events can be dispatched by using the ``dispatchEvent()`` method.
You can easily remove a listener with the ``removeEventListener()`` You can easily remove a listener with the ``removeEventListener()``
method. method.
:: .. code-block:: php
<?php <?php
$evm->removeEventListener(array(self::preFoo, self::postFoo), $this); $evm->removeEventListener(array(self::preFoo, self::postFoo), $this);
@ -74,7 +74,7 @@ which implements the ``\Doctrine\Common\EventSubscriber`` interface
and implements a ``getSubscribedEvents()`` method which returns an and implements a ``getSubscribedEvents()`` method which returns an
array of events it should be subscribed to. array of events it should be subscribed to.
:: .. code-block:: php
<?php <?php
class TestEventSubscriber implements \Doctrine\Common\EventSubscriber class TestEventSubscriber implements \Doctrine\Common\EventSubscriber
@ -98,7 +98,7 @@ array of events it should be subscribed to.
Now when you dispatch an event any event subscribers will be Now when you dispatch an event any event subscribers will be
notified for that event. notified for that event.
:: .. code-block:: php
<?php <?php
$evm->dispatchEvent(TestEvent::preFoo); $evm->dispatchEvent(TestEvent::preFoo);
@ -106,7 +106,7 @@ notified for that event.
Now you can test the ``$eventSubscriber`` instance to see if the Now you can test the ``$eventSubscriber`` instance to see if the
``preFoo()`` method was invoked. ``preFoo()`` method was invoked.
:: .. code-block:: php
<?php <?php
if ($eventSubscriber->preFooInvoked) { if ($eventSubscriber->preFooInvoked) {
@ -178,7 +178,7 @@ the life-time of their registered entities.
You can access the Event constants from the ``Events`` class in the You can access the Event constants from the ``Events`` class in the
ORM package. ORM package.
:: .. code-block:: php
<?php <?php
use Doctrine\ORM\Events; use Doctrine\ORM\Events;
@ -213,7 +213,7 @@ providing a mechanism to register direct callbacks inside the
corresponding entity classes that are executed when the lifecycle corresponding entity classes that are executed when the lifecycle
event occurs. event occurs.
:: .. code-block:: php
<?php <?php
@ -267,9 +267,8 @@ Note that when using annotations you have to apply the
If you want to register lifecycle callbacks from YAML or XML you If you want to register lifecycle callbacks from YAML or XML you
can do it with the following. can do it with the following.
:: .. code-block:: yaml
[yml]
User: User:
type: entity type: entity
fields: fields:
@ -282,9 +281,8 @@ can do it with the following.
XML would look something like this: XML would look something like this:
:: .. code-block:: xml
[xml]
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
@ -307,7 +305,7 @@ You just need to make sure a public ``doStuffOnPrePersist()`` and
``doStuffOnPostPersist()`` method is defined on your ``User`` ``doStuffOnPostPersist()`` method is defined on your ``User``
model. model.
:: .. code-block:: php
<?php <?php
// ... // ...
@ -345,7 +343,7 @@ to write your own listener.
To register an event listener you have to hook it into the To register an event listener you have to hook it into the
EventManager that is passed to the EntityManager factory: EventManager that is passed to the EntityManager factory:
:: .. code-block:: php
<?php <?php
$eventManager = new EventManager(); $eventManager = new EventManager();
@ -357,7 +355,7 @@ EventManager that is passed to the EntityManager factory:
You can also retrieve the event manager instance after the You can also retrieve the event manager instance after the
EntityManager was created: EntityManager was created:
:: .. code-block:: php
<?php <?php
$entityManager->getEventManager()->addEventListener(array(Events::preUpdate), MyEventListener()); $entityManager->getEventManager()->addEventListener(array(Events::preUpdate), MyEventListener());
@ -436,7 +434,7 @@ To make use of the onFlush event you have to be familiar with the
internal UnitOfWork API, which grants you access to the previously internal UnitOfWork API, which grants you access to the previously
mentioned sets. See this example: mentioned sets. See this example:
:: .. code-block:: php
<?php <?php
class FlushExampleListener class FlushExampleListener
@ -513,7 +511,7 @@ available on the ``PreUpdateEventArgs``:
A simple example for this event looks like: A simple example for this event looks like:
:: .. code-block:: php
<?php <?php
class NeverAliceOnlyBobListener class NeverAliceOnlyBobListener
@ -532,7 +530,7 @@ You could also use this listener to implement validation of all the
fields that have changed. This is more efficient than using a fields that have changed. This is more efficient than using a
lifecycle callback when there are expensive validations to call: lifecycle callback when there are expensive validations to call:
:: .. code-block:: php
<?php <?php
class ValidCreditCardListener class ValidCreditCardListener
@ -585,7 +583,7 @@ When the mapping information for an entity is read, it is populated
in to a ``ClassMetadataInfo`` instance. You can hook in to this in to a ``ClassMetadataInfo`` instance. You can hook in to this
process and manipulate the instance. process and manipulate the instance.
:: .. code-block:: php
<?php <?php
$test = new EventTest(); $test = new EventTest();

View File

@ -8,12 +8,11 @@ It is highly recommended to make use of a bytecode cache like APC.
A bytecode cache removes the need for parsing PHP code on every A bytecode cache removes the need for parsing PHP code on every
request and can greatly improve performance. request and can greatly improve performance.
.. note::
"If you care about performance and don't use a bytecode "If you care about performance and don't use a bytecode
cache then you don't really care about performance. Please get one cache then you don't really care about performance. Please get one
and start using it." (Stas Malyshev, Core Contributor to PHP and and start using it."
Zend Employee).
*Stas Malyshev, Core Contributor to PHP and Zend Employee*
Metadata and Query caches Metadata and Query caches

View File

@ -24,7 +24,7 @@ appear in the middle of an otherwise mapped inheritance hierarchy
Example: Example:
:: .. code-block:: php
<?php <?php
/** @MappedSuperclass */ /** @MappedSuperclass */
@ -77,7 +77,7 @@ discriminator column is used.
Example: Example:
:: .. code-block:: php
<?php <?php
namespace MyProject\Model; namespace MyProject\Model;
@ -166,7 +166,7 @@ way to achieve polymorphic queries with Class Table Inheritance.
Example: Example:
:: .. code-block:: php
<?php <?php
namespace MyProject\Model; namespace MyProject\Model;

View File

@ -99,21 +99,21 @@ PEAR command line installation utility.
To install just the ``Common`` package you can run the following To install just the ``Common`` package you can run the following
command: command:
:: .. code-block:: bash
$ sudo pear install pear.doctrine-project.org/DoctrineCommon-<version> $ sudo pear install pear.doctrine-project.org/DoctrineCommon-<version>
If you want to use the Doctrine Database Abstraction Layer you can If you want to use the Doctrine Database Abstraction Layer you can
install it with the following command. install it with the following command.
:: .. code-block:: bash
$ sudo pear install pear.doctrine-project.org/DoctrineDBAL-<version> $ sudo pear install pear.doctrine-project.org/DoctrineDBAL-<version>
Or, if you want to get the works and go for the ORM you can install Or, if you want to get the works and go for the ORM you can install
it with the following command. it with the following command.
:: .. code-block:: bash
$ sudo pear install pear.doctrine-project.org/DoctrineORM-<version> $ sudo pear install pear.doctrine-project.org/DoctrineORM-<version>
@ -122,7 +122,7 @@ it with the following command.
writing this is ``2.0.0BETA3`` for the ORM, so you could install it writing this is ``2.0.0BETA3`` for the ORM, so you could install it
like the following: like the following:
:: .. code-block:: bash
$ sudo pear install pear.doctrine-project.org/DoctrineORM-2.0.0BETA3 $ sudo pear install pear.doctrine-project.org/DoctrineORM-2.0.0BETA3
@ -130,7 +130,7 @@ it with the following command.
When you have a package installed via PEAR you can require and load When you have a package installed via PEAR you can require and load
the ``ClassLoader`` with the following code. the ``ClassLoader`` with the following code.
:: .. code-block:: php
<?php <?php
require 'Doctrine/Common/ClassLoader.php'; require 'Doctrine/Common/ClassLoader.php';
@ -141,7 +141,7 @@ in a folder named ``Doctrine``. You also get a nice command line
utility installed and made available on your system. Now when you utility installed and made available on your system. Now when you
run the ``doctrine`` command you will see what you can do with it. run the ``doctrine`` command you will see what you can do with it.
:: .. code-block:: php
$ doctrine $ doctrine
Doctrine Command Line Interface version 2.0.0BETA3-DEV Doctrine Command Line Interface version 2.0.0BETA3-DEV
@ -197,7 +197,7 @@ GitHub
Alternatively you can clone the latest version of Doctrine 2 via Alternatively you can clone the latest version of Doctrine 2 via
GitHub.com: GitHub.com:
:: .. code-block:: php
$ git clone git://github.com/doctrine/doctrine2.git doctrine $ git clone git://github.com/doctrine/doctrine2.git doctrine
@ -205,7 +205,7 @@ This downloads all the sources of the ORM package. You need to
initialize the Github submodules for the Common and DBAL package initialize the Github submodules for the Common and DBAL package
dependencies: dependencies:
:: .. code-block:: php
$ git submodule init $ git submodule init
$ git submodule update $ git submodule update
@ -238,7 +238,7 @@ Subversion
If you prefer subversion you can also checkout the code from If you prefer subversion you can also checkout the code from
GitHub.com through the subversion protocol: GitHub.com through the subversion protocol:
:: .. code-block:: php
$ svn co http://svn.github.com/doctrine/doctrine2.git doctrine2 $ svn co http://svn.github.com/doctrine/doctrine2.git doctrine2
@ -264,7 +264,7 @@ Overview
After navigating to the sandbox directory, you should see the After navigating to the sandbox directory, you should see the
following structure: following structure:
:: .. code-block:: php
sandbox/ sandbox/
Entities/ Entities/
@ -345,7 +345,7 @@ You should see the output "User saved!".
You should get the following output: You should get the following output:
:: .. code-block:: php
array(1) { array(1) {
[0]=> [0]=>
@ -394,11 +394,8 @@ Can you **find** the easier way?).
6) Explore Doctrine 2! 6) Explore Doctrine 2!
See the following links if you want to start with more complex Instead of reading through the reference manual we also recommend to look at the tutorials:
tutorials rather than reading the manual:
:doc:`Getting Started XML Edition <../tutorials/getting-started-xml-edition>`
- Doctrine2 Cookbook:
`Getting Started XML Edition <http://www.doctrine-project.org/projects/orm/2.0/docs/cookbook/getting-started-xml-edition/en>`_

View File

@ -60,7 +60,7 @@ the fundamental difference between the two different
``product_attributes`` tables you should see how they translate ``product_attributes`` tables you should see how they translate
into a Doctrine Mapping (Using Annotations): into a Doctrine Mapping (Using Annotations):
:: .. code-block:: php
<?php <?php
/** /**
@ -127,7 +127,7 @@ possible either. See the following example:
This schema should be mapped to a Product Entity as follows: This schema should be mapped to a Product Entity as follows:
:: .. code-block:: php
class Product class Product
{ {

View File

@ -24,13 +24,15 @@ instances. So in the end, Doctrine only ever has to work with the
API of the ``ClassMetadata`` class to get mapping information for API of the ``ClassMetadata`` class to get mapping information for
an entity. an entity.
**TIP** The populated ``ClassMetadata`` instances are also cached .. note::
The populated ``ClassMetadata`` instances are also cached
so in a production environment the parsing and populating only ever so in a production environment the parsing and populating only ever
happens once. You can configure the metadata cache implementation happens once. You can configure the metadata cache implementation
using the ``setMetadataCacheImpl()`` method on the using the ``setMetadataCacheImpl()`` method on the
``Doctrine\ORM\Configuration`` class: ``Doctrine\ORM\Configuration`` class:
:: .. code-block:: php
<?php <?php
$em->getConfiguration()->setMetadataCacheImpl(new ApcCache()); $em->getConfiguration()->setMetadataCacheImpl(new ApcCache());
@ -40,7 +42,7 @@ If you want to use one of the included core metadata drivers you
just need to configure it. All the drivers are in the just need to configure it. All the drivers are in the
``Doctrine\ORM\Mapping\Driver`` namespace: ``Doctrine\ORM\Mapping\Driver`` namespace:
:: .. code-block:: php
<?php <?php
$driver = new \Doctrine\ORM\Mapping\Driver\XmlDriver('/path/to/mapping/files'); $driver = new \Doctrine\ORM\Mapping\Driver\XmlDriver('/path/to/mapping/files');
@ -53,7 +55,7 @@ In addition to the included metadata drivers you can very easily
implement your own. All you need to do is define a class which implement your own. All you need to do is define a class which
implements the ``Driver`` interface: implements the ``Driver`` interface:
:: .. code-block:: php
<?php <?php
namespace Doctrine\ORM\Mapping\Driver; namespace Doctrine\ORM\Mapping\Driver;
@ -92,7 +94,7 @@ If you want to write a metadata driver to parse information from
some file format we've made your life a little easier by providing some file format we've made your life a little easier by providing
the ``AbstractFileDriver`` implementation for you to extend from: the ``AbstractFileDriver`` implementation for you to extend from:
:: .. code-block:: php
<?php <?php
class MyMetadataDriver extends AbstractFileDriver class MyMetadataDriver extends AbstractFileDriver
@ -121,7 +123,9 @@ the ``AbstractFileDriver`` implementation for you to extend from:
} }
} }
**NOTE** When using the ``AbstractFileDriver`` it requires that you .. note::
When using the ``AbstractFileDriver`` it requires that you
only have one entity defined per file and the file named after the only have one entity defined per file and the file named after the
class described inside where namespace separators are replaced by class described inside where namespace separators are replaced by
periods. So if you have an entity named ``Entities\User`` and you periods. So if you have an entity named ``Entities\User`` and you
@ -133,7 +137,7 @@ the ``AbstractFileDriver`` implementation for you to extend from:
Now you can use your ``MyMetadataDriver`` implementation by setting Now you can use your ``MyMetadataDriver`` implementation by setting
it with the ``setMetadataDriverImpl()`` method: it with the ``setMetadataDriverImpl()`` method:
:: .. code-block:: php
<?php <?php
$driver = new MyMetadataDriver('/path/to/mapping/files'); $driver = new MyMetadataDriver('/path/to/mapping/files');
@ -170,7 +174,7 @@ your project to programatically use some mapping information to
generate some HTML or something similar you can retrieve it through generate some HTML or something similar you can retrieve it through
the ``ClassMetadataFactory``: the ``ClassMetadataFactory``:
:: .. code-block:: php
<?php <?php
$cmf = $em->getMetadataFactory(); $cmf = $em->getMetadataFactory();
@ -180,7 +184,7 @@ Now you can learn about the entity and use the data stored in the
``ClassMetadata`` instance to get all mapped fields for example and ``ClassMetadata`` instance to get all mapped fields for example and
iterate over them: iterate over them:
:: .. code-block:: php
<?php <?php
foreach ($class->fieldMappings as $fieldMapping) { foreach ($class->fieldMappings as $fieldMapping) {

View File

@ -67,7 +67,7 @@ element in the transformed result. You add an entity result through
``ResultSetMapping#addEntityResult()``. Let's take a look at the ``ResultSetMapping#addEntityResult()``. Let's take a look at the
method signature in detail: method signature in detail:
:: .. code-block:: php
<?php <?php
/** /**
@ -99,7 +99,7 @@ a (root) entity result. You add a joined entity result through
``ResultSetMapping#addJoinedEntityResult()``. Let's take a look at ``ResultSetMapping#addJoinedEntityResult()``. Let's take a look at
the method signature in detail: the method signature in detail:
:: .. code-block:: php
<?php <?php
/** /**
@ -130,7 +130,7 @@ inherently bound to entity results. You add a field result through
``ResultSetMapping#addFieldResult()``. Again, let's examine the ``ResultSetMapping#addFieldResult()``. Again, let's examine the
method signature in detail: method signature in detail:
:: .. code-block:: php
<?php <?php
/** /**
@ -160,7 +160,7 @@ result set can be mapped as a scalar value. To add a scalar result
use ``ResultSetMapping#addScalarResult()``. The method signature in use ``ResultSetMapping#addScalarResult()``. The method signature in
detail: detail:
:: .. code-block:: php
<?php <?php
/** /**
@ -185,7 +185,7 @@ result sets. To add a column as a meta result use
``ResultSetMapping#addMetaResult()``. The method signature in ``ResultSetMapping#addMetaResult()``. The method signature in
detail: detail:
:: .. code-block:: php
<?php <?php
/** /**
@ -210,7 +210,7 @@ Discriminator Column
When joining an inheritance tree you have to give Doctrine a hint When joining an inheritance tree you have to give Doctrine a hint
which meta-column is the discriminator column of this tree. which meta-column is the discriminator column of this tree.
:: .. code-block:: php
<?php <?php
/** /**
@ -234,7 +234,7 @@ looking at some examples.
First a basic example that describes the mapping of a single First a basic example that describes the mapping of a single
entity. entity.
:: .. code-block:: php
<?php <?php
// Equivalent DQL query: "select u from User u where u.name=?1" // Equivalent DQL query: "select u from User u where u.name=?1"
@ -251,7 +251,7 @@ entity.
The result would look like this: The result would look like this:
:: .. code-block:: php
array( array(
[0] => User (Object) [0] => User (Object)
@ -269,7 +269,7 @@ assumes User has a unidirectional or bidirectional one-to-one
association to a CmsAddress, where the User is the owning side and association to a CmsAddress, where the User is the owning side and
thus owns the foreign key. thus owns the foreign key.
:: .. code-block:: php
<?php <?php
// Equivalent DQL query: "select u from User u where u.name=?1" // Equivalent DQL query: "select u from User u where u.name=?1"
@ -295,7 +295,7 @@ Consequently, associations that are *fetch-joined* do not require
the foreign keys to be present in the SQL result set, only the foreign keys to be present in the SQL result set, only
associations that are lazy. associations that are lazy.
:: .. code-block:: php
<?php <?php
// Equivalent DQL query: "select u from User u join u.address a WHERE u.name = ?1" // Equivalent DQL query: "select u from User u join u.address a WHERE u.name = ?1"
@ -332,7 +332,7 @@ assume that there are one or more subclasses that extend User and
either Class Table Inheritance or Single Table Inheritance is used either Class Table Inheritance or Single Table Inheritance is used
to map the hierarchy (both use a discriminator column). to map the hierarchy (both use a discriminator column).
:: .. code-block:: php
<?php <?php
// Equivalent DQL query: "select u from User u where u.name=?1" // Equivalent DQL query: "select u from User u where u.name=?1"

View File

@ -55,7 +55,7 @@ If you want to force a query to return you partial objects,
possibly as a performance tweak, you can use the ``partial`` possibly as a performance tweak, you can use the ``partial``
keyword as follows: keyword as follows:
:: .. code-block:: php
<?php <?php
$q = $em->createQuery("select partial u.{id,name} from MyApp\Domain\User u"); $q = $em->createQuery("select partial u.{id,name} from MyApp\Domain\User u");

View File

@ -13,7 +13,7 @@ If you wish to write your mapping information inside PHP files that
are named after the entity and included to populate the metadata are named after the entity and included to populate the metadata
for an entity you can do so by using the ``PHPDriver``: for an entity you can do so by using the ``PHPDriver``:
:: .. code-block:: php
<?php <?php
$driver = new PHPDriver('/path/to/php/mapping/files'); $driver = new PHPDriver('/path/to/php/mapping/files');
@ -23,7 +23,7 @@ Now imagine we had an entity named ``Entities\User`` and we wanted
to write a mapping file for it using the above configured to write a mapping file for it using the above configured
``PHPDriver`` instance: ``PHPDriver`` instance:
:: .. code-block:: php
<?php <?php
namespace Entities; namespace Entities;
@ -38,7 +38,7 @@ To write the mapping information you just need to create a file
named ``Entities.User.php`` inside of the named ``Entities.User.php`` inside of the
``/path/to/php/mapping/files`` folder: ``/path/to/php/mapping/files`` folder:
:: .. code-block:: php
<?php <?php
// /path/to/php/mapping/files/Entities.User.php // /path/to/php/mapping/files/Entities.User.php
@ -58,10 +58,12 @@ Now we can easily retrieve the populated ``ClassMetadata`` instance
where the ``PHPDriver`` includes the file and the where the ``PHPDriver`` includes the file and the
``ClassMetadataFactory`` caches it for later retrieval: ``ClassMetadataFactory`` caches it for later retrieval:
:: .. code-block:: php
<?php <?php
$class = $em->getMetadataFor('Entities\User'); $class = $em->getClassMetadata('Entities\User');
// or
$class = $em->getMetadataFactory()->getMetadataFor('Entities\User');
Static Function Static Function
--------------- ---------------
@ -72,7 +74,7 @@ itself. This is useful for cases where you want to keep your entity
and mapping information together but don't want to use annotations. and mapping information together but don't want to use annotations.
For this you just need to use the ``StaticPHPDriver``: For this you just need to use the ``StaticPHPDriver``:
:: .. code-block:: php
<?php <?php
$driver = new StaticPHPDriver('/path/to/entities'); $driver = new StaticPHPDriver('/path/to/entities');
@ -81,7 +83,7 @@ For this you just need to use the ``StaticPHPDriver``:
Now you just need to define a static function named Now you just need to define a static function named
``loadMetadata($metadata)`` on your entity: ``loadMetadata($metadata)`` on your entity:
:: .. code-block:: php
<?php <?php
namespace Entities; namespace Entities;

View File

@ -16,7 +16,7 @@ The same way you build a normal Query, you build a ``QueryBuilder``
object, just providing the correct method name. Here is an example object, just providing the correct method name. Here is an example
how to build a ``QueryBuilder`` object: how to build a ``QueryBuilder`` object:
:: .. code-block:: php
<?php <?php
// $em instanceof EntityManager // $em instanceof EntityManager
@ -28,7 +28,7 @@ Once you have created an instance of QueryBuilder, it provides a
set of useful informative functions that you can use. One good set of useful informative functions that you can use. One good
example is to inspect what type of object the ``QueryBuilder`` is. example is to inspect what type of object the ``QueryBuilder`` is.
:: .. code-block:: php
<?php <?php
// $qb instanceof QueryBuilder // $qb instanceof QueryBuilder
@ -47,7 +47,7 @@ It is possible to retrieve the associated ``EntityManager`` of the
current ``QueryBuilder``, its DQL and also a ``Query`` object when current ``QueryBuilder``, its DQL and also a ``Query`` object when
you finish building your DQL. you finish building your DQL.
:: .. code-block:: php
<?php <?php
// $qb instanceof QueryBuilder // $qb instanceof QueryBuilder
@ -92,7 +92,7 @@ of DQL. It takes 3 parameters: ``$dqlPartName``, ``$dqlPart`` and
- -
:: .. code-block:: php
<?php <?php
// $qb instanceof QueryBuilder // $qb instanceof QueryBuilder
@ -112,7 +112,7 @@ as placeholders, although both have a slightly different syntax.
Additionally, you must make your choice: Mixing both styles is not Additionally, you must make your choice: Mixing both styles is not
allowed. Binding parameters can simply be achieved as follows: allowed. Binding parameters can simply be achieved as follows:
:: .. code-block:: php
<?php <?php
// $qb instanceof QueryBuilder // $qb instanceof QueryBuilder
@ -127,7 +127,7 @@ allowed. Binding parameters can simply be achieved as follows:
You are not forced to enumerate your placeholders as the You are not forced to enumerate your placeholders as the
alternative syntax is available: alternative syntax is available:
:: .. code-block:: php
<?php <?php
// $qb instanceof QueryBuilder // $qb instanceof QueryBuilder
@ -146,7 +146,7 @@ If you've got several parameters to bind to your query, you can
also use setParameters() instead of setParameter() with the also use setParameters() instead of setParameter() with the
following syntax: following syntax:
:: .. code-block:: php
<?php <?php
// $qb instanceof QueryBuilder // $qb instanceof QueryBuilder
@ -157,7 +157,7 @@ following syntax:
Getting already bound parameters is easy - simply use the above Getting already bound parameters is easy - simply use the above
mentioned syntax with "getParameter()" or "getParameters()": mentioned syntax with "getParameter()" or "getParameters()":
:: .. code-block:: php
<?php <?php
// $qb instanceof QueryBuilder // $qb instanceof QueryBuilder
@ -178,7 +178,7 @@ instance of ``Doctrine\ORM\Query\Expr\Expr\*`` class. Here is the
same query of example 6 written using same query of example 6 written using
``Doctrine\ORM\Query\Expr\Expr\*`` classes: ``Doctrine\ORM\Query\Expr\Expr\*`` classes:
:: .. code-block:: php
<?php <?php
// $qb instanceof QueryBuilder // $qb instanceof QueryBuilder
@ -201,7 +201,7 @@ Doctrine created a class that can be considered as a helper for
building queries. This class is called ``Expr``, which provides a building queries. This class is called ``Expr``, which provides a
set of useful static methods to help building queries: set of useful static methods to help building queries:
:: .. code-block:: php
<?php <?php
// $qb instanceof QueryBuilder // $qb instanceof QueryBuilder
@ -219,7 +219,7 @@ Although it still sounds complex, the ability to programmatically
create conditions are the main feature of ``Expr``. Here it is a create conditions are the main feature of ``Expr``. Here it is a
complete list of supported helper methods available: complete list of supported helper methods available:
:: .. code-block:: php
<?php <?php
class Expr class Expr
@ -379,7 +379,7 @@ is a set of useful methods to simplify a programmer's life. To
illustrate how to work with them, here is the same example 6 illustrate how to work with them, here is the same example 6
re-written using ``QueryBuilder`` helper methods: re-written using ``QueryBuilder`` helper methods:
:: .. code-block:: php
<?php <?php
// $qb instanceof QueryBuilder // $qb instanceof QueryBuilder
@ -396,7 +396,7 @@ to use string based queries and greatly encouraged to use
``$qb->expr()->*`` methods. Here is a converted example 8 to ``$qb->expr()->*`` methods. Here is a converted example 8 to
suggested standard way to build queries: suggested standard way to build queries:
:: .. code-block:: php
<?php <?php
// $qb instanceof QueryBuilder // $qb instanceof QueryBuilder
@ -413,7 +413,7 @@ suggested standard way to build queries:
Here is a complete list of helper methods available in Here is a complete list of helper methods available in
``QueryBuilder``: ``QueryBuilder``:
:: .. code-block:: php
<?php <?php
class QueryBuilder class QueryBuilder

View File

@ -30,7 +30,7 @@ overview of the available commands or use the --help flag to get
information on the available commands. If you want to know more information on the available commands. If you want to know more
about the use of generate entities for example, you can call: about the use of generate entities for example, you can call:
:: .. code-block:: php
doctrine orm:generate-entities --help doctrine orm:generate-entities --help
@ -50,7 +50,7 @@ Doctrine Console requires the definition of a HelperSet that is the
DI tool to be injected in the Console. In case of a project that is DI tool to be injected in the Console. In case of a project that is
dealing exclusively with DBAL, the ConnectionHelper is required: dealing exclusively with DBAL, the ConnectionHelper is required:
:: .. code-block:: php
<?php <?php
$helperSet = new \Symfony\Components\Console\Helper\HelperSet(array( $helperSet = new \Symfony\Components\Console\Helper\HelperSet(array(
@ -61,7 +61,7 @@ dealing exclusively with DBAL, the ConnectionHelper is required:
When dealing with the ORM package, the EntityManagerHelper is When dealing with the ORM package, the EntityManagerHelper is
required: required:
:: .. code-block:: php
<?php <?php
$helperSet = new \Symfony\Components\Console\Helper\HelperSet(array( $helperSet = new \Symfony\Components\Console\Helper\HelperSet(array(
@ -74,7 +74,7 @@ The HelperSet instance has to be generated in a separate file (i.e.
and predefines the needed HelperSet attributes mentioned above. A and predefines the needed HelperSet attributes mentioned above. A
typical ``cli-config.php`` file looks as follows: typical ``cli-config.php`` file looks as follows:
:: .. code-block:: php
<?php <?php
require_once __DIR__ . '/../../lib/Doctrine/Common/ClassLoader.php'; require_once __DIR__ . '/../../lib/Doctrine/Common/ClassLoader.php';
@ -111,7 +111,7 @@ You can also add your own commands on-top of the Doctrine supported
tools. To include a new command on Doctrine Console, you need to tools. To include a new command on Doctrine Console, you need to
do: do:
:: .. code-block:: php
<?php <?php
$cli->addCommand(new \MyProject\Tools\Console\Commands\MyCustomCommand()); $cli->addCommand(new \MyProject\Tools\Console\Commands\MyCustomCommand());
@ -119,7 +119,7 @@ do:
Additionally, include multiple commands (and overriding previously Additionally, include multiple commands (and overriding previously
defined ones) is possible through the command: defined ones) is possible through the command:
:: .. code-block:: php
<?php <?php
$cli->addCommands(array( $cli->addCommands(array(
@ -200,7 +200,7 @@ the ``createSchema()`` method. First create an instance of the
that you want to use to create the schema. This method receives an that you want to use to create the schema. This method receives an
array of ``ClassMetadataInfo`` instances. array of ``ClassMetadataInfo`` instances.
:: .. code-block:: php
<?php <?php
$tool = new \Doctrine\ORM\Tools\SchemaTool($em); $tool = new \Doctrine\ORM\Tools\SchemaTool($em);
@ -212,7 +212,7 @@ array of ``ClassMetadataInfo`` instances.
To drop the schema you can use the ``dropSchema()`` method. To drop the schema you can use the ``dropSchema()`` method.
:: .. code-block:: php
<?php <?php
$tool->dropSchema($classes); $tool->dropSchema($classes);
@ -222,7 +222,7 @@ model. When you are changing your metadata a lot during development
you might want to drop the complete database instead of only the you might want to drop the complete database instead of only the
tables of the current model to clean up with orphaned tables. tables of the current model to clean up with orphaned tables.
:: .. code-block:: php
<?php <?php
$tool->dropSchema($classes, \Doctrine\ORM\Tools\SchemaTool::DROP_DATABASE); $tool->dropSchema($classes, \Doctrine\ORM\Tools\SchemaTool::DROP_DATABASE);
@ -232,7 +232,7 @@ easily with the ``updateSchema()`` method. It will compare your
existing database schema to the passed array of existing database schema to the passed array of
``ClassMetdataInfo`` instances. ``ClassMetdataInfo`` instances.
:: .. code-block:: php
<?php <?php
$tool->updateSchema($classes); $tool->updateSchema($classes);
@ -242,20 +242,20 @@ use the ``schema-tool`` command.
To create the schema use the ``create`` command: To create the schema use the ``create`` command:
:: .. code-block:: php
$ php doctrine orm:schema-tool:create $ php doctrine orm:schema-tool:create
To drop the schema use the ``drop`` command: To drop the schema use the ``drop`` command:
:: .. code-block:: php
$ php doctrine orm:schema-tool:drop $ php doctrine orm:schema-tool:drop
If you want to drop and then recreate the schema then use both If you want to drop and then recreate the schema then use both
options: options:
:: .. code-block:: php
$ php doctrine orm:schema-tool:drop $ php doctrine orm:schema-tool:drop
$ php doctrine orm:schema-tool:create $ php doctrine orm:schema-tool:create
@ -263,14 +263,14 @@ options:
As you would think, if you want to update your schema use the As you would think, if you want to update your schema use the
``update`` command: ``update`` command:
:: .. code-block:: php
$ php doctrine orm:schema-tool:update $ php doctrine orm:schema-tool:update
All of the above commands also accept a ``--dump-sql`` option that All of the above commands also accept a ``--dump-sql`` option that
will output the SQL for the ran operation. will output the SQL for the ran operation.
:: .. code-block:: php
$ php doctrine orm:schema-tool:create --dump-sql $ php doctrine orm:schema-tool:create --dump-sql
@ -294,7 +294,7 @@ To convert some mapping information between the various supported
formats you can use the ``ClassMetadataExporter`` to get exporter formats you can use the ``ClassMetadataExporter`` to get exporter
instances for the different formats: instances for the different formats:
:: .. code-block:: php
<?php <?php
$cme = new \Doctrine\ORM\Tools\Export\ClassMetadataExporter(); $cme = new \Doctrine\ORM\Tools\Export\ClassMetadataExporter();
@ -302,14 +302,14 @@ instances for the different formats:
Once you have a instance you can use it to get an exporter. For Once you have a instance you can use it to get an exporter. For
example, the yml exporter: example, the yml exporter:
:: .. code-block:: php
<?php <?php
$exporter = $cme->getExporter('yml', '/path/to/export/yml'); $exporter = $cme->getExporter('yml', '/path/to/export/yml');
Now you can export some ``ClassMetadata`` instances: Now you can export some ``ClassMetadata`` instances:
:: .. code-block:: php
<?php <?php
$classes = array( $classes = array(
@ -324,7 +324,7 @@ convert your loaded mapping information to another format. The
``orm:convert-mapping`` command accepts two arguments, the type to ``orm:convert-mapping`` command accepts two arguments, the type to
convert to and the path to generate it: convert to and the path to generate it:
:: .. code-block:: php
$ php doctrine orm:convert-mapping xml /path/to/mapping-path-converted-to-xml $ php doctrine orm:convert-mapping xml /path/to/mapping-path-converted-to-xml
@ -338,7 +338,7 @@ XML, etc. from them.
First you need to retrieve the metadata instances with the First you need to retrieve the metadata instances with the
``DatabaseDriver``: ``DatabaseDriver``:
:: .. code-block:: php
<?php <?php
$em->getConfiguration()->setMetadataDriverImpl( $em->getConfiguration()->setMetadataDriverImpl(
@ -353,7 +353,7 @@ First you need to retrieve the metadata instances with the
Now you can get an exporter instance and export the loaded metadata Now you can get an exporter instance and export the loaded metadata
to yml: to yml:
:: .. code-block:: php
<?php <?php
$exporter = $cme->getExporter('yml', '/path/to/export/yml'); $exporter = $cme->getExporter('yml', '/path/to/export/yml');
@ -363,11 +363,11 @@ to yml:
You can also reverse engineer a database using the You can also reverse engineer a database using the
``orm:convert-mapping`` command: ``orm:convert-mapping`` command:
:: .. code-block:: php
$ php doctrine orm:convert-mapping --from-database yml /path/to/mapping-path-converted-to-yml $ php doctrine orm:convert-mapping --from-database yml /path/to/mapping-path-converted-to-yml
.. warning:: .. note::
Reverse Engineering is not always working perfectly Reverse Engineering is not always working perfectly
depending on special cases. It will only detect Many-To-One depending on special cases. It will only detect Many-To-One

View File

@ -33,7 +33,7 @@ The first approach is to use the implicit transaction handling
provided by the Doctrine ORM EntityManager. Given the following provided by the Doctrine ORM EntityManager. Given the following
code snippet, without any explicit transaction demarcation: code snippet, without any explicit transaction demarcation:
:: .. code-block:: php
<?php <?php
// $em instanceof EntityManager // $em instanceof EntityManager
@ -56,7 +56,7 @@ The explicit alternative is to use the ``Doctrine\DBAL\Connection``
API directly to control the transaction boundaries. The code then API directly to control the transaction boundaries. The code then
looks like this: looks like this:
:: .. code-block:: php
<?php <?php
// $em instanceof EntityManager // $em instanceof EntityManager
@ -90,7 +90,7 @@ transaction or close the ``EntityManager``, apart from the obvious
code reduction. An example that is functionally equivalent to the code reduction. An example that is functionally equivalent to the
previously shown code looks as follows: previously shown code looks as follows:
:: .. code-block:: php
<?php <?php
// $em instanceof EntityManager // $em instanceof EntityManager
@ -171,7 +171,7 @@ has been modified by someone else already.
You designate a version field in an entity as follows. In this You designate a version field in an entity as follows. In this
example we'll use an integer. example we'll use an integer.
:: .. code-block:: php
<?php <?php
class User class User
@ -185,7 +185,7 @@ example we'll use an integer.
Alternatively a datetime type can be used (which maps to an SQL Alternatively a datetime type can be used (which maps to an SQL
timestamp or datetime): timestamp or datetime):
:: .. code-block:: php
<?php <?php
class User class User
@ -220,7 +220,7 @@ locking exception:
You can always verify the version of an entity during a request You can always verify the version of an entity during a request
either when calling ``EntityManager#find()``: either when calling ``EntityManager#find()``:
:: .. code-block:: php
<?php <?php
use Doctrine\DBAL\LockMode; use Doctrine\DBAL\LockMode;
@ -241,7 +241,7 @@ either when calling ``EntityManager#find()``:
Or you can use ``EntityManager#lock()`` to find out: Or you can use ``EntityManager#lock()`` to find out:
:: .. code-block:: php
<?php <?php
use Doctrine\DBAL\LockMode; use Doctrine\DBAL\LockMode;
@ -291,7 +291,7 @@ updates you wanted to prevent with Optimistic Locking.
See the example code, The form (GET Request): See the example code, The form (GET Request):
:: .. code-block:: php
<?php <?php
$post = $em->find('BlogPost', 123456); $post = $em->find('BlogPost', 123456);
@ -301,7 +301,7 @@ See the example code, The form (GET Request):
And the change headline action (POST Request): And the change headline action (POST Request):
:: .. code-block:: php
<?php <?php
$postId = (int)$_GET['id']; $postId = (int)$_GET['id'];

View File

@ -7,17 +7,14 @@ collections of objects. When it comes to persistence, it is
important to understand three main things: important to understand three main things:
- The concept of owning and inverse sides in bidirectional - The :ref:`concept of owning and inverse sides <association-mapping-owning-inverse>`
associations as described in bidirectional associations.
`here <http://www.doctrine-project.org/documentation/manual/2_0/en/association-mapping#owning-side-and-inverse-side>`_.
- If an entity is removed from a collection, the association is - If an entity is removed from a collection, the association is
removed, not the entity itself. A collection of entities always removed, not the entity itself. A collection of entities always
only represents the association to the containing entities, not the only represents the association to the containing entities, not the
entity itself. entity itself.
- Collection-valued persistent fields have to be instances of the - Collection-valued :ref:`persistent fields <architecture_persistent_fields>` have to be instances of the
``Doctrine\Common\Collections\Collection`` interface. ``Doctrine\Common\Collections\Collection`` interface.
`See here <http://www.doctrine-project.org/documentation/manual/2_0/en/architecture#entities:persistent-fields>`_
for more details.
Changes to associations in your code are not synchronized to the Changes to associations in your code are not synchronized to the
database directly, but upon calling ``EntityManager#flush()``. database directly, but upon calling ``EntityManager#flush()``.
@ -34,7 +31,7 @@ entities to show examples of association management. See the PHP
docblocks of each association in the following example for docblocks of each association in the following example for
information about its type and if its the owning or inverse side. information about its type and if its the owning or inverse side.
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -137,7 +134,7 @@ Establishing an association between two entities is
straight-forward. Here are some examples for the unidirectional straight-forward. Here are some examples for the unidirectional
relations of the ``User``: relations of the ``User``:
:: .. code-block:: php
<?php <?php
class User class User
@ -155,7 +152,7 @@ relations of the ``User``:
The interaction code would then look like in the following snippet The interaction code would then look like in the following snippet
(``$em`` here is an instance of the EntityManager): (``$em`` here is an instance of the EntityManager):
:: .. code-block:: php
<?php <?php
$user = $em->find('User', $userId); $user = $em->find('User', $userId);
@ -176,7 +173,7 @@ The interaction code would then look like in the following snippet
In the case of bi-directional associations you have to update the In the case of bi-directional associations you have to update the
fields on both sides: fields on both sides:
:: .. code-block:: php
<?php <?php
class User class User
@ -230,7 +227,7 @@ Removing an association between two entities is similarly
straight-forward. There are two strategies to do so, by key and by straight-forward. There are two strategies to do so, by key and by
element. Here are some examples: element. Here are some examples:
:: .. code-block:: php
<?php <?php
// Remove by Elements // Remove by Elements
@ -296,7 +293,7 @@ association is maintained.
The following code shows updates to the previous User and Comment The following code shows updates to the previous User and Comment
example that encapsulate much of the association management code: example that encapsulate much of the association management code:
:: .. code-block:: php
<?php <?php
class User class User
@ -362,7 +359,7 @@ the details inside the classes can be challenging.
association management. For example: association management. For example:
:: .. code-block:: php
<?php <?php
class User { class User {
@ -392,7 +389,7 @@ code.
Using the User-Comment entities from above, a very simple example Using the User-Comment entities from above, a very simple example
can show the possible caveats you can encounter: can show the possible caveats you can encounter:
:: .. code-block:: php
<?php <?php
$user->getFavorites()->add($favoriteComment); $user->getFavorites()->add($favoriteComment);
@ -439,7 +436,7 @@ of this chapter. Suppose in our application a user is created
whenever he writes his first comment. In this case we would use the whenever he writes his first comment. In this case we would use the
following code: following code:
:: .. code-block:: php
<?php <?php
$user = new User(); $user = new User();
@ -459,7 +456,7 @@ as well.
More complicated is the deletion of all a users comments when he is More complicated is the deletion of all a users comments when he is
removed from the system: removed from the system:
:: .. code-block:: php
$user = $em->find('User', $deleteUserId); $user = $em->find('User', $deleteUserId);
@ -478,7 +475,7 @@ To have Doctrine handle both cases automatically we can change the
``User#commentsAuthored`` property to cascade both the "persist" ``User#commentsAuthored`` property to cascade both the "persist"
and the "remove" operation. and the "remove" operation.
:: .. code-block:: php
<?php <?php
class User class User

View File

@ -36,7 +36,7 @@ unique id. You can uniquely identify each article by that id.
Take the following example, where you find an article with the Take the following example, where you find an article with the
headline "Hello World" with the ID 1234: headline "Hello World" with the ID 1234:
:: .. code-block:: php
<?php <?php
$article = $entityManager->find('CMS\Article', 1234); $article = $entityManager->find('CMS\Article', 1234);
@ -60,7 +60,7 @@ screen. You can even verify that ``$article`` and ``$article2`` are
indeed pointing to the same instance by running the following indeed pointing to the same instance by running the following
code: code:
:: .. code-block:: php
<?php <?php
if ($article === $article2) { if ($article === $article2) {
@ -85,7 +85,7 @@ want.
Take the following example of a single ``Article`` entity fetched Take the following example of a single ``Article`` entity fetched
from newly opened EntityManager. from newly opened EntityManager.
:: .. code-block:: php
<?php <?php
/** @Entity */ /** @Entity */
@ -127,7 +127,7 @@ EntityManager and load their state from the database.
This lazy-loading process happens behind the scenes, hidden from This lazy-loading process happens behind the scenes, hidden from
your code. See the following code: your code. See the following code:
:: .. code-block:: php
<?php <?php
$article = $em->find('Article', 1); $article = $em->find('Article', 1);
@ -157,7 +157,7 @@ A slice of the generated proxy classes code looks like the
following piece of code. A real proxy class override ALL public following piece of code. A real proxy class override ALL public
methods along the lines of the ``getName()`` method shown below: methods along the lines of the ``getName()`` method shown below:
:: .. code-block:: php
<?php <?php
class UserProxy extends User implements Proxy class UserProxy extends User implements Proxy
@ -194,7 +194,7 @@ a result the persistent state of such an entity will subsequently
be properly synchronized with the database when be properly synchronized with the database when
``EntityManager#flush()`` is invoked. ``EntityManager#flush()`` is invoked.
.. warning:: .. note::
Invoking the ``persist`` method on an entity does NOT Invoking the ``persist`` method on an entity does NOT
cause an immediate SQL INSERT to be issued on the database. cause an immediate SQL INSERT to be issued on the database.
@ -208,7 +208,7 @@ be properly synchronized with the database when
Example: Example:
:: .. code-block:: php
<?php <?php
$user = new User; $user = new User;
@ -216,7 +216,7 @@ Example:
$em->persist($user); $em->persist($user);
$em->flush(); $em->flush();
.. warning:: .. note::
Generated entity identifiers / primary keys are Generated entity identifiers / primary keys are
guaranteed to be available after the next successful flush guaranteed to be available after the next successful flush
@ -251,7 +251,7 @@ the ``EntityManager#remove($entity)`` method. By applying the
which means that its persistent state will be deleted once which means that its persistent state will be deleted once
``EntityManager#flush()`` is invoked. ``EntityManager#flush()`` is invoked.
.. warning:: .. note::
Just like ``persist``, invoking ``remove`` on an entity Just like ``persist``, invoking ``remove`` on an entity
does NOT cause an immediate SQL DELETE to be issued on the does NOT cause an immediate SQL DELETE to be issued on the
@ -261,7 +261,7 @@ which means that its persistent state will be deleted once
Example: Example:
:: .. code-block:: php
<?php <?php
$em->remove($user); $em->remove($user);
@ -332,7 +332,7 @@ Doctrine will not hold on to any references to a detached entity.
Example: Example:
:: .. code-block:: php
<?php <?php
$em->detach($entity); $em->detach($entity);
@ -381,7 +381,7 @@ this entity and this copy will subsequently be returned.
Example: Example:
:: .. code-block:: php
<?php <?php
$detachedEntity = unserialize($serializedEntity); // some detached entity $detachedEntity = unserialize($serializedEntity); // some detached entity
@ -389,7 +389,9 @@ Example:
// $entity now refers to the fully managed copy returned by the merge operation. // $entity now refers to the fully managed copy returned by the merge operation.
// The EntityManager $em now manages the persistence of $entity as usual. // The EntityManager $em now manages the persistence of $entity as usual.
**CAUTION** When you want to serialize/unserialize entities you .. note::
When you want to serialize/unserialize entities you
have to make all entity properties protected, never private. The have to make all entity properties protected, never private. The
reason for this is, if you serialize a class that was a proxy reason for this is, if you serialize a class that was a proxy
instance before, the private variables won't be serialized and a instance before, the private variables won't be serialized and a
@ -432,6 +434,13 @@ the ``merge`` operation is to reattach entities to an EntityManager
that come from some cache (and are therefore detached) and you want that come from some cache (and are therefore detached) and you want
to modify and persist such an entity. to modify and persist such an entity.
.. warning::
If you need to perform multiple merges of entities that share certain subparts
of their object-graphs and cascade merge, then you have to call ``EntityManager#clear()`` between the
successive calls to ``EntityManager#merge()``. Otherwise you might end up with
multiple copies of the "same" object in the database, however with different ids.
.. note:: .. note::
If you load some detached entities from a cache and you do If you load some detached entities from a cache and you do
@ -516,7 +525,7 @@ How costly a flush operation is, mainly depends on two factors:
You can get the size of a UnitOfWork as follows: You can get the size of a UnitOfWork as follows:
:: .. code-block:: php
<?php <?php
$uowSize = $em->getUnitOfWork()->size(); $uowSize = $em->getUnitOfWork()->size();
@ -527,7 +536,7 @@ to change tracking (see "Change Tracking Policies") and, of course,
memory consumption, so you may want to check it from time to time memory consumption, so you may want to check it from time to time
during development. during development.
.. warning:: .. note::
Do not invoke ``flush`` after every change to an entity Do not invoke ``flush`` after every change to an entity
or every single invocation of persist/remove/merge/... This is an or every single invocation of persist/remove/merge/... This is an
@ -545,12 +554,14 @@ You can get direct access to the Unit of Work by calling
``EntityManager#getUnitOfWork()``. This will return the UnitOfWork ``EntityManager#getUnitOfWork()``. This will return the UnitOfWork
instance the EntityManager is currently using. instance the EntityManager is currently using.
:: .. code-block:: php
<?php <?php
$uow = $em->getUnitOfWork(); $uow = $em->getUnitOfWork();
**NOTE** Directly manipulating a UnitOfWork is not recommended. .. note::
Directly manipulating a UnitOfWork is not recommended.
When working directly with the UnitOfWork API, respect methods When working directly with the UnitOfWork API, respect methods
marked as INTERNAL by not using them and carefully read the API marked as INTERNAL by not using them and carefully read the API
documentation. documentation.
@ -565,7 +576,7 @@ explicitly need to find out what the current state of an entity is
in the context of a certain ``EntityManager`` you can ask the in the context of a certain ``EntityManager`` you can ask the
underlying ``UnitOfWork``: underlying ``UnitOfWork``:
:: .. code-block:: php
<?php <?php
switch ($em->getUnitOfWork()->getEntityState($entity)) { switch ($em->getUnitOfWork()->getEntityState($entity)) {
@ -610,7 +621,7 @@ identifier / primary key using the
``EntityManager#find($entityName, $id)`` method. Here is an ``EntityManager#find($entityName, $id)`` method. Here is an
example: example:
:: .. code-block:: php
<?php <?php
// $em instanceof EntityManager // $em instanceof EntityManager
@ -622,7 +633,7 @@ instance could be found with the given identifier.
Essentially, ``EntityManager#find()`` is just a shortcut for the Essentially, ``EntityManager#find()`` is just a shortcut for the
following: following:
:: .. code-block:: php
<?php <?php
// $em instanceof EntityManager // $em instanceof EntityManager
@ -641,7 +652,7 @@ To query for one or more entities based on several conditions that
form a logical conjunction, use the ``findBy`` and ``findOneBy`` form a logical conjunction, use the ``findBy`` and ``findOneBy``
methods on a repository as follows: methods on a repository as follows:
:: .. code-block:: php
<?php <?php
// $em instanceof EntityManager // $em instanceof EntityManager
@ -659,7 +670,7 @@ An EntityRepository also provides a mechanism for more concise
calls through its use of ``__call``. Thus, the following two calls through its use of ``__call``. Thus, the following two
examples are equivalent: examples are equivalent:
:: .. code-block:: php
<?php <?php
// A single user by its nickname // A single user by its nickname
@ -699,7 +710,7 @@ A DQL query is represented by an instance of the
``Doctrine\ORM\Query`` class. You create a query using ``Doctrine\ORM\Query`` class. You create a query using
``EntityManager#createQuery($dql)``. Here is a simple example: ``EntityManager#createQuery($dql)``. Here is a simple example:
:: .. code-block:: php
<?php <?php
// $em instanceof EntityManager // $em instanceof EntityManager
@ -713,12 +724,12 @@ schema, only about the object model. DQL supports positional as
well as named parameters, many functions, (fetch) joins, well as named parameters, many functions, (fetch) joins,
aggregates, subqueries and much more. Detailed information about aggregates, subqueries and much more. Detailed information about
DQL and its syntax as well as the Doctrine class can be found in DQL and its syntax as well as the Doctrine class can be found in
`the dedicated chapter <http://www.doctrine-project.org/documentation/manual/2_0/en/dql-doctrine-query-language>`_. :doc:`the dedicated chapter <dql-doctrine-query-language>`.
For programmatically building up queries based on conditions that For programmatically building up queries based on conditions that
are only known at runtime, Doctrine provides the special are only known at runtime, Doctrine provides the special
``Doctrine\ORM\QueryBuilder`` class. More information on ``Doctrine\ORM\QueryBuilder`` class. More information on
constructing queries with a QueryBuilder can be found constructing queries with a QueryBuilder can be found
`in the dedicated chapter <http://www.doctrine-project.org/documentation/manual/2_0/en/query-builder>`_. :doc:`in Query Builder chapter <query-builder>`.
By Native Queries By Native Queries
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
@ -742,7 +753,7 @@ applications that require lots of specialized DQL queries using a
custom repository is one recommended way of grouping these queries custom repository is one recommended way of grouping these queries
in a central location. in a central location.
:: .. code-block:: php
<?php <?php
namespace MyDomain\Model; namespace MyDomain\Model;
@ -768,7 +779,7 @@ in a central location.
You can access your repository now by calling: You can access your repository now by calling:
:: .. code-block:: php
<?php <?php
// $em instanceof EntityManager // $em instanceof EntityManager

View File

@ -46,7 +46,7 @@ In order to work, this requires certain conventions:
- -
:: .. code-block:: php
<?php <?php
$driver->setFileExtension('.xml'); $driver->setFileExtension('.xml');
@ -57,7 +57,7 @@ want to. In order to tell the XmlDriver where to look for your
mapping documents, supply an array of paths as the first argument mapping documents, supply an array of paths as the first argument
of the constructor, like this: of the constructor, like this:
:: .. code-block:: php
<?php <?php
$config = new \Doctrine\ORM\Configuration(); $config = new \Doctrine\ORM\Configuration();
@ -291,9 +291,8 @@ attribute:
If you are using the SEQUENCE strategy you can define an additional If you are using the SEQUENCE strategy you can define an additional
element to describe the sequence: element to describe the sequence:
:: .. code-block:: xml
[xml]
<entity name="MyProject\User"> <entity name="MyProject\User">
<id name="id" type="integer" column="user_id"> <id name="id" type="integer" column="user_id">
<generator strategy="SEQUENCE" /> <generator strategy="SEQUENCE" />

View File

@ -21,7 +21,7 @@ In order to work, this requires certain conventions:
- -
:: .. code-block:: php
<?php <?php
$driver->setFileExtension('.yml'); $driver->setFileExtension('.yml');
@ -32,7 +32,7 @@ want to. In order to tell the YamlDriver where to look for your
mapping documents, supply an array of paths as the first argument mapping documents, supply an array of paths as the first argument
of the constructor, like this: of the constructor, like this:
:: .. code-block:: php
<?php <?php
// $config instanceof Doctrine\ORM\Configuration // $config instanceof Doctrine\ORM\Configuration

View File

@ -19,8 +19,7 @@ What are Entities?
Entities are lightweight PHP Objects that don't need to extend any Entities are lightweight PHP Objects that don't need to extend any
abstract base class or interface. An entity class must not be final abstract base class or interface. An entity class must not be final
or contain final methods. Additionally it must not implement or contain final methods. Additionally it must not implement
**clone nor**wakeup or **clone** nor **wakeup** or :doc:`do so safely <../cookbook/implementing-wakeup-or-clone>`.
`do so safely <http://www.doctrine-project.org/documentation/cookbook/2_0/en/implementing-wakeup-or-clone>`_.
An entity contains persistable properties. A persistable property An entity contains persistable properties. A persistable property
is an instance variable of the entity that contains the data which is an instance variable of the entity that contains the data which
@ -62,7 +61,7 @@ A first prototype
A first simplified design for this domain model might look like the A first simplified design for this domain model might look like the
following set of classes: following set of classes:
:: .. code-block:: php
<?php <?php
class Bug class Bug
@ -134,7 +133,7 @@ simple implementation of this interface.
Now that we know this, we have to clear up our domain model to cope Now that we know this, we have to clear up our domain model to cope
with the assumptions about related collections: with the assumptions about related collections:
:: .. code-block:: php
<?php <?php
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
@ -221,7 +220,7 @@ the assigned and reported bugs from a user, making this relation
bi-directional. We have to change the code to ensure consistency of bi-directional. We have to change the code to ensure consistency of
the bi-directional reference: the bi-directional reference:
:: .. code-block:: php
<?php <?php
class Bug class Bug
@ -270,7 +269,7 @@ methods are only used for ensuring consistency of the references.
You can see from ``User::addReportedBug()`` and You can see from ``User::addReportedBug()`` and
``User::assignedToBug()`` that using this method in userland alone ``User::assignedToBug()`` that using this method in userland alone
would not add the Bug to the collection of the owning side in would not add the Bug to the collection of the owning side in
Bug:::math:`$reporter or Bug::$`engineer. Using these methods and ``Bug::$reporter`` or ``Bug::$engineer``. Using these methods and
calling Doctrine for persistence would not update the collections calling Doctrine for persistence would not update the collections
representation in the database. representation in the database.
@ -294,7 +293,7 @@ the Bug being at the owning side of the relation.
Bugs reference Products by a uni-directional ManyToMany relation in Bugs reference Products by a uni-directional ManyToMany relation in
the database that points from from Bugs to Products. the database that points from from Bugs to Products.
:: .. code-block:: php
<?php <?php
class Bug class Bug
@ -360,9 +359,8 @@ configurations.
The first discussed definition will be for the Product, since it is The first discussed definition will be for the Product, since it is
the most simple one: the most simple one:
:: .. code-block:: xml
[xml]
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
@ -389,9 +387,8 @@ case of PostgreSql and Oracle.
We then go on specifying the definition of a Bug: We then go on specifying the definition of a Bug:
:: .. code-block:: xml
[xml]
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
@ -459,9 +456,8 @@ schema details all the time.
The last missing definition is that of the User entity: The last missing definition is that of the User entity:
:: .. code-block:: xml
[xml]
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
@ -501,13 +497,11 @@ configure and create it to use your entities with Doctrine 2. I
will show the configuration steps and then discuss them step by will show the configuration steps and then discuss them step by
step: step:
:: .. code-block:: php
<?php <?php
// Setup Autoloader (1) // Setup Autoloader (1)
require '/path/to/lib/Doctrine/Common/ClassLoader.php'; // See :doc:`Configuration <../reference/configuration>` for up to date autoloading details.
$loader = new Doctrine\Common\ClassLoader("Doctrine", '/path/to/Doctrine/trunk/lib/');
$loader->register();
$config = new Doctrine\ORM\Configuration(); // (2) $config = new Doctrine\ORM\Configuration(); // (2)
@ -549,7 +543,7 @@ can use whatever suits you best.
The second block contains of the instantiation of the ORM The second block contains of the instantiation of the ORM
Configuration object. Besides the configuration shown in the next Configuration object. Besides the configuration shown in the next
blocks there are several others with are all explained in the blocks there are several others with are all explained in the
`Configuration section of the manual <http://www.doctrine-project.org/documentation/manual/2_0/en/configuration#configuration-options>`_. :doc:`Configuration section of the manual <../reference/configuration>`.
The Proxy Configuration is a required block for your application, The Proxy Configuration is a required block for your application,
you have to specify where Doctrine writes the PHP code for Proxy you have to specify where Doctrine writes the PHP code for Proxy
@ -598,7 +592,7 @@ For the command-line tool to work a cli-config.php file has to be
present in the project root directory, where you will execute the present in the project root directory, where you will execute the
doctrine command. Its a fairly simple file: doctrine command. Its a fairly simple file:
:: .. code-block:: php
<?php <?php
$helperSet = new \Symfony\Components\Console\Helper\HelperSet(array( $helperSet = new \Symfony\Components\Console\Helper\HelperSet(array(
@ -609,9 +603,8 @@ doctrine command. Its a fairly simple file:
You can then change into your project directory and call the You can then change into your project directory and call the
Doctrine command-line tool: Doctrine command-line tool:
:: .. code-block:: bash
[console]
doctrine@my-desktop> cd myproject/ doctrine@my-desktop> cd myproject/
doctrine@my-desktop> doctrine orm:schema-tool:create doctrine@my-desktop> doctrine orm:schema-tool:create
@ -623,7 +616,7 @@ Doctrine command-line tool:
your doctrine command-line client. your doctrine command-line client.
See the See the
`Tools section of the manual <http://www.doctrine-project.org/projects/orm/2.0/docs/reference/tools/en>`_ :doc:`Tools section of the manual <../reference/tools>`
on how to setup the Doctrine console correctly. on how to setup the Doctrine console correctly.
@ -631,17 +624,15 @@ During the development you probably need to re-create the database
several times when changing the Entity metadata. You can then several times when changing the Entity metadata. You can then
either re-create the database: either re-create the database:
:: .. code-block:: bash
[console]
doctrine@my-desktop> doctrine orm:schema-tool:drop doctrine@my-desktop> doctrine orm:schema-tool:drop
doctrine@my-desktop> doctrine orm:schema-tool:create doctrine@my-desktop> doctrine orm:schema-tool:create
Or use the update functionality: Or use the update functionality:
:: .. code-block:: bash
[console]
doctrine@my-desktop> doctrine orm:schema-tool:update doctrine@my-desktop> doctrine orm:schema-tool:update
The updating of databases uses a Diff Algorithm for a given The updating of databases uses a Diff Algorithm for a given
@ -655,7 +646,7 @@ Writing Entities into the Database
Having created the schema we can now start and save entities in the Having created the schema we can now start and save entities in the
database. For starters we need a create user use-case: database. For starters we need a create user use-case:
:: .. code-block:: php
<?php <?php
$newUsername = "beberlei"; $newUsername = "beberlei";
@ -668,7 +659,7 @@ database. For starters we need a create user use-case:
Products can also be created: Products can also be created:
:: .. code-block:: php
<?php <?php
$newProductName = "My Product"; $newProductName = "My Product";
@ -711,7 +702,7 @@ only updating those database columns that really changed.
We are now getting to the "Create a New Bug" requirement and the We are now getting to the "Create a New Bug" requirement and the
code for this scenario may look like this: code for this scenario may look like this:
:: .. code-block:: php
<?php <?php
$reporter = $entityManager->find("User", $theReporterId); $reporter = $entityManager->find("User", $theReporterId);
@ -758,7 +749,7 @@ mapper for the required view representations. When opening the
application, bugs can be paginated through a list-view, which is application, bugs can be paginated through a list-view, which is
the first read-only use-case: the first read-only use-case:
:: .. code-block:: php
<?php <?php
$dql = "SELECT b, e, r FROM Bug b JOIN b.engineer e JOIN b.reporter r ORDER BY b.created DESC"; $dql = "SELECT b, e, r FROM Bug b JOIN b.engineer e JOIN b.reporter r ORDER BY b.created DESC";
@ -840,7 +831,7 @@ read-only requests.
Implementing the same list view as before using array hydration we Implementing the same list view as before using array hydration we
can rewrite our code: can rewrite our code:
:: .. code-block:: php
<?php <?php
$dql = "SELECT b, e, r, p FROM Bug b JOIN b.engineer e ". $dql = "SELECT b, e, r, p FROM Bug b JOIN b.engineer e ".
@ -873,7 +864,7 @@ however there is a convenience method on the Entity Manager that
handles loading by primary key, which we have already seen in the handles loading by primary key, which we have already seen in the
write scenarios: write scenarios:
:: .. code-block:: php
<?php <?php
$bug = $entityManager->find("Bug", (int)$theBugId); $bug = $entityManager->find("Bug", (int)$theBugId);
@ -881,7 +872,7 @@ write scenarios:
However we will soon see another problem with our entities using However we will soon see another problem with our entities using
this approach. Try displaying the engineer's name: this approach. Try displaying the engineer's name:
:: .. code-block:: php
<?php <?php
echo "Bug: ".$bug->description."\n"; echo "Bug: ".$bug->description."\n";
@ -897,7 +888,7 @@ replaced by LazyLoading proxies. Sample code of this proxy
generated code can be found in the specified Proxy Directory, it generated code can be found in the specified Proxy Directory, it
looks like: looks like:
:: .. code-block:: php
<?php <?php
namespace MyProject\Proxies; namespace MyProject\Proxies;
@ -929,7 +920,7 @@ direct access to a public property and trigger the lazy load. We
need to rewrite our entities, make all the properties private or need to rewrite our entities, make all the properties private or
protected and add getters and setters to get a working example: protected and add getters and setters to get a working example:
:: .. code-block:: php
<?php <?php
echo "Bug: ".$bug->getDescription()."\n"; echo "Bug: ".$bug->getDescription()."\n";
@ -952,7 +943,7 @@ list of all open bugs the user reported or was assigned to. This
will be achieved using DQL again, this time with some WHERE clauses will be achieved using DQL again, this time with some WHERE clauses
and usage of bound parameters: and usage of bound parameters:
:: .. code-block:: php
<?php <?php
$dql = "SELECT b, e, r FROM Bug b JOIN b.engineer e JOIN b.reporter r ". $dql = "SELECT b, e, r FROM Bug b JOIN b.engineer e JOIN b.reporter r ".
@ -981,7 +972,7 @@ aggregate values using COUNT, SUM, MIN, MAX or AVG functions.
We will need this knowledge to retrieve the number of open bugs We will need this knowledge to retrieve the number of open bugs
grouped by product: grouped by product:
:: .. code-block:: php
<?php <?php
$dql = "SELECT p.id, p.name, count(b.id) AS openBugs FROM Bug b ". $dql = "SELECT p.id, p.name, count(b.id) AS openBugs FROM Bug b ".
@ -998,7 +989,7 @@ Updating Entities
There is a single use-case missing from the requirements, Engineers There is a single use-case missing from the requirements, Engineers
should be able to close a bug. This looks like: should be able to close a bug. This looks like:
:: .. code-block:: php
<?php <?php
$bug = $entityManager->find("Bug", (int)$theBugId); $bug = $entityManager->find("Bug", (int)$theBugId);
@ -1024,8 +1015,6 @@ improvement compared to updating all the properties.
This tutorial is over here, I hope you had fun. Additional content This tutorial is over here, I hope you had fun. Additional content
will be added to this tutorial incrementally, topics will include: will be added to this tutorial incrementally, topics will include:
::
* Entity Repositories * Entity Repositories
* More on Association Mappings * More on Association Mappings
* Lifecycle Events triggered in the UnitOfWork * Lifecycle Events triggered in the UnitOfWork

View File

@ -1,2 +1,2 @@
#!/bin/bash #!/bin/bash
sphinx-build manual/en /var/www/docs sphinx-build en /var/www/docs

View File

@ -1,79 +0,0 @@
Introduction
============
Architecture
============
Configuration
=============
Basic Mapping
=============
Association Mapping
===================
Inheritance Mapping
===================
Working with objects
====================
Working with associations
=========================
Transactions and Concurrency
============================
Events
======
Batch processing
================
DQL (Doctrine Query Language)
=============================
Query Builder
=============
Native SQL
==========
Change Tracking Policies
========================
Partial Objects
===============
XML Mapping
===========
YAML Mapping
============
Annotations Reference
=====================
PHP Mapping
===========
Caching
=======
Improving Performance
=====================
Tools
=====
Metadata Drivers
================
Best Practices
==============
Limitations and Known Issues
============================

View File

@ -1,26 +0,0 @@
# Introduction
# Architecture
# Configuration
# Basic Mapping
# Association Mapping
# Inheritance Mapping
# Working with objects
# Working with associations
# Transactions and Concurrency
# Events
# Batch processing
# DQL (Doctrine Query Language)
# Query Builder
# Native SQL
# Change Tracking Policies
# Partial Objects
# XML Mapping
# YAML Mapping
# Annotations Reference
# PHP Mapping
# Caching
# Improving Performance
# Tools
# Metadata Drivers
# Best Practices
# Limitations and Known Issues

View File

@ -1,47 +0,0 @@
.. Doctrine 2 ORM documentation master file, created by
sphinx-quickstart on Mon Nov 1 21:19:39 2010.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Doctrine 2 ORM's documentation!
==========================================
Contents:
.. toctree::
:maxdepth: 2
introduction
architecture
configuration
basic-mapping
association-mapping
inheritance-mapping
working-with-objects
working-with-associations
transactions-and-concurrency
events
batch-processing
dql-doctrine-query-language
query-builder
native-sql
change-tracking-policies
partial-objects
xml-mapping
yaml-mapping
annotations-reference
php-mapping
caching
improving-performance
tools
metadata-drivers
best-practices
limitations-and-known-issues
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`