1

I have been trying to get my head wrapped around Migrations in Craft 3 and find myself struggling with added a new section.

I have managed to add a new volume, but not a section. Here’s where I have got to so far…

<?php

namespace craft\contentmigrations;

use Craft;
use craft\db\Migration;

/**
 * m180428_195138_test migration.
 */
class m180428_195138_test extends Migration
{
    /**
     * @inheritdoc
     */
    public function safeUp()
    {

      if (is_null(Craft::$app->volumes->getVolumeByHandle("newvolume"))) {
        $volume = new \craft\volumes\Local([
          "name" => "New volume",
          "handle" => "newvolume",
          "hasUrls" => true,
          "url" => "@web/images/newvolume",
          "path" => "@webroot/images/newvolume"
        ]);

        Craft::$app->volumes->saveVolume($volume);
      }


      if (is_null(Craft::$app->sections->getSectionByHandle("awesomeNews"))) {
        $section = new \craft\models\Section([
          'name' => 'Awesome News',
          'handle' => 'awesomeNews',
          'type' => 'Channel',
          'siteSettings' => [
              new \craft\models\Section_SiteSettings([
                  'siteId' => Craft::$app->sites->getPrimarySite()->id,
                  'enabledByDefault' => true,
                  'hasUrls' => true,
                  'uriFormat' => 'foo/{slug}',
                  'template' => 'foo/_entry',
              ]),
          ]
        ], true);

        Craft::$app->sections->saveSection($section);

      }


    }

    /**
     * @inheritdoc
     */
    public function safeDown()
    {

      $newvolume = Craft::$app->volumes->getVolumeByHandle("newvolume");
      if (!is_null($newvolume)) {
        Craft::$app->volumes->deleteVolumeById($newvolume->id);
      }

      $awesomeNews = Craft::$app->sections->getSectionByHandle("awesomeNews");
      if (!is_null($awesomeNews)) {
        Craft::$app->volumes->deleteSectionById($awesomeNews->id);
      }

    }
}

The migration states it has been successful, however, I only see the new volume, not the section. I have tried to execute this with only the block relating to the section.

Does anyone know if it is possible to create a new section with Migrations? If it is, any idea what may be wrong with the above?

1

The easiest solution for this by far is to just run the $model->getErrors() function in order to see what's wrong.. Then you'll see the following:

"Type is invalid."

Take a look at your Section model

const TYPE_CHANNEL = 'channel';

change

'type' => 'Channel',

to

'type' => 'channel',

or even better

'type' => Section::TYPE_CHANNEL,

Also: every save function returns a variable of type boolean if it was successful or not. You should always check for those values.

| improve this answer | |
  • Thanks for pointing me in the right direction. The incorrect case for channel was an artefact of trying a hundred different ways to get this to work, however, it was this and another error causing the issue. The tip about $model->getErrors() is really useful. Using 'type' => Section::TYPE_CHANNEL, work a treat. Thanks – Simon Leadbetter Apr 29 '18 at 6:59
2

As documentation for Migrations is pretty slim, here is the working code:

<?php

namespace craft\contentmigrations;

use Craft;
use craft\db\Migration;

/**
 * m180428_195138_test migration.
 */
class m180428_195138_test extends Migration
{
    /**
     * @inheritdoc
     */
    public function safeUp()
    {


      if (is_null(Craft::$app->volumes->getVolumeByHandle("newvolume"))) {
        $volume = new \craft\volumes\Local([
          "name" => "New volume",
          "handle" => "newvolume",
          "hasUrls" => true,
          "url" => "@web/images/newvolume",
          "path" => "@webroot/images/newvolume"
        ]);

        $success = Craft::$app->volumes->saveVolume($volume);

      }

      if (is_null(Craft::$app->sections->getSectionByHandle("awesomeNews"))) {
        $section = new \craft\models\Section([
          "name" => "Awesome News",
          "handle" => "awesomeNews",
          "type" => \craft\models\Section::TYPE_CHANNEL,
          "siteSettings" => [
              new \craft\models\Section_SiteSettings([
                  "siteId" => Craft::$app->sites->getPrimarySite()->id,
                  "enabledByDefault" => true,
                  "hasUrls" => true,
                  "uriFormat" => "foo/{slug}",
                  "template" => "foo/_entry",
              ]),
          ]
        ]);

        $success = Craft::$app->sections->saveSection($section);

        $errors = $section->getErrors();
        foreach ($errors as $error) {
          echo $error[0];
        }

      }

      return $success;

    }

    /**
     * @inheritdoc
     */
    public function safeDown()
    {

      $newvolume = Craft::$app->volumes->getVolumeByHandle("newvolume");
      if (!is_null($newvolume)) {
        $success = Craft::$app->volumes->deleteVolumeById($newvolume->id);
      }

      $awesomeNews = Craft::$app->sections->getSectionByHandle("awesomeNews");
      if (!is_null($awesomeNews)) {
        $success = Craft::$app->sections->deleteSectionById($awesomeNews->id);
      }

      return $success;

    }


}

This includes the error checking when creating the new section and the save functions are assigned to a variable which are returned at the end.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.