Commit c161ee51 authored by Nicolas Widart's avatar Nicolas Widart

Squashed 'Modules/Core/' changes from 37d3173..9450e60

9450e60 Remove the theme config item in config file
977f6b2 Use the getName getter
783ecc7 Adding a view composer to select themes
2708f26 Binding the theme managers in the IoC
e831a6d Add test for a non existing directory
2ed39d5 Actually check for no themes
6bcbb96 Remove too many responsabilities from theme manager
e292ec9 Add more tests
8134e47 Adding better styling to commands output
50f25ee Moving the tests is directory
713724b Add a asset publisher test
00975e6 Add some tests assets
4fe6083 Add a theme test
3623024 Add a theme manager test. Extract the theme path to a variable
f81d177 Add a theme manager and publiser commend

git-subtree-dir: Modules/Core
git-subtree-split: 9450e602bd5474759da1bca5b33c9cc7080042fb
parent 35af568e
<?php namespace Modules\Core\Composers;
use Illuminate\Contracts\View\View;
use Modules\Core\Foundation\Theme\ThemeManager;
class ThemeComposer
{
/**
* @var ThemeManager
*/
private $themeManager;
public function __construct()
{
$this->themeManager = app('asgard.themes');
}
public function compose(View $view)
{
$view->with('themes', $this->themeManager->all());
}
}
...@@ -12,14 +12,4 @@ return [ ...@@ -12,14 +12,4 @@ return [
'User', 'User',
'Workshop' 'Workshop'
], ],
/*
|--------------------------------------------------------------------------
| Specify all the front-end themes
| These will be available as a core setting
|--------------------------------------------------------------------------
*/
'front-themes' => [
'demo',
'default'
]
]; ];
<?php namespace Modules\Core\Console; <?php namespace Modules\Core\Console;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Modules\Core\Foundation\Theme\AssetPublisher;
use Modules\Core\Foundation\Theme\ThemeManager;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
class PublishThemeAssetsCommand extends Command class PublishThemeAssetsCommand extends Command
{ {
protected $name = 'asgard:publish:theme'; protected $name = 'asgard:publish:theme';
protected $description = 'Publish theme assets'; protected $description = 'Publish theme assets';
/**
* @var \Modules\Core\Foundation\Theme\ThemeManager
*/
private $themeManager;
public function __construct(ThemeManager $themeManager)
{
parent::__construct();
$this->themeManager = $themeManager;
}
public function fire() public function fire()
{ {
$this->info('Publishing assets for ' . $this->argument('theme')); $theme = $this->argument('theme') ?: '';
if ($theme) {
$this->comment("Publishing assets for [$theme] theme");
} else {
$this->comment('Publishing assets for all themes');
}
with(new AssetPublisher($this->themeManager->find($theme)))
->setFinder($this->laravel['files'])
->setRepository($this->themeManager)
->publish();
$this->info("Assets published for [$theme] theme");
} }
protected function getArguments() protected function getArguments()
......
<?php namespace Modules\Core\Foundation\Theme;
class AssetPublisher
{
/**
* @var \Illuminate\Filesystem\Filesystem
*/
protected $finder;
/**
* @var ThemeManager
*/
protected $repository;
/**
* @var Theme
*/
private $theme;
/**
* @param Theme $theme
*/
public function __construct(Theme $theme)
{
$this->theme = $theme;
}
/**
* @param $finder
* @return $this
*/
public function setFinder($finder)
{
$this->finder = $finder;
return $this;
}
/**
* @param $repository
* @return $this
*/
public function setRepository($repository)
{
$this->repository = $repository;
return $this;
}
/**
* Publish the assets
*/
public function publish()
{
if (!$this->finder->isDirectory($sourcePath = $this->getSourcePath())) {
$message = "Source path does not exist : {$sourcePath}";
throw new \InvalidArgumentException($message);
}
if (!$this->finder->isDirectory($destinationPath = $this->getDestinationPath())) {
$this->finder->makeDirectory($destinationPath, 0775, true);
}
if ($this->finder->copyDirectory($sourcePath, $destinationPath)) {
return true;
}
}
/**
* Get the original source path
* @return string
*/
public function getSourcePath()
{
return $this->theme->getPath() . '/assets';
}
/**
* Get the destination path
* @return string
*/
public function getDestinationPath()
{
return $this->repository->getAssetPath($this->theme->getLowerName());
}
}
<?php namespace Modules\Core\Foundation\Theme;
class Theme
{
/**
* @var string the theme name
*/
private $name;
/**
* @var string the theme path
*/
private $path;
public function __construct($name, $path)
{
$this->name = $name;
$this->path = realpath($path);
}
/**
* @return string
*/
public function getName()
{
return ucfirst($this->name);
}
/**
* @return string
*/
public function getPath()
{
return $this->path;
}
/**
* Get name in lower case.
*
* @return string
*/
public function getLowerName()
{
return strtolower($this->name);
}
}
<?php namespace Modules\Core\Foundation\Theme;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Str;
class ThemeManager implements \Countable
{
/**
* @var Application
*/
private $app;
/**
* @var string Path to scan for themes
*/
private $path;
/**
* @param Application $app
* @param $path
*/
public function __construct(Application $app, $path)
{
$this->app = $app;
$this->path = $path;
}
/**
* @param string $name
* @return Theme|null
*/
public function find($name)
{
foreach ($this->all() as $theme) {
if ($theme->getLowerName() == strtolower($name)) {
return $theme;
}
}
return null;
}
/**
* Return all available themes
* @return array
*/
public function all()
{
$themes = [];
if (!$this->getFinder()->isDirectory($this->path)) {
return $themes;
}
$directories = $this->getFinder()->directories($this->path);
foreach ($directories as $theme) {
if (!Str::startsWith($name = basename($theme), '.')) {
$themes[$name] = new Theme($name, $theme);
}
}
return $themes;
}
/**
* Return the theme assets path
* @param string $theme
* @return string
*/
public function getAssetPath($theme)
{
return public_path($this->getConfig()->get('themify::themes_assets_path') . '/' . $theme);
}
/**
* @return \Illuminate\Filesystem\Filesystem
*/
protected function getFinder()
{
return $this->app['files'];
}
/**
* @return \Illuminate\Config\Repository
*/
protected function getConfig()
{
return $this->app['config'];
}
/**
* Counts all themes
*/
public function count()
{
return count($this->all());
}
}
...@@ -5,6 +5,7 @@ use Illuminate\Routing\Router; ...@@ -5,6 +5,7 @@ use Illuminate\Routing\Router;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Modules\Core\Console\InstallCommand; use Modules\Core\Console\InstallCommand;
use Modules\Core\Console\PublishThemeAssetsCommand; use Modules\Core\Console\PublishThemeAssetsCommand;
use Modules\Core\Foundation\Theme\ThemeManager;
use Modules\Core\Services\Composer; use Modules\Core\Services\Composer;
use Modules\Menu\Entities\Menuitem; use Modules\Menu\Entities\Menuitem;
use Modules\Menu\Repositories\Eloquent\EloquentMenuItemRepository; use Modules\Menu\Repositories\Eloquent\EloquentMenuItemRepository;
...@@ -45,6 +46,7 @@ class CoreServiceProvider extends ServiceProvider ...@@ -45,6 +46,7 @@ class CoreServiceProvider extends ServiceProvider
$this->registerMenuRoutes(); $this->registerMenuRoutes();
$this->registerFilters($this->app['router']); $this->registerFilters($this->app['router']);
$this->registerCommands(); $this->registerCommands();
$this->registerServices();
} }
/** /**
...@@ -104,8 +106,8 @@ class CoreServiceProvider extends ServiceProvider ...@@ -104,8 +106,8 @@ class CoreServiceProvider extends ServiceProvider
private function registerThemeCommand() private function registerThemeCommand()
{ {
$this->app->bindShared('command.asgard.publish.theme', function() { $this->app->bindShared('command.asgard.publish.theme', function($app) {
return new PublishThemeAssetsCommand; return new PublishThemeAssetsCommand(new ThemeManager($app, $app['config']->get('themify::themes_path')));
}); });
} }
...@@ -121,4 +123,12 @@ class CoreServiceProvider extends ServiceProvider ...@@ -121,4 +123,12 @@ class CoreServiceProvider extends ServiceProvider
return $app->make('Modules\Menu\Repositories\MenuItemRepository')->getForRoutes(); return $app->make('Modules\Menu\Repositories\MenuItemRepository')->getForRoutes();
}); });
} }
private function registerServices()
{
$this->app->bindShared('asgard.themes', function ($app) {
$path = $app['config']->get('themify::themes_path');
return new ThemeManager($app, $path);
});
}
} }
<div class="form-group"> <div class="form-group">
<label for="{{ $settingName }}">{{ $moduleInfo['description'] }}</label> <label for="{{ $settingName }}">{{ $moduleInfo['description'] }}</label>
<select class="form-control" name="{{ $settingName }}" id="{{ $settingName }}"> <select class="form-control" name="{{ $settingName }}" id="{{ $settingName }}">
<?php foreach(Config::get('core::config.front-themes') as $theme): ?> <?php foreach($themes as $name => $theme): ?>
<option value="{{ $theme }}" {{ isset($dbSettings[$settingName]) && $dbSettings[$settingName]->plainValue == $theme ? 'selected' : '' }}> <option value="{{ $name }}" {{ isset($dbSettings[$settingName]) && $dbSettings[$settingName]->plainValue == $name ? 'selected' : '' }}>
{{ ucfirst($theme) }} {{ $theme->getName() }}
</option> </option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
......
...@@ -4,6 +4,13 @@ use TestCase; ...@@ -4,6 +4,13 @@ use TestCase;
abstract class BaseTestCase extends TestCase abstract class BaseTestCase extends TestCase
{ {
protected $app;
public function setUp()
{
parent::setUp();
}
protected function checkResponseIsOkAndContains($request, $filter) protected function checkResponseIsOkAndContains($request, $filter)
{ {
$crawler = $this->client->request($request[0], $request[1]); $crawler = $this->client->request($request[0], $request[1]);
......
<?php namespace Modules\Core\Tests; <?php namespace Modules\Core\Tests\Permissions;
use Mockery; use Mockery;
use Modules\Core\Permissions\PermissionManager; use Modules\Core\Permissions\PermissionManager;
......
<?php namespace Modules\Core\Tests\Theme;
use Modules\Core\Foundation\Theme\AssetPublisher;
use Modules\Core\Foundation\Theme\Theme;
use Modules\Core\Foundation\Theme\ThemeManager;
use Modules\Core\Tests\BaseTestCase;
class AssetPublisherTest extends BaseTestCase
{
/**
* @var \Modules\Core\Foundation\Theme\AssetPublisher
*/
protected $publisher;
/**
* @var \Modules\Core\Foundation\Theme\Theme
*/
protected $theme;
/**
* @var \Illuminate\Filesystem\Filesystem
*/
protected $finder;
public function setUp()
{
parent::setUp();
$this->finder = $this->app['files'];
$this->theme = new Theme('testAssets', $this->getThemePath());
$this->publisher = with(new AssetPublisher($this->theme))
->setFinder($this->finder)
->setRepository(new ThemeManager($this->app, $this->getPath()));
}
/** @test */
public function it_gets_the_source_path()
{
$this->assertEquals($this->getThemePath() . '/assets', $this->publisher->getSourcePath());
}
/** @test */
public function it_gets_the_destination_path()
{
$expectedPath = $this->getAssetsThemePath();
$this->assertEquals($expectedPath, $this->publisher->getDestinationPath());
}
/** @test */
public function it_publishes_the_assets()
{
$this->publisher->publish();
$this->assertTrue($this->finder->isDirectory($this->getAssetsThemePath()));
$this->assertTrue($this->finder->isDirectory($this->getAssetsThemePath() . '/css'));
$this->assertTrue($this->finder->isDirectory($this->getAssetsThemePath() . '/js'));
$this->assertTrue($this->finder->isFile($this->getAssetsThemePath() . '/css/main.css'));
$this->assertTrue($this->finder->isFile($this->getAssetsThemePath() . '/js/main.js'));
}
private function getThemePath()
{
return __DIR__ . '/Fixture/Themes/testAssets';
}
private function getAssetsThemePath()
{
return public_path($this->app['config']->get('themify::themes_assets_path') . '/' . 'testassets');
}
private function getPath()
{
return __DIR__ . '/Fixture/Themes';
}
public function tearDown()
{
$this->finder->deleteDirectory($this->getAssetsThemePath());
}
}
<?php namespace Modules\Core\Tests\Theme;
use Modules\Core\Foundation\Theme\ThemeManager;
use Modules\Core\Tests\BaseTestCase;
class ThemeManagerTest extends BaseTestCase
{
/**
* @var \Modules\Core\Foundation\Theme\ThemeManager
*/
protected $repository;
/**
*
*/
public function setUp()
{
parent::setUp();
$this->repository = new ThemeManager($this->app, $this->getPath());
}
/** @test */
public function it_should_return_all_themes()
{
$this->assertTrue(is_array($this->repository->all()));
$this->assertEquals($this->repository->count(), 2);
}
/** @test */
public function it_should_return_a_theme()
{
$theme = $this->repository->find('demo');
$this->assertInstanceOf('Modules\Core\Foundation\Theme\Theme', $theme);
$this->assertEquals('demo', $theme->getLowerName());
}
/** @test */
public function it_should_return_null_if_not_theme_found()
{
$theme = $this->repository->find('fakeTheme');
$this->assertNull($theme);
}
/** @test */
public function it_should_return_empty_array_if_no_themes()
{
$repository = new ThemeManager($this->app, $this->getEmptyThemesPath());
$this->assertEquals([], $repository->all());
}
/** @test */
public function it_should_return_empty_array_if_no_folder()
{
$repository = new ThemeManager($this->app, $this->getFakePath());
$this->assertEquals([], $repository->all());
}
private function getPath()
{
return __DIR__ . '/Fixture/Themes';
}
private function getEmptyThemesPath()
{
return __DIR__ . '/Fixture/EmptyThemes';
}
private function getFakePath()
{
return __DIR__ . '/Fixture/fakeFolder';
}
}
<?php namespace Modules\Core\Tests\Theme;
use Modules\Core\Foundation\Theme\Theme;
use Modules\Core\Tests\BaseTestCase;
class ThemeTest extends BaseTestCase
{
/**
* @var \Modules\Core\Foundation\Theme\Theme
*/
protected $theme;
public function setUp()
{
parent::setUp();
$this->theme = new Theme('demo', $this->getPath());
}
/** @test */
public function it_should_return_name()
{
$this->assertEquals('Demo', $this->theme->getName());
}
/** @test */
public function it_should_return_name_in_lowercase()
{
$this->assertEquals('demo', $this->theme->getLowerName());
}
/** @test */
public function it_should_return_correct_path()
{
$this->assertEquals($this->getPath(), $this->theme->getPath());
}
private function getPath()
{
return __DIR__ . '/Fixture/Themes/demo';
}
}
...@@ -2,3 +2,4 @@ ...@@ -2,3 +2,4 @@
View::creator('core::partials.sidebar-nav', 'Modules\Core\Composers\SidebarViewCreator'); View::creator('core::partials.sidebar-nav', 'Modules\Core\Composers\SidebarViewCreator');
View::composer('core::layouts.master', 'Modules\Core\Composers\MasterViewComposer'); View::composer('core::layouts.master', 'Modules\Core\Composers\MasterViewComposer');
View::composer('core::fields.select-theme', 'Modules\Core\Composers\ThemeComposer');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment