Skip to main content
Efficient MongoDB CRUD operations Drupal: streamline data management, enhancing website performance and the user experience. MongoDB integration in Drupal
MongoDB CRUD operations Drupal

Efficient MongoDB CRUD operations Drupal: streamline data management, enhancing website performance and the user experience. MongoDB integration in Drupal.

MongoDB CRUD operations Drupal

CRUD stands for Create, Read, Update and Delete operations, we will learn how to perform these operations in Drupal and MongoDB atlas. Read our post on Integration of Drupal with MongoDB to improve scalability Part 1 if you want to verify your MondoDB integration with Drupal.

MongoDB CRUD: Create

Once you get the the connection object, first operation of MongoDB CRUD operations Drupal is create. In our example we will create a MongoDb collection Tasks.

We will start the create operation by making a form to create a task. All the fields we can define in buildForm method.

# web/modules/custom/bhimmu_mongodb/src/Form/TaskForm.php
/**
 * {@inheritdoc}
 */
public function buildForm(array $form, FormStateInterface $form_state): array {
  $form['title'] = [
    '#type' => 'textfield',
    '#title' => $this->t('Title'),
    '#required' => TRUE,
  ];
  $form['remark'] = [
    '#type' => 'textarea',
    '#title' => $this->t('Remark'),
    '#required' => TRUE,
  ];
  $form['is_completed'] = [
    '#type' => 'checkbox',
    '#title' => $this->t('Is completed'),
  ];
  $form['actions'] = [
    '#type' => 'actions',
    'submit' => [
      '#type' => 'submit',
      '#value' => $this->t('Save task'),
    ],
  ];
  return $form;
} 

To access this form we need to create a route.

bhimmu_mongodb.crud.create:
  path: '/bhimmu-mongodb/task/create'
  defaults:
    _title: 'Create task'
    _form: 'Drupal\bhimmu_mongodb\Form\TaskForm'
  requirements:
    _permission: 'administer account settings'

Now we can write the logic to save the task to the MongoDB atlas. Form class has an abstract method submitForm to submit the form data. This form is using mongodb.database_factory service to make db connection.

/**
 * {@inheritdoc}
 */
public function submitForm(array &$form, FormStateInterface $form_state): void {
  $collection = $this->mongodbDatabaseFactory->get('default')
      ->selectCollection('Tasks');
  $collection->insertOne([
    'taskName' => $form_state->getValue('title'),
    'remark' => $form_state->getValue('remark'),
    'isComplete' => $form_state->getValue('is_completed'),
  ]);
  $this->messenger()->addStatus($this->t('The task has been created.'));
}

MongoDB CRUD: Read

To see the data saved into MongoDB we need to fetch the data and display somewhere. Second step in MongoDB CRUD operations Drupal is Read. To see a page we will register a route to list all the tasks created in MongoDB.

bhimmu_mongodb.crud:
  path: '/bhimmu-mongodbs/tasks'
  defaults:
    _title: 'Tasks'
    _controller: '\Drupal\bhimmu_mongodb\Controller\BhimmuMongodbController::taskList'
  requirements:
    _permission: 'administer account settings'

This route is calling a method taskList from BhimmuMongodbCntroller class.

/**
 * Builds the response.
 */
