adding new major release

develop v1.0.0-rc
HerrHase 3 years ago
parent 268d6a01b4
commit dcab33c2e1

@ -0,0 +1,4 @@
APP_DEBUG=false
DIRECTUS_API_URL=
DIRECTUS_API_TOKEN=

126
.gitignore vendored

@ -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

@ -1,97 +1,35 @@
# Super Gear Directus
Small Libary to request Directus API. Works with [http://flightphp.com/](Flight).
Project to using a Directus Instance as CMS. Structure is inspired by Laravel, using [FlightPHP](https://github.com/mikecao/flight)
for handle Request.
## Install
## Installation
```bash
composer require tentakelfabrik/super-gear-directus
```
## Requirements
For handle token and url for the Directus Server you have to use
[https://github.com/vlucas/phpdotenv](vlucas/phpdotenv),
```php
env('DIRECTUS_API_URL'),
env('DIRECTUS_API_TOKEN')
```
## Controller
Download last Release, a Composer Installer will be Available in a Future Release.
Example how to use SuperGear\\Directus\\Controllers\\DirectusControllerAbstract,
## Snapshot
```php
class PageController extends DirectusControllerAbstract
{
/** slug for home */
const HOME_SLUG = 'home';
There is a Snapshot for a Basic Setup for the Directus Instance.
/** set default view */
protected $defaultView = 'page/default';
## Quickstart
/**
* get home page from slug
*
*
*/
public function indexAction()
{
$repository = Manager::get('Page');
$page = $repository->findOneBySlug(self::HOME_SLUG);
Create a **.env** from **.env.example** adding token and url for Directus Instance.
if ($this->notFound($page)) {
$this->app->redirect('404');
}
$this->render($page);
}
/**
* get single page from slug
*
*
* @param string $slug
*/
public function getAction($slug)
{
$repository = Manager::get('Page');
$page = $repository->findOneBySlug($slug);
if ($this->notFound($page)) {
$this->app->redirect('404');
}
$this->render($page);
}
/**
* if page not found
*
*/
public function notFoundAction()
{
$page = [
'data' => [
'view' => 'page/404'
]
];
$this->render($page);
}
}
```
DIRECTUS_API_URL=
DIRECTUS_API_TOKEN=
```
## Repositories
Example to use the SuperGear\\Directus\\Respositories\\RepositoryAbstract,
For getting Data use **App\\Respositories\\RepositoryAbstract** to create Repository-Classes.
This is the default class to handle
```PHP
class PageRepository extends RepositoryAbstract
{
/** name of the collection */
protected $name = 'page';
/** endpoint */
protected $endpoint = 'pages';
/**
* find single page with a slug,
@ -102,25 +40,19 @@ class PageRepository extends RepositoryAbstract
*/
public function findOneBySlug($slug)
{
return $this->itemCollection->findOne($this->name, [
'filter[slug][eq]' => $slug,
'filter[status][eq]' => 'published'
]);
}
if (!$slug) {
$slug = [ '_null' => 'true' ];
}
/**
* find single page with a slug,
* page must be published
*
* @param string $slug
* @return array
*/
public function findByView($view)
{
return $this->itemCollection->find($this->name, [
'filter[view][eq]' => $view,
'filter[status][eq]' => 'published'
]);
return $this->queryBuilder
->fields(['title', 'slug', 'content', 'view', 'meta', 'media_teaser.*', 'media_hero.*'])
->aliases('view', 'template')
->filter([
'status' => 'published',
'slug' => $slug
])
->findOne();
}
}
```

@ -1,21 +1,22 @@
<?php
namespace SuperGear\Directus\Controllers;
namespace App\Controllers;
use SuperGear\Directus\FlightAbstract;
use App\Flight\FlightAbstract;
use Exception;
/**
* abstract controller to handle views and response from directus
* abstract controller to handle views and response from directus
*
*
* @author Björn Hase
* @license http://opensource.org/licenses/MIT The MIT License
* @link https://gitlab.tentakelfabrik.de/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
*
*/
abstract class DirectusControllerAbstract extends FlightAbstract
{
/** default template for view */
protected $defaultView = NULL;
/**
@ -36,7 +37,13 @@ abstract class DirectusControllerAbstract extends FlightAbstract
*/
protected function viewExists($view)
{
return file_exists($this->app->get('flight.views.path').'/'.$view.'.blade.php');
$result = false;
if (file_exists($this->app->get('flight.views.path').'/'.$view.'.blade.php')) {
$result = true;
}
return $result;
}
/**
@ -45,23 +52,24 @@ abstract class DirectusControllerAbstract extends FlightAbstract
* @param array $data [description]
* @return [type] [description]
*/
protected function render($item, $data = [])
protected function render($page, $data = [])
{
$view = $this->defaultView;
// if view isset in page and file exists
if (isset($item['data']['view'])) {
if ($this->viewExists($item['data']['view'])) {
$view = $item['data']['view'];
if (isset($page['data']['view'])) {
if ($this->viewExists($page['data']['view'])) {
$view = $page['data']['view'];
} else {
throw new Exception('View '.$item['data']['view'].' not exists');
throw new Exception('View '.$page['data']['view'].' not exists');
}
} else if (!$this->viewExists($view)) {
throw new Exception('View '.$view.' not exists');
}
$this->app->render($view, array_merge([
'page' => $item
'page' => $page,
'flight' => $this->app
],
$data
));

@ -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'])
]
]);

@ -1,7 +1,7 @@
{
"name": "tentakelfabrik/super-gear-directus",
"version": "0.3.0",
"type": "library",
"version": "1.0.0-rc",
"type": "project",
"license": "MIT",
"authors": [
{
@ -12,15 +12,16 @@
],
"minimum-stability": "stable",
"require": {
"php": "^7.0",
"mikecao/flight": "^1.2",
"mikecao/flight": "1.3.*",
"erusev/parsedown": "1.7.*",
"vlucas/phpdotenv": "3.3.*",
"jenssegers/blade": "v1.2.3"
"vlucas/phpdotenv": "5.3.*",
"jenssegers/blade": "1.4.*",
"tentakelfabrik/pirectus": "^0.1.2",
"cocur/slugify": "^4.0"
},
"autoload": {
"psr-4": {
"SuperGear\\Directus\\": "src/"
"App\\": "app/"
}
}
}

1680
composer.lock generated

File diff suppressed because it is too large Load Diff

@ -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>

After

Width:  |  Height:  |  Size: 209 B

File diff suppressed because it is too large Load Diff

@ -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')
);
}
}
Loading…
Cancel
Save