diff --git a/Resources/doc/config.rst b/Resources/doc/config.rst index fe846adb..80f298a8 100644 --- a/Resources/doc/config.rst +++ b/Resources/doc/config.rst @@ -8,7 +8,7 @@ Sample Configuration .. code-block:: yaml - # app/config/config.yml + # config/packages/doctrine_mongodb.yaml doctrine_mongodb: connections: default: @@ -51,20 +51,20 @@ Sample Configuration .. tip:: If each environment requires a different MongoDB connection URI, you can - define it in a separate parameter and reference it in the bundle config: + `define it as an environment variable`_ and reference it in the bundle's config: .. code-block:: yaml - # app/config/parameters.yml - mongodb_server: mongodb://localhost:27017 + # .env + MONGODB_URL=mongodb://localhost:27017 .. code-block:: yaml - # app/config/config.yml + # config/packages/doctrine_mongodb.yaml doctrine_mongodb: connections: default: - server: "%mongodb_server%" + server: '%env(resolve:MONGODB_URL)%' If you wish to use memcache to cache your metadata, you need to configure the ``Memcache`` instance; for example, you can do the following: @@ -133,7 +133,7 @@ can control. The following configuration options exist for a mapping: this path is relative it is assumed to be relative to the bundle root. This only works if the name of your mapping is a bundle name. If you want to use this option to specify absolute paths you should prefix the path with the - kernel parameters that exist in the DIC (for example %kernel.root_dir%). + kernel parameters that exist in the DIC (for example ``%kernel.project_dir%``). - ``prefix`` A common namespace prefix that all documents of this mapping share. This prefix should never conflict with prefixes of other defined @@ -154,14 +154,14 @@ can control. The following configuration options exist for a mapping: To avoid having to configure lots of information for your mappings you should follow these conventions: -1. Put all your documents in a directory ``Document/`` inside your bundle. For - example ``Acme/HelloBundle/Document/``. +1. Put all your documents in a directory ``Document/`` inside your project. For + example ``src/Document/``. 2. If you are using xml, yml or php mapping put all your configuration files into the ``Resources/config/doctrine/`` directory suffixed with mongodb.xml, mongodb.yml or mongodb.php respectively. -3. Annotations is assumed if a ``Document/`` but no +3. Annotations are assumed if a ``Document/`` but no ``Resources/config/doctrine/`` directory is found. The following configuration shows a bunch of mapping examples: @@ -184,7 +184,7 @@ The following configuration shows a bunch of mapping examples: alias: BundleAlias doctrine_extensions: type: xml - dir: "%kernel.root_dir%/../src/vendor/DoctrineExtensions/lib/DoctrineExtensions/Documents" + dir: "%kernel.project_dir%/src/vendor/DoctrineExtensions/lib/DoctrineExtensions/Documents" prefix: DoctrineExtensions\Documents\ alias: DExt @@ -207,7 +207,7 @@ The following configuration shows a bunch of mapping examples: @@ -363,7 +363,7 @@ Connecting to a pool of mongodb servers on 1 connection It is possible to connect to several mongodb servers on one connection if you are using a replica set by listing all of the servers within the connection -string as a comma separated list. +string as a comma separated list and using ``replicaSet`` option. .. configuration-block:: @@ -373,7 +373,7 @@ string as a comma separated list. # ... connections: default: - server: "mongodb://mongodb-01:27017,mongodb-02:27017,mongodb-03:27017" + server: "mongodb://mongodb-01:27017,mongodb-02:27017,mongodb-03:27017/?replicaSet=replSetName" .. code-block:: xml @@ -386,20 +386,25 @@ string as a comma separated list. http://symfony.com/schema/dic/doctrine/odm/mongodb https://symfony.com/schema/dic/doctrine/odm/mongodb/mongodb-1.0.xsd"> - + Where mongodb-01, mongodb-02 and mongodb-03 are the machine hostnames. You can also use IP addresses if you prefer. +.. tip:: + + Please refer to `Replica Sets`_ manual of MongoDB PHP Driver for futher details. + + Using Authentication on a Database Level ---------------------------------------- MongoDB supports authentication and authorisation on a database-level. This is mandatory if you have e.g. a publicly accessible MongoDB Server. To make use of this feature you need to configure credentials -for each of your connections. Also every connection needs a database set to authenticate against. The setting is -represented by the *authSource* `connection string `_. +for each of your connections. Every connection needs also a database to authenticate against. The setting is +represented by the *authSource* `connection string`_. Otherwise you will get a *auth failed* exception. .. configuration-block:: @@ -442,7 +447,8 @@ Specifying a context service ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The MongoDB driver supports receiving a stream context to set SSL and logging -options. This can be used to authenticate using SSL certificates. To do so, create a service that creates your logging context: +options. This can be used to authenticate using SSL certificates. To do so, +create a service that creates your logging context: .. configuration-block:: @@ -635,3 +641,7 @@ Full Default Configuration + +.. _`define it as an environment variable`: https://symfony.com/doc/current/configuration.html#configuration-based-on-environment-variables +.. _`connection string`: https://docs.mongodb.com/manual/reference/connection-string/#urioption.authSource +.. _`Replica Sets`: https://www.php.net/manual/en/mongo.connecting.rs.php diff --git a/Resources/doc/console.rst b/Resources/doc/console.rst index d4efbed4..2efa9270 100644 --- a/Resources/doc/console.rst +++ b/Resources/doc/console.rst @@ -1,7 +1,7 @@ Console Commands ================ -The Doctrine2 ODM integration offers several console commands under the +The Doctrine2 ODM integration offers various console commands under the ``doctrine:mongodb`` namespace. To view the command list you can run the console without any arguments: @@ -9,8 +9,8 @@ without any arguments: php bin/console -A list of available command will print out, many of which start with the -``doctrine:mongodb`` prefix. You can find out more information about any +A list of available commands will be printed out, several of them start +with the ``doctrine:mongodb`` prefix. You can find out more information about any of these commands (or any Symfony command) by running the ``help`` command. For example, to get details about the ``doctrine:mongodb:query`` task, run: @@ -24,4 +24,4 @@ For example, to get details about the ``doctrine:mongodb:query`` task, run: ``DoctrineFixturesBundle`` bundle installed. To learn how to do it, read the "`DoctrineFixturesBundle`_" entry of the documentation. -.. _`DoctrineFixturesBundle`: http://symfony.com/doc/master/bundles/DoctrineFixturesBundle/index.html +.. _`DoctrineFixturesBundle`: https://symfony.com/doc/master/bundles/DoctrineFixturesBundle/index.html diff --git a/Resources/doc/cookbook/registration_form.rst b/Resources/doc/cookbook/registration_form.rst index 5fe353d1..61fc5a8d 100644 --- a/Resources/doc/cookbook/registration_form.rst +++ b/Resources/doc/cookbook/registration_form.rst @@ -2,19 +2,19 @@ Creating a Registration Form ============================ Some forms have extra fields whose values don't need to be stored in the -database. In this example, we'll create a registration form with some extra -fields and (like a "terms accepted" checkbox field) and embed the form that -actually stores the account information. We'll use MongoDB for storing the data. +database. In this example, we'll create a registration form with such +field ("terms accepted" checkbox field) and embed the form that actually +stores the account information. We'll use MongoDB for storing the data. -The simple User model +The User Model --------------------- -So, in this tutorial we begin with the model for a ``User`` document: +We begin this tutorial with the model for a ``User`` document: .. code-block:: php - // src/Acme/AccountBundle/Document/User.php - namespace Acme\AccountBundle\Document; + // src/Document/User.php + namespace App\Document; use Doctrine\Bundle\MongoDBBundle\Validator\Constraints\Unique as MongoDBUnique; use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; @@ -72,13 +72,13 @@ So, in this tutorial we begin with the model for a ``User`` document: } This ``User`` document contains three fields and two of them (email and -password) should display on the form. The email property must be unique -on the database, so we've added this validation at the top of the class. +password) should be displayed in the form. The email property must be unique +in the database, so we've added this validation at the top of the class. .. note:: - If you want to integrate this User within the security system,you need - to implement the `UserInterface`_ of the security component. + If you want to integrate this User within the security system, you need + to implement the ``UserInterface`` of the `Security component`_. Create a Form for the Model --------------------------- @@ -87,10 +87,10 @@ Next, create the form for the ``User`` model: .. code-block:: php - // src/Acme/AccountBundle/Form/Type/UserType.php - namespace Acme\AccountBundle\Form\Type; + // src/Form/Type/UserType.php + namespace App\Form\Type; - use Acme\AccountBundle\Document\User; + use App\Document\User; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\PasswordType; @@ -104,9 +104,9 @@ Next, create the form for the ``User`` model: { $builder->add('email', EmailType::class); $builder->add('password', RepeatedType::class, [ - 'first_name' => 'password', - 'second_name' => 'confirm', - 'type' => PasswordType::class + 'first_name' => 'password', + 'second_name' => 'confirm', + 'type' => PasswordType::class ]); } @@ -118,44 +118,43 @@ Next, create the form for the ``User`` model: } } -We just added two fields: email and password (repeated to confirm the entered -password). The ``data_class`` option tells the form the name of data class -(i.e. your ``User`` document). +We added two fields: email and password (repeated to confirm the entered +password). The ``data_class`` option tells the form the name of the class +that holds the underlying data (i.e. your ``User`` document). .. tip:: - To explore more things about form component, read this documentation `file`_. + To explore more things about the Form component, read its `documentation`_. Embedding the User form into a Registration Form ------------------------------------------------ The form that you'll use for the registration page is not the same as the -form used to simply modify the ``User`` (i.e. ``UserType``). The registration +form used to modify the ``User`` (i.e. ``UserType``). The registration form will contain further fields like "accept the terms", whose value won't be stored in the database. In other words, create a second form for registration, which embeds the ``User`` -form and adds the extra field needed. Start by creating a simple class which -represents the "registration": +form and adds the extra field needed: .. code-block:: php - // src/Acme/AccountBundle/Form/Model/Registration.php - namespace Acme\AccountBundle\Form\Model; + // src/Form/Model/Registration.php + namespace App\Form\Model; - use Acme\AccountBundle\Document\User; + use App\Document\User; use Symfony\Component\Validator\Constraints as Assert; class Registration { /** - * @Assert\Type(type="Acme\AccountBundle\Document\User") + * @Assert\Type(type="App\Document\User") */ protected $user; /** * @Assert\NotBlank() - * @Assert\True() + * @Assert\IsTrue() */ protected $termsAccepted; @@ -176,7 +175,7 @@ represents the "registration": public function setTermsAccepted($termsAccepted) { - $this->termsAccepted = (boolean)$termsAccepted; + $this->termsAccepted = (bool) $termsAccepted; } } @@ -184,11 +183,11 @@ Next, create the form for this ``Registration`` model: .. code-block:: php - // src/Acme/AccountBundle/Form/Type/RegistrationType.php - namespace Acme\AccountBundle\Form\Type; + // src/Form/Type/RegistrationType.php + namespace App\Form\Type; use Symfony\Component\Form\AbstractType; - use Symfony\Component\Form\Extension\Core\Type\CheckboxType + use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\FormBuilderInterface; class RegistrationType extends AbstractType @@ -200,34 +199,35 @@ Next, create the form for this ``Registration`` model: } } -You don't need to use special method for embedding the ``UserType`` form. -A form is a field, too - so you can add this like any other field, with the +You don't need to use any special method to embed the ``UserType`` form. +A form is a field, too - you can add it like any other field, with the expectation that the corresponding ``user`` property will hold an instance of the class ``UserType``. Handling the Form Submission ---------------------------- -Next, you need a controller to handle the form. Start by creating a simple -controller for displaying the registration form: +Next, you need a controller to handle the form. Start by creating a +controller that will display the registration form: .. code-block:: php - // src/Acme/AccountBundle/Controller/AccountController.php - namespace Acme\AccountBundle\Controller; + // src/Controller/AccountController.php + namespace App\Controller; - use Acme\AccountBundle\Form\Model\Registration; - use Acme\AccountBundle\Form\Type\RegistrationType; - use Symfony\Bundle\FrameworkBundle\Controller\Controller; + use App\Form\Model\Registration; + use App\Form\Type\RegistrationType; + use Doctrine\ODM\MongoDB\DocumentManager; + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; - class AccountController extends Controller + class AccountController extends AbstractController { public function registerAction() { $form = $this->createForm(RegistrationType::class, new Registration()); - return $this->render('AcmeAccountBundle:Account:register.html.twig', [ + return $this->render('Account/register.html.twig', [ 'form' => $form->createView() ]); } @@ -237,18 +237,19 @@ and its template: .. code-block:: html+jinja - {# src/Acme/AccountBundle/Resources/views/Account/register.html.twig #} + {# templates/Account/register.html.twig #} {{ form_start(form, {'action': path('create'), 'method': 'POST'}) }} {{ form_widget(form) }} {{ form_end(form) }} -Finally, create the controller which handles the form submission. This performs -the validation and saves the data into MongoDB: +Finally, create another action in ``AccountController``, which will handle +the form submission - perform its validation and save the User into MongoDB: .. code-block:: php + // src/Controller/AccountController.php public function createAction(DocumentManager $dm, Request $request) { $form = $this->createForm(RegistrationType::class, new Registration()); @@ -264,13 +265,13 @@ the validation and saves the data into MongoDB: return $this->redirect(...); } - return $this->render('AcmeAccountBundle:Account:register.html.twig', [ + return $this->render('Account/register.html.twig', [ 'form' => $form->createView() ]); } -That's it! Your form now validates, and allows you to save the ``User`` -object to MongoDB. +That's it! Your form now validates sent data and allows you to save +the ``User`` object to MongoDB. -.. _`UserInterface`: http://symfony.com/doc/current/book/security.html#book-security-user-entity -.. _`file`: http://symfony.com/doc/current/book/forms.html +.. _`Security component`: https://symfony.com/doc/current/security.html +.. _`documentation`: https://symfony.com/doc/current/forms.html diff --git a/Resources/doc/events.rst b/Resources/doc/events.rst index 749c3d9f..72c102e8 100644 --- a/Resources/doc/events.rst +++ b/Resources/doc/events.rst @@ -24,8 +24,8 @@ event managers for all connections. To restrict a listener to a single connection, specify its name in the tag's ``connection`` attribute. The ``priority`` attribute, which defaults to ``0`` if omitted, may be used -to control the order that listeners are registered. Much like Symfony's -`event dispatcher`_, greater numbers will result in the listener executing +to control the order in which listeners are registered. Much like Symfony's +`event dispatcher`_, greater number will result in the listener executing first and listeners with the same priority will be executed in the order that they were registered with the event manager. @@ -39,21 +39,21 @@ when its event is dispatched. services: my_doctrine_listener: - class: Acme\HelloBundle\Listener\MyDoctrineListener + class: App\Listener\MyDoctrineListener # ... tags: - { name: doctrine_mongodb.odm.event_listener, event: postPersist } .. code-block:: xml - + .. code-block:: php - $definition = new Definition('Acme\HelloBundle\Listener\MyDoctrineListener'); + $definition = new Definition('App\Listener\MyDoctrineListener'); // ... $definition->addTag('doctrine_mongodb.odm.event_listener', [ 'event' => 'postPersist', @@ -64,11 +64,11 @@ Event Subscribers ----------------- Use the ``doctrine_mongodb.odm.event_subscriber`` tag -to register a subscriber. Subscribers are responsible for implementing -``Doctrine\Common\EventSubscriber`` and a method for returning the events -they will observe. For this reason, this tag has no ``event`` attribute; -however, the ``connection``, ``priority`` and ``lazy`` attributes are -available. +to register a subscriber. Subscribers must implement the +``Doctrine\Common\EventSubscriber`` interface, which means that they must +contain method returning the events they will observe. For this reason, +this tag has no ``event`` attribute, however the ``connection``, +``priority`` and ``lazy`` attributes are available. .. note:: @@ -77,6 +77,6 @@ available. event(s). For this reason, the aforementioned tags have no ``method`` attribute. -.. _`event dispatcher`: http://symfony.com/doc/current/components/event_dispatcher/introduction.html -.. _`Event Documentation`: http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/events.html +.. _`event dispatcher`: https://symfony.com/doc/current/components/event_dispatcher.html +.. _`Event Documentation`: https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/events.html .. _`tagging`: https://symfony.com/doc/current/service_container/tags.html diff --git a/Resources/doc/first_steps.rst b/Resources/doc/first_steps.rst index 252978ae..77bad798 100644 --- a/Resources/doc/first_steps.rst +++ b/Resources/doc/first_steps.rst @@ -5,17 +5,8 @@ The best way to understand the Doctrine MongoDB ODM is to see it in action. In this section, you'll walk through each step needed to start persisting documents to and from MongoDB. -.. sidebar:: Code along with the example - - If you want to follow along with the example in this chapter, create - an ``AcmeStoreBundle`` via: - - .. code-block:: bash - - php bin/console generate:bundle --namespace=Acme/StoreBundle - -A Simple Example: A Product ---------------------------- +An Introductory Example: A Product +---------------------------------- Creating a Document Class ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -23,12 +14,12 @@ Creating a Document Class Suppose you're building an application where products need to be displayed. Without even thinking about Doctrine or MongoDB, you already know that you need a ``Product`` object to represent those products. Create this class -inside the ``Document`` directory of your ``AcmeStoreBundle``: +inside the ``Document`` subdirectory of your project's source code: .. code-block:: php - // src/Acme/StoreBundle/Document/Product.php - namespace Acme\StoreBundle\Document; + // src/Document/Product.php + namespace App\Document; class Product { @@ -38,9 +29,9 @@ inside the ``Document`` directory of your ``AcmeStoreBundle``: } The class - often called a "document", meaning *a basic class that holds data* - -is simple and helps fulfill the business requirement of needing products -in your application. This class can't be persisted to Doctrine MongoDB yet - -it's just a simple PHP class. +helps fulfill the business requirement of needing products in your application. +This class can't be persisted to Doctrine MongoDB yet - currently it's +only a plain PHP class. Add Mapping Information ~~~~~~~~~~~~~~~~~~~~~~~ @@ -51,7 +42,7 @@ you to persist entire *objects* to MongoDB and fetch entire objects out of MongoDB. This works by mapping a PHP class and its properties to entries of a MongoDB collection. -For Doctrine to be able to do this, you just have to create "metadata", or +For Doctrine to be able to do this, you have to create "metadata", or configuration that tells Doctrine exactly how the ``Product`` class and its properties should be *mapped* to MongoDB. This metadata can be specified in a number of different formats including XML or directly inside the @@ -61,13 +52,13 @@ in a number of different formats including XML or directly inside the .. code-block:: xml - + - + @@ -76,8 +67,8 @@ in a number of different formats including XML or directly inside the .. code-block:: php - // src/Acme/StoreBundle/Document/Product.php - namespace Acme\StoreBundle\Document; + // src/Document/Product.php + namespace App\Document; use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; @@ -115,15 +106,14 @@ Persisting Objects to MongoDB ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Now that you have a mapped ``Product`` document complete with getter and -setter methods, you're ready to persist data to MongoDB. From inside a controller, -this is pretty easy. Add the following method to the ``DefaultController`` -of the bundle: +setter methods, you're ready to persist data to MongoDB. Let's try it from inside +a controller. Create new Controller class inside source directory of your project: .. code-block:: php :linenos: - // src/Acme/StoreBundle/Controller/DefaultController.php - use Acme\StoreBundle\Document\Product; + // src/App/Controller/ProductController.php + use App\Document\Product; use Doctrine\ODM\MongoDB\DocumentManager; use Symfony\Component\HttpFoundation\Response; // ... @@ -137,7 +127,7 @@ of the bundle: $dm->persist($product); $dm->flush(); - return new Response('Created product id '.$product->getId()); + return new Response('Created product id ' . $product->getId()); } .. note:: @@ -147,12 +137,8 @@ of the bundle: Let's walk through this example: -* **lines 8-10** In this section, you instantiate and work with the ``$product`` - object like any other, normal PHP object; - -* **line 12** This line fetches Doctrine's *document manager* object, which is - responsible for handling the process of persisting and fetching objects - to and from MongoDB; +* **lines 9-11** In this section, you instantiate and work with the ``$product`` + object like you would with any other, normal PHP object; * **line 13** The ``persist()`` method tells Doctrine to "manage" the ``$product`` object. This does not actually cause a query to be made to MongoDB (yet); @@ -162,33 +148,6 @@ Let's walk through this example: to MongoDB. In this example, the ``$product`` object has not been persisted yet, so the document manager makes a query to MongoDB, which adds a new entry. -If you are using `autowiring`, you can use type hinting to fetch the ``doctrine_mongodb.odm.document_manager`` service: - -.. code-block:: php - - // App/Controller/DefaultController.php - namespace App\Controller; - - use App\Document\Product; - use Doctrine\ODM\MongoDB\DocumentManager; - use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; - use Symfony\Component\HttpFoundation\Response; - - class DefaultController extends AbstractController - { - public function createProduct(DocumentManager $dm) - { - $product = new Product(); - $product->setName('A Foo Bar'); - $product->setPrice('19.99'); - - $dm->persist($product); - $dm->flush(); - - return new Response('Created product id '.$product->getId()); - } - } - .. note:: In fact, since Doctrine is aware of all your managed objects, when you @@ -202,14 +161,14 @@ they already exist in MongoDB. .. tip:: Doctrine provides a library that allows you to programmatically load testing - data into your project (i.e. "fixture data"). For information, see + data into your project (i.e. "fixture data"). For more information, see `DoctrineFixturesBundle`_. Fetching Objects from MongoDB ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Fetching an object back out of MongoDB is even easier. For example, suppose -you've configured a route to display a specific ``Product`` based on its +Fetching an object back out of MongoDB is also possible. For example, suppose +that you've configured a route to display a specific ``Product`` based on its ``id`` value: .. code-block:: php @@ -218,8 +177,8 @@ you've configured a route to display a specific ``Product`` based on its { $product = $dm->getRepository(Product::class)->find($id); - if (!$product) { - throw $this->createNotFoundException('No product found for id '.$id); + if (! $product) { + throw $this->createNotFoundException('No product found for id ' . $id); } // do something, like pass the $product object into a template @@ -234,13 +193,6 @@ repository object for a document class via: $repository = $dm->getRepository(Product::class); -.. note:: - - The ``AcmeStoreBundle:Product`` string is a shortcut you can use anywhere - in Doctrine instead of the full class name of the document (i.e. ``Acme\StoreBundle\Document\Product``). - As long as your document lives under the ``Document`` namespace of your bundle, - this will work. - Once you have your repository, you have access to all sorts of helpful methods: .. code-block:: php @@ -248,39 +200,35 @@ Once you have your repository, you have access to all sorts of helpful methods: // query by the identifier (usually "id") $product = $repository->find($id); - // dynamic method names to find based on a column value - $product = $repository->findOneById($id); - $product = $repository->findOneByName('foo'); - // find *all* products $products = $repository->findAll(); // find a group of products based on an arbitrary column value - $products = $repository->findByPrice(19.99); + $products = $repository->findBy(['price' => 19.99]); .. note:: - Of course, you can also issue complex queries, which you'll learn more - about in the `Querying for Objects`_ section. + You can also issue complex queries, you can learn more about them + in the `Querying for Objects`_ section. You can also take advantage of the useful ``findBy()`` and ``findOneBy()`` methods to easily fetch objects based on multiple conditions: .. code-block:: php - // query for one product matching be name and price + // query for one product matching by name and price $product = $repository->findOneBy(['name' => 'foo', 'price' => 19.99]); // query for all products matching the name, ordered by price $product = $repository->findBy( ['name' => 'foo'], - ['price' => 'ASC'], + ['price' => 'ASC'] ); Updating an Object ~~~~~~~~~~~~~~~~~~ -Once you've fetched an object from Doctrine, updating it is easy. Suppose +Once you've fetched an object from Doctrine, let's try to update it. Suppose you have a route that maps a product id to an update action in a controller: .. code-block:: php @@ -289,24 +237,25 @@ you have a route that maps a product id to an update action in a controller: { $product = $dm->getRepository(Product::class)->find($id); - if (!$product) { - throw $this->createNotFoundException('No product found for id '.$id); + if (! $product) { + throw $this->createNotFoundException('No product found for id ' . $id); } $product->setName('New product name!'); + $dm->flush(); return $this->redirectToRoute('homepage'); } -Updating an object involves just three steps: +Updating an object involves three steps: 1. Fetching the object from Doctrine; 2. Modifying the object; 3. Calling ``flush()`` on the document manager. Notice that calling ``$dm->persist($product)`` isn't necessary. Recall that -this method simply tells Doctrine to manage or "watch" the ``$product`` object. +this method tells Doctrine to manage or "watch" the ``$product`` object. In this case, since you fetched the ``$product`` object from Doctrine, it's already managed. @@ -321,17 +270,17 @@ method of the document manager: $dm->remove($product); $dm->flush(); -As you might expect, the ``remove()`` method notifies Doctrine that you'd -like to remove the given document from the MongoDB. The actual delete operation -however, isn't actually executed until the ``flush()`` method is called. +The ``remove()`` method notifies Doctrine that you'd like to remove +the given document from the MongoDB. The actual delete operation +however, isn't executed until the ``flush()`` method is called. Querying for Objects -------------------- As you saw above, the built-in repository class allows you to query for one -or many objects based on an number of different parameters. When this is -enough, this is the easiest way to query for documents. Of course, you can -also create more complex queries. +or many objects based on any number of different parameters. When this is +enough, this is the easiest way to query for documents. You can also create +more complex queries. Using the Query Builder ~~~~~~~~~~~~~~~~~~~~~~~ @@ -348,7 +297,7 @@ From inside a controller: ->sort('price', 'ASC') ->limit(10) ->getQuery() - ->execute() + ->execute(); In this case, 10 products with a name of "foo", ordered from lowest price to highest price are returned. @@ -372,10 +321,10 @@ To do this, add the name of the repository class to your mapping definition. .. code-block:: php-annotations - // src/Acme/StoreBundle/Document/Product.php - namespace Acme\StoreBundle\Document; + // src/Document/Product.php + namespace App\Document; - use Acme\StoreBundle\Repository\ProductRepository; + use App\Repository\ProductRepository; use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; /** @@ -388,15 +337,15 @@ To do this, add the name of the repository class to your mapping definition. .. code-block:: xml - + - + @@ -409,8 +358,8 @@ for all of the ``Product`` documents, ordered alphabetically. .. code-block:: php - // src/Acme/StoreBundle/Repository/ProductRepository.php - namespace Acme\StoreBundle\Repository; + // src/Repository/ProductRepository.php + namespace App\Repository; use Doctrine\ODM\MongoDB\Repository\DocumentRepository; @@ -425,7 +374,7 @@ for all of the ``Product`` documents, ordered alphabetically. } } -You can use this new method just like the default finder methods of the repository: +You can use this new method like the default finder methods of the repository: .. code-block:: php @@ -447,10 +396,10 @@ is to use the repository as a service and inject it as a dependency into other s .. code-block:: php - // src/Acme/StoreBundle/Repository/ProductRepository.php - namespace Acme\StoreBundle\Repository; + // src/App/Repository/ProductRepository.php + namespace App\Repository; - use Acme\StoreBundle\Document\Product; + use App\Document\Product; use Doctrine\Bundle\MongoDBBundle\ManagerRegistry; use Doctrine\Bundle\MongoDBBundle\Repository\ServiceDocumentRepository; @@ -474,16 +423,18 @@ repositories as services you can use the following service configuration: .. code-block:: yaml + # config/services.yaml services: _defaults: autowire: true autoconfigure: true - Acme\StoreBundle\Repository\: - resource: '%kernel.root_dir%/../src/Acme/StoreBundle/Repository/*' + App\Repository\: + resource: '../src/Repository/*' .. code-block:: xml + - + -.. _`Basic Mapping Documentation`: http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/basic-mapping.html -.. _`Conditional Operators`: http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/query-builder-api.html#conditional-operators -.. _`DoctrineFixturesBundle`: http://symfony.com/doc/master/bundles/DoctrineFixturesBundle/index.html -.. _`Query Builder`: http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/query-builder-api.html +.. _`Basic Mapping Documentation`: https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/basic-mapping.html +.. _`Conditional Operators`: https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/query-builder-api.html#conditional-operators +.. _`DoctrineFixturesBundle`: https://symfony.com/doc/master/bundles/DoctrineFixturesBundle/index.html +.. _`Query Builder`: https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/query-builder-api.html .. _`autowiring`: https://symfony.com/doc/current/service_container/autowiring.html .. _`autoconfiguration`: https://symfony.com/doc/current/service_container.html#the-autoconfigure-option diff --git a/Resources/doc/form_validation.rst b/Resources/doc/form_validation.rst index da2325be..51319e2d 100644 --- a/Resources/doc/form_validation.rst +++ b/Resources/doc/form_validation.rst @@ -22,4 +22,4 @@ means that the ``em`` option should be used if you wish to specify the document manager explicitly instead of having it be inferred from the document class. .. _`EntityType`: https://symfony.com/doc/current/reference/forms/types/entity.html -.. _`UniqueEntity`: http://symfony.com/doc/current/reference/constraints/UniqueEntity.html +.. _`UniqueEntity`: https://symfony.com/doc/current/reference/constraints/UniqueEntity.html diff --git a/Resources/doc/index.rst b/Resources/doc/index.rst index ac65144d..95233b85 100644 --- a/Resources/doc/index.rst +++ b/Resources/doc/index.rst @@ -10,15 +10,15 @@ persisted transparently to and from MongoDB. You can read more about the Doctrine MongoDB ODM via the project's `documentation`_. -A bundle is available that integrates the Doctrine MongoDB ODM into Symfony, -making it easy to configure and use. +The bundle integrates the Doctrine MongoDB ODM into Symfony, +helping you to configure and use it in your application. .. note:: This documentation will feel a lot like the `Doctrine2 ORM chapter`_, which talks about how the Doctrine ORM can be used to persist data to relational databases (e.g. MySQL). This is on purpose - whether you persist - to a relational database via the ORM or MongoDB via the ODM, the philosophies + to a relational database via the ORM or to MongoDB via the ODM, the philosophies are very much the same. .. toctree:: @@ -36,15 +36,16 @@ Doctrine Extensions: Timestampable, Sluggable, etc. --------------------------------------------------- Doctrine is quite flexible, and a number of third-party extensions are available -that allow you to easily perform repeated and common tasks on your entities. -These include thing such as *Sluggable*, *Timestampable*, *Loggable*, *Translatable*, +that allow you to perform repeated and common tasks on your entities. +These include things such as *Sluggable*, *Timestampable*, *Loggable*, *Translatable*, and *Tree*. -For more information on how to find and use these extensions, see the cookbook -article about `using common Doctrine extensions`_. +For more information about them, see `available Doctrine extensions`_ +and use the `StofDoctrineExtensionsBundle`_ to integrate them in your application. -.. _`MongoDB`: http://www.mongodb.org/ -.. _`Doctrine2 ORM`: http://symfony.com/doc/current/book/doctrine.html -.. _`documentation`: http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/ -.. _`Doctrine2 ORM chapter`: http://symfony.com/doc/current/book/doctrine.html -.. _`using common Doctrine extensions`: http://symfony.com/doc/current/cookbook/doctrine/common_extensions.html +.. _`MongoDB`: https://www.mongodb.com +.. _`Doctrine2 ORM`: https://symfony.com/doc/current/book/doctrine.html +.. _`documentation`: https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/ +.. _`Doctrine2 ORM chapter`: https://symfony.com/doc/current/book/doctrine.html +.. _`available Doctrine extensions`: https://github.com/Atlantic18/DoctrineExtensions +.. _`StofDoctrineExtensionsBundle`: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html diff --git a/Resources/doc/installation.rst b/Resources/doc/installation.rst index 7b34d710..d1171764 100644 --- a/Resources/doc/installation.rst +++ b/Resources/doc/installation.rst @@ -11,8 +11,8 @@ in the `installation chapter`_ of the Composer documentation. Install the bundle with Symfony Flex ------------------------------------ -A Flex recipe for the DoctrineMongoDBBundle is provided through a Contrib Recipe -therefore you need to allow its usage: +A Flex recipe for the DoctrineMongoDBBundle is provided as a Contrib Recipe. +You need to allow its usage first: .. code-block:: bash @@ -25,44 +25,48 @@ therefore you need to allow its usage: Install the bundle with Composer -------------------------------- -To install DoctrineMongoDBBundle with Composer just run the following command: +To install DoctrineMongoDBBundle with Composer run the following command: .. code-block:: bash composer require doctrine/mongodb-odm-bundle -All that is left to do is to update your ``AppKernel.php`` file, and -register the new bundle: + +Enable the Bundle +----------------- + +Your bundle should be automatically enabled if you use Flex. +Otherwise, you'll need to manually enable the bundle by adding the +following line in the ``config/bundles.php`` file of your project: .. code-block:: php - // app/AppKernel.php - public function registerBundles() - { - $bundles = [ - // ... - new Doctrine\Bundle\MongoDBBundle\DoctrineMongoDBBundle(), - ]; + // config/bundles.php + ['all' => true], + ]; Configuration ------------- -To get started, you'll need some basic configuration that sets up the document -manager. The easiest way is to enable ``auto_mapping``, which will activate +Flex recipe will automatically create the ``config/packages/doctrine_mongodb.yaml`` +file with default configuration. Without Flex you need to create the file +manually and fill it with some basic configuration that sets up the document manager. +The recommended way is to enable ``auto_mapping``, which will activate the MongoDB ODM across your application: .. code-block:: yaml - # app/config/parameters.yml + # config/services.yaml parameters: mongodb_server: "mongodb://localhost:27017" .. code-block:: yaml - # app/config/config.yml + # config/packages/doctrine_mongodb.yaml doctrine_mongodb: connections: default: @@ -75,24 +79,31 @@ the MongoDB ODM across your application: .. note:: - Of course, you'll also need to make sure that the MongoDB server is running - in the background. For more details, see the MongoDB `Quick Start`_ guide. + Please also make sure that the MongoDB server is running in the background. + For more details, see the MongoDB `Installation Tutorials`_. + +.. tip:: + You can configure bundle options that depend on where your application + is run (e.g. during tests or development) with `Environment Variables`_. Authentication -------------- -If you use authentication on your MongoDB database you can the provide username, +If you use authentication on your MongoDB database, then you can provide username, password, and authentication database in the following way: - # app/config/parameters.yaml +.. code-block:: yaml + + # config/services.yaml parameters: mongodb_server: "mongodb://username:password@localhost:27017/?authSource=auth-db" .. note:: - The authentication database is different to the default database used by MongoDB. + The authentication database is different from the default database used by MongoDB. .. _`installation chapter`: https://getcomposer.org/doc/00-intro.md .. _`MongoDB driver`: https://docs.mongodb.com/ecosystem/drivers/php/ -.. _`Quick Start`: http://www.mongodb.org/display/DOCS/Quickstart +.. _`Installation Tutorials`: https://docs.mongodb.com/manual/installation/ +.. _`Environment Variables`: https://symfony.com/doc/current/configuration.html#configuration-based-on-environment-variables diff --git a/Resources/doc/security_bundle.rst b/Resources/doc/security_bundle.rst index 7a71551c..ae03893d 100644 --- a/Resources/doc/security_bundle.rst +++ b/Resources/doc/security_bundle.rst @@ -1,25 +1,28 @@ SecurityBundle integration ========================== -A user provider is available for your MongoDB projects, working exactly the -same as the ``entity`` provider described in `the cookbook`_: +A user provider is available for your MongoDB projects if you use +Symfony `SecurityBundle`_. It works exactly the same way as +the ``entity`` user provider described in `the cookbook`_: .. configuration-block:: .. code-block:: yaml + # config/packages/security.yaml security: providers: my_mongo_provider: - mongodb: {class: Acme\DemoBundle\Document\User, property: username} + mongodb: {class: App\Document\User, property: username} .. code-block:: xml - + - + -.. _`the cookbook`: http://symfony.com/doc/current/cookbook/security/entity_provider.html +.. _`SecurityBundle`: https://symfony.com/doc/current/security.html +.. _`the cookbook`: https://symfony.com/doc/current/cookbook/security/user_provider.html