public function taskList(): array {
  // Make header row.
  $header = [
    'id' => $this->t('ID'),
    'title' => $this->t('Title'),
    'is_completed' => $this->t('Is Completed'),
    'remark' => $this->t('Remark'),
    'actions' => $this->t('Actions'),
  ];
  // Invoke MongoDB instance.
  $database = $this->mongodbDatabaseFactory->get('default');
  // Fetch documents from a collection.
  /** @var \MongoDB\Model\BSONDocument $task */
  foreach ($database->Tasks->find() as $task) {
    $task = $task->jsonSerialize();
    $tasks[] = [
      'id' => [
        'data' => [
          '#markup' => $task->_id,
        ],
      ],
      'title' => [
        'data' => [
          '#markup' => $task->taskName,
        ],
      ],
      'is_completed' => [
        'data' => [
          '#markup' => $task->isComplete ? 'Yes': 'No',
        ],
      ],
      'remark' => [
        'data' => [
          '#markup' => $task->remark,
        ],
      ],
      'actions' => [
        'data' => [
          '#type' => 'operations',
          '#links' => [
            'view' => [
              'title' => $this->t('<i class="fa-solid fa-square-rss"></i> View'),
              'url' => Url::fromRoute('bhimmu_mongodb.crud.view', ['task_id' => $task->_id]),
            ],
            'edit' => [
              'title' => $this->t('<i class="fa-solid fa-square-rss"></i> Edit'),
              'url' => Url::fromRoute('bhimmu_mongodb.crud.edit', ['task_id' => $task->_id]),
            ],
            'delete' => [
              'title' => $this->t('<i class="fa-solid fa-square-rss"></i> Delete'),
              'url' => Url::fromRoute('bhimmu_mongodb.crud.delete', ['task_id' => $task->_id]),
            ],
          ],
        ],
      ],
    ];
  }
  $build['content'] = [
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $tasks,
    '#empty' => $this->t('There is no tasks!'),
  ];
  return $build;
}

Clear the cache to see the list of tasks from MongoDB.

Image
Mongo CRUD Read Bhimmu

To read single task, we need to create a route which takes task_id as parameter.

bhimmu_mongodb.crud.view:
  path: '/bhimmu-mongodb/task/{task_id}'
  defaults:
    _title: 'View task'
    _controller: '\Drupal\bhimmu_mongodb\Controller\BhimmuMongodbController::getTask'
  requirements:
    _permission: 'administer account settings'

Then create the Controller method getTask.

public function getTask(string $task_id) {
  $database = $this->mongodbDatabaseFactory->get('default');
  /** @var \MongoDB\Model\BSONDocument $task */
  $task = $database->Tasks->findOne(['_id' => new \MongoDB\BSON\ObjectID($task_id)]);
  $task = $task->jsonSerialize();
  return [
    '#theme' => 'task',
    '#task' => $task,
  ];
}

MongoDB CRUD: Update

In the actions column we have created operations links.

'#links' => [
  'view' => [
    'title' => $this->t('<i class="fa-solid fa-square-rss"></i> View'),
    'url' => Url::fromRoute('bhimmu_mongodb.crud.view', ['task_id' => $task->_id]),
  ],
  'edit' => [
    'title' => $this->t('<i class="fa-solid fa-square-rss"></i> Edit'),
    'url' => Url::fromRoute('bhimmu_mongodb.crud.edit', ['task_id' => $task->_id]),
  ],
  'delete' => [
    'title' => $this->t('<i class="fa-solid fa-square-rss"></i> Delete'),
    'url' => Url::fromRoute('bhimmu_mongodb.crud.delete', ['task_id' => $task->_id]),
  ],
],

To update the mongo collection, we need to open an edit form.

bhimmu_mongodb.crud.edit:
  path: '/bhimmu-mongodb/task/{task_id}/edit'
  defaults:
    _title: 'Create task'
    _form: 'Drupal\bhimmu_mongodb\Form\TaskForm'
  requirements:
    _permission: 'administer account settings'

Here we are using same form to add and edit task.

/**
 * {@inheritdoc}
 */
