Commit eb8e1114 authored by Nicolas Widart's avatar Nicolas Widart

Merge commit 'e782f48a' as 'Modules/Page'

parents 64bd6f40 e782f48a
.idea/
.php_cs.cache
vendor/
Modules/
composer.lock
build/
<?php
$finder = Symfony\CS\Finder\DefaultFinder::create()
->exclude('Modules')
->exclude('vendor')
->in(__DIR__)
;
return Symfony\CS\Config\Config::create()
->setUsingCache(true)
->level(Symfony\CS\FixerInterface::PSR2_LEVEL)
->fixers(array(
// Concatenation should be used with at least one whitespace around.
'concat_with_spaces',
// Unused use statements must be removed.
'ordered_use',
// Removes extra empty lines.
'extra_empty_lines',
// Removes line breaks between use statements.
'remove_lines_between_uses',
// An empty line feed should precede a return statement.
'return',
// Unused use statements must be removed.
'unused_use',
// Remove trailing whitespace at the end of blank lines.
'whitespacy_lines',
// There MUST be one blank line after the namespace declaration.
'line_after_namespace',
// There should be exactly one blank line before a namespace declaration.
'single_blank_line_before_namespace',
// Each namespace use MUST go on its own line and there MUST be one blank line after the use statements block.
'single_line_after_imports',
// Ensure there is no code on the same line as the PHP open tag and it is followed by a blankline.
'blankline_after_open_tag',
// Remove duplicated semicolons.
'duplicate_semicolon',
// PHP multi-line arrays should have a trailing comma.
'multiline_array_trailing_comma',
// There should be no empty lines after class opening brace.
'no_blank_lines_after_class_opening',
// There should not be blank lines between docblock and the documented element.
'no_empty_lines_after_phpdocs',
// Phpdocs should start and end with content, excluding the very first and last line of the docblocks.
'phpdoc_trim',
// Removes line breaks between use statements.
'remove_lines_between_uses',
))
->finder($finder);
checks:
php: true
filter:
excluded_paths: [vendor/*, Tests/*, Modules/*]
coding_style:
php: { }
tools:
external_code_coverage: true
php_code_coverage: true
rules:
php.interface_has_no_interface_suffix:
enabled: false
language: php
php:
- 7
- 5.6
env:
- LARAVEL_VERSION="~5.2" TESTBENCH_VERSION="~3.2"
before_script:
- travis_retry composer self-update
- travis_retry composer install --no-interaction --prefer-source
script:
- phpunit --coverage-text --coverage-clover=coverage.clover
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
sudo: false
notifications:
email:
- n.widart@gmail.com
- josh@joshbrown.me
<?php
namespace Modules\Page\Composers;
use Illuminate\Contracts\View\View;
use Modules\Core\Foundation\Theme\ThemeManager;
use Modules\Page\Services\FinderService;
class TemplateViewComposer
{
/**
* @var ThemeManager
*/
private $themeManager;
/**
* @var FinderService
*/
private $finder;
public function __construct(ThemeManager $themeManager, FinderService $finder)
{
$this->themeManager = $themeManager;
$this->finder = $finder;
}
public function compose(View $view)
{
$view->with('all_templates', $this->getTemplates());
}
private function getTemplates()
{
$path = $this->getCurrentThemeBasePath();
$templates = [];
foreach ($this->finder->excluding(config('asgard.page.config.template-ignored-directories', []))->allFiles($path . '/views') as $template) {
$relativePath = $template->getRelativePath();
$templateName = $this->getTemplateName($template);
$file = $this->removeExtensionsFromFilename($template);
if ($this->hasSubdirectory($relativePath)) {
$templates[str_replace('/', '.', $relativePath) . '.' . $file] = $templateName;
} else {
$templates[$file] = $templateName;
}
}
return $templates;
}
/**
* Get the base path of the current theme.
*
* @return string
*/
private function getCurrentThemeBasePath()
{
return $this->themeManager->find(setting('core::template'))->getPath();
}
/**
* Read template name defined in comments.
*
* @param $template
*
* @return string
*/
private function getTemplateName($template)
{
preg_match("/{{-- Template: (.*) --}}/", $template->getContents(), $templateName);
if (count($templateName) > 1) {
return $templateName[1];
}
return $this->getDefaultTemplateName($template);
}
/**
* If the template name is not defined in comments, build a default.
*
* @param $template
*
* @return mixed
*/
private function getDefaultTemplateName($template)
{
$relativePath = $template->getRelativePath();
$fileName = $this->removeExtensionsFromFilename($template);
return $this->hasSubdirectory($relativePath) ? $relativePath . '/' . $fileName : $fileName;
}
/**
* Remove the extension from the filename.
*
* @param $template
*
* @return mixed
*/
private function removeExtensionsFromFilename($template)
{
return str_replace('.blade.php', '', $template->getFilename());
}
/**
* Check if the relative path is not empty (meaning the template is in a directory).
*
* @param $relativePath
*
* @return bool
*/
private function hasSubdirectory($relativePath)
{
return ! empty($relativePath);
}
}
<?php
return [
/*
|--------------------------------------------------------------------------
| Partials to include on page views
|--------------------------------------------------------------------------
| List the partials you wish to include on the different type page views
| The content of those fields well be caught by the PageWasCreated and PageWasEdited events
*/
'partials' => [
'translatable' => [
'create' => [],
'edit' => [],
],
'normal' => [
'create' => [],
'edit' => [],
],
],
/*
|--------------------------------------------------------------------------
| Dynamic relations
|--------------------------------------------------------------------------
| Add relations that will be dynamically added to the Page entity
*/
'relations' => [
// 'extension' => function ($self) {
// return $self->belongsTo(PageExtension::class, 'id', 'page_id')->first();
// }
],
/*
|--------------------------------------------------------------------------
| Array of middleware that will be applied on the page module front end routes
|--------------------------------------------------------------------------
*/
'middleware' => [],
/*
|--------------------------------------------------------------------------
| Array of directories to ignore when selecting the template for a page
|--------------------------------------------------------------------------
*/
'template-ignored-directories' => [
'layouts',
'partials',
],
/*
|--------------------------------------------------------------------------
| Custom Sidebar Class
|--------------------------------------------------------------------------
| If you want to customise the admin sidebar ordering or grouping
| You can define your own sidebar class for this module.
| No custom sidebar: null
*/
'custom-sidebar' => null,
];
<?php
return [
'page.pages' => [
'index' => 'page::pages.list resource',
'create' => 'page::pages.create resource',
'edit' => 'page::pages.edit resource',
'destroy' => 'page::pages.destroy resource',
],
];
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreatePagesTables extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('page__pages', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->boolean('is_home')->default(0);
$table->string('template');
$table->timestamps();
});
Schema::create('page__page_translations', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('page_id')->unsigned();
$table->string('locale')->index();
$table->string('title');
$table->string('slug');
$table->boolean('status')->default(1);
$table->text('body');
$table->string('meta_title')->nullable();
$table->string('meta_description')->nullable();
$table->string('og_title')->nullable();
$table->string('og_description')->nullable();
$table->string('og_image')->nullable();
$table->string('og_type')->nullable();
$table->unique(['page_id', 'locale']);
$table->foreign('page_id')->references('id')->on('page__pages')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('page__page_translations');
Schema::drop('page__pages');
}
}
<?php
namespace Modules\Page\Database\Seeders;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Seeder;
use Modules\Page\Repositories\PageRepository;
class PageDatabaseSeeder extends Seeder
{
/**
* @var PageRepository
*/
private $page;
public function __construct(PageRepository $page)
{
$this->page = $page;
}
public function run()
{
Model::unguard();
$data = [
'template' => 'home',
'is_home' => 1,
'en' => [
'title' => 'Home page',
'slug' => 'home',
'body' => '<p><strong>You made it!</strong></p>
<p>You&#39;ve installed AsgardCMS and are ready to proceed to the <a href="/en/backend">administration area</a>.</p>
<h2>What&#39;s next ?</h2>
<p>Learn how you can develop modules for AsgardCMS by reading our <a href="https://github.com/AsgardCms/Documentation">documentation</a>.</p>
',
'meta_title' => 'Home page',
],
];
$this->page->create($data);
}
}
<?php
namespace Modules\Page\Entities;
use Dimsav\Translatable\Translatable;
use Illuminate\Database\Eloquent\Model;
use Modules\Core\Traits\NamespacedEntity;
use Modules\Tag\Contracts\TaggableInterface;
use Modules\Tag\Traits\TaggableTrait;
class Page extends Model implements TaggableInterface
{
use Translatable, TaggableTrait, NamespacedEntity;
protected $table = 'page__pages';
public $translatedAttributes = [
'page_id',
'title',
'slug',
'status',
'body',
'meta_title',
'meta_description',
'og_title',
'og_description',
'og_image',
'og_type',
];
protected $fillable = [
'is_home',
'template',
// Translatable fields
'page_id',
'title',
'slug',
'status',
'body',
'meta_title',
'meta_description',
'og_title',
'og_description',
'og_image',
'og_type',
];
protected $casts = [
'is_home' => 'boolean',
];
protected static $entityNamespace = 'asgardcms/page';
public function __call($method, $parameters)
{
#i: Convert array to dot notation
$config = implode('.', ['asgard.page.config.relations', $method]);
#i: Relation method resolver
if (config()->has($config)) {
$function = config()->get($config);
return $function($this);
}
#i: No relation found, return the call to parent (Eloquent) to handle it.
return parent::__call($method, $parameters);
}
}
<?php
namespace Modules\Page\Entities;
use Illuminate\Database\Eloquent\Model;
class PageTranslation extends Model
{
protected $table = 'page__page_translations';
protected $fillable = [
'page_id',
'title',
'slug',
'status',
'body',
'meta_title',
'meta_description',
'og_title',
'og_description',
'og_image',
'og_type',
];
}
<?php
namespace Modules\Page\Events;
class PageWasCreated
{
/**
* @var array
*/
public $data;
/**
* @var int
*/
public $pageId;
public function __construct($pageId, array $data)
{
$this->data = $data;
$this->pageId = $pageId;
}
}
<?php
namespace Modules\Page\Events;
class PageWasDeleted
{
/**
* @var object
*/
public $page;
public function __construct($page)
{
$this->page = $page;
}
}
<?php
namespace Modules\Page\Events;
class PageWasUpdated
{
/**
* @var array
*/
public $data;
/**
* @var int
*/
public $pageId;
public function __construct($pageId, array $data)
{
$this->data = $data;
$this->pageId = $pageId;
}
}
<?php
namespace Modules\Page\Http\Controllers\Admin;
use Modules\Core\Http\Controllers\Admin\AdminBaseController;
use Modules\Page\Entities\Page;
use Modules\Page\Http\Requests\CreatePageRequest;
use Modules\Page\Http\Requests\UpdatePageRequest;
use Modules\Page\Repositories\PageRepository;
class PageController extends AdminBaseController
{
/**
* @var PageRepository
*/
private $page;
public function __construct(PageRepository $page)
{
parent::__construct();
$this->page = $page;
$this->assetPipeline->requireCss('icheck.blue.css');
}
public function index()
{
$pages = $this->page->all();
return view('page::admin.index', compact('pages'));
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
$this->assetPipeline->requireJs('ckeditor.js');
return view('page::admin.create');
}
/**
* Store a newly created resource in storage.
*
* @param CreatePageRequest $request
* @return Response
*/
public function store(CreatePageRequest $request)
{
$this->page->create($request->all());
return redirect()->route('admin.page.page.index')
->withSuccess(trans('page::messages.page created'));
}
/**
* Show the form for editing the specified resource.
*
* @param Page $page
* @return Response
*/
public function edit(Page $page)
{
$this->assetPipeline->requireJs('ckeditor.js');
return view('page::admin.edit', compact('page'));
}
/**
* Update the specified resource in storage.
*
* @param Page $page
* @param UpdatePageRequest $request
* @return Response
*/
public function update(Page $page, UpdatePageRequest $request)
{
$this->page->update($page, $request->all());
if ($request->get('button') === 'index') {
return redirect()->route('admin.page.page.index')
->withSuccess(trans('page::messages.page updated'));
}
return redirect()->back()
->withSuccess(trans('page::messages.page updated'));
}
/**
* Remove the specified resource from storage.
*
* @param Page $page
* @return Response
*/
public function destroy(Page $page)
{
$this->page->destroy($page);
return redirect()->route('admin.page.page.index')
->withSuccess(trans('page::messages.page deleted'));
}
}
<?php
namespace Modules\Page\Http\Controllers;
use Illuminate\Contracts\Foundation\Application;
use Modules\Core\Http\Controllers\BasePublicController;
use Modules\Menu\Repositories\MenuItemRepository;
use Modules\Page\Entities\Page;
use Modules\Page\Repositories\PageRepository;
class PublicController extends BasePublicController
{
/**
* @var PageRepository
*/
private $page;
/**
* @var Application
*/
private $app;
public function __construct(PageRepository $page, Application $app)
{
parent::__construct();
$this->page = $page;
$this->app = $app;
}
/**
* @param $slug
* @return \Illuminate\View\View
*/
public function uri($slug)
{
$page = $this->findPageForSlug($slug);
$this->throw404IfNotFound($page);
$template = $this->getTemplateForPage($page);
return view($template, compact('page'));
}
/**
* @return \Illuminate\View\View
*/
public function homepage()
{
$page = $this->page->findHomepage();
$this->throw404IfNotFound($page);
$template = $this->getTemplateForPage($page);
return view($template, compact('page'));
}
/**
* Find a page for the given slug.
* The slug can be a 'composed' slug via the Menu
* @param string $slug
* @return Page
*/
private function findPageForSlug($slug)
{
$menuItem = app(MenuItemRepository::class)->findByUriInLanguage($slug, locale());
if ($menuItem) {
return $this->page->find($menuItem->page_id);
}
return $this->page->findBySlug($slug);
}
/**
* Return the template for the given page
* or the default template if none found
* @param $page
* @return string
*/
private function getTemplateForPage($page)
{
return (view()->exists($page->template)) ? $page->template : 'default';
}
/**
* Throw a 404 error page if the given page is not found
* @param $page
*/
private function throw404IfNotFound($page)
{
if (is_null($page)) {
$this->app->abort('404');
}
}
}
<?php
namespace Modules\Page\Http\Requests;
use Modules\Core\Internationalisation\BaseFormRequest;
class CreatePageRequest extends BaseFormRequest
{
protected $translationsAttributesKey = 'page::pages.validation.attributes';
public function rules()
{
return [
'template' => 'required',
];
}
public function translationRules()
{
return [
'title' => 'required',
'body' => 'required',
];
}
public function authorize()
{
return true;
}
public function messages()
{
return [
'template.required' => trans('page::messages.template is required'),
'is_home.unique' => trans('page::messages.only one homepage allowed'),
];
}
public function translationMessages()
{
return [
'title.required' => trans('page::messages.title is required'),
'body.required' => trans('page::messages.body is required'),
];
}
}
<?php
namespace Modules\Page\Http\Requests;
use Modules\Core\Internationalisation\BaseFormRequest;
class UpdatePageRequest extends BaseFormRequest
{
protected $translationsAttributesKey = 'page::pages.validation.attributes';
public function rules()
{
return [
'template' => 'required',
];
}
public function translationRules()
{
return [
'title' => 'required',
'body' => 'required',
];
}
public function authorize()
{
return true;
}
public function messages()
{
return [
'template.required' => trans('page::messages.template is required'),
'is_home.unique' => trans('page::messages.only one homepage allowed'),
];
}
public function translationMessages()
{
return [
'title.required' => trans('page::messages.title is required'),
'body.required' => trans('page::messages.body is required'),
];
}
}
<?php
use Illuminate\Routing\Router;
/** @var Router $router */
$router->bind('page', function ($id) {
return app(\Modules\Page\Repositories\PageRepository::class)->find($id);
});
$router->group(['prefix' => '/page'], function (Router $router) {
$router->get('pages', [
'as' => 'admin.page.page.index',
'uses' => 'PageController@index',
'middleware' => 'can:page.pages.index',
]);
$router->get('pages/create', [
'as' => 'admin.page.page.create',
'uses' => 'PageController@create',
'middleware' => 'can:page.pages.create',
]);
$router->post('pages', [
'as' => 'admin.page.page.store',
'uses' => 'PageController@store',
'middleware' => 'can:page.pages.create',
]);
$router->get('pages/{page}/edit', [
'as' => 'admin.page.page.edit',
'uses' => 'PageController@edit',
'middleware' => 'can:page.pages.edit',
]);
$router->put('pages/{page}/edit', [
'as' => 'admin.page.page.update',
'uses' => 'PageController@update',
'middleware' => 'can:page.pages.edit',
]);
$router->delete('pages/{page}', [
'as' => 'admin.page.page.destroy',
'uses' => 'PageController@destroy',
'middleware' => 'can:page.pages.destroy',
]);
});
<?php
use Illuminate\Routing\Router;
/** @var Router $router */
if (! App::runningInConsole()) {
$router->get('/', [
'uses' => 'PublicController@homepage',
'as' => 'homepage',
'middleware' => config('asgard.page.config.middleware'),
]);
$router->any('{uri}', [
'uses' => 'PublicController@uri',
'as' => 'page',
'middleware' => config('asgard.page.config.middleware'),
])->where('uri', '.*');
}
# License (MIT)
Copyright (c) 2016 Nicolas Widart , n.widart@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<?php
namespace Modules\Page\Providers;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\ServiceProvider;
use Modules\Core\Traits\CanPublishConfiguration;
use Modules\Page\Entities\Page;
use Modules\Page\Repositories\Cache\CachePageDecorator;
use Modules\Page\Repositories\Eloquent\EloquentPageRepository;
use Modules\Page\Services\FinderService;
use Modules\Tag\Repositories\TagManager;
class PageServiceProvider extends ServiceProvider
{
use CanPublishConfiguration;
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerBindings();
}
public function boot()
{
$this->publishConfig('page', 'config');
$this->publishConfig('page', 'permissions');
$this->app[TagManager::class]->registerNamespace(new Page());
$this->loadMigrationsFrom(__DIR__.'/../Database/Migrations');
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array();
}
private function registerBindings()
{
$this->app->bind(FinderService::class, function () {
return new FinderService();
});
$this->app->bind(
'Modules\Page\Repositories\PageRepository',
function () {
$repository = new EloquentPageRepository(new Page());
if (! Config::get('app.cache')) {
return $repository;
}
return new CachePageDecorator($repository);
}
);
}
}
<?php
namespace Modules\Page\Providers;
use Modules\Core\Providers\RoutingServiceProvider as CoreRoutingServiceProvider;
class RouteServiceProvider extends CoreRoutingServiceProvider
{
/**
* The root namespace to assume when generating URLs to actions.
* @var string
*/
protected $namespace = 'Modules\Page\Http\Controllers';
/**
* @return string
*/
protected function getFrontendRoute()
{
return __DIR__ . '/../Http/frontendRoutes.php';
}
/**
* @return string
*/
protected function getBackendRoute()
{
return __DIR__ . '/../Http/backendRoutes.php';
}
/**
* @return string
*/
protected function getApiRoute()
{
return false;
}
}
<?php
namespace Modules\Page\Repositories\Cache;
use Modules\Core\Repositories\Cache\BaseCacheDecorator;
use Modules\Page\Repositories\PageRepository;
class CachePageDecorator extends BaseCacheDecorator implements PageRepository
{
/**
* @var PageRepository
*/
protected $repository;
public function __construct(PageRepository $page)
{
parent::__construct();
$this->entityName = 'pages';
$this->repository = $page;
}
/**
* Find the page set as homepage
*
* @return object
*/
public function findHomepage()
{
return $this->cache
->tags([$this->entityName, 'global'])
->remember("{$this->locale}.{$this->entityName}.findHomepage", $this->cacheTime,
function () {
return $this->repository->findHomepage();
}
);
}
/**
* Count all records
* @return int
*/
public function countAll()
{
return $this->cache
->tags([$this->entityName, 'global'])
->remember("{$this->locale}.{$this->entityName}.countAll", $this->cacheTime,
function () {
return $this->repository->countAll();
}
);
}
/**
* @param $slug
* @param $locale
* @return object
*/
public function findBySlugInLocale($slug, $locale)
{
return $this->cache
->tags([$this->entityName, 'global'])
->remember("{$this->locale}.{$this->entityName}.findBySlugInLocale.{$slug}.{$locale}", $this->cacheTime,
function () use ($slug, $locale) {
return $this->repository->findBySlugInLocale($slug, $locale);
}
);
}
}
<?php
namespace Modules\Page\Repositories\Eloquent;
use Illuminate\Database\Eloquent\Builder;
use Modules\Core\Repositories\Eloquent\EloquentBaseRepository;
use Modules\Page\Events\PageWasCreated;
use Modules\Page\Events\PageWasDeleted;
use Modules\Page\Events\PageWasUpdated;
use Modules\Page\Repositories\PageRepository;
class EloquentPageRepository extends EloquentBaseRepository implements PageRepository
{
/**
* Find the page set as homepage
* @return object
*/
public function findHomepage()
{
return $this->model->where('is_home', 1)->first();
}
/**
* Count all records
* @return int
*/
public function countAll()
{
return $this->model->count();
}
/**
* @param mixed $data
* @return object
*/
public function create($data)
{
if (array_get($data, 'is_home') === '1') {
$this->removeOtherHomepage();
}
$page = $this->model->create($data);
event(new PageWasCreated($page->id, $data));
$page->setTags(array_get($data, 'tags', []));
return $page;
}
/**
* @param $model
* @param array $data
* @return object
*/
public function update($model, $data)
{
if (array_get($data, 'is_home') === '1') {
$this->removeOtherHomepage($model->id);
}
$model->update($data);
event(new PageWasUpdated($model->id, $data));
$model->setTags(array_get($data, 'tags', []));
return $model;
}
public function destroy($page)
{
$page->untag();
event(new PageWasDeleted($page));
return $page->delete();
}
/**
* @param $slug
* @param $locale
* @return object
*/
public function findBySlugInLocale($slug, $locale)
{
if (method_exists($this->model, 'translations')) {
return $this->model->whereHas('translations', function (Builder $q) use ($slug, $locale) {
$q->where('slug', $slug);
$q->where('locale', $locale);
})->with('translations')->first();
}
return $this->model->where('slug', $slug)->where('locale', $locale)->first();
}
/**
* Set the current page set as homepage to 0
* @param null $pageId
*/
private function removeOtherHomepage($pageId = null)
{
$homepage = $this->findHomepage();
if ($homepage === null) {
return;
}
if ($pageId === $homepage->id) {
return;
}
$homepage->is_home = 0;
$homepage->save();
}
}
<?php
namespace Modules\Page\Repositories;
use Modules\Core\Repositories\BaseRepository;
interface PageRepository extends BaseRepository
{
/**
* Find the page set as homepage
* @return object
*/
public function findHomepage();
/**
* Count all records
* @return int
*/
public function countAll();
/**
* @param $slug
* @param $locale
* @return object
*/
public function findBySlugInLocale($slug, $locale);
}
@extends('layouts.master')
@section('content-header')
<h1>
{{ trans('page::pages.title.create page') }}
</h1>
<ol class="breadcrumb">
<li><a href="{{ URL::route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li>
<li><a href="{{ URL::route('admin.page.page.index') }}">{{ trans('page::pages.title.pages') }}</a></li>
<li class="active">{{ trans('page::pages.title.create page') }}</li>
</ol>
@stop
@section('styles')
<style>
.checkbox label {
padding-left: 0;
}
</style>
@stop
@section('content')
{!! Form::open(['route' => ['admin.page.page.store'], 'method' => 'post']) !!}
<div class="row">
<div class="col-md-10">
<div class="nav-tabs-custom">
@include('partials.form-tab-headers', ['fields' => ['title', 'body']])
<div class="tab-content">
<?php $i = 0; ?>
<?php foreach (LaravelLocalization::getSupportedLocales() as $locale => $language): ?>
<?php ++$i; ?>
<div class="tab-pane {{ App::getLocale() == $locale ? 'active' : '' }}" id="tab_{{ $i }}">
@include('page::admin.partials.create-fields', ['lang' => $locale])
</div>
<?php endforeach; ?>
<?php if (config('asgard.page.config.partials.normal.create') !== []): ?>
<?php foreach (config('asgard.page.config.partials.normal.create') as $partial): ?>
@include($partial)
<?php endforeach; ?>
<?php endif; ?>
<div class="box-footer">
<button type="submit" class="btn btn-primary btn-flat">{{ trans('core::core.button.create') }}</button>
<button class="btn btn-default btn-flat" name="button" type="reset">{{ trans('core::core.button.reset') }}</button>
<a class="btn btn-danger pull-right btn-flat" href="{{ URL::route('admin.page.page.index')}}"><i class="fa fa-times"></i> {{ trans('core::core.button.cancel') }}</a>
</div>
</div>
</div> {{-- end nav-tabs-custom --}}
</div>
<div class="col-md-2">
<div class="box box-primary">
<div class="box-body">
<div class="checkbox{{ $errors->has('is_home') ? ' has-error' : '' }}">
<input type="hidden" name="is_home" value="0">
<label for="is_home">
<input id="is_home"
name="is_home"
type="checkbox"
class="flat-blue"
value="1" />
{{ trans('page::pages.form.is homepage') }}
{!! $errors->first('is_home', '<span class="help-block">:message</span>') !!}
</label>
</div>
<hr/>
<div class='form-group{{ $errors->has("template") ? ' has-error' : '' }}'>
{!! Form::label("template", trans('page::pages.form.template')) !!}
{!! Form::select("template", $all_templates, old("template", 'default'), ['class' => "form-control", 'placeholder' => trans('page::pages.form.template')]) !!}
{!! $errors->first("template", '<span class="help-block">:message</span>') !!}
</div>
<hr>
@tags('asgardcms/page')
</div>
</div>
</div>
</div>
{!! Form::close() !!}
@stop
@section('footer')
<a data-toggle="modal" data-target="#keyboardShortcutsModal"><i class="fa fa-keyboard-o"></i></a> &nbsp;
@stop
@section('shortcuts')
<dl class="dl-horizontal">
<dt><code>b</code></dt>
<dd>{{ trans('page::pages.navigation.back to index') }}</dd>
</dl>
@stop
@section('scripts')
<script>
$( document ).ready(function() {
$(document).keypressAction({
actions: [
{ key: 'b', route: "<?= route('admin.page.page.index') ?>" }
]
});
$('input[type="checkbox"].flat-blue, input[type="radio"].flat-blue').iCheck({
checkboxClass: 'icheckbox_flat-blue',
radioClass: 'iradio_flat-blue'
});
});
</script>
@stop
@extends('layouts.master')
@section('content-header')
<h1>
{{ trans('page::pages.title.edit page') }}
</h1>
<ol class="breadcrumb">
<li><a href="{{ URL::route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li>
<li><a href="{{ URL::route('admin.page.page.index') }}">{{ trans('page::pages.title.pages') }}</a></li>
<li class="active">{{ trans('page::pages.title.edit page') }}</li>
</ol>
@stop
@section('styles')
<style>
.checkbox label {
padding-left: 0;
}
</style>
@stop
@section('content')
{!! Form::open(['route' => ['admin.page.page.update', $page->id], 'method' => 'put']) !!}
<div class="row">
<div class="col-md-10">
<div class="nav-tabs-custom">
@include('partials.form-tab-headers', ['fields' => ['title', 'body']])
<div class="tab-content">
<?php $i = 0; ?>
<?php foreach (LaravelLocalization::getSupportedLocales() as $locale => $language): ?>
<?php ++$i; ?>
<div class="tab-pane {{ App::getLocale() == $locale ? 'active' : '' }}" id="tab_{{ $i }}">
@include('page::admin.partials.edit-fields', ['lang' => $locale])
</div>
<?php endforeach; ?>
<?php if (config('asgard.page.config.partials.normal.edit') !== []): ?>
<?php foreach (config('asgard.page.config.partials.normal.edit') as $partial): ?>
@include($partial)
<?php endforeach; ?>
<?php endif; ?>
<div class="box-footer">
<button type="submit" class="btn btn-primary btn-flat" name="button" value="index" >
<i class="fa fa-angle-left"></i>
{{ trans('core::core.button.update and back') }}
</button>
<button type="submit" class="btn btn-primary btn-flat">
{{ trans('core::core.button.update') }}
</button>
<button class="btn btn-default btn-flat" name="button" type="reset">{{ trans('core::core.button.reset') }}</button>
<a class="btn btn-danger pull-right btn-flat" href="{{ URL::route('admin.page.page.index')}}"><i class="fa fa-times"></i> {{ trans('core::core.button.cancel') }}</a>
</div>
</div>
</div> {{-- end nav-tabs-custom --}}
</div>
<div class="col-md-2">
<div class="box box-primary">
<div class="box-body">
<div class="checkbox{{ $errors->has('is_home') ? ' has-error' : '' }}">
<input type="hidden" name="is_home" value="0">
<label for="is_home">
<input id="is_home"
name="is_home"
type="checkbox"
class="flat-blue"
{{ isset($page->is_home) && (bool)$page->is_home == true ? 'checked' : '' }}
value="1" />
{{ trans('page::pages.form.is homepage') }}
{!! $errors->first('is_home', '<span class="help-block">:message</span>') !!}
</label>
</div>
<hr/>
<div class='form-group{{ $errors->has("template") ? ' has-error' : '' }}'>
{!! Form::label("template", trans('page::pages.form.template')) !!}
{!! Form::select("template", $all_templates, old("template", $page->template), ['class' => "form-control", 'placeholder' => trans('page::pages.form.template')]) !!}
{!! $errors->first("template", '<span class="help-block">:message</span>') !!}
</div>
<hr>
@tags('asgardcms/page', $page)
</div>
</div>
</div>
</div>
{!! Form::close() !!}
@stop
@section('footer')
<a data-toggle="modal" data-target="#keyboardShortcutsModal"><i class="fa fa-keyboard-o"></i></a> &nbsp;
@stop
@section('shortcuts')
<dl class="dl-horizontal">
<dt><code>b</code></dt>
<dd>{{ trans('page::pages.navigation.back to index') }}</dd>
</dl>
@stop
@section('scripts')
<script>
$( document ).ready(function() {
$(document).keypressAction({
actions: [
{ key: 'b', route: "<?= route('admin.page.page.index') ?>" }
]
});
$('input[type="checkbox"].flat-blue, input[type="radio"].flat-blue').iCheck({
checkboxClass: 'icheckbox_flat-blue',
radioClass: 'iradio_flat-blue'
});
});
</script>
@stop
@extends('layouts.master')
@section('content-header')
<h1>
{{ trans('page::pages.title.pages') }}
</h1>
<ol class="breadcrumb">
<li><a href="{{ URL::route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li>
<li class="active">{{ trans('page::pages.title.pages') }}</li>
</ol>
@stop
@section('content')
<div class="row">
<div class="col-xs-12">
<div class="row">
<div class="btn-group pull-right" style="margin: 0 15px 15px 0;">
<a href="{{ URL::route('admin.page.page.create') }}" class="btn btn-primary btn-flat" style="padding: 4px 10px;">
<i class="fa fa-pencil"></i> {{ trans('page::pages.button.create page') }}
</a>
</div>
</div>
<div class="box box-primary">
<div class="box-header">
</div>
<!-- /.box-header -->
<div class="box-body">
<table class="data-table table table-bordered table-hover">
<thead>
<tr>
<th>Id</th>
<th>{{ trans('page::pages.table.name') }}</th>
<th>{{ trans('page::pages.table.slug') }}</th>
<th>{{ trans('core::core.table.created at') }}</th>
<th data-sortable="false">{{ trans('core::core.table.actions') }}</th>
</tr>
</thead>
<tbody>
<?php if (isset($pages)): ?>
<?php foreach ($pages as $page): ?>
<tr>
<td>
<a href="{{ URL::route('admin.page.page.edit', [$page->id]) }}">
{{ $page->id }}
</a>
</td>
<td>
<a href="{{ URL::route('admin.page.page.edit', [$page->id]) }}">
{{ $page->title }}
</a>
</td>
<td>
<a href="{{ URL::route('admin.page.page.edit', [$page->id]) }}">
{{ $page->slug }}
</a>
</td>
<td>
<a href="{{ URL::route('admin.page.page.edit', [$page->id]) }}">
{{ $page->created_at }}
</a>
</td>
<td>
<div class="btn-group">
<a href="{{ URL::route('admin.page.page.edit', [$page->id]) }}" class="btn btn-default btn-flat"><i class="fa fa-pencil"></i></a>
<button data-toggle="modal" data-target="#modal-delete-confirmation" data-action-target="{{ route('admin.page.page.destroy', [$page->id]) }}" class="btn btn-danger btn-flat"><i class="fa fa-trash"></i></button>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
<tfoot>
<tr>
<th>Id</th>
<th>{{ trans('page::pages.table.name') }}</th>
<th>{{ trans('page::pages.table.slug') }}</th>
<th>{{ trans('core::core.table.created at') }}</th>
<th>{{ trans('core::core.table.actions') }}</th>
</tr>
</tfoot>
</table>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
</div>
</div>
@include('core::partials.delete-modal')
@stop
@section('footer')
<a data-toggle="modal" data-target="#keyboardShortcutsModal"><i class="fa fa-keyboard-o"></i></a> &nbsp;
@stop
@section('shortcuts')
<dl class="dl-horizontal">
<dt><code>c</code></dt>
<dd>{{ trans('page::pages.title.create page') }}</dd>
</dl>
@stop
@section('scripts')
<?php $locale = App::getLocale(); ?>
<script type="text/javascript">
$( document ).ready(function() {
$(document).keypressAction({
actions: [
{ key: 'c', route: "<?= route('admin.page.page.create') ?>" }
]
});
});
$(function () {
$('.data-table').dataTable({
"paginate": true,
"lengthChange": true,
"filter": true,
"sort": true,
"info": true,
"autoWidth": true,
"order": [[ 0, "desc" ]],
"language": {
"url": '<?php echo Module::asset("core:js/vendor/datatables/{$locale}.json") ?>'
}
});
});
</script>
@stop
<div class="box-body">
<div class="box-body">
<div class='form-group{{ $errors->has("{$lang}.title") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[title]", trans('page::pages.form.title')) !!}
{!! Form::text("{$lang}[title]", old("{$lang}.title"), ['class' => 'form-control', 'data-slug' => 'source', 'placeholder' => trans('page::pages.form.title')]) !!}
{!! $errors->first("{$lang}.title", '<span class="help-block">:message</span>') !!}
</div>
<div class='form-group{{ $errors->has("{$lang}.slug") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[slug]", trans('page::pages.form.slug')) !!}
{!! Form::text("{$lang}[slug]", old("{$lang}.slug"), ['class' => 'form-control slug', 'data-slug' => 'target', 'placeholder' => trans('page::pages.form.slug')]) !!}
{!! $errors->first("{$lang}.slug", '<span class="help-block">:message</span>') !!}
</div>
<div class='{{ $errors->has("{$lang}.body") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[body]", trans('page::pages.form.body')) !!}
<textarea class="ckeditor" name="{{$lang}}[body]" rows="10" cols="80">{{ old("{$lang}.body") }}</textarea>
{!! $errors->first("{$lang}.body", '<span class="help-block">:message</span>') !!}
</div>
<?php if (config('asgard.page.config.partials.translatable.create') !== []): ?>
<?php foreach (config('asgard.page.config.partials.translatable.create') as $partial): ?>
@include($partial)
<?php endforeach; ?>
<?php endif; ?>
</div>
<div class="box-group" id="accordion">
<!-- we are adding the .panel class so bootstrap.js collapse plugin detects it -->
<div class="panel box box-primary">
<div class="box-header">
<h4 class="box-title">
<a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo-{{$lang}}">
{{ trans('page::pages.form.meta_data') }}
</a>
</h4>
</div>
<div style="height: 0px;" id="collapseTwo-{{$lang}}" class="panel-collapse collapse">
<div class="box-body">
<div class='form-group{{ $errors->has("{$lang}[meta_title]") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[meta_title]", trans('page::pages.form.meta_title')) !!}
{!! Form::text("{$lang}[meta_title]", old("$lang.meta_title"), ['class' => "form-control", 'placeholder' => trans('page::pages.form.meta_title')]) !!}
{!! $errors->first("{$lang}[meta_title]", '<span class="help-block">:message</span>') !!}
</div>
<div class='form-group{{ $errors->has("{$lang}[meta_description]") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[meta_description]", trans('page::pages.form.meta_description')) !!}
<textarea class="form-control" name="{{$lang}}[meta_description]" rows="10" cols="80">{{ old("$lang.meta_description") }}</textarea>
{!! $errors->first("{$lang}[meta_description]", '<span class="help-block">:message</span>') !!}
</div>
</div>
</div>
</div>
<div class="panel box box-primary">
<div class="box-header">
<h4 class="box-title">
<a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseFacebook-{{$lang}}">
{{ trans('page::pages.form.facebook_data') }}
</a>
</h4>
</div>
<div style="height: 0px;" id="collapseFacebook-{{$lang}}" class="panel-collapse collapse">
<div class="box-body">
<div class='form-group{{ $errors->has("{$lang}[og_title]") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[og_title]", trans('page::pages.form.og_title')) !!}
{!! Form::text("{$lang}[og_title]", old("{$lang}.og_title"), ['class' => "form-control", 'placeholder' => trans('page::pages.form.og_title')]) !!}
{!! $errors->first("{$lang}[og_title]", '<span class="help-block">:message</span>') !!}
</div>
<div class='form-group{{ $errors->has("{$lang}[og_description]") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[og_description]", trans('page::pages.form.og_description')) !!}
<textarea class="form-control" name="{{$lang}}[og_description]" rows="10" cols="80">{{ old("$lang.og_description") }}</textarea>
{!! $errors->first("{$lang}[og_description]", '<span class="help-block">:message</span>') !!}
</div>
<div class="form-group{{ $errors->has("{$lang}[og_type]") ? ' has-error' : '' }}">
<label>{{ trans('page::pages.form.og_type') }}</label>
<select class="form-control" name="{{ $lang }}[og_type]">
<option value="website" {{ old("$lang.og_type") == 'website' ? 'selected' : '' }}>{{ trans('page::pages.facebook-types.website') }}</option>
<option value="product" {{ old("$lang.og_type") == 'product' ? 'selected' : '' }}>{{ trans('page::pages.facebook-types.product') }}</option>
<option value="article" {{ old("$lang.og_type") == 'article' ? 'selected' : '' }}>{{ trans('page::pages.facebook-types.article') }}</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="box-body">
<div class="box-body">
<div class='form-group{{ $errors->has("{$lang}.title") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[title]", trans('page::pages.form.title')) !!}
<?php $old = $page->hasTranslation($lang) ? $page->translate($lang)->title : '' ?>
{!! Form::text("{$lang}[title]", old("{$lang}.title", $old), ['class' => 'form-control', 'data-slug' => 'source', 'placeholder' => trans('page::pages.form.title')]) !!}
{!! $errors->first("{$lang}.title", '<span class="help-block">:message</span>') !!}
</div>
<div class='form-group{{ $errors->has("{$lang}[slug]") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[slug]", trans('page::pages.form.slug')) !!}
<?php $old = $page->hasTranslation($lang) ? $page->translate($lang)->slug : '' ?>
{!! Form::text("{$lang}[slug]", old("{$lang}.slug", $old), ['class' => 'form-control slug', 'data-slug' => 'target', 'placeholder' => trans('page::pages.form.slug')]) !!}
{!! $errors->first("{$lang}.slug", '<span class="help-block">:message</span>') !!}
</div>
<div class='{{ $errors->has("{$lang}.body") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[body]", trans('page::pages.form.body')) !!}
<?php $old = $page->hasTranslation($lang) ? $page->translate($lang)->body : '' ?>
<textarea class="ckeditor" name="{{$lang}}[body]" rows="10" cols="80">
{!! old("$lang.body", $old) !!}
</textarea>
{!! $errors->first("{$lang}.body", '<span class="help-block">:message</span>') !!}
</div>
<?php if (config('asgard.page.config.partials.translatable.edit') !== []): ?>
<?php foreach (config('asgard.page.config.partials.translatable.edit') as $partial): ?>
@include($partial)
<?php endforeach; ?>
<?php endif; ?>
</div>
<div class="box-group" id="accordion">
<!-- we are adding the .panel class so bootstrap.js collapse plugin detects it -->
<div class="panel box box-primary">
<div class="box-header">
<h4 class="box-title">
<a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo-{{$lang}}">
{{ trans('page::pages.form.meta_data') }}
</a>
</h4>
</div>
<div style="height: 0px;" id="collapseTwo-{{$lang}}" class="panel-collapse collapse">
<div class="box-body">
<div class='form-group{{ $errors->has("{$lang}[meta_title]") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[meta_title]", trans('page::pages.form.meta_title')) !!}
<?php $old = $page->hasTranslation($lang) ? $page->translate($lang)->meta_title : '' ?>
{!! Form::text("{$lang}[meta_title]", old("{$lang}.meta_title", $old), ['class' => "form-control", 'placeholder' => trans('page::pages.form.meta_title')]) !!}
{!! $errors->first("{$lang}[meta_title]", '<span class="help-block">:message</span>') !!}
</div>
<div class='form-group{{ $errors->has("{$lang}[meta_description]") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[meta_description]", trans('page::pages.form.meta_description')) !!}
<?php $old = $page->hasTranslation($lang) ? $page->translate($lang)->meta_description : '' ?>
<textarea class="form-control" name="{{$lang}}[meta_description]" rows="10" cols="80">{{ old("$lang.meta_description", $old) }}</textarea>
{!! $errors->first("{$lang}[meta_description]", '<span class="help-block">:message</span>') !!}
</div>
</div>
</div>
</div>
<div class="panel box box-primary">
<div class="box-header">
<h4 class="box-title">
<a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseFacebook-{{$lang}}">
{{ trans('page::pages.form.facebook_data') }}
</a>
</h4>
</div>
<div style="height: 0px;" id="collapseFacebook-{{$lang}}" class="panel-collapse collapse">
<div class="box-body">
<div class='form-group{{ $errors->has("{$lang}[og_title]") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[og_title]", trans('page::pages.form.og_title')) !!}
<?php $old = $page->hasTranslation($lang) ? $page->translate($lang)->og_title : '' ?>
{!! Form::text("{$lang}[og_title]", old("{$lang}.og_title", $old), ['class' => "form-control", 'placeholder' => trans('page::pages.form.og_title')]) !!}
{!! $errors->first("{$lang}[og_title]", '<span class="help-block">:message</span>') !!}
</div>
<div class='form-group{{ $errors->has("{$lang}[og_description]") ? ' has-error' : '' }}'>
{!! Form::label("{$lang}[og_description]", trans('page::pages.form.og_description')) !!}
<?php $old = $page->hasTranslation($lang) ? $page->translate($lang)->og_description : '' ?>
<textarea class="form-control" name="{{$lang}}[og_description]" rows="10" cols="80">{{ old("$lang.og_description", $old) }}</textarea>
{!! $errors->first("{$lang}[og_description]", '<span class="help-block">:message</span>') !!}
</div>
<div class="form-group{{ $errors->has("{$lang}[og_type]") ? ' has-error' : '' }}">
<label>{{ trans('page::pages.form.og_type') }}</label>
<?php $oldType = $page->hasTranslation($lang) ? $page->translate($lang)->og_type : '' ?>
<?php $oldType = null !== old("$lang.og_type") ? old("$lang.og_type") : $oldType; ?>
<select class="form-control" name="{{ $lang }}[og_type]">
<option value="website" {{ $oldType == 'website' ? 'selected' : ''}}>
{{ trans('page::pages.facebook-types.website') }}
</option>
<option value="product" {{ $oldType == 'product' ? 'selected' : ''}}>
{{ trans('page::pages.facebook-types.product') }}
</option>
<option value="article" {{ $oldType == 'article' ? 'selected' : ''}}>
{{ trans('page::pages.facebook-types.article') }}
</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
<?php
namespace Modules\Page\Services;
use Symfony\Component\Finder\Finder;
class FinderService
{
protected $filesystem;
public function __construct()
{
$this->filesystem = Finder::create()->files();
}
/**
* @param array $excludes
*
* @return $this
*/
public function excluding($excludes)
{
$this->filesystem = $this->filesystem->exclude($excludes);
return $this;
}
/**
* Get all of the files from the given directory (recursive).
*
* @param string $directory
* @param bool $hidden
*
* @return array
*/
public function allFiles($directory, $hidden = false)
{
return iterator_to_array($this->filesystem->ignoreDotFiles(! $hidden)->in($directory), false);
}
}
<?php
namespace Modules\Page\Sidebar;
use Maatwebsite\Sidebar\Badge;
use Maatwebsite\Sidebar\Group;
use Maatwebsite\Sidebar\Item;
use Maatwebsite\Sidebar\Menu;
use Modules\Page\Repositories\PageRepository;
use Modules\User\Contracts\Authentication;
class SidebarExtender implements \Maatwebsite\Sidebar\SidebarExtender
{
/**
* @var Authentication
*/
protected $auth;
/**
* @param Authentication $auth
*
* @internal param Guard $guard
*/
public function __construct(Authentication $auth)
{
$this->auth = $auth;
}
/**
* @param Menu $menu
*
* @return Menu
*/
public function extendWith(Menu $menu)
{
$menu->group(trans('core::sidebar.content'), function (Group $group) {
$group->item(trans('page::pages.title.pages'), function (Item $item) {
$item->icon('fa fa-file');
$item->weight(1);
$item->route('admin.page.page.index');
$item->badge(function (Badge $badge, PageRepository $page) {
$badge->setClass('bg-green');
$badge->setValue($page->countAll());
});
$item->authorize(
$this->auth->hasAccess('page.pages.index')
);
});
$group->authorize(
$this->auth->hasAccess('page.*')
);
});
return $menu;
}
}
<?php
namespace Modules\Page\Tests;
use Illuminate\Contracts\Console\Kernel;
use Illuminate\Database\Eloquent\Model;
use Maatwebsite\Sidebar\SidebarServiceProvider;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
use Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider;
use Modules\Core\Providers\CoreServiceProvider;
use Modules\Page\Providers\PageServiceProvider;
use Modules\Page\Repositories\PageRepository;
use Modules\Tag\Providers\TagServiceProvider;
use Nwidart\Modules\LaravelModulesServiceProvider;
use Orchestra\Testbench\TestCase;
abstract class BasePageTest extends TestCase
{
/**
* @var PageRepository
*/
protected $page;
public function setUp()
{
parent::setUp();
$this->resetDatabase();
$this->page = app(PageRepository::class);
}
protected function getPackageProviders($app)
{
return [
LaravelModulesServiceProvider::class,
CoreServiceProvider::class,
TagServiceProvider::class,
PageServiceProvider::class,
LaravelLocalizationServiceProvider::class,
SidebarServiceProvider::class,
];
}
protected function getPackageAliases($app)
{
return [
'Eloquent' => Model::class,
'LaravelLocalization' => LaravelLocalization::class,
];
}
protected function getEnvironmentSetUp($app)
{
$app['path.base'] = __DIR__ . '/..';
$app['config']->set('database.default', 'sqlite');
$app['config']->set('database.connections.sqlite', array(
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
));
$app['config']->set('translatable.locales', ['en', 'fr']);
}
private function resetDatabase()
{
// Relative to the testbench app folder: vendors/orchestra/testbench/src/fixture
$migrationsPath = 'Database/Migrations';
$artisan = $this->app->make(Kernel::class);
// Makes sure the migrations table is created
$artisan->call('migrate', [
'--database' => 'sqlite',
]);
// We empty all tables
$artisan->call('migrate:reset', [
'--database' => 'sqlite',
]);
// Migrate
$artisan->call('migrate', [
'--database' => 'sqlite',
]);
$artisan->call('migrate', [
'--database' => 'sqlite',
'--path' => 'Modules/Tag/Database/Migrations',
]);
}
}
<?php
namespace Modules\Page\Tests;
class PagesTest extends BasePageTest
{
/** @test */
public function it_makes_page_as_homepage()
{
$page = $this->page->create([
'is_home' => 1,
'template' => 'default',
'en' => [
'title' => 'My Page',
'slug' => 'my-page',
'body' => 'My Page Body',
],
]);
$homepage = $this->page->findHomepage();
$this->assertTrue($page->is_home);
$this->assertEquals($page->id, $homepage->id);
}
/** @test */
public function it_can_unset_homepage()
{
$page = $this->page->create([
'is_home' => 1,
'template' => 'default',
'en' => [
'title' => 'My Page',
'slug' => 'my-page',
'body' => 'My Page Body',
],
]);
$page = $this->page->update($page, [
'is_home' => 0,
]);
$this->assertFalse($page->is_home);
}
/** @test */
public function it_unsets_first_homepage_if_another_is_set_as_homepage()
{
$this->page->create([
'is_home' => '1',
'template' => 'default',
'en' => [
'title' => 'My Page',
'slug' => 'my-page',
'body' => 'My Page Body',
],
]);
$pageOther = $this->page->create([
'is_home' => '1',
'template' => 'default',
'en' => [
'title' => 'My Other Page',
'slug' => 'my-other-page',
'body' => 'My Page Body',
],
]);
$page = $this->page->find(1);
$this->assertFalse($page->is_home);
$this->assertTrue($pageOther->is_home);
}
}
url: https://github.com/AsgardCms/Page
versions:
"2.0@unreleased":
added:
- Laravel 5.2 compatibility
- Tags, pages can now own tags.
changed:
- Using new more flexible way of handle permissions via middleware
removed:
- Removing laracasts/flash dependency
"1.15.1":
changed:
- Fixing issue where saving the homepage would remove the is_home status on it
"1.15.0":
added:
- Ability to add middleware on the front end routes
changed:
- Use <code>$router</code> variable in routes file
"1.14.0":
changed:
- Fix ability to uncheck is_home checkbox
- Is home checkbox unique rule has been removed, instead other homepage will now be unchecked
"1.13.1":
changed:
- Load ckeditor using the assetPipeline
"1.13.0":
changed:
- Resolved path problem for different locales
"1.12.1":
added:
- Adding dynamic relations on the Page entity
"1.12.0":
added:
- Adding ability to add additional fields to the pages module
- Individual config publishing for the page module
"1.11.0":
changed:
- Removed language files, they are now in the translation module
"1.10.0":
changed:
- Using the delete modal partial
- Using font awesome icons on index
"1.9.0":
changed:
- Using the new data attribute to disable sorting from datatables
- Removing the duplicate confirm delete modal
- Requiring iCheck from the asset pipeline
- Missing slug class was added on the slug input for automatic slug generation
"1.8.1":
changed:
- Fixed issue with updating pages and triggering event
"1.8.0":
changed:
- Added data attributes for automatic slug creation
"1.7.0":
changed:
- Fix template selector if its name is not defined in the file.
"1.6.0":
added:
- Added naming templates feature
- Added Polish translations
- Added Russian translations
"1.5.0":
added:
- Dutch and Portuguese language
added:
- Making the template selection a dropdown instead of an input
"1.4.0":
added:
- Spanish translations
"1.3.0":
added:
- Added Brazilian Portuguese translations
"1.2.1":
changed:
- Rename the route parameter
- Use the manual model binding
"1.2.0":
changed:
- Use the helper functions in controller
- Typehint the page entity in admin controller
- Use manual route definition over the route resource shortcut
"1.1.1":
removed:
- Removed unused loaded files
"1.1.0":
changed:
- Adding table engine into migrations
"1.0.4":
changed:
- Fixing datatable
"1.0.3":
added:
- Changing index view columns order
"1.0.2":
added:
- Using new sidebar extender class
removed:
- Old SidebarViewComposer
"1.0.1":
changed:
- Fixes AsgardCms/Platform#46 - Old input is kept in all fields
- Using the <code>old()</code> method helper
{
"name": "asgardcms/page-module",
"type": "asgard-module",
"description": "Page module for AsgardCMS. Page management.",
"keywords": [
"asgardcms",
"pages"
],
"license": "MIT",
"authors": [
{
"name": "Nicolas Widart",
"email": "info@asgardcms.com",
"role": "Developer"
}
],
"support": {
"email": "support@asgardcms.com",
"issues": "https://github.com/AsgardCms/Page/issues",
"source": "https://github.com/AsgardCms/Page"
},
"require": {
"php": ">=5.6",
"composer/installers": "~1.0",
"asgardcms/core-module": "~2.0",
"asgardcms/tag-module": "^1.0@dev"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"orchestra/testbench": "3.3.*",
"phpro/grumphp": "^0.9.1",
"friendsofphp/php-cs-fixer": "^1.11"
},
"autoload-dev": {
"psr-4": {
"Modules\\Page\\": ".",
"Modules\\": "Modules/"
}
},
"extra": {
"branch-alias": {
"dev-2.0": "2.0.x-dev"
}
},
"minimum-stability": "dev",
"prefer-stable": true
}
<?php
view()->composer(['page::admin.create', 'page::admin.edit'], 'Modules\Page\Composers\TemplateViewComposer');
parameters:
git_dir: .
bin_dir: vendor/bin
stop_on_failure: true
tasks:
phpcsfixer:
config_file: .php_cs
composer:
file: ./composer.json
jsonlint:
ignore_patterns: []
{
"name": "Page",
"alias": "page",
"description": "Managing pages.",
"keywords": [],
"version": "2.0.0",
"active": 1,
"order": 9999,
"providers": [
"Modules\\Page\\Providers\\RouteServiceProvider",
"Modules\\Page\\Providers\\PageServiceProvider"
],
"files": [
"composers.php"
]
}
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
>
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix=".php">./Tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">.</directory>
<exclude>
<directory suffix=".php">vendor/</directory>
<directory suffix=".php">Modules/</directory>
<directory suffix=".php">Repositories/Cache/</directory>
<directory suffix=".php">Resources/</directory>
<directory suffix=".php">Http/</directory>
<directory suffix=".php">Config/</directory>
<directory suffix=".php">Sidebar/</directory>
<directory suffix=".php">Providers/</directory>
<directory suffix=".php">Composers/</directory>
<directory suffix=".php">Database/Seeders/</directory>
<directory suffix=".php">Tests/</directory>
<directory suffix=".php">composers.php</directory>
</exclude>
</whitelist>
</filter>
<logging>
<log type="tap" target="build/report.tap"/>
<log type="junit" target="build/report.junit.xml"/>
<log type="coverage-html" target="build/coverage" charset="UTF-8" yui="true" highlight="true"/>
<log type="coverage-text" target="build/coverage.txt"/>
<log type="coverage-clover" target="build/logs/clover.xml"/>
</logging>
</phpunit>
# Page module
[![Latest Version](https://img.shields.io/github/release/asgardcms/page.svg?style=flat-square)](https://github.com/asgardcms/page/releases)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
[![Quality Score](https://img.shields.io/scrutinizer/g/asgardcms/page.svg?style=flat-square)](https://scrutinizer-ci.com/g/asgardcms/page)
[![SensioLabs Insight](https://img.shields.io/sensiolabs/i/9771f5e6-88d3-4e8a-b35f-ad5574b405f7.svg)](https://insight.sensiolabs.com/projects/9771f5e6-88d3-4e8a-b35f-ad5574b405f7)
[![CodeClimate](https://img.shields.io/codeclimate/github/AsgardCms/Page.svg)](https://codeclimate.com/github/AsgardCms/Page)
[![Total Downloads](https://img.shields.io/packagist/dd/asgardcms/page-module.svg?style=flat-square)](https://packagist.org/packages/asgardcms/page-module)
[![Total Downloads](https://img.shields.io/packagist/dm/asgardcms/page-module.svg?style=flat-square)](https://packagist.org/packages/asgardcms/page-module)
[![Total Downloads](https://img.shields.io/packagist/dt/asgardcms/page-module.svg?style=flat-square)](https://packagist.org/packages/asgardcms/page-module)
[![Slack](http://slack.asgardcms.com/badge.svg)](http://slack.asgardcms.com/)
| Branch | Travis-ci | Coverage |
| ---------------- | --------------- | --------- |
| master | [![Build Status](https://travis-ci.org/AsgardCms/Page.svg?branch=master)](https://travis-ci.org/AsgardCms/Page) | [![Scrutinizer Coverage](https://img.shields.io/scrutinizer/coverage/g/AsgardCms/Page.svg?maxAge=86400&style=flat-square)](https://scrutinizer-ci.com/g/AsgardCms/Page/?branch=master) |
| 2.0 | [![Build Status](https://travis-ci.org/AsgardCms/Page.svg?branch=2.0)](https://travis-ci.org/AsgardCms/Page) | [![Scrutinizer Coverage](https://img.shields.io/scrutinizer/coverage/g/AsgardCms/Page.svg?maxAge=86400&style=flat-square)](https://scrutinizer-ci.com/g/AsgardCms/Page/?branch=2.0) |
## Installation
The page module is installed by default on an AsgardCms installation. If you want to install it on standalone you can follow the steps.
### Composer requirement
``` json
composer require asgardcms/page-module
```
### Package migrations
Run the migrations:
``` bash
php artisan module:migrate Page
```
## Resources
- [Contribute to AsgardCMS](https://asgardcms.com/en/docs/getting-started/contributing)
- [License](LICENSE.md)
## Info
All AsgardCMS modules respect [Semantic Versioning](http://semver.org/).
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