Can't get isDraft prop on Page::create to work

I’m trying to populate a blog with demo data using the following code:

<?php

use Kirby\Cms\Page;

require __DIR__ . '/vendor/autoload.php';

$app = require(__DIR__ . '/kirby.php');
$app->impersonate('kirby');

$blog = $app->site()->find('blog');

$faker = Faker\Factory::create();
$faker->seed(12345);

for ($i = 0; $i < 100; $i++) {
    $date = $faker->dateTimeThisDecade();
    Page::create([
        'parent'   => $blog,
        'slug'     => join('-', $faker->words(5)),
        'template' => 'article',
        'isDraft'  => $faker->boolean(10),
        'content'  => [
            'title' => $faker->sentence(),
            'date'  => $date->format('Y-m-d H:i:s'),
            'body'  => $faker->paragraphs(5, true),
        ],
    ]);
}

(There is nothing special in the kirby.php file, it just sets up the Kirby app instance)

The blueprint for an article is:

num: '{{ page.date.toDate("Ymd") }}'

fields:
  date:
    type: date
  body:
    type: textarea

The problem is when I run this I get 100% of the articles as drafts. I cannot set the num prop as this tells me that the page cannot be sorted (due to the definition in the blueprint).

The documentation here tells me the isDraft prop sets the draft flag.

I know I could do this differently by randomly publishing the page after creation, I just want to know why this way doesn’t do what I think it should do.

I’ve changed the page creation code to:

$page = Page::create([
        'parent'   => $blog,
        'slug'     => $slug = join('-', $faker->words(5)),
        'isDraft'  => $faker->boolean(25),
        'num'      => null,
        'template' => 'article',
        'content'  => [
            'title' => $faker->sentence(),
            'date'  => $date->format('Y-m-d H:i:s'),
            'body'  => $faker->paragraphs(5, true),
        ],
    ])->save();

but it still creates them all as drafts.

In the Page class create method there is the following at line 564:

if (isset($props['num']) === true) {
	$page = $page->changeStatus('listed', $props['num']);
}

But this is false when $props['num'] is null so changeStatus won’t be called and on line 526 you have:

$props['isDraft']  = ($props['draft'] ?? true);

Which will overwrite the isDraft prop with true because there is no draft prop set.

Why are you setting num to null? Ithink this needs to be set to a date in your case. Id also set the draft prop

I think the problem is here:

$props = array_merge($props, [
			'url'    => null,
			'num'    => null,
			'parent' => $this,
			'site'   => $this->site(),
		]);

No matter what you set for num, when the two arrays are merged, num is always null.

To work around this, you can overwrite the method in a page model.

You can’t set it to a date as it throws an exception due to the blueprint having a custom value for num. I set it to null because that was in the link you posted as a solution.

That code looks like it is from the createChild method which I am not calling.

Even better, this example works for me:

 $newPage = Page::create(
   [
     'parent' => page('notes'),
     'slug' => 'page-2',
     'template' => 'note',
     'draft' => false,
     'num' => date('Ymd'),
   ]
 );

Just to point out the issue specifically (assuming I’m understanding everything correctly) @SeriousKen was calling Page::create() with an array setting 'isDraft' => $faker->boolean(10), but the field should have been 'draft' => $faker->boolean(10).

That is, Page::create() expects the field indicating the draft status of the page to be called draft, not isDraft.

Well, the prop must be called draft instead of isDraft, yes, but if you want to have a listed page, you also need to set the num prop to a valid value for your numbering scheme defined in the blueprint. Otherwise, the page will not be a draft anymore, but still unlisted.

The documentation for Page::create does not list draft as a prop, but isDraft and setting num to any value other than null give me the following exception:

Kirby\Exception\PermissionException: The page "fugit-soluta-officiis-sit-a" cannot be sorted in /home/serious/projects/project01/vendor/getkirby/cms/src/Cms/PageRules.php:153
Stack trace:
#0 /home/serious/projects/project01/vendor/getkirby/cms/src/Cms/PageRules.php(102): Kirby\Cms\PageRules::changeStatusToListed()
#1 /home/serious/projects/project01/vendor/getkirby/cms/src/Cms/PageActions.php(432): Kirby\Cms\PageRules::changeStatus()
#2 /home/serious/projects/project01/vendor/getkirby/cms/src/Cms/PageActions.php(295): Kirby\Cms\Page->commit()
#3 /home/serious/projects/project01/vendor/getkirby/cms/src/Cms/PageActions.php(257): Kirby\Cms\Page->changeStatusToListed()
#4 /home/serious/projects/project01/vendor/getkirby/cms/src/Cms/PageActions.php(565): Kirby\Cms\Page->changeStatus()
#5 /home/serious/projects/project01/seed-blog.php(26): Kirby\Cms\Page::create()
#6 {main}

This is due to the blueprint setting a custom num. If I have a blueprint without the custom num then it works, but the numbering is not the date, even if I set the num prop to a date.

I tested with the setting from your blueprint above and my last code example and Kirby 3.9.0. If that doesn’t work for you, then so be it and feel free to create an issue on GitHub. Just trying to help.

On a side not, this is the same as num: date

Did you try creating multiple pages like my code does? I noticed it actually fails after the first when setting num to a date. I’ll raise an issue on github.

Yes, this also works

  foreach( range(1, 10) as $key) {
    $newPage = Page::create(
      [
        'parent'   => page('notes'),
        'slug'     => 'page-x-' . $key,
        'template' => 'note',
        'status'   => 'listed',
        'draft'    => false,
        'num'      => date('Ymd'),
      ]
    );
  }

in the starterkit with note.yml set to

num: '{{ page.date.toDate("Ymd") }}'

It works for me too, but that’s because it’s using the same date for each page, it fails when I use faker to generate random dates:

foreach( range(1, 10) as $key) {
    $newPage = Page::create(
      [
        'parent'   => page('notes'),
        'slug'     => 'page-x-' . $key,
        'template' => 'note',
        'status'   => 'listed',
        'draft'    => false,
        'num'      => $faker->dateTimeThisDecade()->format('Ymd'),
      ]
    );
  }

I don’t know what format Faker generates, you have to make sure that you use ‘Ymd’

Pasted the code wrong, missed off the ->format('Ymd') as it did in my code originally. Edited to show correct code. Still fails.