[ Part 4 ]- Populating database

Symfony 3 Jobeet tutorial - In this part we will create console command to populate our database with some fake data

Posted by Lukasz D. Tulikowski on February 4, 2017

 

Table of content


    The Initial Data

    To put some initial data in out database, we will create console command which allows us to populate a database. But before we do it, we will need some additional component called Faker. To install this component, we will need Composer.

    To download composer go to your main project folder and run those commands as below

    php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
    php -r "if (hash_file('SHA384', 'composer-setup.php') === '55d6ead61b29c7bdee5cccfb50076874187bd9f21f65d8991d46ec5cc90518f447387fb9f76ebae1fbbacf329e583e30') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
    php composer-setup.php
    php -r "unlink('composer-setup.php');"
    

    On official website https://getcomposer.org/ you will find further information and details about Composer.

    Once you download composer, you can install Symfony bundles, which are packages providing additional functionality to your application. We need bundle called Faker and to download these requirements execute command

    $ php composer.phar require fzaninotto/faker
    

    Now create new command directory in your bundle folder. Command which populate our database looks like that

    <?php
    // src/AppBundle/Command/PopulateDatabaseCommand.php
    namespace AppBundle\Command;
    
    use AppBundle\Entity\Category;
    use AppBundle\Entity\Job;
    use Faker;
    use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    use Symfony\Component\Console\Input\InputOption;
    
    class PopulateDatabaseCommand extends ContainerAwareCommand
    {
        /**
         * {@inheritdoc}
         */
        protected function configure()
        {
            $this
                ->setName('db:init')
                ->setDescription('Initialize database')
                ->addOption('category-count', 'c', InputOption::VALUE_REQUIRED, 'Number of categories.')
                ->addOption('job-count', 'j', InputOption::VALUE_REQUIRED, 'Number of job in category.');
        }
    
        /**
         * {@inheritdoc}
         */
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $this->createUsers($input->getOption('category-count'), $input->getOption('job-count'));
        }
    
        private function createUsers($categoryCount, $jobCount)
        {
            $em = $this->getContainer()->get('doctrine')->getManager();
            $categoryFaker = Faker\Factory::create();
            $jobsCount = $categoryCount * $jobCount;
            while ($categoryCount-- >= 0) {
                $category = new Category();
                $category->setName($categoryFaker->word);
                $em->persist($category);
                while (--$jobsCount >= 0) {
                    $jobFaker = Faker\Factory::create();
                    $job = new Job();
                    $job->setCategory($category);
                    $job->setType('full-time');
                    $job->setCompany($jobFaker->company);
                    $job->setLogo('sensio-labs.gif');
                    $job->setUrl($jobFaker->url);
                    $job->setPosition(implode(' ', $jobFaker->words(2)));
                    $job->setLocation($jobFaker->city.', '.$jobFaker->country);
                    $job->setDescription($jobFaker->paragraph);
                    $job->setHowToApply($jobFaker->sentence);
                    $job->setIsPublic(true);
                    $job->setIsActivated(true);
                    $job->setToken(implode('-', $jobFaker->words(3)));
                    $job->setEmail($jobFaker->email);
                    $job->setExpiresAt(new \DateTime(date('Y-m-d H:i:s', strtotime('+' . mt_rand(0, 30) . ' days ' . mt_rand(0, 24) . ' hours ' . mt_rand(0, 60) . ' minutes'))));
                    $job->setCreatedAt(new \DateTime());
                    $em->persist($job);
                }
                $em->flush();
            }
            exit;
        }
    }
    

    After you put it in your AppBundle under Comamand directory you can list all available commands running

    $ bin/console
    Symfony 3.2.2 (kernel: app, env: dev, debug: true)
    
    Usage:
      command [options] [arguments]
    ...
     db
      db:init                                 Initialize database
    ...
    

    In the output you should see the command you’ve just created. This command takes two arguments. You probably already known them, but when you run

    $ bin/console db:init --help
    Usage:
      db:init [options]
    
    Options:
      -c, --category-count=CATEGORY-COUNT  Number of categories.
      -j, --job-count=JOB-COUNT            Number of job in category.
    ...
    
    

    You will see in details how to use it. Let’s create then five categories and ten jobs in each category.

    $ bin/console db:init -c 5 -j 10
    

    That’s it. Some dummy data has already populated our database! But you still don’t see it anywhere, in case you check MySQL database itself. So it’s time to display what we have in out database generating some views and controllers, but this will be next part of the tutorial.