public function buildForm(array $form, FormStateInterface $form_state): array {
  $task = NULL;
  $task_id = $this->request->getCurrentRequest()->get('task_id');
  if (!empty($task_id)) {
    $database = $this->mongodbDatabaseFactory->get('default');
    /** @var \MongoDB\Model\BSONDocument $task */
    $task = $database->Tasks->findOne(['_id' => new \MongoDB\BSON\ObjectID($task_id)]);
    $task = $task->jsonSerialize();
  }
  $form['title'] = [
    '#type' => 'textfield',
    '#title' => $this->t('Title'),
    '#required' => TRUE,
    '#default_value' => $task?->taskName,
  ];
  $form['remark'] = [
    '#type' => 'textarea',
    '#title' => $this->t('Remark'),
    '#required' => TRUE,
    '#default_value' => $task?->remark,
  ];
  $form['is_completed'] = [
    '#type' => 'checkbox',
    '#title' => $this->t('Is completed'),
    '#default_value' => $task?->isComplete,
  ];
  $form['actions'] = [
    '#type' => 'actions',
    'submit' => [
      '#type' => 'submit',
      '#value' => $this->t('Save task'),
    ],
  ];
  return $form;
}
/**
 * {@inheritdoc}
 */
public function submitForm(array &$form, FormStateInterface $form_state): void {
  $task_id = $task_id = $this->request->getCurrentRequest()->get('task_id');
  $collection = $this->mongodbDatabaseFactory->get('default')
      ->selectCollection('Tasks');
  if (!empty($task_id)) {
    $updateResult = $collection->updateOne(
      [
        '_id' => new \MongoDB\BSON\ObjectID($task_id),
      ],
      ['$set' => ['remark' => $form_state->getValue('remark'),],]);
    $this->messenger()->addStatus($this->t('The task has been updated.'));
  }
  else {
    $collection->insertOne([
      'taskName' => $form_state->getValue('title'),
      'remark' => $form_state->getValue('remark'),
      'isComplete' => $form_state->getValue('is_completed'),
    ]);
    $this->messenger()->addStatus($this->t('The task has been created.'));
  }
  $form_state->setRedirect('bhimmu_mongodb.crud');
}

MongoDB CRUD: Delete

In the last step of MongoDB CRUD operations Drupal is delete. Begin it by registering a route to open a confirm form before deleting any task.

bhimmu_mongodb.crud.delete:
  path: '/bhimmu-mongodb/task/{task_id}/delete'
  defaults:
    _title: 'Task Delete Confirm'
    _form: 'Drupal\bhimmu_mongodb\Form\TaskDeleteConfirmForm'
  requirements:
    _permission: 'administer site configuration'

Confirm Form Class

<?php
declare(strict_types=1);
namespace Drupal\bhimmu_mongodb\Form;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\mongodb\DatabaseFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
 * @todo Add a description for the form.
 */
final class TaskDeleteConfirmForm extends ConfirmFormBase {
  /**
   * MongoDB database factory.
   *
   * @var \Drupal\mongodb\DatabaseFactory
   */
  protected $mongodbDatabaseFactory;
  /**
   * Symfony\Component\HttpFoundation\RequestStack
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  protected $request;
  /**
   * Constructor function.
   *
   * @param \Drupal\mongodb\DatabaseFactory $mongoDB
   */
  public function __construct(DatabaseFactory $mongoDB, RequestStack $request) {
    $this->mongodbDatabaseFactory = $mongoDB;
    $this->request = $request;
  }
  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('mongodb.database_factory'),
      $container->get('request_stack')
    );
  }
  /**
   * {@inheritdoc}
   */
  public function getFormId(): string {
    return 'bhimmu_mongodb_task_delete_confirm';
  }
  /**
   * {@inheritdoc}
   */
  public function getQuestion(): TranslatableMarkup {
    return $this->t('Are you sure you want to do this?');
  }
  /**
   * {@inheritdoc}
   */
  public function getCancelUrl(): Url {
    return new Url('bhimmu_mongodb.crud');
  }
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    // @todo Place your code here.
    $task_id = $task_id = $this->request->getCurrentRequest()->get('task_id');
    $collection = $this->mongodbDatabaseFactory->get('default')
        ->selectCollection('Tasks');
    $collection->deleteOne(['_id' => new \MongoDB\BSON\ObjectID($task_id)]);
    $this->messenger()->addStatus($this->t('Task has been deleted!'));
    $form_state->setRedirectUrl(new Url('bhimmu_mongodb.crud'));
  }
}

Get the full module from Github repository 

Similar Posts