# Migrate users with pages field

**URL:** <https://forum.getkirby.com/t/migrate-users-with-pages-field/23358>\
**Category:** Questions\
**Tags:** v3\
**Created:** [September 8, 2021, 4:25pm UTC](https://forum.getkirby.com/t/migrate-users-with-pages-field/23358 "2021-09-08T16:25:49Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![tinus](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/tinus/32/7851_2.png) [@tinus](https://forum.getkirby.com/u/tinus)\
**Post date:** [September 8, 2021, 4:25pm UTC](https://forum.getkirby.com/t/migrate-users-with-pages-field/23358/1 "2021-09-08T16:25:49Z")

</div>

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:

```auto
      $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:

```auto
<?php
//set_time_limit(360);
require __DIR__. '/kirby/bootstrap.php';

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

// authenticate as almighty
$kirby->impersonate('kirby');

// 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'];
      dump($profile);
      $profile = $profile?Data::encode([$profile], 'yaml'):'';
      dump($profile);
      $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'):'';
      
      unset(
          $data[0],
          $data['username'],
          $data['email'],
          $data['password'],
          $data['role'],
          $data['language'],
          $data['history'],
          $data['sitelanguage'],
          $data['profile'],
          $data['conditionsagreedon']
      );

      // 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>';
    }
}

```

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [September 8, 2021, 6:25pm UTC](https://forum.getkirby.com/t/migrate-users-with-pages-field/23358/2 "2021-09-08T18:25:58Z")

</div>

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`.

---

<div class="post-metadata">

**Author:** ![tinus](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/tinus/32/7851_2.png) [@tinus](https://forum.getkirby.com/u/tinus)\
**Post date:** [September 8, 2021, 7:15pm UTC](https://forum.getkirby.com/t/migrate-users-with-pages-field/23358/3 "2021-09-08T19:15:57Z")

</div>

> [@texnixe](#):
>
> What is stored in `$data['profile']` .

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

so $data[‘profile’] has:

`profiles/tinus`

It is a page that exists and is public.

This is the blueprint for the users:

```auto
fields:
  sitelanguage:
    label: Site language
    type: select
    options:
      nl: Dutch
      en: English
  profile:
    label: Profile page
    type: pages
  conditionsagreedon:
    label: General conditions agreed on
    type: text

```

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

Excellent suggestion.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [September 8, 2021, 7:42pm UTC](https://forum.getkirby.com/t/migrate-users-with-pages-field/23358/4 "2021-09-08T19:42:03Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![tinus](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/tinus/32/7851_2.png) [@tinus](https://forum.getkirby.com/u/tinus)\
**Post date:** [September 8, 2021, 8:26pm UTC](https://forum.getkirby.com/t/migrate-users-with-pages-field/23358/5 "2021-09-08T20:26:18Z")

</div>

Yes … but  
$kirby-\>users()-\>create()

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

I am just using the script from this page:

[https://getkirby.com/docs/cookbook/setup/migrate-users#the-migrate-php-script](https://getkirby.com/docs/cookbook/setup/migrate-users#the-migrate-php-script)

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

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [September 8, 2021, 8:28pm UTC](https://forum.getkirby.com/t/migrate-users-with-pages-field/23358/6 "2021-09-08T20:28:14Z")

</div>

> [@tinus](#):
>
> ```auto
> 'content' => $data,
> 'password' => $password,
> 'sitelanguage' => $sitelanguage,
> 'profile' => $profile,
> 'conditionsagreedon' => $conditionsagreedon
> 
> ```

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:

```auto
   // 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.
    ]);

```

---

<div class="post-metadata">

**Author:** ![tinus](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/tinus/32/7851_2.png) [@tinus](https://forum.getkirby.com/u/tinus)\
**Post date:** [September 8, 2021, 8:33pm UTC](https://forum.getkirby.com/t/migrate-users-with-pages-field/23358/7 "2021-09-08T20:33:46Z")

</div>

Aaah, yes. I understand. Thank you.
