Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating content in PHP #1179

Merged
merged 1 commit into from
Jul 24, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 169 additions & 2 deletions docs/extensions/creating_content.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,172 @@
Creating (and updating) Content
===============================

This page describes how to create new Content and how to update existing Content.
[todo]
Sometimes you will need to create content programatically. For example,
there may be an API of events that need to be managed in Bolt.

## Creating content in PHP

The recommended way for creating Content programatically in Bolt
is using the provided ContentFactory methods.

### Creating content using `ContentFactorry::create`

```php
<?php

namespace App;

use Bolt\Factory\ContentFactory;

class ExampleContentCreator
{
/** @var ContentFactory */
private $factory;

public function __construct(ContentFactory $factory)
{
$this->factory = $factory;
}

public function run(): void
{
// Let's mock some data.
$data = [
[
'title' => 'My first entry',
'teaser' => 'Read more about programatically making content',
'body' => 'Bla bla bla bla bla...'
],
[
'title' => 'My second entry',
'teaser' => 'more more more more'
],
[
'title' => 'Last entry',
'body' => "There's the last entry",
]
];

// Now, let's create some content

foreach($data as $fieldData) {
// "entries" is the Content Type
$content = $this->factory->create('entries');

// Now add some content to it
foreach($fieldData as $name => $value) {
$content->setFieldValue($name, $value);
}

// Shorthand method for persisting and saving content
$this->factory->save($content);
}
}
}
```

Soon you'll notice that, as many times as the `run` method runs,
as many entry records will be created. In some cases, however, you'll
need to either update a record and only create it if no such record exists.

### Upserting content with `ContentFactory::upsert`

Upsert means To insert rows into a database table if they do not already exist,
or update them if they do. In that case, we use the factory's `upsert` method.

It is useful when you want to _update_ existing records and automatically create
those records that are new.

To use `upsert`, we need to tell Bolt how to identify whether or not
a record already exists by passing criteria. For example, do we define a record as a duplicate by
its title, or a combination of fields, or something else.

The criteria is a PHP array that works much like the `setcontent` directives, e.g.
```php
$criteria = [
'title' => 'My first entry'
];
```

```php
$criteria = [
'title' => '%entry%',
'status' => 'published',
'id' => '>50'
];
```

And now, to the full example script for upserting:

```php
<?php

namespace App;

use Bolt\Factory\ContentFactory;

class ExampleContentCreator
{
/** @var ContentFactory */
private $factory;

public function __construct(ContentFactory $factory)
{
$this->factory = $factory;
}

public function run(): void
{
// Let's mock some data.
$data = [
[
'title' => 'My first entry',
'teaser' => 'Read more about programatically making content',
'body' => 'Bla bla bla bla bla...'
],
[
'title' => 'My second entry',
'teaser' => 'more more more more'
],
[
'title' => 'Last entry',
'body' => "There's the last entry",
]
];

// Now, let's upsert some content
foreach($data as $fieldData) {

// Look for records that have the title of the current record
$criteria = [
'title' => $fieldData['title']
];

// This will fetch an existing record, or create a new one if none exists.
$content = $this->factory->upsert('entries', $criteria);

// Now add some content to it
foreach($fieldData as $name => $value) {
$content->setFieldValue($name, $value);
}

$this->factory->save($content);
}
}
}
```

### Create content using `ContentFactory::createStatic`

If you are not able to use Symfony's autowiring (recommended!),
you can also use a static method.

<p class="Note">As the <code>createStatic</code> method does NOT use Symfony
autoloading and autowiring, it is limited in the checks and initialisations
that it can do. Only use it if you cannot autoload and autowire the
<code>ContentFactroy</code>.</p>

## Creating content in the API

For documentation on how to create content in the API,
check the in-CMS documentation at `/bolt/api`.