Finialized ReST doc changes, merged changes from latest Markdown docs.
This commit is contained in:
parent
ee042bc642
commit
46983465fd
@ -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
|
||||
================
|
||||
|
||||
|
@ -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
|
@ -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."
|
@ -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
|
@ -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`
|
||||
|
@ -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
198
en/_templates/layout.html
Normal 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 ' »' 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 = " — "|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 %}© <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
|
||||
{%- else %}
|
||||
{% trans copyright=copyright|e %}© 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>
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
@ -38,7 +38,7 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
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
|
||||
# |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.
|
||||
version = '2.0'
|
||||
# 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
|
||||
# for a list of supported languages.
|
||||
language = 'en'
|
||||
language = 'php'
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# 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
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
show_authors = True
|
||||
|
||||
# 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 = []
|
||||
|
||||
@ -175,7 +173,7 @@ htmlhelp_basename = 'Doctrine2ORMdoc'
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('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
|
@ -1,6 +1,8 @@
|
||||
Aggregate Fields
|
||||
================
|
||||
|
||||
.. sectionauthor:: Benjamin Eberlei <kontakt@beberlei.de>
|
||||
|
||||
You will often come across the requirement to display aggregate
|
||||
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
|
||||
@ -27,7 +29,7 @@ added on the ``Entry`` object.
|
||||
|
||||
Our entities look like:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
the current balance of your account by calling:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
collection, which means we can compute this value at runtime:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class Account
|
||||
@ -168,7 +170,7 @@ the aggregate root of this relation. We can also enforce the
|
||||
correctness of the bi-directional ``Account`` <-> ``Entry``
|
||||
relation with this method:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class Account
|
||||
@ -185,7 +187,7 @@ relation with this method:
|
||||
|
||||
Now look at the following test-code for our entities:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
``Account::addEntry``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class Account
|
||||
@ -236,7 +238,7 @@ account example before. You can call
|
||||
database. All the nested ``Entry`` objects are automatically
|
||||
flushed to the database also.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
``Account::getBalance()`` and ``Account:addEntry()``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class Account
|
||||
@ -301,7 +303,7 @@ Tackling Race Conditions with Aggregate Fields
|
||||
Whenever you denormalize your database schema race-conditions can
|
||||
potentially lead to inconsistent state. See this example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// 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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class Amount
|
||||
@ -344,7 +346,7 @@ Pessimistic locking requires an additional flag set on the
|
||||
``EntityManager::find()`` call, enabling write locking directly in
|
||||
the database using a FOR UPDATE.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\DBAL\LockMode;
|
@ -1,6 +1,8 @@
|
||||
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
|
||||
substitutes tables and columns for Entity names and their fields.
|
||||
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
|
||||
like:
|
||||
|
||||
.. code-clock:: sql
|
||||
.. code-block:: sql
|
||||
|
||||
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
|
||||
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 ...
|
||||
|
||||
@ -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
|
||||
API would look for this use-case:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$pageNum = 1;
|
||||
@ -92,7 +94,7 @@ API would look for this use-case:
|
||||
|
||||
The ``Paginate::count(Query $query)`` looks like:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
implementation is:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
SQL\_NO\_CACHE query hint.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
SQL\_NO\_CACHE on those queries that need it:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class MysqlWalker extends SqlWalker
|
@ -1,6 +1,8 @@
|
||||
DQL User Defined Functions
|
||||
==========================
|
||||
|
||||
.. sectionauthor:: Benjamin Eberlei <kontakt@beberlei.de>
|
||||
|
||||
By default DQL supports a limited subset of all the vendor-specific
|
||||
SQL functions common between all the vendors. However in many cases
|
||||
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
|
||||
features that are unique to the vendor.
|
||||
|
||||
**Note**
|
||||
|
||||
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
|
||||
advanced extension point. You can map arbitrary SQL to your objects
|
||||
and gain access to vendor specific functionalities using the
|
||||
``EntityManager#createNativeQuery()`` API.
|
||||
It is worth to mention that Doctrine 2 also allows you to handwrite
|
||||
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
|
||||
and gain access to vendor specific functionalities using the
|
||||
``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
|
||||
@ -37,7 +38,7 @@ Registering your own DQL functions
|
||||
You can register your functions adding them to the ORM
|
||||
configuration:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
discuss it step by step:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -135,7 +136,7 @@ function call around this output.
|
||||
|
||||
Now registering this DateDiff FunctionNode with the ORM using:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$config = new \Doctrine\ORM\Configuration();
|
||||
@ -143,7 +144,7 @@ Now registering this DateDiff FunctionNode with the ORM using:
|
||||
|
||||
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
|
||||
|
||||
@ -156,7 +157,7 @@ your DQL query using
|
||||
|
||||
I'll skip the blah and show the code for this function:
|
||||
|
||||
::
|
||||
.. code-block:: 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
|
||||
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
|
||||
|
@ -1,6 +1,8 @@
|
||||
Implementing ArrayAccess for Domain Objects
|
||||
===========================================
|
||||
|
||||
.. sectionauthor:: Roman Borschel (roman@code-factory.org)
|
||||
|
||||
This recipe will show you how to implement ArrayAccess for your
|
||||
domain objects in order to allow more uniform access, for example
|
||||
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 go through any getters/setters
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
abstract class DomainObject implements ArrayAccess
|
||||
@ -53,7 +55,7 @@ caveats:
|
||||
- The semantics of offsetExists can differ
|
||||
- offsetUnset will not work with typehinted setters
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
exception (i.e. BadMethodCallException).
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
abstract class DomainObject implements ArrayAccess
|
@ -1,6 +1,8 @@
|
||||
Implementing the Notify ChangeTracking Policy
|
||||
=============================================
|
||||
|
||||
.. sectionauthor:: Roman Borschel (roman@code-factory.org)
|
||||
|
||||
The NOTIFY change-tracking policy is the most effective
|
||||
change-tracking policy provided by Doctrine but it requires some
|
||||
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
|
||||
``Doctrine\Common`` namespace.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
listeners:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// Mapping not shown, either in annotations, xml or yaml as usual
|
@ -1,6 +1,8 @@
|
||||
Implementing Wakeup or Clone
|
||||
============================
|
||||
|
||||
.. sectionauthor:: Roman Borschel (roman@code-factory.org)
|
||||
|
||||
As explained in the
|
||||
`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``
|
||||
@ -15,7 +17,7 @@ Safely implementing \_\_wakeup
|
||||
To safely implement ``__wakeup``, simply enclose your
|
||||
implementation code in an identity check as follows:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class MyEntity
|
||||
@ -40,7 +42,7 @@ Safely implementing \_\_clone
|
||||
|
||||
Safely implementing ``__clone`` is pretty much the same:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class MyEntity
|
@ -42,7 +42,7 @@ Creating your Doctrine CodeIgniter library
|
||||
Now, here is what your Doctrine.php file should look like.
|
||||
Customize it to your needs.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\Common\ClassLoader,
|
||||
@ -75,6 +75,9 @@ Customize it to your needs.
|
||||
$config = new Configuration;
|
||||
$cache = new ArrayCache;
|
||||
$config->setMetadataCacheImpl($cache);
|
||||
$driverImpl = $config->newDefaultAnnotationDriver(array(APPPATH.'models/Entities'));
|
||||
$config->setMetadataDriverImpl($driverImpl);
|
||||
|
||||
$config->setQueryCacheImpl($cache);
|
||||
|
||||
// Proxy configuration
|
||||
@ -115,7 +118,7 @@ Now to use it
|
||||
Whenever you need a reference to the entity manager inside one of
|
||||
your controllers, views, or models you can do this:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
will need to put this line before you get a reference to it:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$this->load->library('doctrine');
|
@ -20,7 +20,7 @@ DoctrineExtensions namespace. You create this file in your
|
||||
library/DoctrineExtensions directory, but will need to set up
|
||||
appropriate autoloaders.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
@ -56,7 +56,7 @@ before the prefix has been set.
|
||||
to clear your caches and drop then recreate your database schema.
|
||||
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
@ -59,7 +59,7 @@ the middle of your page, for example).
|
||||
Such an interface could look like this:
|
||||
|
||||
|
||||
::
|
||||
.. code-block:: 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:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
* 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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use \Doctrine\ORM,
|
@ -1,6 +1,8 @@
|
||||
Validation of Entities
|
||||
======================
|
||||
|
||||
.. sectionauthor:: Benjamin Eberlei <kontakt@beberlei.de>
|
||||
|
||||
Doctrine 2 does not ship with any internal validators, the reason
|
||||
being that we think all the frameworks out there already ship with
|
||||
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
|
||||
is allowed to:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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.
|
||||
First Annotations:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -70,9 +72,8 @@ First Annotations:
|
||||
|
||||
In XML Mappings:
|
||||
|
||||
::
|
||||
.. code-block:: xml
|
||||
|
||||
[xml]
|
||||
<doctrine-mapping>
|
||||
<entity name="Order">
|
||||
<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
|
||||
validation callbacks.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
called "onFlush".
|
||||
|
||||
Further readings:
|
||||
|
||||
|
||||
- `Doctrine 2 Manual: Events <http://www.doctrine-project.org/documentation/manual/2_0/en/events#lifecycle-events>`_
|
||||
|
||||
|
||||
Further readings: :doc:`Lifecycle Events <../reference/events>`
|
70
en/index.rst
Normal file
70
en/index.rst
Normal 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`
|
||||
|
@ -8,39 +8,41 @@ Index
|
||||
-----
|
||||
|
||||
|
||||
- `@Column <#ann_column>`_
|
||||
- `@ChangeTrackingPolicy <#ann_changetrackingpolicy>`_
|
||||
- `@DiscriminatorColumn <#ann_discriminatorcolumn>`_
|
||||
- `@DiscriminatorMap <#ann_discriminatormap>`_
|
||||
- `@Entity <#ann_entity>`_
|
||||
- `@GeneratedValue <#ann_generatedvalue>`_
|
||||
- `@HasLifecycleCallbacks <#ann_haslifecyclecallbacks>`_
|
||||
- `@Index <#ann_indexes>`_
|
||||
- `@Id <#ann_id>`_
|
||||
- `@InheritanceType <#ann_inheritancetype>`_
|
||||
- `@JoinColumn <#ann_joincolumn>`_
|
||||
- `@JoinTable <#ann_jointable>`_
|
||||
- `@ManyToOne <#ann_manytoone>`_
|
||||
- `@ManyToMany <#ann_manytomany>`_
|
||||
- `@MappedSuperclass <#ann_mappedsuperclass>`_
|
||||
- `@OneToOne <#ann_onetoone>`_
|
||||
- `@OneToMany <#ann_onetomany>`_
|
||||
- `@OrderBy <#ann_orderby>`_
|
||||
- `@PostLoad <#ann_postload>`_
|
||||
- `@PostPersist <#ann_postpersist>`_
|
||||
- `@PostRemove <#ann_postremove>`_
|
||||
- `@PostUpdate <#ann_postupdate>`_
|
||||
- `@PrePersist <#ann_prepersist>`_
|
||||
- `@PreRemove <#ann_preremove>`_
|
||||
- `@PreUpdate <#ann_preupdate>`_
|
||||
- `@SequenceGenerator <#ann_sequencegenerator>`_
|
||||
- `@Table <#ann_table>`_
|
||||
- `@UniqueConstraint <#ann_uniqueconstraint>`_
|
||||
- `@Version <#ann_version>`_
|
||||
- :ref:`@Column <annref_column>`
|
||||
- :ref:`@ChangeTrackingPolicy <annref_changetrackingpolicy>`
|
||||
- :ref:`@DiscriminatorColumn <annref_discriminatorcolumn>`
|
||||
- :ref:`@DiscriminatorMap <annref_discriminatormap>`
|
||||
- :ref:`@Entity <annref_entity>`
|
||||
- :ref:`@GeneratedValue <annref_generatedvalue>`
|
||||
- :ref:`@HasLifecycleCallbacks <annref_haslifecyclecallbacks>`
|
||||
- :ref:`@Index <annref_index>`
|
||||
- :ref:`@Id <annref_id>`
|
||||
- :ref:`@InheritanceType <annref_inheritancetype>`
|
||||
- :ref:`@JoinColumn <annref_joincolumn>`
|
||||
- :ref:`@JoinTable <annref_jointable>`
|
||||
- :ref:`@ManyToOne <annref_manytoone>`
|
||||
- :ref:`@ManyToMany <annref_manytomany>`
|
||||
- :ref:`@MappedSuperclass <annref_mappedsuperclass>`
|
||||
- :ref:`@OneToOne <annref_onetoone>`
|
||||
- :ref:`@OneToMany <annref_onetomany>`
|
||||
- :ref:`@OrderBy <annref_orderby>`
|
||||
- :ref:`@PostLoad <annref_postload>`
|
||||
- :ref:`@PostPersist <annref_postpersist>`
|
||||
- :ref:`@PostRemove <annref_postremove>`
|
||||
- :ref:`@PostUpdate <annref_postupdate>`
|
||||
- :ref:`@PrePersist <annref_prepersist>`
|
||||
- :ref:`@PreRemove <annref_preremove>`
|
||||
- :ref:`@PreUpdate <annref_preupdate>`
|
||||
- :ref:`@SequenceGenerator <annref_sequencegenerator>`
|
||||
- :ref:`@Table <annref_table>`
|
||||
- :ref:`@UniqueConstraint <annref_uniqueconstraint>`
|
||||
- :ref:`@Version <annref_version>`
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. _annref_column:
|
||||
|
||||
@Column
|
||||
~~~~~~~
|
||||
|
||||
@ -79,11 +81,11 @@ Optional attributes:
|
||||
attribute still handles the conversion between PHP and Database
|
||||
values. If you use this attribute on a column that is used for
|
||||
joins between tables you should also take a look at
|
||||
`@JoinColumn <#ann_joincolumn>`_.
|
||||
:ref:`@JoinColumn <annref_joincolumn>`.
|
||||
|
||||
Examples:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -101,6 +103,8 @@ Examples:
|
||||
*/
|
||||
protected $height;
|
||||
|
||||
.. _annref_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
|
||||
policy is an interesting option.
|
||||
|
||||
The
|
||||
`details on all the available change tracking policies </../configuration#change-tracking-policies>`_
|
||||
The :doc:`details on all the available change tracking policies <change-tracking-policies>`
|
||||
can be found in the configuration section.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -130,6 +133,8 @@ Example:
|
||||
*/
|
||||
class User {}
|
||||
|
||||
.. _annref_discriminatorcolumn:
|
||||
|
||||
@DiscrimnatorColumn
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -150,6 +155,8 @@ Optional attributes:
|
||||
- type - By default this is string.
|
||||
- length - By default this is 255.
|
||||
|
||||
.. _annref_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
|
||||
depending if the classes are in the namespace or not.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -174,6 +181,8 @@ depending if the classes are in the namespace or not.
|
||||
// ...
|
||||
}
|
||||
|
||||
.. _annref_entity:
|
||||
|
||||
@Entity
|
||||
~~~~~~~
|
||||
|
||||
@ -190,7 +199,7 @@ Optional attributes:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -201,11 +210,13 @@ Example:
|
||||
//...
|
||||
}
|
||||
|
||||
.. _annref_generatedvalue:
|
||||
|
||||
@GeneratedValue
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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
|
||||
conjunction with @Id.
|
||||
|
||||
@ -220,7 +231,7 @@ Required attributes:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -230,6 +241,8 @@ Example:
|
||||
*/
|
||||
protected $id = null;
|
||||
|
||||
.. _annref_haslifecyclecallbacks:
|
||||
|
||||
@HasLifecycleCallbacks
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -242,7 +255,7 @@ ignore the callbacks.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -257,10 +270,12 @@ Example:
|
||||
public function sendOptinMail() {}
|
||||
}
|
||||
|
||||
.. _annref_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
|
||||
generate a database index on the specified table columns. It only
|
||||
has meaning in the SchemaTool schema generation context.
|
||||
@ -273,7 +288,7 @@ Required attributes:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -284,6 +299,8 @@ Example:
|
||||
{
|
||||
}
|
||||
|
||||
.. _annref_id:
|
||||
|
||||
@Id
|
||||
~~~~~~~
|
||||
|
||||
@ -295,7 +312,7 @@ be marked with @Id.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -304,6 +321,8 @@ Example:
|
||||
*/
|
||||
protected $id = null;
|
||||
|
||||
.. _annref_inheritancetype:
|
||||
|
||||
@InheritanceType
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -313,12 +332,12 @@ inheritance. Currently Single Table and Class Table Inheritance are
|
||||
supported.
|
||||
|
||||
This annotation has always been used in conjunction with the
|
||||
`@DiscriminatorMap <#ann_discriminatormap>`_ and
|
||||
`@DiscriminatorColumn <#ann_discriminatorcolumn>`_ annotations.
|
||||
:ref:`@DiscriminatorMap <annref_discriminatormap>` and
|
||||
:ref:`@DiscriminatorColumn <annref_discriminatorcolumn>` annotations.
|
||||
|
||||
Examples:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -343,12 +362,14 @@ Examples:
|
||||
// ...
|
||||
}
|
||||
|
||||
.. _annref_joincolumn:
|
||||
|
||||
@JoinColumn
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
This annotation is used in the context of relations in
|
||||
`@ManyToOne <#ann_manytoone>`_, `@OneToOne <#ann_onetoone>`_ fields
|
||||
and in the Context of `@JoinTable <#ann_jointable>`_ nested inside
|
||||
:ref:`@ManyToOne <annref_manytoone>`, :ref:`@OneToOne <annref_onetoone>` fields
|
||||
and in the Context of :ref:`@JoinTable <annref_jointable>` nested inside
|
||||
a @ManyToMany. This annotation is not required. If its not
|
||||
specified the attributes *name* and *referencedColumnName* are
|
||||
inferred from the table and primary key names.
|
||||
@ -378,13 +399,13 @@ Optional attributes:
|
||||
this attribute on @JoinColumn is necessary if you need slightly
|
||||
different column definitions for joining columns, for example
|
||||
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
|
||||
make foreign keys work.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -393,18 +414,22 @@ Example:
|
||||
*/
|
||||
private $customer;
|
||||
|
||||
.. _annref_joincolumns:
|
||||
|
||||
@JoinColumns
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
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.
|
||||
|
||||
.. _annref_jointable:
|
||||
|
||||
@JoinTable
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Using `@OneToMany <#ann_onetomany>`_ or
|
||||
`@ManyToMany <#ann_manytomany>`_ on the owning side of the relation
|
||||
Using :ref:`@OneToMany <annref_onetomany>` or
|
||||
:ref:`@ManyToMany <annref_manytomany>` on the owning side of the relation
|
||||
requires to specify the @JoinTable annotation which describes the
|
||||
details of the database join table. If you do not specify
|
||||
@JoinTable on these relations reasonable mapping defaults apply
|
||||
@ -427,7 +452,7 @@ Optional attributes:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -439,6 +464,8 @@ Example:
|
||||
*/
|
||||
public $phonenumbers;
|
||||
|
||||
.. _annref_manytoone:
|
||||
|
||||
@ManyToOne
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
@ -462,19 +489,21 @@ Optional attributes:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
* @ManyToOne(targetEntity="Cart", cascade="ALL", fetch="EAGER")
|
||||
* @ManyToOne(targetEntity="Cart", cascade={"ALL"}, fetch="EAGER")
|
||||
*/
|
||||
private $cart;
|
||||
|
||||
.. _annref_manytomany:
|
||||
|
||||
@ManyToMany
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
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
|
||||
configuration values using the table and names of the two related
|
||||
entities.
|
||||
@ -505,7 +534,7 @@ Optional attributes:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -526,6 +555,8 @@ Example:
|
||||
*/
|
||||
private $features;
|
||||
|
||||
.. _annref_mappedsuperclass:
|
||||
|
||||
@MappedSuperclass
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -536,15 +567,17 @@ the Class docblock and has no additional attributes.
|
||||
|
||||
The @MappedSuperclass annotation cannot be used in conjunction with
|
||||
@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
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
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
|
||||
`@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.
|
||||
|
||||
Required attributes:
|
||||
@ -567,7 +600,7 @@ Optional attributes:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -576,6 +609,8 @@ Example:
|
||||
*/
|
||||
private $customer;
|
||||
|
||||
.. _annref_onetomany:
|
||||
|
||||
@OneToMany
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
@ -599,7 +634,7 @@ Optional attributes:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -607,11 +642,13 @@ Example:
|
||||
*/
|
||||
public $phonenumbers;
|
||||
|
||||
.. _annref_orderby:
|
||||
|
||||
@OrderBy
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
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
|
||||
retrieved from the database by using an ORDER BY clause.
|
||||
|
||||
@ -620,7 +657,7 @@ snippet:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: 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``
|
||||
class of the ``@ManyToMany`` or ``@OneToMany`` annotation.
|
||||
|
||||
.. _annref_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
|
||||
DocBlock.
|
||||
|
||||
.. _annref_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
|
||||
DocBlock.
|
||||
|
||||
.. _annref_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
|
||||
DocBlock.
|
||||
|
||||
.. _annref_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
|
||||
DocBlock.
|
||||
|
||||
.. _annref_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
|
||||
DocBlock.
|
||||
|
||||
.. _annref_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
|
||||
DocBlock.
|
||||
|
||||
.. _annref_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
|
||||
DocBlock.
|
||||
|
||||
.. _annref_sequencegenerator:
|
||||
|
||||
@SequenceGenerator
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -707,7 +760,7 @@ Optional attributes:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -718,6 +771,8 @@ Example:
|
||||
*/
|
||||
protected $id = null;
|
||||
|
||||
.. _annref_table:
|
||||
|
||||
@Table
|
||||
~~~~~~~
|
||||
|
||||
@ -740,7 +795,7 @@ Optional attributes:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -752,10 +807,12 @@ Example:
|
||||
*/
|
||||
class User { }
|
||||
|
||||
.. _annref_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
|
||||
generate a database unique constraint on the specified table
|
||||
columns. It only has meaning in the SchemaTool schema generation
|
||||
@ -769,7 +826,7 @@ Required attributes:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -780,17 +837,19 @@ Example:
|
||||
{
|
||||
}
|
||||
|
||||
.. _annref_version:
|
||||
|
||||
@Version
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Marker annotation that defines a specified column as version
|
||||
attribute used in an optimistic locking scenario. It only works on
|
||||
`@Column <#ann_column>`_ annotations that have the type integer or
|
||||
datetime.
|
||||
:ref:`@Column <annref_column>` annotations that have the type integer or
|
||||
datetime. Combining @Version with :ref:`@Id <annref_id>` is not supported.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
@ -60,6 +60,8 @@ DETACHED or REMOVED.
|
||||
identity, associated with an EntityManager, that will be removed
|
||||
from the database upon transaction commit.
|
||||
|
||||
.. _architecture_persistent_fields:
|
||||
|
||||
Persistent fields
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
@ -7,6 +7,8 @@ owning and inverse sides which is important to understand when
|
||||
working with bidirectional associations. Please read these
|
||||
explanations carefully.
|
||||
|
||||
.. _association-mapping-owning-inverse:
|
||||
|
||||
Owning Side and Inverse Side
|
||||
----------------------------
|
||||
|
||||
@ -131,7 +133,7 @@ follows:
|
||||
|
||||
As an example, consider this mapping:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @OneToOne(targetEntity="Shipping") */
|
||||
@ -140,7 +142,7 @@ As an example, consider this mapping:
|
||||
This is essentially the same as the following, more verbose,
|
||||
mapping:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -152,7 +154,7 @@ mapping:
|
||||
The @JoinTable definition used for many-to-many mappings has
|
||||
similar defaults. As an example, consider this mapping:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class User
|
||||
@ -166,7 +168,7 @@ similar defaults. As an example, consider this mapping:
|
||||
This is essentially the same as the following, more verbose,
|
||||
mapping:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
contains a collection of groups:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @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
|
||||
empty ``ArrayCollection`` in your entities constructor:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
been associated with an EntityManager yet:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$group = $entityManager->find('Group', $groupId);
|
||||
@ -266,13 +268,13 @@ associations are correctly defined.
|
||||
|
||||
You can either use the Doctrine Command Line Tool:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
doctrine orm:validate-schema
|
||||
|
||||
Or you can trigger the validation manually:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
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
|
||||
the ``Product`` so it is unidirectional.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @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
|
||||
it is bidirectional.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @Entity */
|
||||
@ -409,7 +411,7 @@ One-To-One, Self-referencing
|
||||
You can easily have self referencing one-to-one relationships like
|
||||
below.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @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
|
||||
association:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @Entity */
|
||||
@ -516,7 +518,7 @@ Many-To-One, Unidirectional
|
||||
You can easily implement a many-to-one unidirectional association
|
||||
with the following:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @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
|
||||
class:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @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
|
||||
database perspective is known as an adjacency list approach.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @Entity */
|
||||
@ -670,7 +672,7 @@ Real many-to-many associations are less common. The following
|
||||
example shows a unidirectional association between User and Group
|
||||
entities:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @Entity */
|
||||
@ -734,7 +736,7 @@ Many-To-Many, Bidirectional
|
||||
Here is a similar many-to-many relationship as above except this
|
||||
one is bidirectional.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @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
|
||||
understandable:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class Article
|
||||
@ -823,7 +825,7 @@ understandable:
|
||||
This allows to group the tag adding on the ``Article`` side of the
|
||||
association:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
field named ``$friendsWithMe`` and ``$myFriends``.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @Entity */
|
||||
@ -899,7 +901,7 @@ collection.
|
||||
Additional to any ``@OneToMany`` or ``@ManyToMany`` annotation you
|
||||
can specify the ``@OrderBy`` in the following way:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @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
|
||||
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
|
||||
|
||||
However the following:
|
@ -23,7 +23,8 @@ chapters for XML and YAML mapping, respectively.
|
||||
.. note::
|
||||
|
||||
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
|
||||
in an instance of the ``Doctrine\ORM\Mapping\ClassMetadata`` class
|
||||
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
|
||||
``@Entity`` marker annotation.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @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
|
||||
``@Table`` annotation as follows:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -161,7 +162,7 @@ since it is the most flexible.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @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
|
||||
follows:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @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
|
||||
you wish. Here is an example skeleton of such a custom type class:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
know about it. This can be achieved through the
|
||||
``Doctrine\DBAL\Configuration#setCustomTypes(array $types)``
|
||||
method.
|
||||
|
||||
.. note::
|
||||
|
||||
``Doctrine\ORM\Configuration`` is a subclass of
|
||||
``Doctrine\DBAL\Configuration``, so the methods are available on
|
||||
your ORM Configuration instance as well.
|
||||
method. ``Doctrine\ORM\Configuration`` is a subclass of
|
||||
``Doctrine\DBAL\Configuration``, so the methods are available on
|
||||
your ORM Configuration instance as well.
|
||||
|
||||
|
||||
Here is an example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// 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
|
||||
can use your new type in your mapping like this:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
additionally register this mapping with your database platform:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
annotation. Here is an example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
like this:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
besides specifying the sequence's name:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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.*
|
||||
|
||||
**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
|
||||
statement. For a database schema created manually (and not
|
||||
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
|
||||
backticks. Here is an example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @Column(name="`number`", type="integer") */
|
@ -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
|
||||
internally but also mean more work during ``flush``.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$batchSize = 20;
|
||||
@ -54,7 +54,7 @@ DQL UPDATE
|
||||
The by far most efficient way for bulk updates is to use a DQL
|
||||
UPDATE query. Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
with the batching strategy that was already used for bulk inserts:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$batchSize = 20;
|
||||
@ -87,7 +87,9 @@ with the batching strategy that was already used for bulk inserts:
|
||||
++$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
|
||||
result sets is not suitable for incremental hydration.
|
||||
|
||||
@ -107,7 +109,7 @@ DELETE query.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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.
|
||||
The following example shows how to do this:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$batchSize = 20;
|
||||
@ -137,7 +139,9 @@ The following example shows how to do this:
|
||||
++$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
|
||||
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
|
||||
problems using the following approach:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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]);
|
||||
}
|
||||
|
||||
**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
|
||||
result sets is not suitable for incremental hydration.
|
||||
|
@ -85,7 +85,7 @@ Initialize collections in the constructor
|
||||
It is recommended best practice to initialize any business
|
||||
collections in entities in the constructor. Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace MyProject\Model;
|
@ -47,14 +47,14 @@ APC
|
||||
|
||||
In order to use the APC cache driver you must have it compiled and
|
||||
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
|
||||
can use it as well as how to install it.
|
||||
|
||||
Below is a simple example of how you could use the APC cache driver
|
||||
by itself.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$cacheDriver = new \Doctrine\Common\Cache\ApcCache();
|
||||
@ -65,14 +65,14 @@ Memcache
|
||||
|
||||
In order to use the Memcache cache driver you must have it compiled
|
||||
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
|
||||
you can use it as well as how to install it.
|
||||
|
||||
Below is a simple example of how you could use the Memcache cache
|
||||
driver by itself.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
driver by itself.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
``ArrayCache`` implementation as our example here.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
``save()`` method.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$cacheDriver->save('cache_id', 'my_data');
|
||||
@ -136,7 +136,7 @@ below.
|
||||
You can save any type of data whether it be a string, array,
|
||||
object, etc.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
of the cache entry.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
``contains()`` which is the ID of the cache entry.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$array = $cacheDriver->fetch('my_array');
|
||||
@ -184,7 +184,7 @@ you can delete all entries.
|
||||
By Cache ID
|
||||
^^^^^^^^^^^
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$cacheDriver->delete('my_array');
|
||||
@ -192,7 +192,7 @@ By Cache ID
|
||||
You can also pass wild cards to the ``delete()`` method and it will
|
||||
return an array of IDs that were matched and deleted.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
regular expression to delete cache entries.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
faster if you have many cache entries.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
suffix.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$deleted = $cacheDriver->deleteBySuffix('_my_account');
|
||||
@ -238,7 +238,7 @@ All
|
||||
If you simply want to delete all cache entries you can do so with
|
||||
the ``deleteAll()`` method.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$deleted = $cacheDriver->deleteAll();
|
||||
@ -249,12 +249,14 @@ Counting
|
||||
If you want to count how many entries are stored in the cache
|
||||
driver instance you can use the ``count()`` method.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
echo $cacheDriver->count();
|
||||
|
||||
**NOTE** In order to use ``deleteByRegex()``, ``deleteByPrefix()``,
|
||||
.. note::
|
||||
|
||||
In order to use ``deleteByRegex()``, ``deleteByPrefix()``,
|
||||
``deleteBySuffix()``, ``deleteAll()``, ``count()`` or ``getIds()``
|
||||
you must enable an option for the cache driver to manage your cache
|
||||
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
|
||||
``setNamespace()`` method.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
use on your ORM configuration.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
cache implementation.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
the result cache.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
result cache driver.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
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
|
||||
``setResultCacheLifetime()`` method.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
yourself with the ``setResultCacheId()`` method.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
the second and third argument to ``useResultCache()``.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
first.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ ./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.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ ./doctrine clear-cache --query
|
||||
|
||||
To clear the metadata cache use the ``--metadata`` option.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ ./doctrine clear-cache --metadata
|
||||
|
||||
To clear the result cache use the ``--result`` option.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ ./doctrine clear-cache --result
|
||||
|
||||
@ -435,29 +439,31 @@ clear.
|
||||
Just like the API of the cache drivers you can clear based on an
|
||||
ID, regular expression, prefix or suffix.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ ./doctrine clear-cache --result --id=cache_id
|
||||
|
||||
Or if you want to clear based on a regular expressions.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ ./doctrine clear-cache --result --regex=users_.*
|
||||
|
||||
Or with a prefix.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ ./doctrine clear-cache --result --prefix=users_
|
||||
|
||||
And finally with a suffix.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ ./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
|
||||
necessary to be specific about what you clear. You only ever need
|
||||
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.
|
||||
|
||||
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>`_.
|
||||
|
||||
|
@ -46,7 +46,7 @@ them to EntityManager#persist().
|
||||
|
||||
This policy can be configured as follows:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -68,7 +68,7 @@ the ``NotifyPropertyChanged`` interface from the Doctrine
|
||||
namespace. As a guideline, such an implementation can look as
|
||||
follows:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
behaviour:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// ...
|
@ -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
|
||||
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
|
||||
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
|
||||
@ -44,7 +46,7 @@ different types of Doctrine Installations:
|
||||
PEAR or Tarball Download
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// test.php
|
||||
@ -59,7 +61,7 @@ Git
|
||||
The Git bootstrap assumes that you have fetched the related
|
||||
packages through ``git submodule update --init``
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?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
|
||||
Tool or the YAML Mapping driver:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// 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
|
||||
connection parameters:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\ORM\EntityManager,
|
||||
@ -145,7 +147,9 @@ connection parameters:
|
||||
|
||||
$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
|
||||
parts in Doctrine that are optimized for caching are the metadata
|
||||
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***)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$config->setProxyDir($dir);
|
||||
@ -181,7 +185,7 @@ down.
|
||||
Proxy Namespace (***REQUIRED***)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$config->setProxyNamespace($namespace);
|
||||
@ -194,7 +198,7 @@ Doctrine, refer to the "Proxy Objects" section further down.
|
||||
Metadata Driver (***REQUIRED***)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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 ``Doctrine\ORM\Configuration``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$driverImpl = $config->newDefaultAnnotationDriver('/path/to/lib/MyProject/Entities');
|
||||
@ -236,7 +240,7 @@ directories of Entities.
|
||||
Metadata Cache (***RECOMMENDED***)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$config->setMetadataCacheImpl($cache);
|
||||
@ -265,7 +269,7 @@ per-request basis.
|
||||
Query Cache (***RECOMMENDED***)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$config->setQueryCacheImpl($cache);
|
||||
@ -295,7 +299,7 @@ per-request basis.
|
||||
SQL Logger (***Optional***)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$config->setSQLLogger($logger);
|
||||
@ -311,7 +315,7 @@ implementation that logs to the standard output using ``echo`` and
|
||||
Auto-generating Proxy Classes (***OPTIONAL***)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
identifier. You could simply do this:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
controls this behavior is:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
proxy classes like so:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ ./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
|
||||
aggregate these drivers based on namespaces:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$chain = new DriverChain();
|
@ -1,17 +1,18 @@
|
||||
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
|
||||
**Q**uery **L**anguage (HQL) or the **J**ava **P**ersistence
|
||||
**Q**uery **L**anguage (JPQL).
|
||||
Query Language (HQL) or the Java Persistence Query Language (JPQL).
|
||||
|
||||
In essence, DQL provides powerful querying capabilities over your
|
||||
object model. Imagine all your objects lying around in some storage
|
||||
(like an object database). When writing DQL queries, think about
|
||||
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
|
||||
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,
|
||||
@ -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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$query = $em->createQuery('SELECT u FROM MyProject\Model\User u WHERE u.age > 20');
|
||||
@ -115,7 +116,7 @@ Example:
|
||||
|
||||
Regular join of the address:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$query = $em->createQuery('SELECT u FROM MyProject\Model\User u');
|
||||
@ -173,7 +174,7 @@ Hydrate all User entities:
|
||||
|
||||
Retrieve the IDs of all CmsUsers:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
users instance:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$query = $em->createQuery('SELECT u FROM ForumUser u ORDER BY u.id DESC');
|
||||
@ -241,7 +242,7 @@ Or in Descending Order:
|
||||
|
||||
Using Aggregate Functions:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$query = $em->createQuery('SELECT COUNT(u.id) FROM Entities\User u');
|
||||
@ -249,7 +250,7 @@ Using Aggregate Functions:
|
||||
|
||||
With WHERE Clause and Positional Parameter:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$query = $em->createQuery('SELECT COUNT(DISTINCT u.name) FROM CmsUser');
|
||||
@ -281,7 +282,7 @@ With COUNT DISTINCT:
|
||||
|
||||
With Arithmetic Expression in WHERE clause:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
article-ids:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: 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');
|
||||
@ -314,7 +315,7 @@ Using several Fetch JOINs:
|
||||
|
||||
BETWEEN in WHERE clause:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$query = $em->createQuery('SELECT u.name FROM CmsUser u WHERE u.id IN(46)');
|
||||
@ -344,7 +345,7 @@ IN() Expression:
|
||||
|
||||
CONCAT() DQL Function:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
hierarchies:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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``
|
||||
DQL keyword:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
then phonenumber-id:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
array
|
||||
0 =>
|
||||
@ -543,7 +544,7 @@ Arithmetic operators
|
||||
|
||||
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
|
||||
|
||||
@ -582,7 +583,7 @@ parser with own specialized platform functions.
|
||||
|
||||
You can register custom DQL functions in your ORM Configuration:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
classes have to implement the base class :
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
\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
|
||||
scenario it is a generic Person and Employee example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace Entities;
|
||||
@ -704,7 +705,7 @@ entities looks like the following:
|
||||
Now when persist a new ``Employee`` instance it will set the
|
||||
discriminator value for us automatically:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
``SINGLE_TABLE`` to ``JOINED``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -789,7 +790,7 @@ query. You create a Query instance be calling
|
||||
Alternatively you can create an empty ``Query`` instance and invoke
|
||||
``Query#setDql($dql)`` afterwards. Here are some examples:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $em instanceof EntityManager
|
||||
@ -821,9 +822,11 @@ the Query class. Here they are:
|
||||
array) that is largely interchangeable with the object graph
|
||||
generated by ``Query#getResultList()`` for read-only purposes.
|
||||
|
||||
**NOTE** An array graph can differ from the corresponding object
|
||||
graph in certain scenarios due to the difference of the identity
|
||||
semantics between arrays and objects.
|
||||
.. note::
|
||||
|
||||
An array graph can differ from the corresponding object
|
||||
graph in certain scenarios due to the difference of the identity
|
||||
semantics between arrays and objects.
|
||||
|
||||
|
||||
|
||||
@ -862,7 +865,7 @@ order to accommodate for the scalar values.
|
||||
|
||||
A pure result usually looks like this:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
array
|
||||
[0] => Object
|
||||
@ -873,7 +876,7 @@ A pure result usually looks like this:
|
||||
A mixed result on the other hand has the following general
|
||||
structure:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
array
|
||||
array
|
||||
@ -900,7 +903,7 @@ clause, we get a mixed result.
|
||||
|
||||
Here is how the result could look like:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
foreach ($results as $row) {
|
||||
@ -944,7 +947,7 @@ Object Hydration
|
||||
|
||||
Object hydration hydrates the result set into the object graph:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
is hydrated into an array that represents the object graph:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$users = $query->getArrayResult();
|
||||
@ -975,7 +978,7 @@ Scalar Hydration
|
||||
If you want to return a flat rectangular result set instead of an
|
||||
object graph you can use scalar hydration:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
single scalar hydration:
|
||||
|
||||
::
|
||||
.. code-block:: 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');
|
||||
@ -1005,7 +1008,7 @@ single scalar hydration:
|
||||
|
||||
You can use the ``getSingleScalarResult()`` shortcut as well:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$numArticles = $query->getSingleScalarResult();
|
||||
@ -1016,7 +1019,7 @@ Custom Hydration Modes
|
||||
You can easily add your own custom hydration modes by first
|
||||
creating a class which extends ``AbstractHydrator``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$em->getConfiguration()->addCustomHydrationMode('CustomHydrator', 'MyProject\Hydrators\CustomHydrator');
|
||||
|
||||
Now the hydrator is ready to be used in your queries:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
Result Cache API:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$query = $em->createQuery('SELECT u FROM MyProject\Model\User u WHERE u.id = ?1');
|
||||
@ -1229,14 +1232,14 @@ Terminals
|
||||
Query Language
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement
|
||||
|
||||
Statements
|
||||
~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
SelectStatement ::= SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
|
||||
UpdateStatement ::= UpdateClause [WhereClause]
|
||||
@ -1245,7 +1248,7 @@ Statements
|
||||
Identifiers
|
||||
~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
/* Alias Identification usage (the "u" of "u.name") */
|
||||
IdentificationVariable ::= identifier
|
||||
@ -1282,7 +1285,7 @@ Identifiers
|
||||
Path Expressions
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
/* "u.Group" or "u.Phonenumbers" declarations */
|
||||
JoinAssociationPathExpression ::= IdentificationVariable "." (CollectionValuedAssociationField | SingleValuedAssociationField)
|
||||
@ -1311,7 +1314,7 @@ Path Expressions
|
||||
Clauses
|
||||
~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
SelectClause ::= "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}*
|
||||
SimpleSelectClause ::= "SELECT" ["DISTINCT"] SimpleSelectExpression
|
||||
@ -1328,7 +1331,7 @@ Clauses
|
||||
Items
|
||||
~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
UpdateItem ::= IdentificationVariable "." (StateField | SingleValuedAssociationField) "=" NewValue
|
||||
OrderByItem ::= (ResultVariable | StateFieldPathExpression) ["ASC" | "DESC"]
|
||||
@ -1338,7 +1341,7 @@ Items
|
||||
From, Join and Index by
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {JoinVariableDeclaration}*
|
||||
SubselectIdentificationVariableDeclaration ::= IdentificationVariableDeclaration | (AssociationPathExpression ["AS"] AliasIdentificationVariable)
|
||||
@ -1351,7 +1354,7 @@ From, Join and Index by
|
||||
Select Expressions
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
SelectExpression ::= IdentificationVariable | PartialObjectExpression | (AggregateExpression | "(" Subselect ")" | FunctionDeclaration | ScalarExpression) [["AS"] AliasResultVariable]
|
||||
SimpleSelectExpression ::= ScalarExpression | IdentificationVariable |
|
||||
@ -1362,7 +1365,7 @@ Select Expressions
|
||||
Conditional Expressions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
ConditionalExpression ::= ConditionalTerm {"OR" ConditionalTerm}*
|
||||
ConditionalTerm ::= ConditionalFactor {"AND" ConditionalFactor}*
|
||||
@ -1375,7 +1378,7 @@ Conditional Expressions
|
||||
Collection Expressions
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
EmptyCollectionComparisonExpression ::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY"
|
||||
CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression
|
||||
@ -1383,7 +1386,7 @@ Collection Expressions
|
||||
Literal Values
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
Literal ::= string | char | integer | float | boolean
|
||||
InParameter ::= Literal | InputParameter
|
||||
@ -1391,7 +1394,7 @@ Literal Values
|
||||
Input Parameter
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
InputParameter ::= PositionalParameter | NamedParameter
|
||||
PositionalParameter ::= "?" integer
|
||||
@ -1400,7 +1403,7 @@ Input Parameter
|
||||
Arithmetic Expressions
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
ArithmeticExpression ::= SimpleArithmeticExpression | "(" Subselect ")"
|
||||
SimpleArithmeticExpression ::= ArithmeticTerm {("+" | "-") ArithmeticTerm}*
|
||||
@ -1413,7 +1416,7 @@ Arithmetic Expressions
|
||||
Scalar and Type Expressions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary | StateFieldPathExpression
|
||||
BooleanPrimary | CaseExpression | EntityTypeExpression
|
||||
@ -1440,7 +1443,7 @@ Scalar and Type Expressions
|
||||
Aggregate Expressions
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
AggregateExpression ::= ("AVG" | "MAX" | "MIN" | "SUM") "(" ["DISTINCT"] StateFieldPathExpression ")" |
|
||||
"COUNT" "(" ["DISTINCT"] (IdentificationVariable | SingleValuedPathExpression) ")"
|
||||
@ -1450,7 +1453,7 @@ Other Expressions
|
||||
|
||||
QUANTIFIED/BETWEEN/COMPARISON/LIKE/NULL/EXISTS
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")"
|
||||
BetweenExpression ::= ArithmeticExpression ["NOT"] "BETWEEN" ArithmeticExpression "AND" ArithmeticExpression
|
||||
@ -1464,7 +1467,7 @@ QUANTIFIED/BETWEEN/COMPARISON/LIKE/NULL/EXISTS
|
||||
Functions
|
||||
~~~~~~~~~
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
FunctionDeclaration ::= FunctionsReturningStrings | FunctionsReturningNumerics | FunctionsReturningDateTime
|
||||
|
@ -12,7 +12,7 @@ central point of Doctrine's event listener system. Listeners are
|
||||
registered on the manager and events are dispatched through the
|
||||
manager.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$evm = new EventManager();
|
||||
@ -20,7 +20,7 @@ manager.
|
||||
Now we can add some event listeners to the ``$evm``. Let's create a
|
||||
``EventTest`` class to play around with.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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()``
|
||||
method.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
array of events it should be subscribed to.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
notified for that event.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$evm->dispatchEvent(TestEvent::preFoo);
|
||||
@ -106,7 +106,7 @@ notified for that event.
|
||||
Now you can test the ``$eventSubscriber`` instance to see if the
|
||||
``preFoo()`` method was invoked.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
ORM package.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
event occurs.
|
||||
|
||||
::
|
||||
.. code-block:: 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
|
||||
can do it with the following.
|
||||
|
||||
::
|
||||
.. code-block:: yaml
|
||||
|
||||
[yml]
|
||||
User:
|
||||
type: entity
|
||||
fields:
|
||||
@ -282,9 +281,8 @@ can do it with the following.
|
||||
|
||||
XML would look something like this:
|
||||
|
||||
::
|
||||
.. code-block:: xml
|
||||
|
||||
[xml]
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<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``
|
||||
model.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// ...
|
||||
@ -345,7 +343,7 @@ to write your own listener.
|
||||
To register an event listener you have to hook it into the
|
||||
EventManager that is passed to the EntityManager factory:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
EntityManager was created:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
mentioned sets. See this example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class FlushExampleListener
|
||||
@ -513,7 +511,7 @@ available on the ``PreUpdateEventArgs``:
|
||||
|
||||
A simple example for this event looks like:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
lifecycle callback when there are expensive validations to call:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
process and manipulate the instance.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$test = new EventTest();
|
@ -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
|
||||
request and can greatly improve performance.
|
||||
|
||||
.. note::
|
||||
|
||||
"If you care about performance and don't use a bytecode
|
||||
cache then you don't really care about performance. Please get one
|
||||
and start using it." (Stas Malyshev, Core Contributor to PHP and
|
||||
Zend Employee).
|
||||
and start using it."
|
||||
|
||||
*Stas Malyshev, Core Contributor to PHP and Zend Employee*
|
||||
|
||||
|
||||
Metadata and Query caches
|
@ -24,7 +24,7 @@ appear in the middle of an otherwise mapped inheritance hierarchy
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @MappedSuperclass */
|
||||
@ -77,7 +77,7 @@ discriminator column is used.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace MyProject\Model;
|
||||
@ -166,7 +166,7 @@ way to achieve polymorphic queries with Class Table Inheritance.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace MyProject\Model;
|
@ -99,21 +99,21 @@ PEAR command line installation utility.
|
||||
To install just the ``Common`` package you can run the following
|
||||
command:
|
||||
|
||||
::
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo pear install pear.doctrine-project.org/DoctrineCommon-<version>
|
||||
|
||||
If you want to use the Doctrine Database Abstraction Layer you can
|
||||
install it with the following command.
|
||||
|
||||
::
|
||||
.. code-block:: bash
|
||||
|
||||
$ 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
|
||||
it with the following command.
|
||||
|
||||
::
|
||||
.. code-block:: bash
|
||||
|
||||
$ 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
|
||||
like the following:
|
||||
|
||||
::
|
||||
.. code-block:: bash
|
||||
|
||||
$ 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
|
||||
the ``ClassLoader`` with the following code.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?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
|
||||
run the ``doctrine`` command you will see what you can do with it.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ doctrine
|
||||
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
|
||||
GitHub.com:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ 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
|
||||
dependencies:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ git submodule init
|
||||
$ git submodule update
|
||||
@ -238,7 +238,7 @@ Subversion
|
||||
If you prefer subversion you can also checkout the code from
|
||||
GitHub.com through the subversion protocol:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ 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
|
||||
following structure:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
sandbox/
|
||||
Entities/
|
||||
@ -345,7 +345,7 @@ You should see the output "User saved!".
|
||||
|
||||
You should get the following output:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
array(1) {
|
||||
[0]=>
|
||||
@ -394,11 +394,8 @@ Can you **find** the easier way?).
|
||||
|
||||
6) Explore Doctrine 2!
|
||||
|
||||
See the following links if you want to start with more complex
|
||||
tutorials rather than reading the manual:
|
||||
|
||||
|
||||
- Doctrine2 Cookbook:
|
||||
`Getting Started XML Edition <http://www.doctrine-project.org/projects/orm/2.0/docs/cookbook/getting-started-xml-edition/en>`_
|
||||
Instead of reading through the reference manual we also recommend to look at the tutorials:
|
||||
|
||||
:doc:`Getting Started XML Edition <../tutorials/getting-started-xml-edition>`
|
||||
|
||||
|
@ -60,7 +60,7 @@ the fundamental difference between the two different
|
||||
``product_attributes`` tables you should see how they translate
|
||||
into a Doctrine Mapping (Using Annotations):
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -127,7 +127,7 @@ possible either. See the following example:
|
||||
|
||||
This schema should be mapped to a Product Entity as follows:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
class Product
|
||||
{
|
@ -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
|
||||
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
|
||||
happens once. You can configure the metadata cache implementation
|
||||
using the ``setMetadataCacheImpl()`` method on the
|
||||
``Doctrine\ORM\Configuration`` class:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
``Doctrine\ORM\Mapping\Driver`` namespace:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
implements the ``Driver`` interface:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
the ``AbstractFileDriver`` implementation for you to extend from:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
class described inside where namespace separators are replaced by
|
||||
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
|
||||
it with the ``setMetadataDriverImpl()`` method:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
the ``ClassMetadataFactory``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
iterate over them:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
foreach ($class->fieldMappings as $fieldMapping) {
|
@ -67,7 +67,7 @@ element in the transformed result. You add an entity result through
|
||||
``ResultSetMapping#addEntityResult()``. Let's take a look at the
|
||||
method signature in detail:
|
||||
|
||||
::
|
||||
.. code-block:: 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
|
||||
the method signature in detail:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -130,7 +130,7 @@ inherently bound to entity results. You add a field result through
|
||||
``ResultSetMapping#addFieldResult()``. Again, let's examine the
|
||||
method signature in detail:
|
||||
|
||||
::
|
||||
.. code-block:: 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
|
||||
detail:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -185,7 +185,7 @@ result sets. To add a column as a meta result use
|
||||
``ResultSetMapping#addMetaResult()``. The method signature in
|
||||
detail:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -210,7 +210,7 @@ Discriminator Column
|
||||
When joining an inheritance tree you have to give Doctrine a hint
|
||||
which meta-column is the discriminator column of this tree.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/**
|
||||
@ -234,7 +234,7 @@ looking at some examples.
|
||||
First a basic example that describes the mapping of a single
|
||||
entity.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// Equivalent DQL query: "select u from User u where u.name=?1"
|
||||
@ -251,7 +251,7 @@ entity.
|
||||
|
||||
The result would look like this:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
array(
|
||||
[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
|
||||
thus owns the foreign key.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// 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
|
||||
associations that are lazy.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// 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
|
||||
to map the hierarchy (both use a discriminator column).
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// Equivalent DQL query: "select u from User u where u.name=?1"
|
@ -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``
|
||||
keyword as follows:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$q = $em->createQuery("select partial u.{id,name} from MyApp\Domain\User u");
|
@ -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
|
||||
for an entity you can do so by using the ``PHPDriver``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
``PHPDriver`` instance:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
``/path/to/php/mapping/files`` folder:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?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
|
||||
``ClassMetadataFactory`` caches it for later retrieval:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$class = $em->getMetadataFor('Entities\User');
|
||||
$class = $em->getClassMetadata('Entities\User');
|
||||
// or
|
||||
$class = $em->getMetadataFactory()->getMetadataFor('Entities\User');
|
||||
|
||||
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.
|
||||
For this you just need to use the ``StaticPHPDriver``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
``loadMetadata($metadata)`` on your entity:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace Entities;
|
@ -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
|
||||
how to build a ``QueryBuilder`` object:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
example is to inspect what type of object the ``QueryBuilder`` is.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
you finish building your DQL.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $qb instanceof QueryBuilder
|
||||
@ -92,7 +92,7 @@ of DQL. It takes 3 parameters: ``$dqlPartName``, ``$dqlPart`` and
|
||||
|
||||
-
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
allowed. Binding parameters can simply be achieved as follows:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
alternative syntax is available:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
following syntax:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $qb instanceof QueryBuilder
|
||||
@ -157,7 +157,7 @@ following syntax:
|
||||
Getting already bound parameters is easy - simply use the above
|
||||
mentioned syntax with "getParameter()" or "getParameters()":
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
``Doctrine\ORM\Query\Expr\Expr\*`` classes:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
set of useful static methods to help building queries:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
complete list of supported helper methods available:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
re-written using ``QueryBuilder`` helper methods:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
suggested standard way to build queries:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $qb instanceof QueryBuilder
|
||||
@ -413,7 +413,7 @@ suggested standard way to build queries:
|
||||
Here is a complete list of helper methods available in
|
||||
``QueryBuilder``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class QueryBuilder
|
@ -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
|
||||
about the use of generate entities for example, you can call:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
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
|
||||
dealing exclusively with DBAL, the ConnectionHelper is required:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
required:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
typical ``cli-config.php`` file looks as follows:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?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
|
||||
do:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$cli->addCommand(new \MyProject\Tools\Console\Commands\MyCustomCommand());
|
||||
@ -119,7 +119,7 @@ do:
|
||||
Additionally, include multiple commands (and overriding previously
|
||||
defined ones) is possible through the command:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
array of ``ClassMetadataInfo`` instances.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
tables of the current model to clean up with orphaned tables.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
``ClassMetdataInfo`` instances.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$tool->updateSchema($classes);
|
||||
@ -242,20 +242,20 @@ use the ``schema-tool`` command.
|
||||
|
||||
To create the schema use the ``create`` command:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ php doctrine orm:schema-tool:create
|
||||
|
||||
To drop the schema use the ``drop`` command:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ php doctrine orm:schema-tool:drop
|
||||
|
||||
If you want to drop and then recreate the schema then use both
|
||||
options:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ php doctrine orm:schema-tool:drop
|
||||
$ php doctrine orm:schema-tool:create
|
||||
@ -263,14 +263,14 @@ options:
|
||||
As you would think, if you want to update your schema use the
|
||||
``update`` command:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ php doctrine orm:schema-tool:update
|
||||
|
||||
All of the above commands also accept a ``--dump-sql`` option that
|
||||
will output the SQL for the ran operation.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ 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
|
||||
instances for the different formats:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
example, the yml exporter:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$exporter = $cme->getExporter('yml', '/path/to/export/yml');
|
||||
|
||||
Now you can export some ``ClassMetadata`` instances:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
convert to and the path to generate it:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ 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
|
||||
``DatabaseDriver``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
to yml:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$exporter = $cme->getExporter('yml', '/path/to/export/yml');
|
||||
@ -363,11 +363,11 @@ to yml:
|
||||
You can also reverse engineer a database using the
|
||||
``orm:convert-mapping`` command:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$ php doctrine orm:convert-mapping --from-database yml /path/to/mapping-path-converted-to-yml
|
||||
|
||||
.. warning::
|
||||
.. note::
|
||||
|
||||
Reverse Engineering is not always working perfectly
|
||||
depending on special cases. It will only detect Many-To-One
|
@ -33,7 +33,7 @@ The first approach is to use the implicit transaction handling
|
||||
provided by the Doctrine ORM EntityManager. Given the following
|
||||
code snippet, without any explicit transaction demarcation:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
looks like this:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
previously shown code looks as follows:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
example we'll use an integer.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class User
|
||||
@ -185,7 +185,7 @@ example we'll use an integer.
|
||||
Alternatively a datetime type can be used (which maps to an SQL
|
||||
timestamp or datetime):
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class User
|
||||
@ -220,7 +220,7 @@ locking exception:
|
||||
You can always verify the version of an entity during a request
|
||||
either when calling ``EntityManager#find()``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\DBAL\LockMode;
|
||||
@ -241,7 +241,7 @@ either when calling ``EntityManager#find()``:
|
||||
|
||||
Or you can use ``EntityManager#lock()`` to find out:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use Doctrine\DBAL\LockMode;
|
||||
@ -291,7 +291,7 @@ updates you wanted to prevent with Optimistic Locking.
|
||||
|
||||
See the example code, The form (GET Request):
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$post = $em->find('BlogPost', 123456);
|
||||
@ -301,7 +301,7 @@ See the example code, The form (GET Request):
|
||||
|
||||
And the change headline action (POST Request):
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$postId = (int)$_GET['id'];
|
@ -7,17 +7,14 @@ collections of objects. When it comes to persistence, it is
|
||||
important to understand three main things:
|
||||
|
||||
|
||||
- The concept of owning and inverse sides in bidirectional
|
||||
associations as described
|
||||
`here <http://www.doctrine-project.org/documentation/manual/2_0/en/association-mapping#owning-side-and-inverse-side>`_.
|
||||
- The :ref:`concept of owning and inverse sides <association-mapping-owning-inverse>`
|
||||
in bidirectional associations.
|
||||
- If an entity is removed from a collection, the association is
|
||||
removed, not the entity itself. A collection of entities always
|
||||
only represents the association to the containing entities, not the
|
||||
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.
|
||||
`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
|
||||
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
|
||||
information about its type and if its the owning or inverse side.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @Entity */
|
||||
@ -137,7 +134,7 @@ Establishing an association between two entities is
|
||||
straight-forward. Here are some examples for the unidirectional
|
||||
relations of the ``User``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class User
|
||||
@ -155,7 +152,7 @@ relations of the ``User``:
|
||||
The interaction code would then look like in the following snippet
|
||||
(``$em`` here is an instance of the EntityManager):
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
fields on both sides:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
element. Here are some examples:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// Remove by Elements
|
||||
@ -296,7 +293,7 @@ association is maintained.
|
||||
The following code shows updates to the previous User and Comment
|
||||
example that encapsulate much of the association management code:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class User
|
||||
@ -362,7 +359,7 @@ the details inside the classes can be challenging.
|
||||
association management. For example:
|
||||
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class User {
|
||||
@ -392,7 +389,7 @@ code.
|
||||
Using the User-Comment entities from above, a very simple example
|
||||
can show the possible caveats you can encounter:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
following code:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$user = new User();
|
||||
@ -459,7 +456,7 @@ as well.
|
||||
More complicated is the deletion of all a users comments when he is
|
||||
removed from the system:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
$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"
|
||||
and the "remove" operation.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class User
|
@ -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
|
||||
headline "Hello World" with the ID 1234:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
code:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
if ($article === $article2) {
|
||||
@ -85,7 +85,7 @@ want.
|
||||
Take the following example of a single ``Article`` entity fetched
|
||||
from newly opened EntityManager.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
/** @Entity */
|
||||
@ -127,7 +127,7 @@ EntityManager and load their state from the database.
|
||||
This lazy-loading process happens behind the scenes, hidden from
|
||||
your code. See the following code:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
methods along the lines of the ``getName()`` method shown below:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
``EntityManager#flush()`` is invoked.
|
||||
|
||||
.. warning::
|
||||
.. note::
|
||||
|
||||
Invoking the ``persist`` method on an entity does NOT
|
||||
cause an immediate SQL INSERT to be issued on the database.
|
||||
@ -208,7 +208,7 @@ be properly synchronized with the database when
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$user = new User;
|
||||
@ -216,7 +216,7 @@ Example:
|
||||
$em->persist($user);
|
||||
$em->flush();
|
||||
|
||||
.. warning::
|
||||
.. note::
|
||||
|
||||
Generated entity identifiers / primary keys are
|
||||
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
|
||||
``EntityManager#flush()`` is invoked.
|
||||
|
||||
.. warning::
|
||||
.. note::
|
||||
|
||||
Just like ``persist``, invoking ``remove`` on an entity
|
||||
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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$em->remove($user);
|
||||
@ -332,7 +332,7 @@ Doctrine will not hold on to any references to a detached entity.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$em->detach($entity);
|
||||
@ -381,7 +381,7 @@ this entity and this copy will subsequently be returned.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$detachedEntity = unserialize($serializedEntity); // some detached entity
|
||||
@ -389,7 +389,9 @@ Example:
|
||||
// $entity now refers to the fully managed copy returned by the merge operation.
|
||||
// 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
|
||||
reason for this is, if you serialize a class that was a proxy
|
||||
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
|
||||
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::
|
||||
|
||||
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:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
during development.
|
||||
|
||||
.. warning::
|
||||
.. note::
|
||||
|
||||
Do not invoke ``flush`` after every change to an entity
|
||||
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
|
||||
instance the EntityManager is currently using.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
marked as INTERNAL by not using them and carefully read the API
|
||||
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
|
||||
underlying ``UnitOfWork``:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
switch ($em->getUnitOfWork()->getEntityState($entity)) {
|
||||
@ -610,7 +621,7 @@ identifier / primary key using the
|
||||
``EntityManager#find($entityName, $id)`` method. Here is an
|
||||
example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $em instanceof EntityManager
|
||||
@ -622,7 +633,7 @@ instance could be found with the given identifier.
|
||||
Essentially, ``EntityManager#find()`` is just a shortcut for the
|
||||
following:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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``
|
||||
methods on a repository as follows:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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
|
||||
examples are equivalent:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// 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
|
||||
``EntityManager#createQuery($dql)``. Here is a simple example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $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,
|
||||
aggregates, subqueries and much more. Detailed information about
|
||||
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
|
||||
are only known at runtime, Doctrine provides the special
|
||||
``Doctrine\ORM\QueryBuilder`` class. More information on
|
||||
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
|
||||
~~~~~~~~~~~~~~~~~
|
||||
@ -742,7 +753,7 @@ applications that require lots of specialized DQL queries using a
|
||||
custom repository is one recommended way of grouping these queries
|
||||
in a central location.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
namespace MyDomain\Model;
|
||||
@ -768,7 +779,7 @@ in a central location.
|
||||
|
||||
You can access your repository now by calling:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $em instanceof EntityManager
|
@ -46,7 +46,7 @@ In order to work, this requires certain conventions:
|
||||
|
||||
-
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
of the constructor, like this:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$config = new \Doctrine\ORM\Configuration();
|
||||
@ -291,9 +291,8 @@ attribute:
|
||||
If you are using the SEQUENCE strategy you can define an additional
|
||||
element to describe the sequence:
|
||||
|
||||
::
|
||||
.. code-block:: xml
|
||||
|
||||
[xml]
|
||||
<entity name="MyProject\User">
|
||||
<id name="id" type="integer" column="user_id">
|
||||
<generator strategy="SEQUENCE" />
|
@ -21,7 +21,7 @@ In order to work, this requires certain conventions:
|
||||
|
||||
-
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
of the constructor, like this:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// $config instanceof Doctrine\ORM\Configuration
|
@ -19,8 +19,7 @@ What are Entities?
|
||||
Entities are lightweight PHP Objects that don't need to extend any
|
||||
abstract base class or interface. An entity class must not be final
|
||||
or contain final methods. Additionally it must not implement
|
||||
**clone nor**wakeup or
|
||||
`do so safely <http://www.doctrine-project.org/documentation/cookbook/2_0/en/implementing-wakeup-or-clone>`_.
|
||||
**clone** nor **wakeup** or :doc:`do so safely <../cookbook/implementing-wakeup-or-clone>`.
|
||||
|
||||
An entity contains persistable properties. A persistable property
|
||||
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
|
||||
following set of classes:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
with the assumptions about related collections:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
the bi-directional reference:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class Bug
|
||||
@ -270,7 +269,7 @@ methods are only used for ensuring consistency of the references.
|
||||
You can see from ``User::addReportedBug()`` and
|
||||
``User::assignedToBug()`` that using this method in userland alone
|
||||
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
|
||||
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
|
||||
the database that points from from Bugs to Products.
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
class Bug
|
||||
@ -360,9 +359,8 @@ configurations.
|
||||
The first discussed definition will be for the Product, since it is
|
||||
the most simple one:
|
||||
|
||||
::
|
||||
.. code-block:: xml
|
||||
|
||||
[xml]
|
||||
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
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:
|
||||
|
||||
::
|
||||
.. code-block:: xml
|
||||
|
||||
[xml]
|
||||
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
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:
|
||||
|
||||
::
|
||||
.. code-block:: xml
|
||||
|
||||
[xml]
|
||||
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
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
|
||||
step:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// Setup Autoloader (1)
|
||||
require '/path/to/lib/Doctrine/Common/ClassLoader.php';
|
||||
$loader = new Doctrine\Common\ClassLoader("Doctrine", '/path/to/Doctrine/trunk/lib/');
|
||||
$loader->register();
|
||||
// See :doc:`Configuration <../reference/configuration>` for up to date autoloading details.
|
||||
|
||||
$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
|
||||
Configuration object. Besides the configuration shown in the next
|
||||
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,
|
||||
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
|
||||
doctrine command. Its a fairly simple file:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
Doctrine command-line tool:
|
||||
|
||||
::
|
||||
.. code-block:: bash
|
||||
|
||||
[console]
|
||||
doctrine@my-desktop> cd myproject/
|
||||
doctrine@my-desktop> doctrine orm:schema-tool:create
|
||||
|
||||
@ -623,7 +616,7 @@ Doctrine command-line tool:
|
||||
your doctrine command-line client.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@ -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
|
||||
either re-create the database:
|
||||
|
||||
::
|
||||
.. code-block:: bash
|
||||
|
||||
[console]
|
||||
doctrine@my-desktop> doctrine orm:schema-tool:drop
|
||||
doctrine@my-desktop> doctrine orm:schema-tool:create
|
||||
|
||||
Or use the update functionality:
|
||||
|
||||
::
|
||||
.. code-block:: bash
|
||||
|
||||
[console]
|
||||
doctrine@my-desktop> doctrine orm:schema-tool:update
|
||||
|
||||
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
|
||||
database. For starters we need a create user use-case:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$newUsername = "beberlei";
|
||||
@ -668,7 +659,7 @@ database. For starters we need a create user use-case:
|
||||
|
||||
Products can also be created:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
code for this scenario may look like this:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
the first read-only use-case:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
can rewrite our code:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
write scenarios:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$bug = $entityManager->find("Bug", (int)$theBugId);
|
||||
@ -881,7 +872,7 @@ write scenarios:
|
||||
However we will soon see another problem with our entities using
|
||||
this approach. Try displaying the engineer's name:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
looks like:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
protected and add getters and setters to get a working example:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
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
|
||||
and usage of bound parameters:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
grouped by product:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$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
|
||||
should be able to close a bug. This looks like:
|
||||
|
||||
::
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$bug = $entityManager->find("Bug", (int)$theBugId);
|
||||
@ -1024,12 +1015,10 @@ improvement compared to updating all the properties.
|
||||
This tutorial is over here, I hope you had fun. Additional content
|
||||
will be added to this tutorial incrementally, topics will include:
|
||||
|
||||
::
|
||||
|
||||
* Entity Repositories
|
||||
* More on Association Mappings
|
||||
* Lifecycle Events triggered in the UnitOfWork
|
||||
* Ordering of Collections
|
||||
* Entity Repositories
|
||||
* More on Association Mappings
|
||||
* Lifecycle Events triggered in the UnitOfWork
|
||||
* Ordering of Collections
|
||||
|
||||
Additional details on all the topics discussed here can be found in
|
||||
the respective manual chapters.
|
@ -1,2 +1,2 @@
|
||||
#!/bin/bash
|
||||
sphinx-build manual/en /var/www/docs
|
||||
sphinx-build en /var/www/docs
|
||||
|
@ -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
|
||||
============================
|
||||
|
||||
|
@ -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
|
@ -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`
|
||||
|
Loading…
x
Reference in New Issue
Block a user