Trying a new generation script
This commit is contained in:
+334
@@ -0,0 +1,334 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Blending the ORM and MongoDB ODM — Doctrine MongoDB ODM 1.1.5 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/bootstrap/css/bootstrap.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/layout.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/configurationblock.css" type="text/css" />
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.1.5',
|
||||
COLLAPSE_MODINDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
};
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script src="../_static/bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
$(document).ready(function() {
|
||||
$("#versions").change(function() {
|
||||
var docsUrl = $(this).val();
|
||||
window.location.href = docsUrl;
|
||||
});
|
||||
});
|
||||
-->
|
||||
</script>
|
||||
<link rel="shortcut icon" href="../_static/doctrine.ico"/>
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="top" title="Doctrine MongoDB ODM 1.1.5 documentation" href="../index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="header">
|
||||
<h1 id="h1title"></h1>
|
||||
<div id="logo">
|
||||
<a href="http://www.doctrine-project.org/">Doctrine - PHP Database Libraries</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav" class="cls">
|
||||
<div class="tl cls">
|
||||
<ul>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/">Home</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/about.html">About</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/projects.html">Projects</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/contribute.html">Contribute</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/community.html">Community</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/archive.html">Blog</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/jira">Development</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content" class="cls">
|
||||
<div class="related">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li><a href="/">Doctrine Homepage</a> »</li>
|
||||
<li><a href="../index.html">Doctrine MongoDB ODM 1.1.5 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
<div class="body" >
|
||||
|
||||
<div class="section" id="blending-the-orm-and-mongodb-odm">
|
||||
<h1>Blending the ORM and MongoDB ODM<a class="headerlink" href="#blending-the-orm-and-mongodb-odm" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Since the start of the <a class="reference external" href="http://www.doctrine-project.org/projects/mongodb_odm">Doctrine MongoDB Object Document Mapper</a> project people have asked how it can be integrated with the <a class="reference external" href="http://www.doctrine-project.org/projects/orm">ORM</a>. This article will demonstrates how you can integrate the two transparently, maintaining a clean domain model.</p>
|
||||
<p>This example will have a <cite>Product</cite> that is stored in MongoDB and the <cite>Order</cite> stored in a MySQL database.</p>
|
||||
<div class="section" id="define-product">
|
||||
<h2>Define Product<a class="headerlink" href="#define-product" title="Permalink to this headline">¶</a></h2>
|
||||
<p>First lets define our <cite>Product</cite> document:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Document */</span>
|
||||
<span class="k">class</span> <span class="nc">Product</span>
|
||||
<span class="p">{</span>
|
||||
<span class="sd">/** @Id */</span>
|
||||
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Field(type="string") */</span>
|
||||
<span class="k">private</span> <span class="nv">$title</span><span class="p">;</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">getId</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">id</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">getTitle</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">title</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">setTitle</span><span class="p">(</span><span class="nv">$title</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="na">title</span> <span class="o">=</span> <span class="nv">$title</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="define-entity">
|
||||
<h2>Define Entity<a class="headerlink" href="#define-entity" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Next create the <cite>Order</cite> entity that has a <cite>$product</cite> and <cite>$productId</cite> property linking it to the <cite>Product</cite> that is stored with MongoDB:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">namespace</span> <span class="nx">Entities</span><span class="p">;</span>
|
||||
|
||||
<span class="k">use</span> <span class="nx">Documents\Product</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/**</span>
|
||||
<span class="sd"> * @Entity</span>
|
||||
<span class="sd"> * @Table(name="orders")</span>
|
||||
<span class="sd"> */</span>
|
||||
<span class="k">class</span> <span class="nc">Order</span>
|
||||
<span class="p">{</span>
|
||||
<span class="sd">/**</span>
|
||||
<span class="sd"> * @Id @Column(type="integer")</span>
|
||||
<span class="sd"> * @GeneratedValue(strategy="AUTO")</span>
|
||||
<span class="sd"> */</span>
|
||||
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/**</span>
|
||||
<span class="sd"> * @Column(type="string")</span>
|
||||
<span class="sd"> */</span>
|
||||
<span class="k">private</span> <span class="nv">$productId</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/**</span>
|
||||
<span class="sd"> * @var Documents\Product</span>
|
||||
<span class="sd"> */</span>
|
||||
<span class="k">private</span> <span class="nv">$product</span><span class="p">;</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">getId</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">id</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">getProductId</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">productId</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">setProduct</span><span class="p">(</span><span class="nx">Product</span> <span class="nv">$product</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="na">productId</span> <span class="o">=</span> <span class="nv">$product</span><span class="o">-></span><span class="na">getId</span><span class="p">();</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="na">product</span> <span class="o">=</span> <span class="nv">$product</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">getProduct</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">product</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="event-subscriber">
|
||||
<h2>Event Subscriber<a class="headerlink" href="#event-subscriber" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Now we need to setup an event subscriber that will set the <cite>$product</cite> property of all <cite>Order</cite> instances to a reference to the document product so it can be lazily loaded when it is accessed the first time. So first register a new event subscriber:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$eventManager</span> <span class="o">=</span> <span class="nv">$em</span><span class="o">-></span><span class="na">getEventManager</span><span class="p">();</span>
|
||||
<span class="nv">$eventManager</span><span class="o">-></span><span class="na">addEventListener</span><span class="p">(</span>
|
||||
<span class="k">array</span><span class="p">(</span><span class="nx">\Doctrine\ORM\Events</span><span class="o">::</span><span class="na">postLoad</span><span class="p">),</span> <span class="k">new</span> <span class="nx">MyEventSubscriber</span><span class="p">(</span><span class="nv">$dm</span><span class="p">)</span>
|
||||
<span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>So now we need to define a class named <cite>MyEventSubscriber</cite> and pass a dependency to the <cite>DocumentManager</cite>. It will have a <cite>postLoad()</cite> method that sets the product document reference:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\DocumentManager</span><span class="p">;</span>
|
||||
<span class="k">use</span> <span class="nx">Doctrine\ORM\Event\LifecycleEventArgs</span><span class="p">;</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">MyEventSubscriber</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">__construct</span><span class="p">(</span><span class="nx">DocumentManager</span> <span class="nv">$dm</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="na">dm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">postLoad</span><span class="p">(</span><span class="nx">LifecycleEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$order</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-></span><span class="na">getEntity</span><span class="p">();</span>
|
||||
<span class="nv">$em</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-></span><span class="na">getEntityManager</span><span class="p">();</span>
|
||||
<span class="nv">$productReflProp</span> <span class="o">=</span> <span class="nv">$em</span><span class="o">-></span><span class="na">getClassMetadata</span><span class="p">(</span><span class="s1">'Entities\Order'</span><span class="p">)</span>
|
||||
<span class="o">-></span><span class="na">reflClass</span><span class="o">-></span><span class="na">getProperty</span><span class="p">(</span><span class="s1">'product'</span><span class="p">);</span>
|
||||
<span class="nv">$productReflProp</span><span class="o">-></span><span class="na">setAccessible</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
|
||||
<span class="nv">$productReflProp</span><span class="o">-></span><span class="na">setValue</span><span class="p">(</span>
|
||||
<span class="nv">$order</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-></span><span class="na">dm</span><span class="o">-></span><span class="na">getReference</span><span class="p">(</span><span class="s1">'Documents\Product'</span><span class="p">,</span> <span class="nv">$order</span><span class="o">-></span><span class="na">getProductId</span><span class="p">())</span>
|
||||
<span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <cite>postLoad</cite> method will be invoked after an ORM entity is loaded from the database. This allows us to use the <cite>DocumentManager</cite> to set the <cite>$product</cite> property with a reference to the <cite>Product</cite> document with the product id we previously stored.</p>
|
||||
</div>
|
||||
<div class="section" id="working-with-products-and-orders">
|
||||
<h2>Working with Products and Orders<a class="headerlink" href="#working-with-products-and-orders" title="Permalink to this headline">¶</a></h2>
|
||||
<p>First create a new <cite>Product</cite>:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$product</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\Documents\Product</span><span class="p">();</span>
|
||||
<span class="nv">$product</span><span class="o">-></span><span class="na">setTitle</span><span class="p">(</span><span class="s1">'Test Product'</span><span class="p">);</span>
|
||||
<span class="nv">$dm</span><span class="o">-></span><span class="na">persist</span><span class="p">(</span><span class="nv">$product</span><span class="p">);</span>
|
||||
<span class="nv">$dm</span><span class="o">-></span><span class="na">flush</span><span class="p">();</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now create a new <cite>Order</cite> and link it to a <cite>Product</cite> in MySQL:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$order</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\Entities\Order</span><span class="p">();</span>
|
||||
<span class="nv">$order</span><span class="o">-></span><span class="na">setProduct</span><span class="p">(</span><span class="nv">$product</span><span class="p">);</span>
|
||||
<span class="nv">$em</span><span class="o">-></span><span class="na">persist</span><span class="p">(</span><span class="nv">$order</span><span class="p">);</span>
|
||||
<span class="nv">$em</span><span class="o">-></span><span class="na">flush</span><span class="p">();</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Later we can retrieve the entity and lazily load the reference to the document in MongoDB:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$order</span> <span class="o">=</span> <span class="nv">$em</span><span class="o">-></span><span class="na">find</span><span class="p">(</span><span class="s1">'Order'</span><span class="p">,</span> <span class="nv">$order</span><span class="o">-></span><span class="na">getId</span><span class="p">());</span>
|
||||
|
||||
<span class="c1">// Instance of an uninitialized product proxy</span>
|
||||
<span class="nv">$product</span> <span class="o">=</span> <span class="nv">$order</span><span class="o">-></span><span class="na">getProduct</span><span class="p">();</span>
|
||||
|
||||
<span class="c1">// Initializes proxy and queries the database</span>
|
||||
<span class="k">echo</span> <span class="s2">"Order Title: "</span> <span class="o">.</span> <span class="nv">$product</span><span class="o">-></span><span class="na">getTitle</span><span class="p">();</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you were to print the <cite>$order</cite> you would see that we got back regular PHP objects:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nb">print_r</span><span class="p">(</span><span class="nv">$order</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The above would output the following:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="x">Order Object</span>
|
||||
<span class="x">(</span>
|
||||
<span class="x"> [id:Entities\Order:private] => 53</span>
|
||||
<span class="x"> [productId:Entities\Order:private] => 4c74a1868ead0ed7a9000000</span>
|
||||
<span class="x"> [product:Entities\Order:private] => Proxies\DocumentsProductProxy Object</span>
|
||||
<span class="x"> (</span>
|
||||
<span class="x"> [__isInitialized__] => 1</span>
|
||||
<span class="x"> [id:Documents\Product:private] => 4c74a1868ead0ed7a9000000</span>
|
||||
<span class="x"> [title:Documents\Product:private] => Test Product</span>
|
||||
<span class="x"> )</span>
|
||||
<span class="x">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="sphinxsidebar">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
|
||||
<div id="searchbox" style="">
|
||||
<h3>Search</h3>
|
||||
<form class="search" action="http://readthedocs.org/search/project/" method="get">
|
||||
<input type="text" name="q" size="18">
|
||||
<input type="submit" value="Go">
|
||||
<input type="hidden" name="selected_facets" value="project:">
|
||||
</form>
|
||||
</div>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Blending the ORM and MongoDB ODM</a><ul>
|
||||
<li><a class="reference internal" href="#define-product">Define Product</a></li>
|
||||
<li><a class="reference internal" href="#define-entity">Define Entity</a></li>
|
||||
<li><a class="reference internal" href="#event-subscriber">Event Subscriber</a></li>
|
||||
<li><a class="reference internal" href="#working-with-products-and-orders">Working with Products and Orders</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/cookbook/blending-orm-and-mongodb-odm.rst.txt"
|
||||
rel="nofollow">Show Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© Copyright 2013, Doctrine Project Team.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.2.
|
||||
<br/>
|
||||
<a target="_BLANK" href="http://www.servergrove.com"><img src="http://www.doctrine-project.org/_static/servergrove.jpg" /></a> <br/><br/>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id" value="BAE2E3XANQ77Y" />
|
||||
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
|
||||
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bot-rcnr">
|
||||
<div class="tl"><!-- corner --></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-288343-7";
|
||||
urchinTracker();
|
||||
</script>
|
||||
<a class="githublink" href="http://github.com/doctrine"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
|
||||
</body>
|
||||
</html>
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Implementing ArrayAccess for Domain Objects — Doctrine MongoDB ODM 1.1.5 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/bootstrap/css/bootstrap.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/layout.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/configurationblock.css" type="text/css" />
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.1.5',
|
||||
COLLAPSE_MODINDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
};
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script src="../_static/bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
$(document).ready(function() {
|
||||
$("#versions").change(function() {
|
||||
var docsUrl = $(this).val();
|
||||
window.location.href = docsUrl;
|
||||
});
|
||||
});
|
||||
-->
|
||||
</script>
|
||||
<link rel="shortcut icon" href="../_static/doctrine.ico"/>
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="top" title="Doctrine MongoDB ODM 1.1.5 documentation" href="../index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="header">
|
||||
<h1 id="h1title"></h1>
|
||||
<div id="logo">
|
||||
<a href="http://www.doctrine-project.org/">Doctrine - PHP Database Libraries</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav" class="cls">
|
||||
<div class="tl cls">
|
||||
<ul>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/">Home</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/about.html">About</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/projects.html">Projects</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/contribute.html">Contribute</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/community.html">Community</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/archive.html">Blog</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/jira">Development</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content" class="cls">
|
||||
<div class="related">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li><a href="/">Doctrine Homepage</a> »</li>
|
||||
<li><a href="../index.html">Doctrine MongoDB ODM 1.1.5 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
<div class="body" >
|
||||
|
||||
<div class="section" id="implementing-arrayaccess-for-domain-objects">
|
||||
<h1>Implementing ArrayAccess for Domain Objects<a class="headerlink" href="#implementing-arrayaccess-for-domain-objects" title="Permalink to this headline">¶</a></h1>
|
||||
<p><em>Section author: Roman Borschel (<a class="reference external" href="mailto:roman%40code-factory.org">roman<span>@</span>code-factory<span>.</span>org</a>)</em></p>
|
||||
<p>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
|
||||
<a class="reference external" href="http://martinfowler.com/eaaCatalog/layerSupertype.html">Layer Supertype</a>
|
||||
for all our domain objects.</p>
|
||||
<div class="section" id="option-1">
|
||||
<h2>Option 1<a class="headerlink" href="#option-1" title="Permalink to this headline">¶</a></h2>
|
||||
<p>In this implementation we will make use of PHPs highly dynamic
|
||||
nature to dynamically access properties of a subtype in a supertype
|
||||
at runtime. Note that this implementation has 2 main caveats:</p>
|
||||
<ul class="simple">
|
||||
<li>It will not work with private fields</li>
|
||||
<li>It will not go through any getters/setters</li>
|
||||
</ul>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">abstract</span> <span class="k">class</span> <span class="nc">DomainObject</span> <span class="k">implements</span> <span class="nx">ArrayAccess</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">offsetExists</span><span class="p">(</span><span class="nv">$offset</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nb">isset</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="nv">$offset</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">offsetSet</span><span class="p">(</span><span class="nv">$offset</span><span class="p">,</span> <span class="nv">$value</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="nv">$offset</span> <span class="o">=</span> <span class="nv">$value</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">offsetGet</span><span class="p">(</span><span class="nv">$offset</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="nv">$offset</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">offsetUnset</span><span class="p">(</span><span class="nv">$offset</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="nv">$offset</span> <span class="o">=</span> <span class="k">null</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="option-2">
|
||||
<h2>Option 2<a class="headerlink" href="#option-2" title="Permalink to this headline">¶</a></h2>
|
||||
<p>In this implementation we will dynamically invoke getters/setters.
|
||||
Again we use PHPs dynamic nature to invoke methods on a subtype
|
||||
from a supertype at runtime. This implementation has the following
|
||||
caveats:</p>
|
||||
<ul class="simple">
|
||||
<li>It relies on a naming convention</li>
|
||||
<li>The semantics of offsetExists can differ</li>
|
||||
<li>offsetUnset will not work with typehinted setters</li>
|
||||
</ul>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">abstract</span> <span class="k">class</span> <span class="nc">DomainObject</span> <span class="k">implements</span> <span class="nx">ArrayAccess</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">offsetExists</span><span class="p">(</span><span class="nv">$offset</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="c1">// In this example we say that exists means it is not null</span>
|
||||
<span class="nv">$value</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="p">{</span><span class="s2">"get</span><span class="si">$offset</span><span class="s2">"</span><span class="p">}();</span>
|
||||
<span class="k">return</span> <span class="nv">$value</span> <span class="o">!==</span> <span class="k">null</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">offsetSet</span><span class="p">(</span><span class="nv">$offset</span><span class="p">,</span> <span class="nv">$value</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="p">{</span><span class="s2">"set</span><span class="si">$offset</span><span class="s2">"</span><span class="p">}(</span><span class="nv">$value</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">offsetGet</span><span class="p">(</span><span class="nv">$offset</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="p">{</span><span class="s2">"get</span><span class="si">$offset</span><span class="s2">"</span><span class="p">}();</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">offsetUnset</span><span class="p">(</span><span class="nv">$offset</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="p">{</span><span class="s2">"set</span><span class="si">$offset</span><span class="s2">"</span><span class="p">}(</span><span class="k">null</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="read-only">
|
||||
<h2>Read-only<a class="headerlink" href="#read-only" title="Permalink to this headline">¶</a></h2>
|
||||
<p>You can slightly tweak option 1 or option 2 in order to make array
|
||||
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).</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">abstract</span> <span class="k">class</span> <span class="nc">DomainObject</span> <span class="k">implements</span> <span class="nx">ArrayAccess</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">offsetExists</span><span class="p">(</span><span class="nv">$offset</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="c1">// option 1 or option 2</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">offsetSet</span><span class="p">(</span><span class="nv">$offset</span><span class="p">,</span> <span class="nv">$value</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">throw</span> <span class="k">new</span> <span class="nx">BadMethodCallException</span><span class="p">(</span><span class="s2">"Array access of class "</span> <span class="o">.</span> <span class="nb">get_class</span><span class="p">(</span><span class="nv">$this</span><span class="p">)</span> <span class="o">.</span> <span class="s2">" is read-only!"</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">offsetGet</span><span class="p">(</span><span class="nv">$offset</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="c1">// option 1 or option 2</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">offsetUnset</span><span class="p">(</span><span class="nv">$offset</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">throw</span> <span class="k">new</span> <span class="nx">BadMethodCallException</span><span class="p">(</span><span class="s2">"Array access of class "</span> <span class="o">.</span> <span class="nb">get_class</span><span class="p">(</span><span class="nv">$this</span><span class="p">)</span> <span class="o">.</span> <span class="s2">" is read-only!"</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="sphinxsidebar">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
|
||||
<div id="searchbox" style="">
|
||||
<h3>Search</h3>
|
||||
<form class="search" action="http://readthedocs.org/search/project/" method="get">
|
||||
<input type="text" name="q" size="18">
|
||||
<input type="submit" value="Go">
|
||||
<input type="hidden" name="selected_facets" value="project:">
|
||||
</form>
|
||||
</div>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Implementing ArrayAccess for Domain Objects</a><ul>
|
||||
<li><a class="reference internal" href="#option-1">Option 1</a></li>
|
||||
<li><a class="reference internal" href="#option-2">Option 2</a></li>
|
||||
<li><a class="reference internal" href="#read-only">Read-only</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/cookbook/implementing-array-access-for-domain-objects.rst.txt"
|
||||
rel="nofollow">Show Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© Copyright 2013, Doctrine Project Team.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.2.
|
||||
<br/>
|
||||
<a target="_BLANK" href="http://www.servergrove.com"><img src="http://www.doctrine-project.org/_static/servergrove.jpg" /></a> <br/><br/>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id" value="BAE2E3XANQ77Y" />
|
||||
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
|
||||
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bot-rcnr">
|
||||
<div class="tl"><!-- corner --></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-288343-7";
|
||||
urchinTracker();
|
||||
</script>
|
||||
<a class="githublink" href="http://github.com/doctrine"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
|
||||
</body>
|
||||
</html>
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Implementing the Notify ChangeTracking Policy — Doctrine MongoDB ODM 1.1.5 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/bootstrap/css/bootstrap.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/layout.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/configurationblock.css" type="text/css" />
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.1.5',
|
||||
COLLAPSE_MODINDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
};
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script src="../_static/bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
$(document).ready(function() {
|
||||
$("#versions").change(function() {
|
||||
var docsUrl = $(this).val();
|
||||
window.location.href = docsUrl;
|
||||
});
|
||||
});
|
||||
-->
|
||||
</script>
|
||||
<link rel="shortcut icon" href="../_static/doctrine.ico"/>
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="top" title="Doctrine MongoDB ODM 1.1.5 documentation" href="../index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="header">
|
||||
<h1 id="h1title"></h1>
|
||||
<div id="logo">
|
||||
<a href="http://www.doctrine-project.org/">Doctrine - PHP Database Libraries</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav" class="cls">
|
||||
<div class="tl cls">
|
||||
<ul>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/">Home</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/about.html">About</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/projects.html">Projects</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/contribute.html">Contribute</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/community.html">Community</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/archive.html">Blog</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/jira">Development</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content" class="cls">
|
||||
<div class="related">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li><a href="/">Doctrine Homepage</a> »</li>
|
||||
<li><a href="../index.html">Doctrine MongoDB ODM 1.1.5 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
<div class="body" >
|
||||
|
||||
<div class="section" id="implementing-the-notify-changetracking-policy">
|
||||
<h1>Implementing the Notify ChangeTracking Policy<a class="headerlink" href="#implementing-the-notify-changetracking-policy" title="Permalink to this headline">¶</a></h1>
|
||||
<p><em>Section author: Roman Borschel (<a class="reference external" href="mailto:roman%40code-factory.org">roman<span>@</span>code-factory<span>.</span>org</a>)</em></p>
|
||||
<p>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
|
||||
code should look like. We will implement it on a
|
||||
<a class="reference external" href="http://martinfowler.com/eaaCatalog/layerSupertype.html">Layer Supertype</a>
|
||||
for all our domain objects.</p>
|
||||
<div class="section" id="implementing-notifypropertychanged">
|
||||
<h2>Implementing NotifyPropertyChanged<a class="headerlink" href="#implementing-notifypropertychanged" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The NOTIFY policy is based on the assumption that the entities
|
||||
notify interested listeners of changes to their properties. For
|
||||
that purpose, a class that wants to use this policy needs to
|
||||
implement the <code class="docutils literal"><span class="pre">NotifyPropertyChanged</span></code> interface from the
|
||||
<code class="docutils literal"><span class="pre">Doctrine\Common</span></code> namespace.</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">use</span> <span class="nx">Doctrine\Common\NotifyPropertyChanged</span><span class="p">,</span>
|
||||
<span class="nx">Doctrine\Common\PropertyChangedListener</span><span class="p">;</span>
|
||||
|
||||
<span class="k">abstract</span> <span class="k">class</span> <span class="nc">DomainObject</span> <span class="k">implements</span> <span class="nx">NotifyPropertyChanged</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">private</span> <span class="nv">$_listeners</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">addPropertyChangedListener</span><span class="p">(</span><span class="nx">PropertyChangedListener</span> <span class="nv">$listener</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="na">_listeners</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$listener</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="sd">/** Notifies listeners of a change. */</span>
|
||||
<span class="k">protected</span> <span class="k">function</span> <span class="nf">_onPropertyChanged</span><span class="p">(</span><span class="nv">$propName</span><span class="p">,</span> <span class="nv">$oldValue</span><span class="p">,</span> <span class="nv">$newValue</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">_listeners</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">_listeners</span> <span class="k">as</span> <span class="nv">$listener</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nv">$listener</span><span class="o">-></span><span class="na">propertyChanged</span><span class="p">(</span><span class="nv">$this</span><span class="p">,</span> <span class="nv">$propName</span><span class="p">,</span> <span class="nv">$oldValue</span><span class="p">,</span> <span class="nv">$newValue</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Then, in each property setter of concrete, derived domain classes,
|
||||
you need to invoke _onPropertyChanged as follows to notify
|
||||
listeners:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="c1">// Mapping not shown, either in annotations, xml or yaml as usual</span>
|
||||
<span class="k">class</span> <span class="nc">MyEntity</span> <span class="k">extends</span> <span class="nx">DomainObject</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">private</span> <span class="nv">$data</span><span class="p">;</span>
|
||||
<span class="c1">// ... other fields as usual</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">setData</span><span class="p">(</span><span class="nv">$data</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nv">$data</span> <span class="o">!=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">data</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// check: is it actually modified?</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="na">_onPropertyChanged</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-></span><span class="na">data</span><span class="p">,</span> <span class="nv">$data</span><span class="p">);</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="na">data</span> <span class="o">=</span> <span class="nv">$data</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The check whether the new value is different from the old one is
|
||||
not mandatory but recommended. That way you can avoid unnecessary
|
||||
updates and also have full control over when you consider a
|
||||
property changed.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="sphinxsidebar">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
|
||||
<div id="searchbox" style="">
|
||||
<h3>Search</h3>
|
||||
<form class="search" action="http://readthedocs.org/search/project/" method="get">
|
||||
<input type="text" name="q" size="18">
|
||||
<input type="submit" value="Go">
|
||||
<input type="hidden" name="selected_facets" value="project:">
|
||||
</form>
|
||||
</div>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Implementing the Notify ChangeTracking Policy</a><ul>
|
||||
<li><a class="reference internal" href="#implementing-notifypropertychanged">Implementing NotifyPropertyChanged</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/cookbook/implementing-the-notify-changetracking-policy.rst.txt"
|
||||
rel="nofollow">Show Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© Copyright 2013, Doctrine Project Team.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.2.
|
||||
<br/>
|
||||
<a target="_BLANK" href="http://www.servergrove.com"><img src="http://www.doctrine-project.org/_static/servergrove.jpg" /></a> <br/><br/>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id" value="BAE2E3XANQ77Y" />
|
||||
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
|
||||
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bot-rcnr">
|
||||
<div class="tl"><!-- corner --></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-288343-7";
|
||||
urchinTracker();
|
||||
</script>
|
||||
<a class="githublink" href="http://github.com/doctrine"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
|
||||
</body>
|
||||
</html>
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Implementing Wakeup or Clone — Doctrine MongoDB ODM 1.1.5 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/bootstrap/css/bootstrap.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/layout.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/configurationblock.css" type="text/css" />
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.1.5',
|
||||
COLLAPSE_MODINDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
};
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script src="../_static/bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
$(document).ready(function() {
|
||||
$("#versions").change(function() {
|
||||
var docsUrl = $(this).val();
|
||||
window.location.href = docsUrl;
|
||||
});
|
||||
});
|
||||
-->
|
||||
</script>
|
||||
<link rel="shortcut icon" href="../_static/doctrine.ico"/>
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="top" title="Doctrine MongoDB ODM 1.1.5 documentation" href="../index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="header">
|
||||
<h1 id="h1title"></h1>
|
||||
<div id="logo">
|
||||
<a href="http://www.doctrine-project.org/">Doctrine - PHP Database Libraries</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav" class="cls">
|
||||
<div class="tl cls">
|
||||
<ul>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/">Home</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/about.html">About</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/projects.html">Projects</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/contribute.html">Contribute</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/community.html">Community</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/archive.html">Blog</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/jira">Development</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content" class="cls">
|
||||
<div class="related">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li><a href="/">Doctrine Homepage</a> »</li>
|
||||
<li><a href="../index.html">Doctrine MongoDB ODM 1.1.5 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
<div class="body" >
|
||||
|
||||
<div class="section" id="implementing-wakeup-or-clone">
|
||||
<h1>Implementing Wakeup or Clone<a class="headerlink" href="#implementing-wakeup-or-clone" title="Permalink to this headline">¶</a></h1>
|
||||
<p><em>Section author: Roman Borschel (<a class="reference external" href="mailto:roman%40code-factory.org">roman<span>@</span>code-factory<span>.</span>org</a>)</em></p>
|
||||
<p>As explained in the
|
||||
<a class="reference internal" href="../reference/architecture.html"><span class="doc">restrictions for document classes in the manual</span></a>.
|
||||
it is usually not allowed for a document to implement <code class="docutils literal"><span class="pre">__wakeup</span></code>
|
||||
or <code class="docutils literal"><span class="pre">__clone</span></code>, because Doctrine makes special use of them.
|
||||
However, it is quite easy to make use of these methods in a safe
|
||||
way by guarding the custom wakeup or clone code with a document
|
||||
identity check, as demonstrated in the following sections.</p>
|
||||
<div class="section" id="safely-implementing-wakeup">
|
||||
<h2>Safely implementing __wakeup<a class="headerlink" href="#safely-implementing-wakeup" title="Permalink to this headline">¶</a></h2>
|
||||
<p>To safely implement <code class="docutils literal"><span class="pre">__wakeup</span></code>, simply enclose your
|
||||
implementation code in an identity check as follows:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">MyDocument</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span> <span class="c1">// This is the identifier of the document.</span>
|
||||
<span class="c1">//...</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">__wakeup</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="c1">// If the document has an identity, proceed as normal.</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">id</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="c1">// ... Your code here as normal ...</span>
|
||||
<span class="p">}</span>
|
||||
<span class="c1">// otherwise do nothing, do NOT throw an exception!</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="c1">//...</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="safely-implementing-clone">
|
||||
<h2>Safely implementing __clone<a class="headerlink" href="#safely-implementing-clone" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Safely implementing <code class="docutils literal"><span class="pre">__clone</span></code> is pretty much the same:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
<span class="k">class</span> <span class="nc">MyDocument</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span> <span class="c1">// This is the identifier of the document.</span>
|
||||
<span class="c1">//...</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">__clone</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="c1">// If the document has an identity, proceed as normal.</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">id</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="c1">// ... Your code here as normal ...</span>
|
||||
<span class="p">}</span>
|
||||
<span class="c1">// otherwise do nothing, do NOT throw an exception!</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="c1">//...</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="summary">
|
||||
<h2>Summary<a class="headerlink" href="#summary" title="Permalink to this headline">¶</a></h2>
|
||||
<p>As you have seen, it is quite easy to safely make use of
|
||||
<code class="docutils literal"><span class="pre">__wakeup</span></code> and <code class="docutils literal"><span class="pre">__clone</span></code> in your documents without adding any
|
||||
really Doctrine-specific or Doctrine-dependant code.</p>
|
||||
<p>These implementations are possible and safe because when Doctrine
|
||||
invokes these methods, the documents never have an identity (yet).
|
||||
Furthermore, it is possibly a good idea to check for the identity
|
||||
in your code anyway, since it's rarely the case that you want to
|
||||
unserialize or clone a document with no identity.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="sphinxsidebar">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
|
||||
<div id="searchbox" style="">
|
||||
<h3>Search</h3>
|
||||
<form class="search" action="http://readthedocs.org/search/project/" method="get">
|
||||
<input type="text" name="q" size="18">
|
||||
<input type="submit" value="Go">
|
||||
<input type="hidden" name="selected_facets" value="project:">
|
||||
</form>
|
||||
</div>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Implementing Wakeup or Clone</a><ul>
|
||||
<li><a class="reference internal" href="#safely-implementing-wakeup">Safely implementing __wakeup</a></li>
|
||||
<li><a class="reference internal" href="#safely-implementing-clone">Safely implementing __clone</a></li>
|
||||
<li><a class="reference internal" href="#summary">Summary</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/cookbook/implementing-wakeup-or-clone.rst.txt"
|
||||
rel="nofollow">Show Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© Copyright 2013, Doctrine Project Team.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.2.
|
||||
<br/>
|
||||
<a target="_BLANK" href="http://www.servergrove.com"><img src="http://www.doctrine-project.org/_static/servergrove.jpg" /></a> <br/><br/>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id" value="BAE2E3XANQ77Y" />
|
||||
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
|
||||
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bot-rcnr">
|
||||
<div class="tl"><!-- corner --></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-288343-7";
|
||||
urchinTracker();
|
||||
</script>
|
||||
<a class="githublink" href="http://github.com/doctrine"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
|
||||
</body>
|
||||
</html>
|
||||
+366
@@ -0,0 +1,366 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Mapping Classes to the ORM and ODM — Doctrine MongoDB ODM 1.1.5 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/bootstrap/css/bootstrap.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/layout.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/configurationblock.css" type="text/css" />
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.1.5',
|
||||
COLLAPSE_MODINDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
};
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script src="../_static/bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
$(document).ready(function() {
|
||||
$("#versions").change(function() {
|
||||
var docsUrl = $(this).val();
|
||||
window.location.href = docsUrl;
|
||||
});
|
||||
});
|
||||
-->
|
||||
</script>
|
||||
<link rel="shortcut icon" href="../_static/doctrine.ico"/>
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="top" title="Doctrine MongoDB ODM 1.1.5 documentation" href="../index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="header">
|
||||
<h1 id="h1title"></h1>
|
||||
<div id="logo">
|
||||
<a href="http://www.doctrine-project.org/">Doctrine - PHP Database Libraries</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav" class="cls">
|
||||
<div class="tl cls">
|
||||
<ul>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/">Home</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/about.html">About</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/projects.html">Projects</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/contribute.html">Contribute</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/community.html">Community</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/archive.html">Blog</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/jira">Development</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content" class="cls">
|
||||
<div class="related">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li><a href="/">Doctrine Homepage</a> »</li>
|
||||
<li><a href="../index.html">Doctrine MongoDB ODM 1.1.5 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
<div class="body" >
|
||||
|
||||
<div class="section" id="mapping-classes-to-the-orm-and-odm">
|
||||
<h1>Mapping Classes to the ORM and ODM<a class="headerlink" href="#mapping-classes-to-the-orm-and-odm" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Because of the non intrusive design of Doctrine it is possible for you to have plain PHP classes
|
||||
that are mapped to both a relational database with the Doctrine2 Object Relational Mapper and
|
||||
MongoDB with the Doctrine MongoDB Object Document Mapper, or any other persistence layer that
|
||||
implements the Doctrine Common <a class="reference external" href="https://github.com/doctrine/common/tree/master/lib/Doctrine/Common/Persistence">persistence</a> interfaces.</p>
|
||||
<div class="section" id="test-subject">
|
||||
<h2>Test Subject<a class="headerlink" href="#test-subject" title="Permalink to this headline">¶</a></h2>
|
||||
<p>For this cookbook entry we need to define a class that can be persisted to both MySQL and MongoDB.
|
||||
We'll use a <code class="docutils literal"><span class="pre">BlogPost</span></code> as you may want to write some generic blogging functionality that has support
|
||||
for multiple Doctrine persistence layers:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">namespace</span> <span class="nx">Doctrine\Blog</span><span class="p">;</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">BlogPost</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
|
||||
<span class="k">private</span> <span class="nv">$title</span><span class="p">;</span>
|
||||
<span class="k">private</span> <span class="nv">$body</span><span class="p">;</span>
|
||||
|
||||
<span class="c1">// ...</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="mapping-information">
|
||||
<h2>Mapping Information<a class="headerlink" href="#mapping-information" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Now we just need to provide the mapping information for the Doctrine persistence layers so they know
|
||||
how to consume the objects and persist them to the database.</p>
|
||||
<div class="section" id="orm">
|
||||
<h3>ORM<a class="headerlink" href="#orm" title="Permalink to this headline">¶</a></h3>
|
||||
<p>First define the mapping for the ORM:</p>
|
||||
<div class="configuration-block">
|
||||
<ul class="simple">
|
||||
<li><em>PHP</em><div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">namespace</span> <span class="nx">Doctrine\Blog</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Entity(repositoryClass="Doctrine\Blog\ORM\BlogPostRepository") */</span>
|
||||
<span class="k">class</span> <span class="nc">BlogPost</span>
|
||||
<span class="p">{</span>
|
||||
<span class="sd">/** @Id @Column(type="integer") */</span>
|
||||
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Column(type="string") */</span>
|
||||
<span class="k">private</span> <span class="nv">$title</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Column(type="text") */</span>
|
||||
<span class="k">private</span> <span class="nv">$body</span><span class="p">;</span>
|
||||
|
||||
<span class="c1">// ...</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><em>XML</em><div class="highlight-xml"><div class="highlight"><pre><span class="cp"><?xml version="1.0" encoding="UTF-8"?></span>
|
||||
<span class="nt"><doctrine-mapping</span> <span class="na">xmlns=</span><span class="s">"http://doctrine-project.org/schemas/orm/doctrine-mapping"</span>
|
||||
<span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span>
|
||||
<span class="na">xsi:schemaLocation=</span><span class="s">"http://doctrine-project.org/schemas/orm/doctrine-mapping</span>
|
||||
<span class="s"> http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"</span><span class="nt">></span>
|
||||
|
||||
<span class="nt"><entity</span> <span class="na">name=</span><span class="s">"Documents\BlogPost"</span> <span class="na">repository-class=</span><span class="s">"Doctrine\Blog\ORM\BlogPostRepository"</span><span class="nt">></span>
|
||||
<span class="nt"><id</span> <span class="na">name=</span><span class="s">"id"</span> <span class="na">type=</span><span class="s">"integer"</span> <span class="nt">/></span>
|
||||
<span class="nt"><field</span> <span class="na">name=</span><span class="s">"name"</span> <span class="na">type=</span><span class="s">"string"</span> <span class="nt">/></span>
|
||||
<span class="nt"><field</span> <span class="na">name=</span><span class="s">"email"</span> <span class="na">type=</span><span class="s">"text"</span> <span class="nt">/></span>
|
||||
<span class="nt"></entity></span>
|
||||
<span class="nt"></doctrine-mapping></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><em>YAML</em><div class="highlight-yaml"><div class="highlight"><pre><span class="l l-Scalar l-Scalar-Plain">Documents\BlogPost</span><span class="p p-Indicator">:</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">repositoryClass</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Doctrine\Blog\ORM\BlogPostRepository</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">integer</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">fields</span><span class="p p-Indicator">:</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">title</span><span class="p p-Indicator">:</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">string</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">body</span><span class="p p-Indicator">:</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">text</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>Now you are able to persist the <code class="docutils literal"><span class="pre">Documents\BlogPost</span></code> with an instance of <code class="docutils literal"><span class="pre">EntityManager</span></code>:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$blogPost</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">BlogPost</span><span class="p">()</span>
|
||||
<span class="nv">$blogPost</span><span class="o">-></span><span class="na">setTitle</span><span class="p">(</span><span class="s1">'test'</span><span class="p">);</span>
|
||||
|
||||
<span class="nv">$em</span><span class="o">-></span><span class="na">persist</span><span class="p">(</span><span class="nv">$blogPost</span><span class="p">);</span>
|
||||
<span class="nv">$em</span><span class="o">-></span><span class="na">flush</span><span class="p">();</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can find the blog post:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$blogPost</span> <span class="o">=</span> <span class="nv">$em</span><span class="o">-></span><span class="na">getRepository</span><span class="p">(</span><span class="s1">'Documents\BlogPost'</span><span class="p">)</span><span class="o">-></span><span class="na">findOneByTitle</span><span class="p">(</span><span class="s1">'test'</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="mongodb-odm">
|
||||
<h3>MongoDB ODM<a class="headerlink" href="#mongodb-odm" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Now map the same class to the Doctrine MongoDB ODM:</p>
|
||||
<div class="configuration-block">
|
||||
<ul class="simple">
|
||||
<li><em>PHP</em><div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Document(repositoryClass="Doctrine\Blog\ODM\MongoDB\BlogPostRepository") */</span>
|
||||
<span class="k">class</span> <span class="nc">BlogPost</span>
|
||||
<span class="p">{</span>
|
||||
<span class="sd">/** @Id */</span>
|
||||
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Field(type="string") */</span>
|
||||
<span class="k">private</span> <span class="nv">$title</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Field(type="string") */</span>
|
||||
<span class="k">private</span> <span class="nv">$body</span><span class="p">;</span>
|
||||
|
||||
<span class="c1">// ...</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><em>XML</em><div class="highlight-xml"><div class="highlight"><pre><span class="cp"><?xml version="1.0" encoding="UTF-8"?></span>
|
||||
<span class="nt"><doctrine-mongo-mapping</span> <span class="na">xmlns=</span><span class="s">"http://doctrine-project.org/schemas/orm/doctrine-mapping"</span>
|
||||
<span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span>
|
||||
<span class="na">xsi:schemaLocation=</span><span class="s">"http://doctrine-project.org/schemas/orm/doctrine-mapping</span>
|
||||
<span class="s"> http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"</span><span class="nt">></span>
|
||||
|
||||
<span class="nt"><document</span> <span class="na">name=</span><span class="s">"Documents\BlogPost"</span> <span class="na">repository-class=</span><span class="s">"Doctrine\Blog\ODM\MongoDB\BlogPostRepository"</span><span class="nt">></span>
|
||||
<span class="nt"><field</span> <span class="na">fieldName=</span><span class="s">"id"</span> <span class="na">type=</span><span class="s">"id"</span> <span class="nt">/></span>
|
||||
<span class="nt"><field</span> <span class="na">fieldName=</span><span class="s">"name"</span> <span class="na">type=</span><span class="s">"string"</span> <span class="nt">/></span>
|
||||
<span class="nt"><field</span> <span class="na">fieldName=</span><span class="s">"email"</span> <span class="na">type=</span><span class="s">"text"</span> <span class="nt">/></span>
|
||||
<span class="nt"></document></span>
|
||||
<span class="nt"></doctrine-mongo-mapping></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><em>YAML</em><div class="highlight-yaml"><div class="highlight"><pre><span class="l l-Scalar l-Scalar-Plain">Documents\BlogPost</span><span class="p p-Indicator">:</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">repositoryClass</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Doctrine\Blog\ODM\MongoDB\BlogPostRepository</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">fields</span><span class="p p-Indicator">:</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">id</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">title</span><span class="p p-Indicator">:</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">string</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">body</span><span class="p p-Indicator">:</span>
|
||||
<span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">text</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>Now the same class is able to be persisted in the same way using an instance of <code class="docutils literal"><span class="pre">DocumentManager</span></code>:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$blogPost</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">BlogPost</span><span class="p">()</span>
|
||||
<span class="nv">$blogPost</span><span class="o">-></span><span class="na">setTitle</span><span class="p">(</span><span class="s1">'test'</span><span class="p">);</span>
|
||||
|
||||
<span class="nv">$dm</span><span class="o">-></span><span class="na">persist</span><span class="p">(</span><span class="nv">$blogPost</span><span class="p">);</span>
|
||||
<span class="nv">$dm</span><span class="o">-></span><span class="na">flush</span><span class="p">();</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can find the blog post:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$blogPost</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-></span><span class="na">getRepository</span><span class="p">(</span><span class="s1">'Documents\BlogPost'</span><span class="p">)</span><span class="o">-></span><span class="na">findOneByTitle</span><span class="p">(</span><span class="s1">'test'</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="repository-classes">
|
||||
<h2>Repository Classes<a class="headerlink" href="#repository-classes" title="Permalink to this headline">¶</a></h2>
|
||||
<p>You can implement the same repository interface for the ORM and MongoDB ODM easily:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">namespace</span> <span class="nx">Doctrine\Blog\ORM</span><span class="p">;</span>
|
||||
|
||||
<span class="k">use</span> <span class="nx">Doctrine\ORM\EntityRepository</span><span class="p">;</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">BlogPostRepository</span> <span class="k">extends</span> <span class="nx">EntityRepository</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">findPostById</span><span class="p">(</span><span class="nv">$id</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">findOneBy</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">'id'</span> <span class="o">=></span> <span class="nv">$id</span><span class="p">));</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now define the same repository methods for the MongoDB ODM:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">namespace</span> <span class="nx">Doctrine\Blog\ODM\MongoDB</span><span class="p">;</span>
|
||||
|
||||
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\DocumentRepository</span><span class="p">;</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">BlogPostRepository</span> <span class="k">extends</span> <span class="nx">DocumentRepository</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">findPostById</span><span class="p">(</span><span class="nv">$id</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">findOneBy</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">'id'</span> <span class="o">=></span> <span class="nv">$id</span><span class="p">));</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>As you can see the repositories are the same and the final returned data is the same vanilla
|
||||
PHP objects. The data is transparently injected to the objects for you automatically so you
|
||||
are not forced to extend some base class or shape your domain in any certain way for it to work
|
||||
with the Doctrine persistence layers.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="sphinxsidebar">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
|
||||
<div id="searchbox" style="">
|
||||
<h3>Search</h3>
|
||||
<form class="search" action="http://readthedocs.org/search/project/" method="get">
|
||||
<input type="text" name="q" size="18">
|
||||
<input type="submit" value="Go">
|
||||
<input type="hidden" name="selected_facets" value="project:">
|
||||
</form>
|
||||
</div>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Mapping Classes to the ORM and ODM</a><ul>
|
||||
<li><a class="reference internal" href="#test-subject">Test Subject</a></li>
|
||||
<li><a class="reference internal" href="#mapping-information">Mapping Information</a><ul>
|
||||
<li><a class="reference internal" href="#orm">ORM</a></li>
|
||||
<li><a class="reference internal" href="#mongodb-odm">MongoDB ODM</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#repository-classes">Repository Classes</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/cookbook/mapping-classes-to-orm-and-odm.rst.txt"
|
||||
rel="nofollow">Show Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© Copyright 2013, Doctrine Project Team.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.2.
|
||||
<br/>
|
||||
<a target="_BLANK" href="http://www.servergrove.com"><img src="http://www.doctrine-project.org/_static/servergrove.jpg" /></a> <br/><br/>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id" value="BAE2E3XANQ77Y" />
|
||||
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
|
||||
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bot-rcnr">
|
||||
<div class="tl"><!-- corner --></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-288343-7";
|
||||
urchinTracker();
|
||||
</script>
|
||||
<a class="githublink" href="http://github.com/doctrine"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
|
||||
</body>
|
||||
</html>
|
||||
+271
@@ -0,0 +1,271 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Keeping Your Modules Independent — Doctrine MongoDB ODM 1.1.5 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/bootstrap/css/bootstrap.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/layout.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/configurationblock.css" type="text/css" />
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.1.5',
|
||||
COLLAPSE_MODINDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
};
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script src="../_static/bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
$(document).ready(function() {
|
||||
$("#versions").change(function() {
|
||||
var docsUrl = $(this).val();
|
||||
window.location.href = docsUrl;
|
||||
});
|
||||
});
|
||||
-->
|
||||
</script>
|
||||
<link rel="shortcut icon" href="../_static/doctrine.ico"/>
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="top" title="Doctrine MongoDB ODM 1.1.5 documentation" href="../index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="header">
|
||||
<h1 id="h1title"></h1>
|
||||
<div id="logo">
|
||||
<a href="http://www.doctrine-project.org/">Doctrine - PHP Database Libraries</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav" class="cls">
|
||||
<div class="tl cls">
|
||||
<ul>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/">Home</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/about.html">About</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/projects.html">Projects</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/contribute.html">Contribute</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/community.html">Community</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/archive.html">Blog</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/jira">Development</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content" class="cls">
|
||||
<div class="related">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li><a href="/">Doctrine Homepage</a> »</li>
|
||||
<li><a href="../index.html">Doctrine MongoDB ODM 1.1.5 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
<div class="body" >
|
||||
|
||||
<div class="section" id="keeping-your-modules-independent">
|
||||
<h1>Keeping Your Modules Independent<a class="headerlink" href="#keeping-your-modules-independent" title="Permalink to this headline">¶</a></h1>
|
||||
<p>One of the goals of using modules is to create discrete units of functionality
|
||||
that do not have many (if any) dependencies, allowing you to use that
|
||||
functionality in other applications without including unnecessary items.</p>
|
||||
<p>Doctrine MongoDB ODM includes a utility called
|
||||
<code class="docutils literal"><span class="pre">ResolveTargetDocumentListener</span></code>, that functions by intercepting certain calls
|
||||
inside Doctrine and rewriting <code class="docutils literal"><span class="pre">targetDocument</span></code> parameters in your metadata
|
||||
mapping at runtime. This allows your bundle to use an interface or abstract
|
||||
class in its mappings while still allowing the mapping to resolve to a concrete
|
||||
document class at runtime.</p>
|
||||
<p>This functionality allows you to define relationships between different
|
||||
documents without creating hard dependencies.</p>
|
||||
<div class="section" id="background">
|
||||
<h2>Background<a class="headerlink" href="#background" title="Permalink to this headline">¶</a></h2>
|
||||
<p>In the following example, we have an <cite>InvoiceModule</cite> that provides invoicing
|
||||
functionality, and a <cite>CustomerModule</cite> that contains customer management tools.
|
||||
We want to keep these separated, because they can be used in other systems
|
||||
without each other; however, we'd like to use them together in our application.</p>
|
||||
<p>In this case, we have an <code class="docutils literal"><span class="pre">Invoice</span></code> document with a relationship to a
|
||||
non-existent object, an <code class="docutils literal"><span class="pre">InvoiceSubjectInterface</span></code>. The goal is to get
|
||||
the <code class="docutils literal"><span class="pre">ResolveTargetDocumentListener</span></code> to replace any mention of the interface
|
||||
with a real class that implements that interface.</p>
|
||||
</div>
|
||||
<div class="section" id="configuration">
|
||||
<h2>Configuration<a class="headerlink" href="#configuration" title="Permalink to this headline">¶</a></h2>
|
||||
<p>We're going to use the following basic documents (which are incomplete
|
||||
for brevity) to explain how to set up and use the
|
||||
<code class="docutils literal"><span class="pre">ResolveTargetDocumentListener</span></code>.</p>
|
||||
<p>A Customer document:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
<span class="c1">// src/Acme/AppModule/Document/Customer.php</span>
|
||||
|
||||
<span class="k">namespace</span> <span class="nx">Acme\AppModule\Document</span><span class="p">;</span>
|
||||
|
||||
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Mapping\Annotations</span> <span class="k">as</span> <span class="nx">ODM</span><span class="p">;</span>
|
||||
<span class="k">use</span> <span class="nx">Acme\CustomerModule\Document\Customer</span> <span class="k">as</span> <span class="nx">BaseCustomer</span><span class="p">;</span>
|
||||
<span class="k">use</span> <span class="nx">Acme\InvoiceModule\Model\InvoiceSubjectInterface</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/**</span>
|
||||
<span class="sd"> * @ODM\Document</span>
|
||||
<span class="sd"> */</span>
|
||||
<span class="k">class</span> <span class="nc">Customer</span> <span class="k">extends</span> <span class="nx">BaseCustomer</span> <span class="k">implements</span> <span class="nx">InvoiceSubjectInterface</span>
|
||||
<span class="p">{</span>
|
||||
<span class="c1">// In our example, any methods defined in the InvoiceSubjectInterface</span>
|
||||
<span class="c1">// are already implemented in the BaseCustomer</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>An Invoice document:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
<span class="c1">// src/Acme/InvoiceModule/Document/Invoice.php</span>
|
||||
|
||||
<span class="k">namespace</span> <span class="nx">Acme\InvoiceModule\Document</span><span class="p">;</span>
|
||||
|
||||
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Mapping\Annotations</span> <span class="k">as</span> <span class="nx">ODM</span><span class="p">;</span>
|
||||
<span class="k">use</span> <span class="nx">Acme\InvoiceModule\Model\InvoiceSubjectInterface</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/**</span>
|
||||
<span class="sd"> * @ODM\Document</span>
|
||||
<span class="sd"> */</span>
|
||||
<span class="k">class</span> <span class="nc">Invoice</span>
|
||||
<span class="p">{</span>
|
||||
<span class="sd">/**</span>
|
||||
<span class="sd"> * @ODM\ReferenceOne(targetDocument="Acme\InvoiceModule\Model\InvoiceSubjectInterface")</span>
|
||||
<span class="sd"> * @var InvoiceSubjectInterface</span>
|
||||
<span class="sd"> */</span>
|
||||
<span class="k">protected</span> <span class="nv">$subject</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>An InvoiceSubjectInterface:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
<span class="c1">// src/Acme/InvoiceModule/Model/InvoiceSubjectInterface.php</span>
|
||||
|
||||
<span class="k">namespace</span> <span class="nx">Acme\InvoiceModule\Model</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/**</span>
|
||||
<span class="sd"> * An interface that the invoice Subject object should implement.</span>
|
||||
<span class="sd"> * In most circumstances, only a single object should implement</span>
|
||||
<span class="sd"> * this interface as the ResolveTargetDocumentListener can only</span>
|
||||
<span class="sd"> * change the target to a single object.</span>
|
||||
<span class="sd"> */</span>
|
||||
<span class="k">interface</span> <span class="nx">InvoiceSubjectInterface</span>
|
||||
<span class="p">{</span>
|
||||
<span class="c1">// List any additional methods that your InvoiceModule</span>
|
||||
<span class="c1">// will need to access on the subject so that you can</span>
|
||||
<span class="c1">// be sure that you have access to those methods.</span>
|
||||
|
||||
<span class="sd">/**</span>
|
||||
<span class="sd"> * @return string</span>
|
||||
<span class="sd"> */</span>
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">getName</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Next, we need to configure the listener. Add this to the area where you setup
|
||||
Doctrine MongoDB ODM. You must set this up in the way outlined below, otherwise
|
||||
you cannot be guaranteed that the targetDocument resolution will occur reliably:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
<span class="nv">$evm</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\Doctrine\Common\EventManager</span><span class="p">;</span>
|
||||
<span class="nv">$rtdl</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Tools\ResolveTargetDocumentListener</span><span class="p">;</span>
|
||||
|
||||
<span class="c1">// Adds a target-document class</span>
|
||||
<span class="nv">$rtdl</span><span class="o">-></span><span class="na">addResolveTargetDocument</span><span class="p">(</span>
|
||||
<span class="s1">'Acme\\InvoiceModule\\Model\\InvoiceSubjectInterface'</span><span class="p">,</span>
|
||||
<span class="s1">'Acme\\CustomerModule\\Document\\Customer'</span><span class="p">,</span>
|
||||
<span class="k">array</span><span class="p">()</span>
|
||||
<span class="p">);</span>
|
||||
|
||||
<span class="c1">// Add the ResolveTargetDocumentListener</span>
|
||||
<span class="nv">$evm</span><span class="o">-></span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Events</span><span class="o">::</span><span class="na">loadClassMetadata</span><span class="p">,</span> <span class="nv">$rtdl</span><span class="p">);</span>
|
||||
|
||||
<span class="c1">// Create the document manager as you normally would</span>
|
||||
<span class="nv">$dm</span> <span class="o">=</span> <span class="nx">\Doctrine\ODM\MongoDB\DocumentManager</span><span class="o">::</span><span class="na">create</span><span class="p">(</span><span class="nv">$connectionOptions</span><span class="p">,</span> <span class="nv">$config</span><span class="p">,</span> <span class="nv">$evm</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="final-thoughts">
|
||||
<h2>Final Thoughts<a class="headerlink" href="#final-thoughts" title="Permalink to this headline">¶</a></h2>
|
||||
<p>With <code class="docutils literal"><span class="pre">ResolveTargetDocumentListener</span></code>, we are able to decouple our bundles so
|
||||
that they are usable by themselves and easier to maintain independently, while
|
||||
still being able to define relationships between different objects.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="sphinxsidebar">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
|
||||
<div id="searchbox" style="">
|
||||
<h3>Search</h3>
|
||||
<form class="search" action="http://readthedocs.org/search/project/" method="get">
|
||||
<input type="text" name="q" size="18">
|
||||
<input type="submit" value="Go">
|
||||
<input type="hidden" name="selected_facets" value="project:">
|
||||
</form>
|
||||
</div>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Keeping Your Modules Independent</a><ul>
|
||||
<li><a class="reference internal" href="#background">Background</a></li>
|
||||
<li><a class="reference internal" href="#configuration">Configuration</a></li>
|
||||
<li><a class="reference internal" href="#final-thoughts">Final Thoughts</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/cookbook/resolve-target-document-listener.rst.txt"
|
||||
rel="nofollow">Show Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© Copyright 2013, Doctrine Project Team.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.2.
|
||||
<br/>
|
||||
<a target="_BLANK" href="http://www.servergrove.com"><img src="http://www.doctrine-project.org/_static/servergrove.jpg" /></a> <br/><br/>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id" value="BAE2E3XANQ77Y" />
|
||||
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
|
||||
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bot-rcnr">
|
||||
<div class="tl"><!-- corner --></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-288343-7";
|
||||
urchinTracker();
|
||||
</script>
|
||||
<a class="githublink" href="http://github.com/doctrine"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,300 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Simple Search Engine — Doctrine MongoDB ODM 1.1.5 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/bootstrap/css/bootstrap.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/layout.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/configurationblock.css" type="text/css" />
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.1.5',
|
||||
COLLAPSE_MODINDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
};
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script src="../_static/bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
$(document).ready(function() {
|
||||
$("#versions").change(function() {
|
||||
var docsUrl = $(this).val();
|
||||
window.location.href = docsUrl;
|
||||
});
|
||||
});
|
||||
-->
|
||||
</script>
|
||||
<link rel="shortcut icon" href="../_static/doctrine.ico"/>
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="top" title="Doctrine MongoDB ODM 1.1.5 documentation" href="../index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="header">
|
||||
<h1 id="h1title"></h1>
|
||||
<div id="logo">
|
||||
<a href="http://www.doctrine-project.org/">Doctrine - PHP Database Libraries</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav" class="cls">
|
||||
<div class="tl cls">
|
||||
<ul>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/">Home</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/about.html">About</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/projects.html">Projects</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/contribute.html">Contribute</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/community.html">Community</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/archive.html">Blog</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/jira">Development</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content" class="cls">
|
||||
<div class="related">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li><a href="/">Doctrine Homepage</a> »</li>
|
||||
<li><a href="../index.html">Doctrine MongoDB ODM 1.1.5 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
<div class="body" >
|
||||
|
||||
<div class="section" id="simple-search-engine">
|
||||
<h1>Simple Search Engine<a class="headerlink" href="#simple-search-engine" title="Permalink to this headline">¶</a></h1>
|
||||
<p>It is very easy to implement a simple keyword search engine with MongoDB. Because of
|
||||
its flexible schema less nature we can store the keywords we want to search through directly
|
||||
on the document. MongoDB is capable of indexing the embedded documents so the results are fast
|
||||
and scalable.</p>
|
||||
<div class="section" id="sample-model-product">
|
||||
<h2>Sample Model: Product<a class="headerlink" href="#sample-model-product" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Imagine you had a <code class="docutils literal"><span class="pre">Product</span></code> document and you want to search the products by keywords. You can
|
||||
setup a document like the following with a <code class="docutils literal"><span class="pre">$keywords</span></code> property that is mapped as a collection:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Document */</span>
|
||||
<span class="k">class</span> <span class="nc">Product</span>
|
||||
<span class="p">{</span>
|
||||
<span class="sd">/** @Id */</span>
|
||||
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Field(type="string") */</span>
|
||||
<span class="k">private</span> <span class="nv">$title</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Field(type="collection") @Index */</span>
|
||||
<span class="k">private</span> <span class="nv">$keywords</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
|
||||
|
||||
<span class="c1">// ...</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="working-with-keywords">
|
||||
<h2>Working with Keywords<a class="headerlink" href="#working-with-keywords" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Now, create a product and add some keywords:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$product</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Product</span><span class="p">();</span>
|
||||
<span class="nv">$product</span><span class="o">-></span><span class="na">setTitle</span><span class="p">(</span><span class="s1">'Nike Air Jordan 2011'</span><span class="p">);</span>
|
||||
<span class="nv">$product</span><span class="o">-></span><span class="na">addKeyword</span><span class="p">(</span><span class="s1">'nike shoes'</span><span class="p">);</span>
|
||||
<span class="nv">$product</span><span class="o">-></span><span class="na">addKeyword</span><span class="p">(</span><span class="s1">'jordan shoes'</span><span class="p">);</span>
|
||||
<span class="nv">$product</span><span class="o">-></span><span class="na">addKeyword</span><span class="p">(</span><span class="s1">'air jordan'</span><span class="p">);</span>
|
||||
<span class="nv">$product</span><span class="o">-></span><span class="na">addKeyword</span><span class="p">(</span><span class="s1">'shoes'</span><span class="p">);</span>
|
||||
<span class="nv">$product</span><span class="o">-></span><span class="na">addKeyword</span><span class="p">(</span><span class="s1">'2011'</span><span class="p">);</span>
|
||||
|
||||
<span class="nv">$dm</span><span class="o">-></span><span class="na">persist</span><span class="p">(</span><span class="nv">$product</span><span class="p">);</span>
|
||||
<span class="nv">$dm</span><span class="o">-></span><span class="na">flush</span><span class="p">();</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The above example populates the keywords manually but you could very easily write some code which
|
||||
automatically generates your keywords from a string built by the Product that may include the title,
|
||||
description and other fields. You could also use a tool like the <a class="reference external" href="http://www.alchemyapi.com">AlchemyAPI</a> if you want to do
|
||||
some more intelligent keyword extraction.</p>
|
||||
</div>
|
||||
<div class="section" id="searching-keywords">
|
||||
<h2>Searching Keywords<a class="headerlink" href="#searching-keywords" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Searching the keywords in the <code class="docutils literal"><span class="pre">Product</span></code> collection is easy! You can run a query like the following
|
||||
to find documents that have at least one of the keywords:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$keywords</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">'nike shoes'</span><span class="p">,</span> <span class="s1">'air jordan'</span><span class="p">);</span>
|
||||
|
||||
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-></span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">'Product'</span><span class="p">)</span>
|
||||
<span class="o">-></span><span class="na">field</span><span class="p">(</span><span class="s1">'keywords'</span><span class="p">)</span><span class="o">-></span><span class="na">in</span><span class="p">(</span><span class="nv">$keywords</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can make the query more strict by using the <code class="docutils literal"><span class="pre">all()</span></code> method instead of <code class="docutils literal"><span class="pre">in()</span></code>:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$keywords</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">'nike shoes'</span><span class="p">,</span> <span class="s1">'air jordan'</span><span class="p">);</span>
|
||||
|
||||
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-></span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">'Product'</span><span class="p">)</span>
|
||||
<span class="o">-></span><span class="na">field</span><span class="p">(</span><span class="s1">'keywords'</span><span class="p">)</span><span class="o">-></span><span class="na">all</span><span class="p">(</span><span class="nv">$keywords</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The above query would only return products that have both of the keywords!</p>
|
||||
<div class="section" id="user-input">
|
||||
<h3>User Input<a class="headerlink" href="#user-input" title="Permalink to this headline">¶</a></h3>
|
||||
<p>You can easily build keywords from a user search form by exploding whitespace and passing
|
||||
the results to your query. Here is an example:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$queryString</span> <span class="o">=</span> <span class="nv">$_REQUEST</span><span class="p">[</span><span class="s1">'q'</span><span class="p">];</span>
|
||||
<span class="nv">$keywords</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">' '</span><span class="p">,</span> <span class="nv">$queryString</span><span class="p">);</span>
|
||||
|
||||
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-></span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">'Product'</span><span class="p">)</span>
|
||||
<span class="o">-></span><span class="na">field</span><span class="p">(</span><span class="s1">'keywords'</span><span class="p">)</span><span class="o">-></span><span class="na">all</span><span class="p">(</span><span class="nv">$keywords</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="embedded-documents">
|
||||
<h2>Embedded Documents<a class="headerlink" href="#embedded-documents" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If you want to use an embedded document instead of just an array then you can. It will allow you to store
|
||||
additional information with each keyword, like its weight.</p>
|
||||
<div class="section" id="definition">
|
||||
<h3>Definition<a class="headerlink" href="#definition" title="Permalink to this headline">¶</a></h3>
|
||||
<p>You can setup a <code class="docutils literal"><span class="pre">Keyword</span></code> document like the following:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="sd">/** @EmbeddedDocument */</span>
|
||||
<span class="k">class</span> <span class="nc">Keyword</span>
|
||||
<span class="p">{</span>
|
||||
<span class="sd">/** @Field(type="string") @Index */</span>
|
||||
<span class="k">private</span> <span class="nv">$keyword</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Field(type="int") */</span>
|
||||
<span class="k">private</span> <span class="nv">$weight</span><span class="p">;</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">__construct</span><span class="p">(</span><span class="nv">$keyword</span><span class="p">,</span> <span class="nv">$weight</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="na">keyword</span> <span class="o">=</span> <span class="nv">$keyword</span><span class="p">;</span>
|
||||
<span class="nv">$this</span><span class="o">-></span><span class="na">weight</span> <span class="o">=</span> <span class="nv">$weight</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="c1">// ...</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now you can embed the <code class="docutils literal"><span class="pre">Keyword</span></code> document many times in the <code class="docutils literal"><span class="pre">Product</span></code>:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @Document */</span>
|
||||
<span class="k">class</span> <span class="nc">Product</span>
|
||||
<span class="p">{</span>
|
||||
<span class="c1">// ...</span>
|
||||
|
||||
<span class="sd">/** @EmbedMany(targetDocument="Keyword") */</span>
|
||||
<span class="k">private</span> <span class="nv">$keywords</span><span class="p">;</span>
|
||||
|
||||
<span class="c1">// ...</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>With the new embedded document to add a keyword to a <code class="docutils literal"><span class="pre">Product</span></code> the API is a little different,
|
||||
you would have to do the following:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$product</span><span class="o">-></span><span class="na">addKeyword</span><span class="p">(</span><span class="k">new</span> <span class="nx">Keyword</span><span class="p">(</span><span class="s1">'nike shoes'</span><span class="p">,</span> <span class="mi">1</span><span class="p">));</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This is a very basic search engine example and can work for many small and simple applications. If you
|
||||
need better searching functionality you can look at integrating something like <a class="reference external" href="http://lucene.apache.org/solr">Solr</a> in your project.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="sphinxsidebar">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
|
||||
<div id="searchbox" style="">
|
||||
<h3>Search</h3>
|
||||
<form class="search" action="http://readthedocs.org/search/project/" method="get">
|
||||
<input type="text" name="q" size="18">
|
||||
<input type="submit" value="Go">
|
||||
<input type="hidden" name="selected_facets" value="project:">
|
||||
</form>
|
||||
</div>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Simple Search Engine</a><ul>
|
||||
<li><a class="reference internal" href="#sample-model-product">Sample Model: Product</a></li>
|
||||
<li><a class="reference internal" href="#working-with-keywords">Working with Keywords</a></li>
|
||||
<li><a class="reference internal" href="#searching-keywords">Searching Keywords</a><ul>
|
||||
<li><a class="reference internal" href="#user-input">User Input</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#embedded-documents">Embedded Documents</a><ul>
|
||||
<li><a class="reference internal" href="#definition">Definition</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/cookbook/simple-search-engine.rst.txt"
|
||||
rel="nofollow">Show Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© Copyright 2013, Doctrine Project Team.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.2.
|
||||
<br/>
|
||||
<a target="_BLANK" href="http://www.servergrove.com"><img src="http://www.doctrine-project.org/_static/servergrove.jpg" /></a> <br/><br/>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id" value="BAE2E3XANQ77Y" />
|
||||
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
|
||||
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bot-rcnr">
|
||||
<div class="tl"><!-- corner --></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-288343-7";
|
||||
urchinTracker();
|
||||
</script>
|
||||
<a class="githublink" href="http://github.com/doctrine"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,343 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Soft Delete Extension — Doctrine MongoDB ODM 1.1.5 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/bootstrap/css/bootstrap.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/layout.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/configurationblock.css" type="text/css" />
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.1.5',
|
||||
COLLAPSE_MODINDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
};
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script src="../_static/bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
$(document).ready(function() {
|
||||
$("#versions").change(function() {
|
||||
var docsUrl = $(this).val();
|
||||
window.location.href = docsUrl;
|
||||
});
|
||||
});
|
||||
-->
|
||||
</script>
|
||||
<link rel="shortcut icon" href="../_static/doctrine.ico"/>
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="top" title="Doctrine MongoDB ODM 1.1.5 documentation" href="../index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="header">
|
||||
<h1 id="h1title"></h1>
|
||||
<div id="logo">
|
||||
<a href="http://www.doctrine-project.org/">Doctrine - PHP Database Libraries</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav" class="cls">
|
||||
<div class="tl cls">
|
||||
<ul>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/">Home</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/about.html">About</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/projects.html">Projects</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/contribute.html">Contribute</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/community.html">Community</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/archive.html">Blog</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/jira">Development</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content" class="cls">
|
||||
<div class="related">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li><a href="/">Doctrine Homepage</a> »</li>
|
||||
<li><a href="../index.html">Doctrine MongoDB ODM 1.1.5 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
<div class="body" >
|
||||
|
||||
<div class="section" id="soft-delete-extension">
|
||||
<h1>Soft Delete Extension<a class="headerlink" href="#soft-delete-extension" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Sometimes you may not want to delete data from your database completely, but you want to
|
||||
disable or temporarily delete some records so they do not appear anymore in your frontend.
|
||||
Then, later you might want to restore that deleted data like it was never deleted.</p>
|
||||
<p>This is possible with the <code class="docutils literal"><span class="pre">SoftDelete</span></code> extension which can be found on <a class="reference external" href="https://github.com/doctrine/mongodb-odm-softdelete">github</a>.</p>
|
||||
<div class="section" id="installation">
|
||||
<h2>Installation<a class="headerlink" href="#installation" title="Permalink to this headline">¶</a></h2>
|
||||
<p>First you just need to get the code by cloning the <a class="reference external" href="https://github.com/doctrine/mongodb-odm-softdelete">github</a> repository:</p>
|
||||
<div class="highlight-console"><div class="highlight"><pre><span class="gp">$</span> git clone git://github.com/doctrine/mongodb-odm-softdelete.git
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now once you have the code you can setup the autoloader for it:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$classLoader</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ClassLoader</span><span class="p">(</span><span class="s1">'Doctrine\ODM\MongoDB\SoftDelete'</span><span class="p">,</span> <span class="s1">'mongodb-odm-softdelete/lib'</span><span class="p">);</span>
|
||||
<span class="nv">$classLoader</span><span class="o">-></span><span class="na">register</span><span class="p">();</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="setup">
|
||||
<h2>Setup<a class="headerlink" href="#setup" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Now you can autoload the classes you need to setup the <code class="docutils literal"><span class="pre">SoftDeleteManager</span></code> instance you need to manage
|
||||
the soft delete state of your documents:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\SoftDelete\Configuration</span><span class="p">;</span>
|
||||
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\SoftDelete\UnitOfWork</span><span class="p">;</span>
|
||||
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\SoftDelete\SoftDeleteManager</span><span class="p">;</span>
|
||||
<span class="k">use</span> <span class="nx">Doctrine\Common\EventManager</span><span class="p">;</span>
|
||||
|
||||
<span class="c1">// $dm is a DocumentManager instance we should already have</span>
|
||||
|
||||
<span class="nv">$config</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Configuration</span><span class="p">();</span>
|
||||
<span class="nv">$evm</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventManager</span><span class="p">();</span>
|
||||
<span class="nv">$sdm</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SoftDeleteManager</span><span class="p">(</span><span class="nv">$dm</span><span class="p">,</span> <span class="nv">$config</span><span class="p">,</span> <span class="nv">$evm</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="softdeleteable-interface">
|
||||
<h2>SoftDeleteable Interface<a class="headerlink" href="#softdeleteable-interface" title="Permalink to this headline">¶</a></h2>
|
||||
<p>In order for your documents to work with the SoftDelete functionality they must implement
|
||||
the <code class="docutils literal"><span class="pre">SoftDeleteable</span></code> interface:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">interface</span> <span class="nx">SoftDeleteable</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">function</span> <span class="nf">getDeletedAt</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="example-implementation">
|
||||
<h2>Example Implementation<a class="headerlink" href="#example-implementation" title="Permalink to this headline">¶</a></h2>
|
||||
<p>An implementation might look like this in a <code class="docutils literal"><span class="pre">User</span></code> document:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\SoftDelete\SoftDeleteable</span><span class="p">;</span>
|
||||
|
||||
<span class="sd">/** @mongodb:Document */</span>
|
||||
<span class="k">class</span> <span class="nc">User</span> <span class="k">implements</span> <span class="nx">SoftDeleteable</span>
|
||||
<span class="p">{</span>
|
||||
<span class="c1">// ...</span>
|
||||
|
||||
<span class="sd">/** @mongodb:Date @mongodb:Index */</span>
|
||||
<span class="k">private</span> <span class="nv">$deletedAt</span><span class="p">;</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">getDeletedAt</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">deletedAt</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="c1">// ...</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="usage">
|
||||
<h2>Usage<a class="headerlink" href="#usage" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Once you have the <code class="docutils literal"><span class="pre">$sdm</span></code> you can start managing the soft delete state of your documents:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$jwage</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-></span><span class="na">getRepository</span><span class="p">(</span><span class="s1">'User'</span><span class="p">)</span><span class="o">-></span><span class="na">findOneByUsername</span><span class="p">(</span><span class="s1">'jwage'</span><span class="p">);</span>
|
||||
<span class="nv">$fabpot</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-></span><span class="na">getRepository</span><span class="p">(</span><span class="s1">'User'</span><span class="p">)</span><span class="o">-></span><span class="na">findOneByUsername</span><span class="p">(</span><span class="s1">'fabpot'</span><span class="p">);</span>
|
||||
<span class="nv">$sdm</span><span class="o">-></span><span class="na">delete</span><span class="p">(</span><span class="nv">$jwage</span><span class="p">);</span>
|
||||
<span class="nv">$sdm</span><span class="o">-></span><span class="na">delete</span><span class="p">(</span><span class="nv">$fabpot</span><span class="p">);</span>
|
||||
<span class="nv">$sdm</span><span class="o">-></span><span class="na">flush</span><span class="p">();</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The call to <code class="docutils literal"><span class="pre">SoftDeleteManager#flush()</span></code> would persist the deleted state to the database
|
||||
for all the documents it knows about and run a query like the following:</p>
|
||||
<div class="highlight-javascript"><div class="highlight"><pre><span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nx">update</span><span class="p">({</span> <span class="nx">_id</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">$in</span> <span class="o">:</span> <span class="nx">userIds</span> <span class="p">}},</span> <span class="p">{</span> <span class="nx">$set</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">deletedAt</span> <span class="o">:</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">()</span> <span class="p">}</span> <span class="p">})</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now if we were to restore the documents:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$sdm</span><span class="o">-></span><span class="na">restore</span><span class="p">(</span><span class="nv">$jwage</span><span class="p">);</span>
|
||||
<span class="nv">$sdm</span><span class="o">-></span><span class="na">flush</span><span class="p">();</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>It would execute a query like the following:</p>
|
||||
<div class="highlight-javascript"><div class="highlight"><pre><span class="nx">db</span><span class="p">.</span><span class="nx">users</span><span class="p">.</span><span class="nx">update</span><span class="p">({</span> <span class="nx">_id</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">$in</span> <span class="o">:</span> <span class="nx">userIds</span> <span class="p">}},</span> <span class="p">{</span> <span class="nx">$unset</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">deletedAt</span> <span class="o">:</span> <span class="kc">true</span> <span class="p">}</span> <span class="p">})</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="events">
|
||||
<h2>Events<a class="headerlink" href="#events" title="Permalink to this headline">¶</a></h2>
|
||||
<p>We trigger some additional lifecycle events when documents are soft deleted and restored:</p>
|
||||
<ul class="simple">
|
||||
<li>Events::preSoftDelete</li>
|
||||
<li>Events::postSoftDelete</li>
|
||||
<li>Events::preRestore</li>
|
||||
<li>Events::postRestore</li>
|
||||
</ul>
|
||||
<p>Using the events is easy, just define a class like the following:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">TestEventSubscriber</span> <span class="k">implements</span> <span class="nx">\Doctrine\Common\EventSubscriber</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">preSoftDelete</span><span class="p">(</span><span class="nx">LifecycleEventArgs</span> <span class="nv">$args</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$document</span> <span class="o">=</span> <span class="nv">$args</span><span class="o">-></span><span class="na">getDocument</span><span class="p">();</span>
|
||||
<span class="nv">$sdm</span> <span class="o">=</span> <span class="nv">$args</span><span class="o">-></span><span class="na">getSoftDeleteManager</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">getSubscribedEvents</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="k">array</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">preSoftDelete</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now we just need to add the event subscriber to the EventManager:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$eventSubscriber</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">TestEventSubscriber</span><span class="p">();</span>
|
||||
<span class="nv">$evm</span><span class="o">-></span><span class="na">addEventSubscriber</span><span class="p">(</span><span class="nv">$eventSubscriber</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>When we soft delete something the preSoftDelete() method will be invoked before any queries are sent
|
||||
to the database:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="nv">$sdm</span><span class="o">-></span><span class="na">delete</span><span class="p">(</span><span class="nv">$fabpot</span><span class="p">);</span>
|
||||
<span class="nv">$sdm</span><span class="o">-></span><span class="na">flush</span><span class="p">();</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="cascading-soft-deletes">
|
||||
<h2>Cascading Soft Deletes<a class="headerlink" href="#cascading-soft-deletes" title="Permalink to this headline">¶</a></h2>
|
||||
<p>You can easily implement cascading soft deletes by using events in a certain way. Imagine you have
|
||||
a User and Post document and you want to soft delete a users posts when you delete him.</p>
|
||||
<p>You just need to setup an event listener like the following:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">use</span> <span class="nx">Doctrine\Common\EventSubscriber</span><span class="p">;</span>
|
||||
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\SoftDelete\Event\LifecycleEventArgs</span><span class="p">;</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">CascadingSoftDeleteListener</span> <span class="k">implements</span> <span class="nx">EventSubscriber</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">preSoftDelete</span><span class="p">(</span><span class="nx">LifecycleEventArgs</span> <span class="nv">$args</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$sdm</span> <span class="o">=</span> <span class="nv">$args</span><span class="o">-></span><span class="na">getSoftDeleteManager</span><span class="p">();</span>
|
||||
<span class="nv">$document</span> <span class="o">=</span> <span class="nv">$args</span><span class="o">-></span><span class="na">getDocument</span><span class="p">();</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nv">$document</span> <span class="nx">instanceof</span> <span class="nx">User</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nv">$sdm</span><span class="o">-></span><span class="na">deleteBy</span><span class="p">(</span><span class="s1">'Post'</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'user.id'</span> <span class="o">=></span> <span class="nv">$document</span><span class="o">-></span><span class="na">getId</span><span class="p">()));</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">preRestore</span><span class="p">(</span><span class="nx">LifecycleEventArgs</span> <span class="nv">$args</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$sdm</span> <span class="o">=</span> <span class="nv">$args</span><span class="o">-></span><span class="na">getSoftDeleteManager</span><span class="p">();</span>
|
||||
<span class="nv">$document</span> <span class="o">=</span> <span class="nv">$args</span><span class="o">-></span><span class="na">getDocument</span><span class="p">();</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nv">$document</span> <span class="nx">instanceof</span> <span class="nx">User</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nv">$sdm</span><span class="o">-></span><span class="na">restoreBy</span><span class="p">(</span><span class="s1">'Post'</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">'user.id'</span> <span class="o">=></span> <span class="nv">$document</span><span class="o">-></span><span class="na">getId</span><span class="p">()));</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">getSubscribedEvents</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="k">array</span><span class="p">(</span>
|
||||
<span class="nx">Events</span><span class="o">::</span><span class="na">preSoftDelete</span><span class="p">,</span>
|
||||
<span class="nx">Events</span><span class="o">::</span><span class="na">preRestore</span>
|
||||
<span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now when you delete an instance of User it will also delete any Post documents where they
|
||||
reference the User being deleted. If you restore the User, his Post documents will also be restored.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="sphinxsidebar">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
|
||||
<div id="searchbox" style="">
|
||||
<h3>Search</h3>
|
||||
<form class="search" action="http://readthedocs.org/search/project/" method="get">
|
||||
<input type="text" name="q" size="18">
|
||||
<input type="submit" value="Go">
|
||||
<input type="hidden" name="selected_facets" value="project:">
|
||||
</form>
|
||||
</div>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Soft Delete Extension</a><ul>
|
||||
<li><a class="reference internal" href="#installation">Installation</a></li>
|
||||
<li><a class="reference internal" href="#setup">Setup</a></li>
|
||||
<li><a class="reference internal" href="#softdeleteable-interface">SoftDeleteable Interface</a></li>
|
||||
<li><a class="reference internal" href="#example-implementation">Example Implementation</a></li>
|
||||
<li><a class="reference internal" href="#usage">Usage</a></li>
|
||||
<li><a class="reference internal" href="#events">Events</a></li>
|
||||
<li><a class="reference internal" href="#cascading-soft-deletes">Cascading Soft Deletes</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/cookbook/soft-delete-extension.rst.txt"
|
||||
rel="nofollow">Show Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© Copyright 2013, Doctrine Project Team.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.2.
|
||||
<br/>
|
||||
<a target="_BLANK" href="http://www.servergrove.com"><img src="http://www.doctrine-project.org/_static/servergrove.jpg" /></a> <br/><br/>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id" value="BAE2E3XANQ77Y" />
|
||||
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
|
||||
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bot-rcnr">
|
||||
<div class="tl"><!-- corner --></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-288343-7";
|
||||
urchinTracker();
|
||||
</script>
|
||||
<a class="githublink" href="http://github.com/doctrine"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
|
||||
</body>
|
||||
</html>
|
||||
+256
@@ -0,0 +1,256 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Validation of Documents — Doctrine MongoDB ODM 1.1.5 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/bootstrap/css/bootstrap.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/layout.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/configurationblock.css" type="text/css" />
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.1.5',
|
||||
COLLAPSE_MODINDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
};
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/configurationblock.js"></script>
|
||||
<script src="../_static/bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
$(document).ready(function() {
|
||||
$("#versions").change(function() {
|
||||
var docsUrl = $(this).val();
|
||||
window.location.href = docsUrl;
|
||||
});
|
||||
});
|
||||
-->
|
||||
</script>
|
||||
<link rel="shortcut icon" href="../_static/doctrine.ico"/>
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="top" title="Doctrine MongoDB ODM 1.1.5 documentation" href="../index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="header">
|
||||
<h1 id="h1title"></h1>
|
||||
<div id="logo">
|
||||
<a href="http://www.doctrine-project.org/">Doctrine - PHP Database Libraries</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav" class="cls">
|
||||
<div class="tl cls">
|
||||
<ul>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/">Home</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/about.html">About</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/projects.html">Projects</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/contribute.html">Contribute</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/community.html">Community</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/archive.html">Blog</a></li>
|
||||
<li><a target="_top" href="http://www.doctrine-project.org/jira">Development</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content" class="cls">
|
||||
<div class="related">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li><a href="/">Doctrine Homepage</a> »</li>
|
||||
<li><a href="../index.html">Doctrine MongoDB ODM 1.1.5 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
<div class="body" >
|
||||
|
||||
<div class="section" id="validation-of-documents">
|
||||
<h1>Validation of Documents<a class="headerlink" href="#validation-of-documents" title="Permalink to this headline">¶</a></h1>
|
||||
<p><em>Section author: Benjamin Eberlei <<a class="reference external" href="mailto:kontakt%40beberlei.de">kontakt<span>@</span>beberlei<span>.</span>de</a>></em></p>
|
||||
<p>Doctrine 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.
|
||||
What we offer are hooks to execute any kind of validation.</p>
|
||||
<div class="admonition note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">You don't need to validate your documents in the lifecycle
|
||||
events. Its only one of many options. Of course you can also
|
||||
perform validations in value setters or any other method of your
|
||||
documents that are used in your code.</p>
|
||||
</div>
|
||||
<p>Documents can register lifecycle event methods with Doctrine that
|
||||
are called on different occasions. For validation we would need to
|
||||
hook into the events called before persisting and updating. Even
|
||||
though we don't support validation out of the box, the
|
||||
implementation is even simpler than in Doctrine 1 and you will get
|
||||
the additional benefit of being able to re-use your validation in
|
||||
any other part of your domain.</p>
|
||||
<p>Say we have an <code class="docutils literal"><span class="pre">Order</span></code> with several <code class="docutils literal"><span class="pre">OrderLine</span></code> instances. We
|
||||
never want to allow any customer to order for a larger sum than he
|
||||
is allowed to:</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">Order</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">assertCustomerAllowedBuying</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="nv">$orderLimit</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">customer</span><span class="o">-></span><span class="na">getOrderLimit</span><span class="p">();</span>
|
||||
|
||||
<span class="nv">$amount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
|
||||
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">orderLines</span> <span class="k">AS</span> <span class="nv">$line</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nv">$amount</span> <span class="o">+=</span> <span class="nv">$line</span><span class="o">-></span><span class="na">getAmount</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nv">$amount</span> <span class="o">></span> <span class="nv">$orderLimit</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">throw</span> <span class="k">new</span> <span class="nx">CustomerOrderLimitExceededException</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now this is some pretty important piece of business logic in your
|
||||
code, enforcing it at any time is important so that customers with
|
||||
a unknown reputation don't owe your business too much money.</p>
|
||||
<p>We can enforce this constraint in any of the metadata drivers.
|
||||
First Annotations:</p>
|
||||
<div class="configuration-block">
|
||||
<ul class="simple">
|
||||
<li><em>PHP</em><div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="sd">/** @Document @HasLifecycleCallbacks */</span>
|
||||
<span class="k">class</span> <span class="nc">Order</span>
|
||||
<span class="p">{</span>
|
||||
<span class="sd">/** @PrePersist @PreUpdate */</span>
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">assertCustomerAllowedBuying</span><span class="p">()</span> <span class="p">{}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><em>XML</em><div class="highlight-xml"><div class="highlight"><pre><span class="nt"><doctrine-mapping></span>
|
||||
<span class="nt"><document</span> <span class="na">name=</span><span class="s">"Order"</span><span class="nt">></span>
|
||||
<span class="nt"><lifecycle-callbacks></span>
|
||||
<span class="nt"><lifecycle-callback</span> <span class="na">type=</span><span class="s">"prePersist"</span> <span class="na">method=</span><span class="s">"assertCustomerallowedBuying"</span> <span class="nt">/></span>
|
||||
<span class="nt"><lifecycle-callback</span> <span class="na">type=</span><span class="s">"preUpdate"</span> <span class="na">method=</span><span class="s">"assertCustomerallowedBuying"</span> <span class="nt">/></span>
|
||||
<span class="nt"></lifecycle-callbacks></span>
|
||||
<span class="nt"></document></span>
|
||||
<span class="nt"></doctrine-mapping></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>Now validation is performed whenever you call
|
||||
<code class="docutils literal"><span class="pre">DocumentManager#persist($order)</span></code> or when you call
|
||||
<code class="docutils literal"><span class="pre">DocumentManager#flush()</span></code> and an order is about to be updated. Any
|
||||
Exception that happens in the lifecycle callbacks will be cached by
|
||||
the DocumentManager and the current transaction is rolled back.</p>
|
||||
<p>Of course you can do any type of primitive checks, not null,
|
||||
email-validation, string size, integer and date ranges in your
|
||||
validation callbacks.</p>
|
||||
<div class="highlight-php"><div class="highlight"><pre><span class="cp"><?php</span>
|
||||
|
||||
<span class="sd">/** @Document @HasLifecycleCallbacks */</span>
|
||||
<span class="k">class</span> <span class="nc">Order</span>
|
||||
<span class="p">{</span>
|
||||
<span class="sd">/** @PrePersist @PreUpdate */</span>
|
||||
<span class="k">public</span> <span class="k">function</span> <span class="nf">validate</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">plannedShipDate</span> <span class="nx">instanceof</span> <span class="nx">DateTime</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="k">throw</span> <span class="k">new</span> <span class="nx">ValidateException</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">plannedShipDate</span><span class="o">-></span><span class="na">format</span><span class="p">(</span><span class="s1">'U'</span><span class="p">)</span> <span class="o"><</span> <span class="nb">time</span><span class="p">())</span> <span class="p">{</span>
|
||||
<span class="k">throw</span> <span class="k">new</span> <span class="nx">ValidateException</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">customer</span> <span class="o">==</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">throw</span> <span class="k">new</span> <span class="nx">OrderRequiresCustomerException</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>What is nice about lifecycle events is, you can also re-use the
|
||||
methods at other places in your domain, for example in combination
|
||||
with your form library. Additionally there is no limitation in the
|
||||
number of methods you register on one particular event, i.e. you
|
||||
can register multiple methods for validation in "PrePersist" or
|
||||
"PreUpdate" or mix and share them in any combinations between those
|
||||
two events.</p>
|
||||
<p>There is no limit to what you can and can't validate in
|
||||
"PrePersist" and "PreUpdate" as long as you don't create new document
|
||||
instances. This was already discussed in the previous blog post on
|
||||
the Versionable extension, which requires another type of event
|
||||
called "onFlush".</p>
|
||||
<p>Further readings: <a class="reference internal" href="../reference/events.html"><span class="doc">Lifecycle Events</span></a></p>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="sphinxsidebar">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
|
||||
<div id="searchbox" style="">
|
||||
<h3>Search</h3>
|
||||
<form class="search" action="http://readthedocs.org/search/project/" method="get">
|
||||
<input type="text" name="q" size="18">
|
||||
<input type="submit" value="Go">
|
||||
<input type="hidden" name="selected_facets" value="project:">
|
||||
</form>
|
||||
</div>
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/cookbook/validation-of-documents.rst.txt"
|
||||
rel="nofollow">Show Source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© Copyright 2013, Doctrine Project Team.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.2.
|
||||
<br/>
|
||||
<a target="_BLANK" href="http://www.servergrove.com"><img src="http://www.doctrine-project.org/_static/servergrove.jpg" /></a> <br/><br/>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id" value="BAE2E3XANQ77Y" />
|
||||
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
|
||||
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="bot-rcnr">
|
||||
<div class="tl"><!-- corner --></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-288343-7";
|
||||
urchinTracker();
|
||||
</script>
|
||||
<a class="githublink" href="http://github.com/doctrine"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user