Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
aerni committed Sep 11, 2024
1 parent 7b4f3aa commit 2972f59
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 16 deletions.
10 changes: 7 additions & 3 deletions src/Factories/Concerns/CreatesEntry.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ public function newModel(array $attributes = [])
$entry->slug($slug);
}

if (($site = Arr::pull($attributes, 'site')) && $entry->sites()->contains($site)) {
$entry->locale($site);
}
$site = Arr::pull($attributes, 'site');

$site = $entry->sites()->contains($site)
? $site
: $entry->sites()->first();

$entry->locale($site);

$entry->published(Arr::pull($attributes, 'published', true));

Expand Down
19 changes: 12 additions & 7 deletions src/Factories/Concerns/WithSites.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Aerni\Factory\Factories\Concerns;

use Statamic\Facades\Site;
use Illuminate\Support\Collection;
use Statamic\Contracts\Entries\Entry;
use Statamic\Contracts\Taxonomies\Term;
Expand All @@ -15,23 +16,27 @@ public function inSite(string $site): self

public function inRandomSite(): self
{
return $this->sequence(fn () => ['site' => $this->getSitesFromContentModel()->random()]);
return $this->state(fn () => ['site' => $this->getSitesFromContentModel()->random()]);
}

public function perSite(): self
{
$sites = $this->getSitesFromContentModel()->map(fn ($site) => ['site' => $site]);

// TODO: This won't work if count() is used after perSite(). Can we make this work with a callback?
return $this->sequence(...$sites)->count(($this->count ?? 1) * $sites->count());
}

protected function getSitesFromContentModel(): Collection
{
$contentModel = $this->newModel();

return match (true) {
$contentModel instanceof Entry => $contentModel->sites(),
$contentModel instanceof Term => $contentModel->taxonomy()->sites(),
};
return once(function () {
$contentModel = $this->newModel();

return match (true) {
$contentModel instanceof Entry => $contentModel->sites(),
$contentModel instanceof Term => $contentModel->taxonomy()->sites(),
default => Site::all()->map->handle(),
};
});
}
}
42 changes: 36 additions & 6 deletions src/Factories/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@

use Closure;
use Faker\Generator;
use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Factories\CrossJoinSequence;
use Illuminate\Database\Eloquent\Factories\Sequence;
use Statamic\Facades\Site;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Traits\Conditionable;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Container\Container;
use Statamic\Contracts\Entries\Entry;
use Statamic\Contracts\Taxonomies\Term;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Support\Traits\Conditionable;
use Illuminate\Database\Eloquent\Factories\Sequence;
use Illuminate\Database\Eloquent\Factories\CrossJoinSequence;

abstract class Factory
{
Expand Down Expand Up @@ -160,6 +162,7 @@ protected function getExpandedAttributes(): array
protected function getRawAttributes(): array
{
return $this->states
->pipe($this->evaluateSiteStates(...))
->reduce(function (array $carry, $state) {
if ($state instanceof Closure) {
$state = $state->bindTo($this);
Expand All @@ -169,6 +172,30 @@ protected function getRawAttributes(): array
}, $this->definition());
}

protected function evaluateSiteStates(Collection $states): Collection
{
$evaluatedSiteStates = $states
->map(fn ($state) => (clone $state)()) /* Clone the closure so that we don't run into issues when evaluating the same closure later. Needed for sequences to work correctly. */
->filter(fn ($state) => isset($state['site']));

if ($evaluatedSiteStates->isEmpty()) {
return $states;
}

$siteState = $evaluatedSiteStates->last();

$site = $this->getSitesFromContentModel()->flip()->has($siteState['site'])
? Site::get($siteState['site'])
: Site::get($this->getSitesFromContentModel()->first());

$this->faker = Container::getInstance()->makeWith(Generator::class, ['locale' => $site->locale()]);

// TODO: This breaks the perSite() sequence but works for inSite() and inRandomSite().
return $states->diffKeys($evaluatedSiteStates)
->push(fn () => ['site' => $site->handle()])
->values();
}

protected function expandAttributes(array $definition)
{
return collect($definition)
Expand Down Expand Up @@ -289,7 +316,10 @@ protected function newInstance(array $arguments = []): self

protected function withFaker(): Generator
{
return Container::getInstance()->make(Generator::class);
// TODO: This won't work for new content models that don't use the WithSites trait.
$site = Site::get($this->getSitesFromContentModel()->first());

return Container::getInstance()->makeWith(Generator::class, ['locale' => $site->locale()]);
}

public function modelName(): string
Expand Down
1 change: 1 addition & 0 deletions tests/FactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ public function test_entry_can_be_created_in_site()

$entries = FactoryTestEntryFactory::times(5)->perSite()->create();
$this->assertCount(10, $entries);
dd($entries->map->locale());
$entries->each(fn ($entry, $index) => $this->assertSame($index % 2 === 0 ? 'default' : 'german', $entry->locale()));
}

Expand Down

0 comments on commit 2972f59

Please sign in to comment.