Migrate users with pages field

I am trying to migrate users from kirby2 to kirby3 using the script from the cookbook.

The script works for everything except a page/pages field.

at the moment I have this code:

      $profile              = @$data['profile'];
      $profile              = $profile?Data::encode([$profile], 'yaml'):'';

The data this produces looks good but the $kirby->users()->create function then apparently empties the data for the profile field.

This is the whole script:

require __DIR__ . '/kirby/bootstrap.php';

$kirby = new Kirby;
$dir   = $kirby->root('accounts');

// authenticate as almighty

// loop through each K2 account file
foreach (Dir::files($dir) as $account) {

    // read K2 account file
    $data  = Data::read($dir . '/' . $account, 'yaml');

    if (isset($data['username'])){
      // prepare data to be processed
      $name        = $data['username'];
      $email       = $data['email'];
      $password    = $data['password'];
      $role        = $data['role'];
      $language    = $data['language'];
      $sitelanguage         = @$data['sitelanguage'];
      $profile              = @$data['profile'];
      $profile              = $profile?Data::encode([$profile], 'yaml'):'';
      $conditionsagreedon   = @$data['conditionsagreedon'];

      $date = $conditionsagreedon;
      $newDate = DateTime::createFromFormat('d/m/Y H:i:s', $date);
      $conditionsagreedon = $newDate?$newDate->format('Y-m-d H:i:s'):'';

      // create new K3 user account
      $user = $kirby->users()->create([
          'email'    => $email,
          'name'     => $name,
          'role'     => $role,
          'language' => $language,
          'content'  => $data,
          'password' => $password,
          'sitelanguage' => $sitelanguage,
          'profile' => $profile,
          'conditionsagreedon' => $conditionsagreedon

      // write K2 password hash to .htpasswd
      F::write($dir . '/' . $user->id() . '/.htpasswd', $password);

      // delete K2 account file
      F::remove($dir . '/' . $account);

      echo 'User migrated: ' . $user->email() . '<br>';

What is stored in $data['profile'].

On a sidenote, instead of @$data['sitelanguage']; I think it would be better to use the null coalescing operator $data['sitelanguage'] ?? null.

$data[‘profile’] is a page field from kirby2. In kirby3 it is a pages field.

so $data[‘profile’] has:


It is a page that exists and is public.

This is the blueprint for the users:

    label: Site language
    type: select
      nl: Dutch
      en: English
    label: Profile page
    type: pages
    label: General conditions agreed on
    type: text

Excellent suggestion.

Any content that is not email, language, name, or role should be stored in the content array (apart from the password, which you should remove, because it is stored in the .htpasswd file in the next step with F::write()-

A user account folder in the end has three basic files (apart from maybe additional files):

  • .htpasswd
  • user.txt (for the content)
  • index.php with the array role, email, name, and language

Yes … but

creates those files and in the txt file there is an empty Profile field.

I am just using the script from this page:


With some added fields. Apparently I am doing something wrong but I don’t understand what.

But you have content => $data and then those additional fields which should be in the $data array (or a new array, because the original $data array needs to be changed). And the password doesn’t belong there at all.

This is the original code from the recipe:

   // create new K3 user account
    $user = $kirby->users()->create([
        'email'    => $email,
        'name'     => $name,
        'role'     => $role,
        'language' => $language,
        'content'  => $data // this array should contain all the fields that should be stored in the `user.txt` file, i.e. all fields defined in your blueprint.

Aaah, yes. I understand. Thank you.