@ -0,0 +1,4 @@ | |||
APP_DEBUG=false | |||
DIRECTUS_API_URL= | |||
DIRECTUS_API_TOKEN= |
@ -1,7 +1,123 @@ | |||
composer.phar | |||
# ---> Node | |||
# Logs | |||
logs | |||
*.log | |||
npm-debug.log* | |||
yarn-debug.log* | |||
yarn-error.log* | |||
lerna-debug.log* | |||
# Diagnostic reports (https://nodejs.org/api/report.html) | |||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | |||
# Runtime data | |||
pids | |||
*.pid | |||
*.seed | |||
*.pid.lock | |||
# Directory for instrumented libs generated by jscoverage/JSCover | |||
lib-cov | |||
# Coverage directory used by tools like istanbul | |||
coverage | |||
*.lcov | |||
# nyc test coverage | |||
.nyc_output | |||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | |||
.grunt | |||
# Bower dependency directory (https://bower.io/) | |||
bower_components | |||
# node-waf configuration | |||
.lock-wscript | |||
# Compiled binary addons (https://nodejs.org/api/addons.html) | |||
build/Release | |||
# Dependency directories | |||
node_modules/ | |||
jspm_packages/ | |||
# Snowpack dependency directory (https://snowpack.dev/) | |||
web_modules/ | |||
# TypeScript cache | |||
*.tsbuildinfo | |||
# Optional npm cache directory | |||
.npm | |||
# Optional eslint cache | |||
.eslintcache | |||
# Microbundle cache | |||
.rpt2_cache/ | |||
.rts2_cache_cjs/ | |||
.rts2_cache_es/ | |||
.rts2_cache_umd/ | |||
# Optional REPL history | |||
.node_repl_history | |||
# Output of 'npm pack' | |||
*.tgz | |||
/vendor/ | |||
node_modules | |||
# Yarn Integrity file | |||
.yarn-integrity | |||
# dotenv environment variables file | |||
.env | |||
*.log | |||
rysnc_exclude | |||
.env.test | |||
# parcel-bundler cache (https://parceljs.org/) | |||
.cache | |||
.parcel-cache | |||
# Next.js build output | |||
.next | |||
out | |||
# Nuxt.js build / generate output | |||
.nuxt | |||
# Gatsby files | |||
.cache/ | |||
# Comment in the public line in if your project uses Gatsby and not Next.js | |||
# https://nextjs.org/blog/next-9-1#public-directory-support | |||
# public | |||
# vuepress build output | |||
.vuepress/dist | |||
# Serverless directories | |||
.serverless/ | |||
# FuseBox cache | |||
.fusebox/ | |||
# DynamoDB Local files | |||
.dynamodb/ | |||
# TernJS port file | |||
.tern-port | |||
# Stores VSCode versions used for testing VSCode extensions | |||
.vscode-test | |||
# yarn v2 | |||
.yarn/cache | |||
.yarn/unplugged | |||
.yarn/build-state.yml | |||
.yarn/install-state.gz | |||
.pnp.* | |||
vendor | |||
storage/cache | |||
!storage/cache/.gitkeep | |||
@ -0,0 +1,56 @@ | |||
<?php | |||
namespace App\Controllers; | |||
use App\Controllers\DirectusControllerAbstract; | |||
use App\Repositories\Manager; | |||
/** | |||
* controller for page items from directus | |||
* | |||
* | |||
* @author Björn Hase, Tentakelfabrik | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitea.tentakelfabrik.de/Tentakelfabrik/super-gear-directus | |||
* | |||
*/ | |||
class PageController extends DirectusControllerAbstract | |||
{ | |||
/** default view */ | |||
protected $defaultView = 'page/default'; | |||
/** 404 */ | |||
protected $page404 = [ | |||
'data' => [ | |||
'title' => '404', | |||
'view' => 'page/404' | |||
] | |||
]; | |||
/** | |||
* get single page from slug | |||
* | |||
* | |||
* @param string $slug | |||
*/ | |||
public function getAction($slug = NULL) | |||
{ | |||
$repository = Manager::get('Page'); | |||
$page = $repository->findOneBySlug($slug); | |||
if ($page['data'] === NULL) { | |||
$this->app>redirect('/404', 301); | |||
} else { | |||
$this->render($page); | |||
} | |||
} | |||
/** | |||
* if page not found | |||
* | |||
*/ | |||
public function notFoundAction() | |||
{ | |||
$this->render($this->page404); | |||
} | |||
} |
@ -0,0 +1,30 @@ | |||
<?php | |||
namespace App\Flight; | |||
use Flight; | |||
/** | |||
* abstract FlightAbstract to get instance of flight engine | |||
* | |||
* @author Björn Hase, Tentakelfabrik | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitea.tentakelfabrik.de/Tentakelfabrik/super-gear-directus | |||
* | |||
*/ | |||
abstract class FlightAbstract | |||
{ | |||
/** object of flight */ | |||
protected $app; | |||
/** | |||
* getting object of flight | |||
* | |||
* | |||
*/ | |||
public function __construct() | |||
{ | |||
$this->app = Flight::app(); | |||
} | |||
} |
@ -1,16 +1,18 @@ | |||
<?php | |||
namespace SuperGear\Directus\Helpers; | |||
namespace App\Helpers; | |||
use Parsedown; | |||
/** | |||
* Helper to extend Parsedown | |||
* Helper to extend Parsedown | |||
* | |||
* @author Björn Hase, Tentakelfabrik | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitea.tentakelfabrik.de/Tentakelfabrik/super-gear-directus | |||
* | |||
* @author Björn Hase | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitlab.tentakelfabrik.de/super-gear/directus GitHub Repository | |||
*/ | |||
class MarkdownHelper extends Parsedown | |||
{ | |||
/** |
@ -1,18 +1,20 @@ | |||
<?php | |||
namespace SuperGear\Directus\Repositories; | |||
namespace App\Repositories; | |||
use Exception; | |||
/** | |||
* Manager Class to create Repository Objects that | |||
* are located in App\Repositories\ | |||
* Manager Class to create Repository Objects that | |||
* are located in App\Repositories\ | |||
* | |||
* | |||
* @author Björn Hase | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitlab.tentakelfabrik.de/super-gear/super-gear-directus GitHub Repository | |||
* @author Björn Hase, Tentakelfabrik | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitea.tentakelfabrik.de/Tentakelfabrik/super-gear-directus | |||
* | |||
*/ | |||
class Manager | |||
{ | |||
/** |
@ -0,0 +1,48 @@ | |||
<?php | |||
namespace App\Repositories; | |||
use App\Repositories\RepositoryAbstract; | |||
/** | |||
* request pages items from directus | |||
* | |||
* @author Björn Hase, Tentakelfabrik | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitea.tentakelfabrik.de/Tentakelfabrik/super-gear-directus | |||
* | |||
*/ | |||
class PageRepository extends RepositoryAbstract | |||
{ | |||
/** endpoint */ | |||
protected $endpoint = 'pages'; | |||
/** | |||
* find single page with a slug, | |||
* page must be published | |||
* | |||
* @param string $slug | |||
* @return array | |||
*/ | |||
public function findOneBySlug($slug) | |||
{ | |||
// if slug not set, search for empty slug | |||
if (!$slug) { | |||
$slug = [ '_null' => 'true' ]; | |||
} | |||
return $this->queryBuilder | |||
->fields([ | |||
'title', 'slug', 'content', 'view', 'meta', | |||
'media_teaser.*', | |||
'media_hero.*' | |||
]) | |||
->aliases('view', 'template') | |||
->filter([ | |||
'status' => 'published', | |||
'slug' => $slug | |||
]) | |||
->findOne(); | |||
} | |||
} |
@ -0,0 +1,36 @@ | |||
<?php | |||
namespace App\Repositories; | |||
/** | |||
* | |||
* | |||
* @author Björn Hase, Tentakelfabrik | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitea.tentakelfabrik.de/Tentakelfabrik/super-gear-directus | |||
* | |||
*/ | |||
abstract class RepositoryAbstract | |||
{ | |||
/** endpoint for request */ | |||
protected $endpoint; | |||
/** queryBuilder from pirectus */ | |||
protected $queryBuilder; | |||
/** | |||
* | |||
* | |||
*/ | |||
public function __construct() | |||
{ | |||
$pirectus = \Flight::pirectus(); | |||
if ($pirectus) { | |||
$this->queryBuilder = $pirectus->items($this->endpoint); | |||
} else { | |||
throw new \Exception('Error! Pirectus not initialized!'); | |||
} | |||
} | |||
} |
@ -0,0 +1,37 @@ | |||
<?php | |||
// adding functions | |||
require_once(__DIR__.'/Functions/Blade.php'); | |||
// adding env | |||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__.'/../'); | |||
$dotenv->load(); | |||
// display all errors if debug is true | |||
if ($_ENV['APP_DEBUG'] === true) { | |||
error_reporting(E_ALL); | |||
ini_set('display_errors', 1); | |||
} | |||
// create app | |||
$flight = Flight::app(); | |||
// setting view path | |||
$flight->set('flight.views.path', __DIR__.'/../resources/views'); | |||
// adding blade for templates | |||
$flight->register('view', 'Jenssegers\Blade\Blade', [ $flight->get('flight.views.path'), __DIR__.'/../storage/cache']); | |||
$flight->map('render', function($view, $data) { | |||
echo Flight::view()->make($view, $data); | |||
}); | |||
// setting path | |||
$flight->set('basePath', __DIR__.'/../'); | |||
$flight->set('publicPath', __DIR__.'/../public'); | |||
$flight->set('storagePath', __DIR__.'/../storage'); | |||
// adding pirectus | |||
$flight->register('pirectus', 'Pirectus\Pirectus', [ $_ENV['DIRECTUS_API_URL'], [ | |||
'auth' => new \Pirectus\Auth\TokenAuth($_ENV['DIRECTUS_API_TOKEN']) | |||
] | |||
]); |
@ -0,0 +1,10 @@ | |||
<?php | |||
require __DIR__.'/../vendor/autoload.php'; | |||
require __DIR__.'/../app/bootstrap.php'; | |||
// default routes | |||
$flight->route('GET /404', array(new App\Controllers\PageController, 'notFoundAction')); | |||
$flight->route('GET /(@slug:[a-zA-Z0-9_-])', array(new App\Controllers\PageController, 'getAction')); | |||
$flight->start(); |
@ -0,0 +1,38 @@ | |||
@inject('pageRepository', 'App\Repositories\PageRepository') | |||
@inject('markdownHelper', 'App\Helpers\MarkdownHelper') | |||
@inject('slugify', 'Cocur\Slugify\Slugify') | |||
<!DOCTYPE html> | |||
<html lang="de-DE" class="no-js"> | |||
<head> | |||
<meta charset="utf-8"> | |||
<meta http-equiv="x-ua-compatible" content="ie=edge"> | |||
<title> | |||
Elina Penner | {{ $page['data']['title'] }} | |||
</title> | |||
<meta name="viewport" content="width=device-width, initial-scale=1"> | |||
<link href="{{ (isset($_SERVER['HTTPS']) ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'] }}" rel="canonical"> | |||
<link href="{{ asset('/css/index.css') }}" rel="stylesheet" type="text/css"> | |||
@stack('head') | |||
</head> | |||
<body class="{{ $slugify->slugify($page['data']['view']) }}"> | |||
<header class="site-header"> | |||
<h1 class="site-header__title"> | |||
Super Gear Directus | |||
</h1> | |||
</header> | |||
<main class="site-main"> | |||
@yield('content') | |||
</main> | |||
<footer class="site-footer"> | |||
</footer> | |||
@stack('scripts') | |||
</body> | |||
</html> |
@ -0,0 +1,8 @@ | |||
@extends('layout') | |||
@section('header') | |||
@endsection | |||
@section('content') | |||
Wrong? Go <a href="/">back</a>! | |||
@endsection |
@ -0,0 +1,12 @@ | |||
@extends('layout') | |||
@inject('markdownHelper', 'App\Helpers\MarkdownHelper') | |||
@section('content') | |||
<h1> | |||
{{ $page['data']['title'] }} | |||
</h1> | |||
<div class="content"> | |||
{!! $markdownHelper->parse($page['data']['content']) !!} | |||
</div> | |||
@endsection |
@ -0,0 +1,3 @@ | |||
<svg class="icon @if (isset($classes)) {{ implode(' ', $classes) }} @endif" aria-hidden="true" @if (isset($alt)) alt="{{ $alt }}" @endif > | |||
<use xlink:href="/symbol-defs.svg#icon-{{ $icon }}"></use> | |||
</svg> |
@ -1,114 +0,0 @@ | |||
<?php | |||
namespace SuperGear\Directus\Collections; | |||
/** | |||
* send request with curl to directus instance | |||
* | |||
* | |||
* @author Björn Hase | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitlab.tentakelfabrik.de/super-gear/directus GitHub Repository | |||
* | |||
*/ | |||
class AbstractCollection | |||
{ | |||
/** url */ | |||
private $url = NULL; | |||
/** token */ | |||
private $token = NULL; | |||
/** curl */ | |||
private $curl = NULL; | |||
/** endpoint */ | |||
protected $endpoint = NULL; | |||
/** | |||
* | |||
* @param string $url | |||
* @param string $token | |||
*/ | |||
public function __construct($url, $token) | |||
{ | |||
$this->url = $url; | |||
$this->token = $token; | |||
} | |||
/** | |||
* | |||
* | |||
* @param string $name | |||
* @param array $parameters | |||
* @return mixed | |||
*/ | |||
public function findOne($name, $parameters = []) | |||
{ | |||
// adding single to parameters | |||
$parameters['single'] = true; | |||
$response = $this->request($name, $this->endpoint, $parameters); | |||
return $response; | |||
} | |||
/** | |||
* | |||
* | |||
* @param string $name | |||
* @param array $parameters | |||
* @return mixed | |||
* | |||
*/ | |||
public function find($name, $parameters = []) | |||
{ | |||
return $this->request($name, $this->endpoint, $parameters); | |||
} | |||
/** | |||
* request $endpoint | |||
* | |||
* @param string $name | |||
* @param string $endpoint | |||
* @param array $parameters | |||
* @return mixed | |||
* | |||
*/ | |||
protected function request($name, $endpoint, $parameters = []) | |||
{ | |||
// init curl and setup token | |||
$curl = curl_init(); | |||
curl_setopt($curl, CURLOPT_HTTPHEADER, [ | |||
'Accept: application/json', | |||
'Content-Type: application/json', | |||
'Authorization: Bearer '.$this->token | |||
]); | |||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); | |||
$response = []; | |||
if (count($parameters) > 0) { | |||
$query = http_build_query($parameters); | |||
} | |||
$url = $this->url.$endpoint.'/'.$name; | |||
// query parameters are set, add them to url | |||
if (isset($query)) { | |||
$url = $url.'?'.$query; | |||
} | |||
curl_setopt($curl, CURLOPT_URL, $url); | |||
$response = curl_exec($curl); | |||
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE); | |||
$info = curl_getinfo($curl); | |||
curl_close($curl); | |||
$response = json_decode($response, true); | |||
return $response; | |||
} | |||
} |
@ -1,28 +0,0 @@ | |||
<?php | |||
namespace SuperGear\Directus\Collections; | |||
/** | |||
* endpoint "items" for directus | |||
* | |||
* | |||
* @author Björn Hase | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitlab.tentakelfabrik.de/super-gear/directus GitHub Repository | |||
* | |||
*/ | |||
class ItemCollection extends AbstractCollection | |||
{ | |||
/** | |||
* | |||
* @param string $url | |||
* @param string $token | |||
*/ | |||
public function __construct($url, $token) | |||
{ | |||
// adding endpoint for items | |||
$this->endpoint = '/items'; | |||
parent::__construct($url, $token); | |||
} | |||
} |
@ -1,27 +0,0 @@ | |||
<?php | |||
namespace SuperGear\Directus; | |||
use Flight; | |||
/** | |||
* abstract FlightAbstract get instance of flight engine | |||
* | |||
* @author Björn Hase | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitlab.tentakelfabrik.de/super-gear/super-gear-directus GitHub Repository | |||
*/ | |||
abstract class FlightAbstract | |||
{ | |||
/** object of flight */ | |||
protected $app; | |||
/** | |||
* getting object of flight | |||
* | |||
*/ | |||
public function __construct() | |||
{ | |||
$this->app = Flight::app(); | |||
} | |||
} |
@ -1,179 +0,0 @@ | |||
<?php | |||
namespace SuperGear\Directus\Repositories; | |||
/** | |||
* class for paginate request | |||
* | |||
* @author Björn Hase | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitlab.tentakelfabrik.de/super-gear/directus GitHub Repository | |||
* | |||
*/ | |||
abstract class PaginationRepositoryAbstract extends RepositoryAbstract | |||
{ | |||
/** current page */ | |||
protected $page; | |||
/** limit for request */ | |||
protected $limit; | |||
/** max pages */ | |||
protected $maxPages; | |||
/** pages that are visible */ | |||
protected $showPages = 7; | |||
/** | |||
* setting max pages | |||
* | |||
* @param integer | |||
* @param array | |||
* | |||
*/ | |||
protected function setMaxPages($limit, $results) | |||
{ | |||
$this->maxPages = intval(round($results['meta']['filter_count'] / $limit)); | |||
} | |||
/** | |||
* getting offset for request | |||
* | |||
* @param integer | |||
* @return integer | |||
* | |||
*/ | |||
protected function getOffset($page, $limit) | |||
{ | |||
return (($page - 1) * $limit); | |||
} | |||
/** | |||
* get pages that are showing | |||
* | |||
* @param integer | |||
* @return array | |||
* | |||
*/ | |||
protected function getPages($page) | |||
{ | |||
// results | |||
$pages = []; | |||
// count of pages that can be shown | |||
$showPages = $this->showPages; | |||
// get avarage value to show pages | |||
$averagePages = $this->showPages / 2; | |||
// run throw all pages | |||
for ($i = 1; $i <= $this->maxPages; $i++) { | |||
// check if $page has to show | |||
$show = false; | |||
// show always first and last page | |||
if ($i === 1 || $i === $this->maxPages) { | |||
$show = true; | |||
} | |||
// if showing pages are aviable check if page can be shown | |||
if ($show === false && $showPages > 0) { | |||
// if page from 1 to avarage | |||
if (($i <= $averagePages && $page <= $averagePages) || | |||
// if page is less than maxPages | |||
(($i >= ($maxPages - $averagePages)) && $page >= ($maxPages - $averagePages)) || | |||
// put current pages as avarage value | |||
($i >= ($page - $averagePages) && $i <= ($page + $averagePages))) { | |||
$showPages--; | |||
$show = true; | |||
} | |||
} | |||
if ($show) { | |||
$pages[] = $i; | |||
} | |||
} | |||
return $pages; | |||
} | |||
/** | |||
* if previous is possible | |||
* | |||
* @param integer $page | |||
* | |||
*/ | |||
protected function getPrevious($page) | |||
{ | |||
$result = NULL; | |||
if ($page > 1) { | |||
$result = $page - 1; | |||
} | |||
return $result; | |||
} | |||
/** | |||
* if next is possible | |||
* | |||
* @param integer $page | |||
* | |||
*/ | |||
protected function getNext($page) | |||
{ | |||
$result = NULL; | |||
if ($page < $this->maxPages) { | |||
$result = $page + 1; | |||
} | |||
return $result; | |||
} | |||
/** | |||
* prepare query to get limited items | |||
* | |||
* @param integer $page | |||
* @param integer $limit | |||
* @param array $query | |||
* | |||
*/ | |||
protected function prepare($page, $limit, $query) | |||
{ | |||
// setting page and limit | |||
$this->page = $page; | |||
$this->limit = $limit; | |||
return array_merge($query, [ | |||
'offset' => $this->getOffset($this->page, $this->limit), | |||
'limit' => $this->limit, | |||
'meta' => 'result_count,filter_count,total_count' | |||
]); | |||
} | |||
/** | |||
* paginate results | |||
* | |||
* @param integer $page | |||
* @param integer $limit | |||
* @param array $results | |||
* | |||
*/ | |||
protected function paginate($results) | |||
{ | |||
$this->setMaxPages($this->limit, $results); | |||
$results['meta']['current'] = $this->page; | |||
$results['meta']['previous'] = $this->getPrevious($this->page); | |||
$results['meta']['next'] = $this->getNext($this->page); | |||
$results['meta']['pages'] = $this->getPages($this->page); | |||
$results['meta']['max_pages'] = $this->maxPages; | |||
return $results; | |||
} | |||
} |
@ -1,38 +0,0 @@ | |||
<?php | |||
namespace SuperGear\Directus\Repositories; | |||
use SuperGear\Directus\Collections\ItemCollection; | |||
/** | |||
* Abstract Repository to wrap ItemCollection | |||
* | |||
* | |||
* @author Björn Hase | |||
* @license http://opensource.org/licenses/MIT The MIT License | |||
* @link https://gitlab.tentakelfabrik.de/super-gear/super-gear-directus GitHub Repository | |||
*/ | |||
abstract class RepositoryAbstract | |||
{ | |||
/** name of the collection */ | |||
protected $name; | |||
/** client for itemCollection */ | |||
protected $itemCollection; | |||
/** | |||
* | |||
* | |||
*/ | |||
public function __construct() | |||
{ | |||
if (!$this->name) { | |||
throw new \Exception('$name is not set!'); | |||
}; | |||
$this->itemCollection = new ItemCollection( | |||
env('DIRECTUS_API_URL'), | |||
env('DIRECTUS_API_TOKEN') | |||
); | |||
} | |||
} |