Heyho Community,
hier mal ein kleines Release von mir.
•-)•–––––––––––––––––––––––––––––––––––––––––––––––– ––––––––––––––––––––––––––––––––•(-•
Inhaltsverzeichnis:
1. Vorwort / Erklärung
2. Voraussetzungen
3. Übersicht
4. Codes
5. Schlusswort
•-)•–––––––––––––––––––––––––––––––––––––––––––––––– ––––––––––––––––––––––––––––––––•(-•
1. Vorwort / Erklärung:
Erstmal, was hab ich denn hier released: Es handelt sich um einen relativ schlicht gehaltenes Blog-Framework auf MVC (ModelViewController) Basis mit integriertem, kleinem CMS. Das ganze sieht von der View her nicht gerade schön aus – war aber auch nicht der Kern/das Ziel meines Projekts. Im Vordergrund stand die Funktionalität des Ganzen. Außerdem liegt Schönheit bekanntlich im Auge des Betrachters. Ihr könnt es ja mit z. B. Twitter Bootstrap verschönern.
•-)•–––––––––––––––––––––––––––––––––––––––––––––––– ––––––––––––––––––––––––––––––––•(-•
2. Voraussetzungen:
Voraussetzungen gibt es eigentlich nicht viele. Das Ganze ist auf PHP 7 Basis auf einem Apache 2.4 Localhost Server (XAMPP) mit PDO-Unterstützung aufgebaut worden. Ebenso sollte eine Datenbank aufgebaut werden mit dem Namen ‚blog‘ welche drei Tabellen beinhaltet: users, posts und comments.
DB-Name: blog
Tablename: users
- id [int(11), AUTO_INCREMENT, Primary]
- username [varchar(255)]
- password [varchar(225)]
Tablename: posts
- id [int(11), AUTO_INCREMENT, Primary]
- title [varchar(255)]
- content [text]
Tablename: comments
- id [int(11), AUTO_INCREMENT, Primary]
- content [text]
- post_id [int(11)]
•-)•–––––––––––––––––––––––––––––––––––––––––––––––– ––––––––––––––––––––––––––––––––•(-•
3. Übersicht:
HTML Code:
*-------------------------------------------*
| - autoload.php |
| - init.php |
| [ ] public |
| - index.php |
| [ ] src |
| [ ] Core |
| - AbstractController.php |
| - AbstractRepository.php |
| - AbstractModel.php |
| - Container.php |
| [ ] Post |
| - PostModel.php |
| - PostsRepository.php |
| - CommentModel.php |
| - CommentsRepository.php |
| - PostsController.php |
| - PostsAdminController.php |
| [ ] User |
| - LoginController.php |
| - LoginService.php |
| - UserModel.php |
| - UserRepository.php |
| [ ] views |
| [ ] post |
| [ ] admin |
| - edit.php |
| - index.php |
| - index.php |
| - show.php |
| [ ] user |
| - dashboard.php |
| - login.php |
*-------------------------------------------*
•-)•–––––––––––––––––––––––––––––––––––––––––––––––– ––––––––––––––––––––––––––––––––•(-•
4. Codes:
PHP Code:
<?php
spl_autoload_register(function ($class) {
// project-specific namespace prefix
$prefix = 'App\\';
// base directory for the namespace prefix
$base_dir = __DIR__ . '/src/';
// does the class use the namespace prefix?
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
// no, move to the next registered autoloader
return;
}
// get the relative class name
$relative_class = substr($class, $len);
// replace the namespace prefix with the base directory, replace namespace
// separators with directory separators in the relative class name, append
// with .php
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
// if the file exists, require it
if (file_exists($file)) {
require $file;
}
});
?>
PHP Code:
<?php
require __DIR__ . "/autoload.php";
function esc($str)
{
return htmlentities($str, ENT_QUOTES, 'UTF-8');
}
$container = new App\Core\Container();
?>
PHP Code:
<?php
session_start();
require __DIR__ . "/../init.php";
$pathInfo = $_SERVER['PATH_INFO'];
$routes = [
'/index' => [
'controller' => 'postsController',
'method' => 'index'
],
'/post' => [
'controller' => 'postsController',
'method' => 'show'
],
'/login' => [
'controller' => 'loginController',
'method' => 'login'
],
'/dashboard' => [
'controller' => 'loginController',
'method' => 'dashboard'
],
'/logout' => [
'controller' => 'loginController',
'method' => 'logout'
],
'/posts-admin' => [
'controller' => 'postsAdminController',
'method' => 'index'
],
'/posts-edit' => [
'controller' => 'postsAdminController',
'method' => 'edit'
]
];
if (isset($routes[$pathInfo])) {
$route = $routes[$pathInfo];
$controller = $container->make($route['controller']);
$method = $route['method'];
$controller->$method();
}
?>
PHP Code:
<?php
namespace App\Core;
use PDO;
use Exception;
use App\Post\PostsRepository;
use App\Post\CommentsRepository;
use App\Post\PostsController;
use App\Post\PostsAdminController;
use App\User\UsersRepository;
use App\User\LoginController;
use App\User\LoginService;
class Container
{
private $receipts = [];
private $instances = [];
public function __construct()
{
$this->receipts = [
'postsAdminController' => function() {
return new PostsAdminController(
$this->make('postsRepository'),
$this->make('loginService')
);
},
'loginService' => function() {
return new LoginService(
$this->make('usersRepository')
);
},
'loginController' => function() {
return new LoginController(
$this->make('loginService')
);
},
'postsController' => function () {
return new PostsController(
$this->make('postsRepository'),
$this->make('commentsRepository')
);
},
'postsRepository' => function() {
return new PostsRepository(
$this->make('pdo')
);
},
'commentsRepository' => function() {
return new CommentsRepository(
$this->make('pdo')
);
},
'usersRepository' => function() {
return new UsersRepository(
$this->make('pdo')
);
},
'pdo' => function() {
try {
/*
1. host / server
2. db-name
3. username
4. password
*/
$pdo = new PDO (
'mysql:host=localhost;
dbname=blog;
charset=utf8',
'root',
''
);
}
catch (PDOException $e) {
echo "Connection failed.";
}
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
return $pdo;
}
];
}
public function make($name)
{
if (!empty($this->instances[$name])) {
return $this->instances[$name];
}
if (isset($this->receipts[$name])) {
$this->instances[$name] = $this->receipts[$name]();
}
return $this->instances[$name];
}
}
?>
PHP Code:
<?php
namespace App\Core;
abstract class AbstractController
{
protected function render($view, $params)
{
extract($params);
include __DIR__ . "/../../views/{$view}.php";
}
}
?>
PHP Code:
<?php
namespace App\Core;
use ArrayAccess;
abstract class AbstractModel implements ArrayAccess
{
public function offsetExists($offset)
{
return isset($this->$offset);
}
public function offsetGet($offset)
{
return $this->$offset;
}
public function offsetSet($offset, $value)
{
$this->$offset = $value;
}
public function offsetUnset($offset)
{
unset($this->$offset);
}
}
?>
PHP Code:
<?php
namespace App\Core;
use PDO;
abstract class AbstractRepository
{
protected $pdo;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
abstract public function getTableName();
abstract public function getModelName();
function all()
{
$table = $this->getTableName();
$model = $this->getModelName();
$stmt = $this->pdo->query("SELECT * FROM `$table`");
$posts = $stmt->fetchAll(PDO::FETCH_CLASS, $model);
return $posts;
}
function find($id)
{
$table = $this->getTableName();
$model = $this->getModelName();
$stmt = $this->pdo->prepare("SELECT * FROM `$table` WHERE id = :id");
$stmt->execute(['id' => $id]);
$stmt->setFetchMode(PDO::FETCH_CLASS, $model);
$post = $stmt->fetch(PDO::FETCH_CLASS);
return $post;
}
}
PHP Code:
<?php
namespace App\Post;
use App\Core\AbstractController;
use App\User\LoginService;
class PostsAdminController extends AbstractController
{
public function __construct(
PostsRepository $postsRepository,
LoginService $loginService
)
{
$this->postsRepository = $postsRepository;
$this->loginService = $loginService;
}
public function index()
{
$this->loginService->check();
$all = $this->postsRepository->all();
$this->render("post/admin/index", [
'all' => $all
]);
}
public function edit()
{
$this->loginService->check();
$id = $_GET['id'];
$entry = $this->postsRepository->find($id);
$savedSuccess = false;
if (!empty($_POST['title']) AND !empty($_POST['content']))
{
$entry->title = $_POST['title'];
$entry->content = $_POST['content'];
$this->postsRepository->update($entry);
$savedSuccess = true;
}
$this->render("post/admin/edit", [
'entry' => $entry,
'savedSuccess' => $savedSuccess
]);
}
}
PHP Code:
<?php
namespace App\Post;
use App\Core\AbstractController;
class PostsController extends AbstractController
{
public function __construct(
PostsRepository $postsRepository,
CommentsRepository $commentsRepository
)
{
$this->postsRepository = $postsRepository;
$this->commentsRepository = $commentsRepository;
}
public function index()
{
$posts = $this->postsRepository->all();
$this->render("post/index", [
'posts' => $posts
]);
}
public function show()
{
$id = $_GET['id'];
if (isset($_POST['content'])) {
$content = $_POST['content'];
$this->commentsRepository->insertForPost($id, $content);
}
$post = $this->postsRepository->find($id);
$comments = $this->commentsRepository->allByPost($id);
$this->render("post/show", [
'post' => $post,
'comments' => $comments
]);
}
}
?>
PHP Code:
<?php
namespace App\Post;
use App\Core\AbstractModel;
class PostModel extends AbstractModel
{
public $id;
public $title;
public $content;
}
?>
PHP Code:
<?php
namespace App\Post;
use App\Core\AbstractRepository;
class PostsRepository extends AbstractRepository
{
public function getTableName()
{
return "posts";
}
/*
*
*/
public function getModelName()
{
return "App\\Post\\PostModel";
}
/*
*
*/
public function update(PostModel $model)
{
$table = $this->getTableName();
$stmt = $this->pdo->prepare("UPDATE `{$table}` SET `content` = :content, `title` = :title WHERE `id` = :id");
$stmt->execute([
'id' => $model->id,
'title' => $model->title,
'content' => $model->content
]);
}
}
PHP Code:
<?php
namespace App\Post;
use App\Core\AbstractModel;
class CommentModel extends AbstractModel
{
public $id;
public $content;
public $post_id;
}
?>
PHP Code:
<?php
namespace App\Post;
use PDO;
use App\Core\AbstractRepository;
class CommentsRepository extends AbstractRepository
{
public function getTableName()
{
return "comments";
}
public function getModelName()
{
return "App\\Post\\CommentModel";
}
public function insertForPost($postId, $content)
{
$table = $this->getTableName();
$stmt = $this->pdo->prepare(
"INSERT INTO `$table` (`content`, `post_id`) VALUES (:content, :postId)"
);
$stmt->execute([
'content' => $content,
'postId' => $postId
]);
}
/** returns array of comments
* TODO ficken
* [MENTION=1985011]param[/MENTION] integer $id
* [MENTION=326673]return[/MENTION] array
*/
public function allByPost($id)
{
$table = $this->getTableName();
$model = $this->getModelName();
$stmt = $this->pdo->prepare("SELECT * FROM `$table` WHERE post_id = :id");
$stmt->execute(['id' => $id]);
$comments = $stmt->fetchAll(PDO::FETCH_CLASS, $model);
return $comments;
}
}
?>
PHP Code:
<?php
namespace App\User;
use App\Core\AbstractController;
class LoginController extends AbstractController
{
public function __construct(LoginService $loginService)
{
$this->loginService = $loginService;
}
public function dashboard()
{
$this->loginService->check();
$this->render("user/dashboard", []);
}
public function logout()
{
$this->loginService->logout();
header("Location: login");
}
public function login()
{
$error = null;
if (!empty($_POST['username']) AND !empty($_POST['password']))
{
$username = $_POST['username'];
$password = $_POST['password'];
if ($this->loginService->attempt($username, $password))
{
header("Location: dashboard");
return;
}
else
{
$error = "Das Passwort stimmt nicht!";
}
}
$this->render("user/login", [
'error' => $error
]);
}
}
PHP Code:
<?php
namespace App\User;
class LoginService
{
public function __construct(UsersRepository $usersRepository)
{
$this->usersRepository = $usersRepository;
}
public function check()
{
if (isset($_SESSION['login']))
{
return true;
}
else
{
header("Location: login");
die();
}
}
public function attempt($username, $password)
{
$user = $this->usersRepository->findByUsername($username);
if(empty($user))
{
return false;
}
if (password_verify($password, $user->password))
{
$_SESSION['login'] = $user->username;
session_regenerate_id(true);
return true;
}
else
{
return false;
}
}
public function logout()
{
unset($_SESSION['login']);
session_regenerate_id(true);
}
}
?>
PHP Code:
<?php
namespace App\User;
use App\Core\AbstractModel;
class UserModel extends AbstractModel
{
public $id;
public $username;
public $password;
}
PHP Code:
<?php
namespace App\User;
use App\Core\AbstractRepository;
use PDO;
class UsersRepository extends AbstractRepository
{
public function getModelName()
{
return "App\\User\\UserModel";
}
public function getTableName()
{
return "users";
}
public function findByUsername($username)
{
$table = $this->getTableName();
$model = $this->getModelName();
$stmt = $this->pdo->prepare("SELECT * FROM `$table` WHERE username = :username");
$stmt->execute(['username' => $username]);
$stmt->setFetchMode(PDO::FETCH_CLASS, $model);
$user = $stmt->fetch(PDO::FETCH_CLASS);
return $user;
}
}
?>
HTML Code:
<!DOCTYPE html>
<html lang=de-DE>
<head>
<meta charset="utf-8">
<title>Blog © aiimsh0ckz</title>
</head>
<body>
<a href='index'>Home</a> |
<a href='dashboard'>Dashboard</a> |
<a href='posts-admin'>Controlpanel</a>
<hr />
HTML Code:
<hr />
<h3>2016 © <a href="http://www.elitepvpers.com/forum/members/4390540-aiimsh0ckz.html">aiimsh0ckz</a></h3>
</body>
</html>
PHP Code:
<?php
require(__DIR__ . "/../layout/header.php");
echo "<h1>Index</h1>";
foreach($posts AS $post):
echo "<li>
<a href='post?id={$post->id}'>
";
$title = "{$post->title}";
echo esc($title);
echo "
</a>
</li>";
endforeach;
require(__DIR__ . "/../layout/footer.php");
?>
PHP Code:
<?php
require(__DIR__ . "/../layout/header.php");
echo "<h1>Post</h1>";
echo "<hr />";
echo "<pre>";
echo "<h2>";
echo $post['title'];
echo "</h2>";
echo nl2br($post['content']);
echo "</pre>";
echo "<hr />";
echo "<h3> Comments </h3>";
foreach ($comments AS $comment):
echo "<li>";
echo esc($comment->content);
echo "</li>";
endforeach;
echo "
<hr />
<form method='post' action='post?id=" . $post['id'] . "'>
<textarea name='content'></textarea>
<br />
<input type='submit' value='Kommentar hinzufügen'></input>
</form>
";
require(__DIR__ . "/../layout/footer.php");
?>
PHP Code:
<?php
require(__DIR__ . "/../../layout/header.php");
echo "<h1>Posts verwalten</h1>";
foreach ($all AS $entry):
echo "<li><a href='posts-edit?id=" . esc($entry->id) ."'>" .
esc($entry->title)
. "</li></a>";
endforeach;
require(__DIR__ . "/../../layout/footer.php");
?>
PHP Code:
<?php
require(__DIR__ . "/../../layout/header.php");
echo "<h1>Post editieren</h1>";
if (!empty($savedSuccess))
{
echo "<script>alert('Der Post wurde erfolgreich gespeichert')</script>";
}
echo "
<form method='post' action='posts-edit?id=" . esc($entry->id) ."'>
<input type='text' name='title' value='" . esc($entry->title) ."'/>
<br /><br/>
<textarea name='content'>" . esc($entry->content) . "</textarea>
<input type='submit' value='Post speichern!' />
</form>
";
require(__DIR__ . "/../../layout/footer.php");
?>
PHP Code:
<?php
require(__DIR__ . "/../layout/header.php");
echo "<h1>Dashboard</h1>";
echo "
<li><a href='posts-admin'>Posts verwalten</a></li>
<li><a href='logout'>Logout</a></li>
";
require(__DIR__ . "/../layout/footer.php");
?>
PHP Code:
<?php
require(__DIR__ . "/../layout/header.php");
if ( !empty($error))
{
echo "<p> $error </p>";
}
echo "
<form method='POST' method='login'>
<input type='text' name='username' />
<input type='password' name='password' />
<input type='submit' value='Einloggen' />
</form>
";
require(__DIR__ . "/../layout/footer.php");
?>
•-)•–––––––––––––––––––––––––––––––––––––––––––––––– ––––––––––––––––––––––––––––––––•(-•
5. Schlusswort:
Quote:
|
„I code as I fuck: Quick, messy and without comments. Why without comments? It was hard to code, so it should be hard to understand aswell!“
|
Der Blog ist noch in der „Beta-Phase“. Da kommen noch einige Funktionen dazu. Falls ihr selbst Funktionen dazu wollt, fragt einfach kurz nach und ich schreib sie (ggf. gegen etwas Kleingold) für euch! Hoffe das ganze gefällt euch und ihr findet zurecht. Falls nicht, helfe ich euch gerne per TeamViewer bei der Einrichtung. :) Natürlich findet ihr das ganze Projekt auch zum Download im Anhang ([Only registered and activated users can see links. Click Here To Register...] für die ganzen "Mimimi"-Kiddos).
Greez,
aiimsh0ckz.