Using Atlas 3 with Slim

This cookbook entry describes how to use the Atlas 3 ORMand its command-line tooling with Slim.

Installation

Install Atlas using Composer. The ORM and CLI packages are delivered separately,since you are likely to need the command line tooling only in development:

  1. composer require atlas/orm ~3.0
  2. composer require --dev atlas/cli ~2.0

Note:

If you are using PHPStorm, you may wish to copy the IDE meta file to yourproject to get full autocompletion on Atlas classes:

  1. cp ./vendor/atlas/orm/resources/phpstorm.meta.php ./.phpstorm.meta.php

Settings and Configuration

Now you need to add some database connection settings to your configuration.You can add them under any array key you like; the following example uses['settings']['atlas']:

  1. <?php
  2. // ./config/settings.php
  3. return [
  4. 'settings' => [
  5. 'displayErrorDetails' => true,
  6. 'determineRouteBeforeAppMiddleware' => false,
  7. 'atlas' => [
  8. 'pdo' => [
  9. 'mysql:dbname=testdb;host=localhost',
  10. 'username',
  11. 'password',
  12. ],
  13. 'namespace' => 'DataSource',
  14. 'directory' => dirname(__DIR__) . '/src/classes/DataSource',
  15. ]
  16. ]
  17. ];

The pdo elements are used as arguments for yourPDO connection.

The namespace and directory elements specify the namespace for your Atlasdata source classes, and the directory where they will be saved by the skeletongenerator. Your composer.json will need have a PSR autoloader entry for these;the above example corresponds to the Slimtutorial application.

Generating Skeleton Classes

Now you can generate your skeleton data source classes with the Atlas CLItooling. First, create the target directory, then issue the skeleton command:

  1. mkdir -p ./src/classes/DataSource
  2. php ./vendor/bin/atlas-skeleton.php ./config/settings.php settings.atlas

The first argument to atlas-skeleton is the path to your Slim config file. Thesecond argument is a dot-separated list of the keys leading to the Atlas arraywithin the settings.

With that command, Atlas will examine your database and generate a series ofclasses and traits for each table in the schema. You can see the files generatedfor each table here.

Container Service Definition

With the data mapper classes in place, you can now add the Atlas ORM as aservice in the Slim container:

  1. <?php
  2. $container = $app->getContainer();
  3. $container['atlas'] = function ($container) {
  4. $args = $container['settings']['atlas']['pdo'];
  5. $atlasBuilder = new AtlasBuilder(...$args);
  6. $atlasBuilder->setFactory(function ($class) use ($container) {
  7. if ($container->has($class)) {
  8. return $container->get($class);
  9. }
  10. return new $class();
  11. });
  12. return $atlasBuilder->newAtlas();
  13. };

This uses the AtlasBuilder class to create and return a new ORM instance, withthe PDO connection arguments from your settings configuration.

Note:

This service definition tells Atlas to use the Container itself as a factoryfor certain class constructions. If you have Atlas TableEvent or MapperEventclasses defined as services in the Container, Atlas will use the Containerto build them for you.

Using the ORM

At this point, you can use the full power of the Atlas ORM in your action code.The following examples are adapted from thetutorial application:

  1. <?php
  2. use DataSource\Ticket\Ticket;
  3. use DataSource\Component\Component;
  4. $app->get('/tickets', function (Request $request, Response $response) {
  5. $this->logger->addInfo("Ticket list");
  6. $tickets = $this->atlas->select(Ticket::class)->fetchRecordSet();
  7. $response = $this->view->render(
  8. $response,
  9. "tickets.phtml",
  10. [
  11. "tickets" => $tickets,
  12. "router" => $this->router
  13. ]
  14. );
  15. return $response;
  16. });
  17. $app->get('/ticket/{id}', function (Request $request, Response $response, $args) {
  18. $ticket_id = (int) $args['id'];
  19. $ticket = $this->atlas->fetchRecord(Ticket::class, $ticket_id);
  20. $response = $this->view->render(
  21. $response,
  22. "ticketdetail.phtml",
  23. [
  24. "ticket" => $ticket
  25. ]
  26. );
  27. return $response;
  28. })->setName('ticket-detail');
  29. $app->post('/ticket/new', function (Request $request, Response $response) {
  30. $data = $request->getParsedBody();
  31. $ticket = $this->atlas->newRecord(Ticket::class);
  32. $ticket->title = filter_var($data['title'], FILTER_SANITIZE_STRING);
  33. $ticket->description = filter_var($data['description'], FILTER_SANITIZE_STRING);
  34. $component_id = (int) $data['component'];
  35. $component = $this->atlas->fetchRecord(Component::class, $component_id)
  36. $ticket->component = $component->getName();
  37. $this->atlas->persist($ticket);
  38. $response = $response->withRedirect("/tickets");
  39. return $response;
  40. });

That’s it!

For more information on how to use Atlas to its greatest extent, be sure toread the official documentation:

Enjoy!