Skip to content

Commit

Permalink
Merge 62134be into 345c5b3
Browse files Browse the repository at this point in the history
  • Loading branch information
Gummibeer committed Oct 14, 2019
2 parents 345c5b3 + 62134be commit cbdacee
Show file tree
Hide file tree
Showing 21 changed files with 348 additions and 30 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -3,3 +3,4 @@
/.phpunit.result.cache
/build/
/phpunit.xml
/tests/export/
5 changes: 3 additions & 2 deletions composer.json
Expand Up @@ -43,9 +43,10 @@
"Astrotomic\\Stancy\\StancyServiceProvider"
],
"aliases": {
"ExportFactory": "Astrotomic\\Stancy\\Facades\\ExportFactory",
"FeedFactory": "Astrotomic\\Stancy\\Facades\\FeedFactory",
"SitemapFactory": "Astrotomic\\Stancy\\Facades\\SitemapFactory",
"PageFactory": "Astrotomic\\Stancy\\Facades\\PageFactory"
"PageFactory": "Astrotomic\\Stancy\\Facades\\PageFactory",
"SitemapFactory": "Astrotomic\\Stancy\\Facades\\SitemapFactory"
}
}
},
Expand Down
12 changes: 12 additions & 0 deletions src/Contracts/ExportFactory.php
@@ -0,0 +1,12 @@
<?php

namespace Astrotomic\Stancy\Contracts;

interface ExportFactory
{
public function addSheetList(array $list): void;

public function addSheetCollectionName(string $name): void;

public function addFeeds(array $except = []): void;
}
21 changes: 21 additions & 0 deletions src/Facades/ExportFactory.php
@@ -0,0 +1,21 @@
<?php

namespace Astrotomic\Stancy\Facades;

use Astrotomic\Stancy\Contracts\ExportFactory as ExportFactoryContract;
use Illuminate\Support\Facades\Facade;

/**
* @method static void addSheetList(string[] $list)
* @method static void addSheetCollectionName(string $name)
* @method static void addFeeds(string[] $except = [])
*
* @see SitemapFactoryContract
*/
class ExportFactory extends Facade
{
protected static function getFacadeAccessor()
{
return ExportFactoryContract::class;
}
}
2 changes: 1 addition & 1 deletion src/Facades/SitemapFactory.php
Expand Up @@ -7,7 +7,7 @@
use Spatie\Sitemap\Sitemap;

/**
* @method static Sitemap makeFromSheetList(array $list)
* @method static Sitemap makeFromSheetList(string[] $list)
* @method static Sitemap makeFromSheetCollectionName(string $name)
*
* @see SitemapFactoryContract
Expand Down
74 changes: 74 additions & 0 deletions src/Factories/ExportFactory.php
@@ -0,0 +1,74 @@
<?php

namespace Astrotomic\Stancy\Factories;

use Astrotomic\Stancy\Contracts\ExportFactory as ExportFactoryContract;
use Astrotomic\Stancy\Contracts\Page as PageContract;
use Astrotomic\Stancy\Contracts\PageFactory as PageFactoryContract;
use Astrotomic\Stancy\Traits\ConvertsSheetToPage;
use Illuminate\Contracts\Routing\UrlGenerator as UrlGeneratorContract;
use Illuminate\Support\Str;
use Spatie\Export\Exporter;
use Spatie\Sheets\Facades\Sheets;

class ExportFactory implements ExportFactoryContract
{
use ConvertsSheetToPage;

/** @var Exporter */
protected $exporter;

/** @var UrlGeneratorContract */
protected $urlGenerator;

public function __construct(PageFactoryContract $pageFactory, Exporter $exporter, UrlGeneratorContract $urlGenerator)
{
$this->pageFactory = $pageFactory;
$this->exporter = $exporter;
$this->urlGenerator = $urlGenerator;
}

/**
* @param string[] $list
*
* @return void
*/
public function addSheetList(array $list): void
{
foreach ($list as $entry) {
if (Str::contains($entry, ':')) {
[$collection, $path] = explode(':', $entry);

$this->addPages([$this->sheetToPage(Sheets::collection($collection)->get($path))]);

continue;
}

$this->addPages($this->sheetsToPages(Sheets::collection($entry)->all()->all()));
}
}

public function addSheetCollectionName(string $name): void
{
$this->addSheetList([$name]);
}

public function addFeeds(array $except = []): void
{
collect(config('feed.feeds'))->except($except)->each(function (array $config): void {
$this->exporter->paths([$config['url']]);
});
}

/**
* @param PageContract[] $pages
*
* @return void
*/
protected function addPages(array $pages): void
{
foreach ($pages as $page) {
$this->exporter->paths([Str::replaceFirst($this->urlGenerator->to('/'), '', $page->getUrl())]);
}
}
}
22 changes: 2 additions & 20 deletions src/Factories/SitemapFactory.php
Expand Up @@ -5,15 +5,14 @@
use Astrotomic\Stancy\Contracts\Page as PageContract;
use Astrotomic\Stancy\Contracts\PageFactory as PageFactoryContract;
use Astrotomic\Stancy\Contracts\SitemapFactory as SitemapFactoryContract;
use Astrotomic\Stancy\Traits\ConvertsSheetToPage;
use Illuminate\Support\Str;
use Spatie\Sheets\Facades\Sheets;
use Spatie\Sheets\Sheet;
use Spatie\Sitemap\Sitemap;

class SitemapFactory implements SitemapFactoryContract
{
/** @var PageFactoryContract */
protected $pageFactory;
use ConvertsSheetToPage;

public function __construct(PageFactoryContract $pageFactory)
{
Expand Down Expand Up @@ -64,21 +63,4 @@ protected function makeFromPages(array $pages): Sitemap

return $sitemap;
}

/**
* @param Sheet[] $sheets
*
* @return PageContract[]
*/
protected function sheetsToPages(array $sheets): array
{
return array_map(function (Sheet $sheet): PageContract {
return $this->sheetToPage($sheet);
}, $sheets);
}

protected function sheetToPage(Sheet $sheet): PageContract
{
return $this->pageFactory->makeFromSheet($sheet);
}
}
10 changes: 10 additions & 0 deletions src/Models/Page.php
Expand Up @@ -3,6 +3,7 @@
namespace Astrotomic\Stancy\Models;

use Astrotomic\Stancy\Contracts\Page as PageContract;
use Astrotomic\Stancy\Contracts\Routable;
use Exception;
use Illuminate\Contracts\View\Factory as ViewFactoryContract;
use Illuminate\Contracts\View\View;
Expand Down Expand Up @@ -134,6 +135,15 @@ public function toSitemapItem(): Tag
return $this->data->toSitemapItem();
}

public function getUrl(): string
{
if (! ($this->data instanceof Routable)) {
throw new Exception(sprintf('The page data has to be instance of %s to allow access to the URL.', Routable::class));
}

return $this->data->getUrl();
}

protected function parse(): void
{
if ($this->page === null) {
Expand Down
2 changes: 1 addition & 1 deletion src/Models/PageData.php
Expand Up @@ -28,7 +28,7 @@ public function toSitemapItem(): Tag
throw new Exception(sprintf('You have to define the transformation to a valid %s yourself if you want to use a sitemap.', Tag::class));
}

// https://github.com/spatie/data-transfer-object/issues/64
// ToDo: https://github.com/spatie/data-transfer-object/issues/64
protected function parseArray(array $array): array
{
foreach ($array as $key => $value) {
Expand Down
9 changes: 9 additions & 0 deletions src/StancyServiceProvider.php
Expand Up @@ -2,10 +2,12 @@

namespace Astrotomic\Stancy;

use Astrotomic\Stancy\Contracts\ExportFactory as ExportFactoryContract;
use Astrotomic\Stancy\Contracts\FeedFactory as FeedFactoryContract;
use Astrotomic\Stancy\Contracts\Page as PageContract;
use Astrotomic\Stancy\Contracts\PageFactory as PageFactoryContract;
use Astrotomic\Stancy\Contracts\SitemapFactory as SitemapFactoryContract;
use Astrotomic\Stancy\Factories\ExportFactory;
use Astrotomic\Stancy\Factories\FeedFactory;
use Astrotomic\Stancy\Factories\PageFactory;
use Astrotomic\Stancy\Factories\SitemapFactory;
Expand All @@ -20,6 +22,7 @@ public function register(): void
$this->registerPage();
$this->registerFeed();
$this->registerSitemap();
$this->registerExporter();
}

/** @codeCoverageIgnore */
Expand All @@ -29,6 +32,7 @@ public function provides(): array
PageFactoryContract::class,
PageContract::class,
FeedFactoryContract::class,
ExportFactoryContract::class,
SitemapFactoryContract::class,
];
}
Expand All @@ -48,4 +52,9 @@ protected function registerSitemap(): void
{
$this->app->singleton(SitemapFactoryContract::class, SitemapFactory::class);
}

protected function registerExporter(): void
{
$this->app->singleton(ExportFactoryContract::class, ExportFactory::class);
}
}
33 changes: 33 additions & 0 deletions src/Traits/ConvertsSheetToPage.php
@@ -0,0 +1,33 @@
<?php

namespace Astrotomic\Stancy\Traits;

use Astrotomic\Stancy\Contracts\Page as PageContract;
use Astrotomic\Stancy\Contracts\PageFactory as PageFactoryContract;
use Spatie\Sheets\Sheet;

/**
* @internal
*/
trait ConvertsSheetToPage
{
/** @var PageFactoryContract */
protected $pageFactory;

/**
* @param Sheet[] $sheets
*
* @return PageContract[]
*/
protected function sheetsToPages(array $sheets): array
{
return array_map(function (Sheet $sheet): PageContract {
return $this->sheetToPage($sheet);
}, $sheets);
}

protected function sheetToPage(Sheet $sheet): PageContract
{
return $this->pageFactory->makeFromSheet($sheet);
}
}
108 changes: 108 additions & 0 deletions tests/Factories/ExportFactoryTest.php
@@ -0,0 +1,108 @@
<?php

namespace Astrotomic\Stancy\Tests\Factories;

use Astrotomic\Stancy\Contracts\Page as PageContract;
use Astrotomic\Stancy\Facades\ExportFactory as ExportFactoryFacade;
use Astrotomic\Stancy\Facades\PageFactory;
use Astrotomic\Stancy\Factories\ExportFactory;
use Astrotomic\Stancy\Tests\TestCase;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\Route;
use Spatie\Export\Exporter;
use Spatie\Snapshots\MatchesSnapshots;

final class ExportFactoryTest extends TestCase
{
use MatchesSnapshots;

/** @test */
public function it_can_resolve_instance(): void
{
static::assertInstanceOf(ExportFactory::class, $this->getExportFactory());
}

/** @test */
public function it_can_use_facade(): void
{
ExportFactoryFacade::shouldReceive('addSheetList', 'addSheetCollectionName', 'addFeeds');

ExportFactoryFacade::addSheetCollectionName('blog');
ExportFactoryFacade::addSheetList(['blog:first-post', 'blog:second-post']);
ExportFactoryFacade::addFeeds();
}

/** @test */
public function it_can_export_feeds(): void
{
Carbon::setTestNow('2019-09-25 11:53:14');

Route::feeds();

$this->getExportFactory()->addFeeds();

$this->app->make(Exporter::class)->export();

// ToDo: https://github.com/spatie/laravel-export/issues/6
$filePath = __DIR__.'/../export/feed/blog.atom/index.html';

static::assertFileExists($filePath);
static::assertMatchesXmlSnapshot(file_get_contents($filePath));
}

/** @test */
public function it_can_export_pages(): void
{
Route::get('/', function (): PageContract {
return PageFactory::makeFromSheetName('content', 'yamlFrontMatterPredefined');
});

$this->getExportFactory()->addSheetList(['content:yamlFrontMatterPredefined']);

$this->app->make(Exporter::class)->export();

$filePath = __DIR__.'/../export/index.html';

static::assertFileExists($filePath);
// ToDo: https://github.com/spatie/phpunit-snapshot-assertions/pull/76
// static::assertMatchesHtmlSnapshot(file_get_contents($filePath));
static::assertEquals('<h1>hello world</h1>', trim(file_get_contents($filePath)));
}

/** @test */
public function it_can_export_a_collection(): void
{
Route::get('/{slug}', function (string $slug): PageContract {
return PageFactory::makeFromSheetName('blog', $slug);
});

$this->getExportFactory()->addSheetCollectionName('blog');

$this->app->make(Exporter::class)->export();

$filePath1 = __DIR__.'/../export/first-post/index.html';
$filePath2 = __DIR__.'/../export/second-post/index.html';

static::assertFileExists($filePath1);
// ToDo: https://github.com/spatie/phpunit-snapshot-assertions/pull/76
// static::assertMatchesHtmlSnapshot(file_get_contents($filePath1));
static::assertEquals('<h1>first post</h1>', trim(file_get_contents($filePath1)));

static::assertFileExists($filePath2);
// ToDo: https://github.com/spatie/phpunit-snapshot-assertions/pull/76
// static::assertMatchesHtmlSnapshot(file_get_contents($filePath2));
static::assertEquals('<h1>second post</h1>', trim(file_get_contents($filePath2)));
}

/** @test */
public function it_thorws_exception_if_page_data_is_not_instance_of_routable(): void
{
static::expectException(Exception::class);
static::expectExceptionMessage('The page data has to be instance of Astrotomic\Stancy\Contracts\Routable to allow access to the URL.');

$this->getExportFactory()->addSheetList(['content:home']);

$this->app->make(Exporter::class)->export();
}
}

0 comments on commit cbdacee

Please sign in to comment.